EarTrumpet 更新日志 EarTrumpet:Windows 开源第三方高级音量混音器;C# / WPF,基于Windows Core Audio(WASAPI / MMDevice)COM 接口;替代增强系统sndvol.exe音量合成器;托盘常驻,实现按应用会话音量调节、会话迁移、全局热键、鼠标滚轮音量、音频峰值表、多语言、明暗主题等能力

EarTrumpet 更新日志

EarTrumpet/CHANGELOG.md at master · File-New-Project/EarTrumpet · GitHub

EarTrumpet

PixPin_2026-09-11_10-24-26PixPin_2026-09-11_10-25-36

EarTrumpet‑Next 全新架构设计(Windows 现代高级音频混音器)

目标:保留 EarTrumpet 全部核心能力,解决原版 WPF / RawInput / COM 互操作

历史痛点;适配 Win11 22H2‑26H2,兼容 Win10 21H2+;同时支持 MSIX 打包 + 便携版本;替换老旧组件、修复 DPI / 渲染 / 输入时序 bug、提升稳定性、降低 CPU/GPU 占用、扩展现代音频能力。

原版痛点汇总:

  1. WPF 渲染:高 DPI、亚克力 Acrylic、Flyout 弹出位置、软件渲染模式 CPU 开销;
  2. 手写 COM 互操作,大量样板代码,内存泄漏风险;
  3. RawInput 全局滚轮自己封装,全屏游戏、虚拟机、鼠标热插拔处理不完善;
  4. 会话枚举异步事件处理复杂,COM 对象生命周期管理易错,容易空引用崩溃;
  5. 配置两套存储分支(MSIX Windows.Storage/ 便携版注册表)维护成本高;
  6. UI 与业务强耦合,单元测试困难;
  7. 缺少现代音频能力:空间音频、音频端点效果、多流、AIGC 音频辅助、会话持久化配置。

技术栈选型

  • 应用框架:WinUI 3(Windows App SDK 1.6+) 替代 WPF
  • 语言:C# 12 /.NET 8(长期支持)
  • COM 互操作:CsWin32 源码生成器,抛弃手写 Interop,编译期生成 MMDevice / CoreAudio 全部 COM 接口
  • 输入层:Windows App SDK Input API + 可选 RawInput 封装库;热键使用 RegisterHotKey + 现代输入事件;
  • IOC / 依赖注入:Microsoft.Extensions.DependencyInjection;分层架构;
  • 配置层:System.Text.Json,统一配置文件;MSIX 使用ApplicationData;便携版使用同目录 json 配置,消除注册表;
  • 日志诊断:Microsoft.Extensions.Logging + ETW 事件跟踪;
  • UI 组件:WinUI3 内置控件 + 社区 Toolkit;支持 Mica、Mica‑Alt、Acrylic,每显示器 DPI 感知 Per‑Monitor‑V2;
  • 部署:MSIX (MSIX‑Packaged) + 非打包 Unpackaged 便携双模式;支持 winget /chocolatey;
  • 跨进程无驱动;依旧用户态应用,不安装服务、不安装内核驱动,复用系统 Windows Core Audio (audiosrv),不替换系统音频栈。

整体分层架构(自上而下)

┌─────────────────────────────────────┐
│  UI表现层 WinUI3                     │
│  托盘图标、Flyout弹出面板、主混音窗口、设置页面、峰值可视化 │
├─────────────────────────────────────┤
│  ViewModel层 MVVM CommunityToolkit.Mvvm │
│  设备集合、音频会话集合、热键配置、滚轮配置、主题状态 │
├─────────────────────────────────────┤
│  业务领域层 Domain                    │
│  AudioDeviceService、AudioSessionService、HotkeyService、MouseWheelService、NotificationService │
│  核心业务逻辑,完全与UI解耦,可以单元测试 │
├─────────────────────────────────────┤
│  抽象接口契约层 Abstractions          │
│  IAudioDeviceManager / IAudioSessionManager / IHotkeyManager │
├─────────────────────────────────────┤
│ 系统适配器层 Adapter(封装系统API)    │
│ CoreAudioAdapter(CsWin32生成MMDevice/WASAPI COM)
│ Win32InputAdapter、ShellTrayAdapter、StorageAdapter
└─────────────────────────────────────┐
          Windows OS底层系统API
          mmdevapi.dll / audioses.dll / user32.dll / shell32.dll

关键架构原则:

  1. UI 完全与音频业务解耦;业务层不引用任何 WinUI/WPF 控件;
  2. 所有系统 API 通过适配器抽象,便于单元测试 Mock;
  3. COM 对象生命周期统一托管,避免泄漏;
  4. 异步事件队列化,解决设备插拔、会话创建销毁的时序竞态(原版大量崩溃来源)。

一、底层原理(业务不变,实现全部重写)

业务本质不变:不接管音频数据流,只控制 WASAPI 会话元数据:音量、静音、路由迁移、读取峰值电平;混音全部交给 audiosrv /audiodg。

  1. 通过 IMMDeviceEnumerator 枚举音频端点,监听 IMMNotificationClient 设备插拔、默认设备变更;
  2. 通过 IAudioSessionManager2 枚举每个设备的音频会话 IAudioSessionControl2;获取 PID、AppUserModelId;
  3. ISimpleAudioVolume 读写会话音量、静音;
  4. IAudioEndpointVolume 设备主音量;
  5. IAudioMeterInformation 获取峰值电平,用于 UI 柱状可视化;
  6. 会话迁移:调用系统策略接口实现应用会话切换输出设备;
  7. 输入:热键、鼠标滚轮两种模式(托盘图标上方 / RawInput 全局模式);
  8. 托盘常驻后台;单实例;开机自启。

重大改进点对比原版 EarTrumpet

模块 原版 EarTrumpet (WPF) EarTrumpet‑Next(WinUI3+.NET8+CsWin32)
COM 互操作 手写 C# Interop 定义,容易写错 IID、Guid,内存泄漏风险 CsWin32 源码生成,编译期校验全部 COM 接口、GUID、结构体;无需手写
UI 渲染 WPF,Acrylic 各种 bug,软件渲染 CPU 高,Flyout 位置计算复杂 WinUI3 原生 Mica/Acrylic;系统原生 Flyout 弹窗;Per‑Monitor‑V2 DPI 原生支持
配置存储 MSIX 用 Windows.Storage;便携版 HKCU 注册表,两套逻辑 统一 JSON 配置;MSIX 映射 ApplicationData;便携版程序目录 json;一套业务逻辑
输入处理 手写 RawInput,热键自己维护窗口消息循环 封装 Win32 输入适配器;RawInput 做健壮封装,自动处理鼠标热插拔、虚拟机降级、全屏独占检测;热键使用 RegisterHotKey,异常捕获
对象生命周期 COM 对象手动 Release,容易遗忘造成句柄泄漏 COM 包装类实现 IDisposable;using 模式;弱事件模式,防止事件订阅泄漏
事件时序 COM 回调直接切 UI 线程,容易出现竞态空引用 全部系统回调进入后台事件队列;节流、去抖动;再调度到 UI 线程;防止快速插拔设备崩溃
可测试性 UI 与业务混杂,很难单元测试 业务层完全抽象,可以 Mock 系统适配器做单元测试

二、依赖文件清单

系统原生依赖(运行环境)

系统 DLL 用途
mmdevapi.dll MMDevice 音频设备枚举 COM
audioses.dll WASAPI 音频会话管理
user32.dll 热键、RawInput、窗口、托盘 Shell 通知图标
shell32.dll 托盘通知图标、AppUserModelId、应用图标解析
dwmapi.dll Mica/Acrylic 合成效果

托管技术栈依赖(NuGet)

  1. WindowsAppSDK 1.6+:WinUI3 控件、窗口管理、托盘通知图标 API、应用生命周期、打包 Unpackaged 支持
  2. CsWin32:编译期生成全部 Win32 & Core‑Audio COM 接口,无运行时 dll
  3. CommunityToolkit.Mvvm:MVVM,ObservableObject,RelayCommand
  4. Microsoft.Extensions.DependencyInjection:DI 容器,分层注入
  5. Microsoft.Extensions.Logging:日志;输出到文件 + ETW 事件,方便排错
  6. System.Text.Json:配置序列化,抛弃注册表存储配置

无 WPF 依赖;不再依赖旧版 WPF 渲染栈。

程序自身组件划分(项目拆分)

  1. EarTrumpetNext.Abstractions:接口契约;不依赖任何系统 API
  2. EarTrumpetNext.Domain:业务服务,音频设备、会话、热键、滚轮逻辑,可单元测试
  3. EarTrumpetNext.Adapters.Win32:系统适配器,CsWin32 实现 CoreAudio、输入、shell 托盘、存储
  4. EarTrumpetNext.UI.WinUI:WinUI3 UI 层,ViewModel、窗口、Flyout、设置页面
  5. EarTrumpetNext.Host:入口主程序,DI 组装,单实例检测,应用生命周期管理

三、依赖关系

  1. 系统服务依赖(不变)
    • Windows Audio audiosrv;Windows Audio Endpoint Builder;服务停止则全部音频 API 失效,程序优雅降级提示。
  2. Shell 依赖
    • 托盘图标使用 Windows App SDK 托盘 API,相比原版自己创建隐藏 HWND 更加稳定;explorer.exe崩溃重启时,SDK 自动重建托盘图标,不需要手写恢复逻辑。
  3. 权限
    • 普通用户权限运行,不需要管理员;MSIX 打包版本需要 runFullTrust受限能力,才能读取跨进程音频会话。
  4. 输入依赖边界
    • 全局滚轮 RawInput 模式:适配器层增加探测逻辑:虚拟机 / 远程桌面环境自动探测,注册失败自动降级为「仅图标上方滚轮」;鼠标热插拔自动重新注册 RawInput。
  5. 生命周期依赖
    • 单实例检测;第二实例直接通知主进程弹出 Flyout,直接退出。
  6. 配置:
    • 打包版:配置存于系统应用隔离存储;
    • 非打包便携版:程序同目录 config.json,用户数据目录缓存图标缓存。

四、配套链设计

  1. 托盘配套:Windows App SDK 原生托盘通知图标;支持主题感知图标(深色 / 浅色任务栏自动切换图标);右键上下文菜单。
  2. 热键配套
    • 全局热键使用系统RegisterHotKey;热键冲突自动捕获提示;支持 Win/Ctrl/Shift/Alt 组合;
    • 增加:热键可以绑定到「指定设备」、「指定应用会话」音量。
  3. 鼠标滚轮双模式配套(重点改进原版缺陷)
    • 模式 1:仅托盘图标上方响应滚轮;
    • 模式 2:全局 RawInput 滚轮;增加可选修饰键锁(必须按住 Win/Ctrl 才响应全局滚轮,规避误滚动同时滚动页面 + 调音量);
    • 适配器内置:虚拟机、RDP 远程桌面、全屏独占游戏检测;RawInput 注册失败自动降级;鼠标设备热插拔自动重注册;异常捕获,不会造成程序崩溃。
  4. 可视化配套
    • 音频峰值表:WinUI3 Composition API 硬件加速绘制柱状图;不再使用 CPU 绘制;降低功耗。
  5. 本地化配套
    • 使用 Windows App SDK 资源管理器;多语言、RTL 从右向左布局原生支持;
  6. 部署配套
    • MSIX 打包版本;Unpackaged 便携版本;winget manifest;
    • 开机自启:打包版使用 StartupTask;便携版使用注册表 Run,UI 提供开关。
  7. 诊断排错配套(原版薄弱点)
    • ETW Trace 事件;日志文件;设置页面内置「诊断信息导出」一键导出音频设备列表、会话列表、配置、错误日志,便于 issue 排错;
  8. 系统互操作配套
    • UI 提供跳转系统设置:系统音量合成器、应用音量首选项、声音控制面板;保留和系统原生工具共存;
  9. 扩展预留配套
    • 插件接口预留:允许第三方插件扩展会话规则、音量预设。

五、完整逻辑链路

链路 1:程序启动初始化

EarTrumpet‑Next Host入口
  →单实例检测;存在其他实例,发送通知唤醒主进程,退出
  →DI容器组装:注入抽象接口 + Win32适配器实现
  →加载配置JSON;配置损坏自动恢复默认配置
  →启动 AudioDeviceService:调用IMMDeviceEnumerator;注册IMMNotificationClient设备变更回调
  →启动 AudioSessionService:监听会话创建/销毁/音量变更事件
  →启动 HotkeyService:加载热键配置,注册系统全局热键
  →启动 MouseWheelService:读取滚轮模式配置,初始化对应输入监听
  →初始化Windows App SDK托盘图标;后台常驻;不阻塞主线程
  →后台事件队列:所有COM系统回调先进入队列,做节流去抖动,再调度UI线程更新ViewModel集合
  →UI层WinUI3 Flyout预初始化,等待托盘点击触发弹出

重点优化:原版 COM 回调直接抛到 UI 线程,设备快速插拔会大量并发事件,造成空引用崩溃;新版本全部进入后台事件队列,做防抖合并,再更新 UI。

链路 2:调节会话音量(滑块 / 热键 / 滚轮)

UI操作 → ViewModel命令 → 调用Domain层IAudioSessionService
  →适配器层CoreAudioAdapter调用ISimpleAudioVolume::SetMasterVolume
  →audiosrv音频服务应用音量参数
  →系统COM事件回调音量变更 → 进入事件队列 → UI刷新滑块、峰值电平表

链路 3:音频会话迁移(应用切换输出设备)

用户UI操作会话迁移
  →Domain层调用系统音频策略API,执行会话端点重定向
  →audiosrv完成会话路由
  →收到会话状态变更事件;刷新UI会话所属设备

链路 4:鼠标滚轮两种模式执行链路(适配器层封装)

鼠标硬件事件到达Win32InputAdapter

if(模式=托盘图标上方响应)
  →只处理托盘图标区域鼠标消息;光标不在图标直接丢弃事件

if(模式=全局RawInput模式)
  →WM_INPUT原始输入事件;适配器自动判断运行环境:虚拟机/RDP直接降级;
  →解析滚轮增量;判断修饰键条件;
  →条件满足才调用音量服务;原始消息不吞噬继续流转给前台应用。

链路 5:耳机 / USB 声卡热插拔

硬件插拔 → IMMNotificationClient COM回调
  →事件投递后台队列,防抖合并短时间多次插拔事件
  →AudioDeviceService刷新设备集合;重新枚举全部设备上音频会话
  →通知ViewModel更新UI设备下拉与会话列表

六、边界约束(充分规避原版历史坑点)

1. 系统 API 硬边界(无法绕过)

  1. WASAPI 独占模式应用:会话迁移、部分元数据读取失败;UI 做友好提示,不崩溃;
  2. DRM 受保护音频会话:无法读取部分会话信息,做降级显示;
  3. Windows 本身不持久保存应用会话音量;程序可以新增扩展能力:增加自定义规则,按进程 / AppUserModelId 记忆预设音量(软件层记忆,不是系统能力)。

2. 输入层边界

  1. RawInput 全局滚轮:全屏独占游戏硬件抢占鼠标时,RawInput 事件收不到,适配器探测,UI 给出提示;不会崩溃;
  2. 鼠标热插拔:适配器自动重新注册 RawInput;
  3. 热键冲突:注册热键失败捕获异常,UI 弹窗告知用户快捷键被其他软件占用。

3. UI 渲染边界

  1. WinUI3 原生 Per‑Monitor‑V2 DPI;Flyout 弹窗由系统管理,不再手写坐标计算,彻底解决原版弹出越界 bug;
  2. Mica/Acrylic 效果不可用时(远程桌面、基础主题)自动降级为纯色背景。

4. COM 对象生命周期边界

  1. 全部 CoreAudio COM 对象包装实现IDisposable;离开作用域自动 Release;using 模式;
  2. 弱事件模式订阅 COM 回调,防止对象无法 GC 内存泄漏;
  3. 程序退出时,顺序释放 RawInput、热键、COM 对象、托盘资源;异常崩溃时操作系统自动清理注册项,不留残留。

5. 部署运行边界

  1. 最低支持 Windows10 21H2,Windows11 全版本;不支持 Win7;
  2. Unpackaged 便携版本自带 Windows App SDK 依赖;不需要商店安装组件。

七、新增高阶能力(原版缺失)

  1. 会话音量预设 / 配置文件:保存一套多应用音量快照,一键加载;
  2. 软件层记忆应用默认音量(进程 / AppUserModelId 匹配),启动应用自动恢复音量;
  3. 空间音频端点信息展示;
  4. 音量步进曲线可自定义;
  5. 会话分组规则自定义;
  6. 一键导出诊断报告,方便 GitHub issue 排错;
  7. 支持多输出设备同时监听、快速切换默认设备热键。

Mermaid 整体架构时序(简化)

sequenceDiagram
    participant OS as Windows OS(MMDevice/Audiosrv)
    participant Adapter as Win32适配器层(CsWin32)
    participant Domain as Domain业务服务
    participant VM as ViewModel(MVVM)
    participant UI as WinUI3 UI /托盘Flyout

    Note over OS,UI:程序启动
    OS-->>Adapter:COM设备与会话回调
    Adapter->>Domain:事件投递后台队列(防抖合并)
    Domain->>VM:更新可观察集合
    VM->>UI:数据绑定刷新UI;托盘图标初始化

    Note over OS,UI:用户调节音量
    UI->>VM:UI交互命令
    VM->>Domain:调用音频会话服务
    Domain->>Adapter:调用Core‑Audio COM设置音量
    Adapter->>OS:系统音频服务生效
    OS-->>Adapter:音量变更回调事件
    Adapter->>Domain:进入事件队列
    Domain->>VM:更新会话状态
    VM->>UI:滑块、峰值表刷新

 

EarTrumpet 深度解构分析

项目仓库:https://github.com/File‑New‑Project/EarTrumpet/blob/master/CHANGELOG.md

EarTrumpet:Windows 开源第三方高级音量混音器;C# / WPF,基于Windows Core Audio(WASAPI / MMDevice)COM 接口;替代增强系统sndvol.exe音量合成器;托盘常驻,实现按应用会话音量调节、会话迁移、全局热键、鼠标滚轮音量、音频峰值表、多语言、明暗主题等能力。

分析框架:底层原理|依赖文件|依赖关系|配套链|逻辑链路|边界;结合 CHANGELOG 历史 bug 与修复记录。

一、底层原理

  1. 整体架构分层
    • 底层 COM 互操作层 (P‑Invoke):封装 Windows Core Audio COM 接口,不直接操作音频数据流,只做会话元数据、音量、静音、设备路由的控制,音频混音仍然交给系统 audiosrv/audiodg 服务完成。
    • 业务模型层:AudioDeviceManager设备管理器、音频会话生命周期管理器;维护进程PID‑AppUserModelId‑会话‑图标‑显示名称映射;监听设备插拔、会话创建 / 销毁、音量变化事件CSDN博...。
    • UI 表现层 (WPF):托盘图标、弹出 Flyout 悬浮面板、主混音窗口、设置窗口;支持 Acrylic 亚克力、明暗主题、高对比度、每显示器 DPI 感知;2.3.0 版本改为软件渲染,规避 GPU 功耗问题。
    • 持久化层:打包版使用Windows.Storage;非打包版使用注册表存储配置;存储热键、滚轮行为、对数音量、界面状态、崩溃上报开关等配置GitHub。
    • 输入处理层:RawInput 全局热键钩子、托盘图标鼠标滚轮处理;支持 Win 修饰键、多组全局快捷键;区分 “图标上方滚轮” 与 “全局任意位置滚轮” 两种模式(2.3.0 新增)。
  2. 核心 Windows COM 接口(底层能力来源)

    COM 接口 作用
    IMMDeviceEnumerator / IMMNotificationClient 枚举音频端点;监听耳机 / 声卡插拔、默认设备变更事件博客园
    IAudioSessionManager2 枚举每个设备上全部音频会话IAudioSessionControl2;获取 PID、会话状态博客园
    ISimpleAudioVolume 设置 / 读取单个应用会话音量、静音状态(0.0‑1.0 浮点)CSDN博...
    IAudioEndpointVolume 设备主音量、设备静音控制
    IAudioMeterInformation 读取会话音频峰值电平,做 UI 音量柱状可视化CSDN博...
    PolicyConfigClient 设置系统默认音频输出设备CSDN博...

关键:EarTrumpet不接管音频流混音;只是控制系统已有的 WASAPI 会话参数;音频混合、硬件交互依然由 Windows 音频服务完成。

  1. 会话分组逻辑 早期版本按可执行文件名分组;2.0.8.0 改为按应用安装路径分组,解决多进程同一个 App 会话拆分混乱问题。

UWP/Store 应用依靠AppUserModelID识别;Win32 依靠 PID+exe 路径。

  1. 进程模型
  • 单实例应用;托盘常驻后台;Flyout 悬浮面板启动即预创建等待弹出;混音窗口、设置窗口按需创建。
  • MSIX 打包版需要受限能力runFullTrust,才能跨进程读取其他进程音频会话信息;支持开机自启windows.startupTask。

二、依赖文件

系统原生依赖(Windows 音频栈)

系统文件 作用
mmdevapi.dll MMDevice 音频设备枚举 COM 组件,核心底层依赖博客园
audioses.dll WASAPI 音频会话管理 COM 实现
audioeng.dll 音频引擎;audiodg.exe 进程内执行音频处理
user32.dll RawInput 全局热键、鼠标消息、托盘通知图标 API
shell32.dll 获取应用图标、AppUserModelID、shell 信息
uxtheme.dll、dwmapi.dll DWM 窗口合成、亚克力 Acrylic、主题色彩读取

.NET/ WPF 运行时依赖

  • .NET(早期.NET Framework,新版.NET6+);WPF 桌面运行库;
  • MSIX 打包:vcruntime VC++ 运行库(CHANGELOG 记录:2.3.0 修复 AppInstaller 安装失败,缺少 VC++ lib 场景)。

EarTrumpet 自身组件

  1. EarTrumpet.exe主可执行(WPF 应用);
  2. 资源组件:多语言本地化资源(Crowdin 翻译;大量版本持续修复各语种翻译);图标资源;

无独立后台服务、无驱动;全部在用户态应用进程内运行。

三、依赖关系

1. Windows 系统服务依赖

  1. Windows Audio(audiosrv):必须运行;服务停止,则全部 Core‑Audio COM 接口失效,EarTrumpet 完全不可用博客园。
  2. Windows Audio Endpoint Builder(AudioEndpointBuilder):负责音频端点、插孔检测;停止后设备枚举为空。

EarTrumpet 只是客户端,服务崩溃则程序只能显示空白 / 无设备。

2. 配置持久化依赖

  1. MSIX/Store 打包版本:Windows.Storage应用数据存储;CHANGELOG 提到该 API 存在一定概率存储失败的遥测统计问题GitHub。
  2. 非打包便携版本:注册表;路径:HKCU\Software\EarTrumpet;保存热键、界面偏好、开关选项。

3. COM 与权限依赖

  1. MSIX 包需要声明受限能力 runFullTrust,否则无法跨进程访问第三方进程音频会话信息。
  2. 用户权限:普通用户权限即可,不需要管理员;音频会话 API 普通用户有权限读取与修改自己可见的音频会话。

4. Shell / 任务栏依赖

  • 依赖explorer.exe资源管理器托盘通知图标 API;

CHANGELOG:2.1.4 修复 Shell 崩溃重启后托盘图标消失问题;2.1.2 修复图标句柄泄漏造成崩溃;2.1.9 修复 ShyTaskbar (Win11 隐藏任务栏) 触摸菜单行为异常。

5. UI 渲染依赖

  • DWM 桌面窗口管理器;负责亚克力、窗口位置、透明效果;

2.2.1 版本对 Acrylic 减速问题增加 workaround;2.3.0 强制软件渲染,避免占用 GPU 功耗,规避 GPU 相关渲染 bug。

四、配套链

  1. 底层系统配套:Windows Core Audio 栈(audiosrv、audiodg);系统自带sndvol.exe仍然共存,二者调用同一套 COM 接口;EarTrumpet 只是 UI 层替代,不替换系统音频服务。
  2. 输入配套:Windows RawInput API 实现全局热键;支持 Win 修饰键快捷键(2.3.0 新增);鼠标滚轮消息处理。
  3. 本地化配套:Crowdin 多语言翻译体系;支持 RTL 从右向左书写系统(阿拉伯语等,2.1.0 修复 RTL 布局)。
  4. 部署配套
    • Microsoft Store MSIX 打包;
    • AppInstaller .appxinstaller;Chocolatey 包管理;
    • 开机自启:MSIX 使用startupTask能力;便携版使用注册表 Run。
  5. 遥测与崩溃配套:可开关崩溃上报(2.1.6 增加开关);收集存储失败、会话枚举异常诊断信息。
  6. 互补系统入口:上下文菜单保留跳转系统原生「应用音量和设备首选项」「音量混合器」(2.3.0 增加旧版快捷入口)。

五、完整逻辑链路

链路 1:程序启动‑初始化链路

EarTrumpet.exe 启动
  → 单实例检测;多实例直接退出
  → 读取配置(MSIX用Windows.Storage / 便携版读注册表)
  → 初始化AudioDeviceManager:调用IMMDeviceEnumerator
    → 注册IMMNotificationClient监听设备插拔、默认设备变更
  → 初始化音频会话监听:IAudioSessionManager2
  → 预创建Flyout弹出面板(不显示,待命)
  → 创建托盘通知区图标;注册鼠标、滚轮、右键菜单事件
  → 初始化RawInput全局热键钩子;加载用户热键配置
  → 读取系统主题/DWM设置,初始化WPF UI颜色、高对比度、DPI缩放
  → 后台循环枚举各设备音频会话:
    → 获取PID,读取图标、AppUserModelId、显示名称;做会话分组
    → 读取ISimpleAudioVolume音量、静音;IAudioMeterInformation电平
    → 更新UI绑定集合;会话销毁/新建实时更新集合

链路 2:用户调节音量(鼠标滑块 / 滚轮 / 热键)

用户操作UI滑块 / 鼠标滚轮 / 全局热键
  → 业务层定位目标音频会话 IAudioSessionControl2
    → 调用 ISimpleAudioVolume::SetMasterVolume / SetMute
  → Windows audiosrv/audioeng 接收设置,生效到音频会话
  → COM事件回调通知EarTrumpet;更新UI滑块位置、电平表

链路 3:音频会话迁移(把应用切换到别的声卡输出,EarTrumpet 标志性功能)

用户拖拽App会话到另一台音频设备
  → 调用Core‑Audio会话迁移API
  → audiosrv服务执行WASAPI会话端点重定向
  → 应用音频流路由到目标设备;EarTrumpet刷新会话列表UI

注意:部分独占模式 WASAPI 应用不支持会话迁移,属于系统 API 边界限制,不是程序 bug。

链路 4:设备热插拔事件

耳机/USB声卡插拔 → MMDevice触发IMMNotificationClient回调
  → EarTrumpet接收回调;重新枚举全部音频端点设备
  → 更新设备下拉列表UI;重建对应设备的音频会话枚举

六、边界(约束、坑点,大量来自 CHANGELOG 历史故障)

1. API 与音频会话边界(系统硬限制,EarTrumpet 无法绕过)

  1. WASAPI 独占模式 (Exclusive‑Mode):部分专业音频软件开启独占,会话迁移会失效;部分会话元数据获取失败。
  2. 系统合成器会话、受保护 DRM 音频会话:部分元数据、图标读取失败;CHANGELOG 提到 Netflix 受保护媒体早期版本识别问题(1.2.0)。
  3. 音频会话生命周期:会话播放结束后系统立刻销毁会话对象;EarTrumpet 无法保留已关闭应用的音量记忆(系统不持久保存每 App 音量,Windows 只保存当前活跃会话状态)。
  4. 部分虚拟音频设备、驱动实现不规范,返回异常会话信息,造成 UI 异常、崩溃。

2. UI/DPI/Shell 边界

  1. 多显示器、每显示器 DPI 感知:早期版本 Flyout 弹出到屏幕工作区之外(1.3.1 / 2.1.9 大量修复弹出位置越界);高 DPI 托盘图标模糊(2.0.7 修复)。
  2. 任务栏自动隐藏、ShyTaskbar (Win11 新隐藏任务栏) 会改变窗口可用区域,造成 Flyout 高度异常、触摸菜单异常(2.1.10、2.2.1 修复)。
  3. Explorer Shell 崩溃重启:托盘图标句柄会丢失;2.1.4 增加处理,但依然存在恢复时序窗口。
  4. Acrylic 亚克力效果依赖 DWM;部分 Windows 版本存在 Acrylic 性能卡顿,程序内置 workaround 开关(2.2.1)。
  5. 2.3.0 改为软件渲染,规避 GPU 占用,但会轻微增加 CPU 渲染开销。

3. 热键与鼠标滚轮边界

  1. 全局 RawInput 热键在全屏独占游戏下有可能被游戏输入钩子抢占,热键失效;
  2. 鼠标滚轮:VR / 虚拟化场景会收到异常滚轮消息,造成音量乱跳;2.2.2 修复该场景误触发问题。
  3. 鼠标滚轮两种模式:仅托盘图标上方 / 全局任意位置滚动(2.3.0 可开关),全局模式会接收全部鼠标滚轮消息,部分软件交互会冲突。

4. 持久化存储边界

  1. MSIX 打包版依赖Windows.Storage,存在偶发写入失败;非打包版本依赖注册表权限;
  2. 配置只保存EarTrumpet 自身设置;不保存各个应用的音量数值,应用音量存储在 Windows 音频服务内部,重启应用后由系统处理。

5. 图标、本地化边界

  1. UWP/MS‑Store 应用图标提取逻辑复杂;早期版本打包桌面应用图标缺失(2.1.8 修复 Microsoft Flight Simulator 图标);libmpv 系列应用图标异常(2.1.6 修复 Plex)。
  2. 非英语系统、RTL 阿拉伯系布局存在大量 UIbug,历史版本持续迭代修复。
  3. 系统字体损坏会造成程序启动崩溃;2.1.3 增加字体损坏帮助对话框提示。

6. 崩溃与异常边界(CHANGELOG 历史高频故障点)

  1. COM 对象泄漏、句柄泄漏:早期版本图标句柄泄漏、热键未反注册,程序长期运行后崩溃(2.1.2 修复)。
  2. 设备快速插拔,COM 回调异步时序问题,空引用崩溃(2.0.1 修复设备快速增删崩溃)。
  3. 无任何音频播放设备时,空设备集合,早期版本空引用崩溃(2.0.4 修复)。
  4. 多进程同一个应用产生多个音频会话,枚举逻辑异常;历史版本多次修复多‑session 场景。

7. 安装运行边界

  1. 最低 Windows 版本限制;不支持 Win7;仅 Win10 1709 以后;
  2. MSIX 安装依赖 VC++ 运行库;缺失会安装失败(2.3.0 修复)。

Mermaid 简化时序

sequenceDiagram
    participant ET as EarTrumpet.exe(WPF)
    participant Shell as explorer.exe
    participant CA as Windows Core‑Audio COM(mmdevapi.dll)
    participant Svc as audiosrv 音频服务

    Note over ET: 程序启动
    ET->>CA: IMMDeviceEnumerator 枚举音频设备
    CA->>ET: 返回设备列表;注册设备变更回调
    ET->>CA: IAudioSessionManager2 枚举会话
    CA->>Svc: 查询活跃WASAPI会话
    Svc-->>CA: 返回会话PID/音量/状态
    CA-->>ET: 会话元数据集合
    ET->>ET: PID→图标、应用名称映射,UI绑定;托盘图标初始化

    Note over ET: 用户拖动滑块调节音量
    ET->>CA: ISimpleAudioVolume::SetMasterVolume
    CA->>Svc: 更新音频会话音量参数
    Svc-->>CA: 设置完成,事件回调通知
    CA-->>ET: 音量变更事件
    ET->>ET: 更新UI滑块、电平可视化

    Note over ET: 耳机热插拔
    Svc->>CA: 设备状态改变触发IMMNotificationClient
    CA-->>ET: 回调设备变更通知
    ET->>CA: 重新枚举设备与会话
    ET->>ET: 刷新UI设备列表与会话面板

EarTrumpet:「图标上方滚轮」VS「全局任意位置滚轮」模式完整解构

来源:EarTrumpet 2.3.0 新增双模式,基于 Windows RawInput + 托盘窗口消息循环;用于鼠标滚轮调节音量。

分析框架:底层原理|依赖文件|依赖关系|配套链|逻辑链路|边界

一、底层原理总览

Windows 鼠标滚轮消息WM_MOUSEWHEEL有两种送达路径:

  1. 消息路由 A(窗口消息):滚轮消息发送给鼠标光标当前悬停的窗口句柄 HWND。
  2. 消息路由 B(RawInput 原始输入):操作系统把硬件原始输入事件直接投递到注册过 RawInput 的进程,不受鼠标光标在哪、哪个窗口激活影响。

EarTrumpet 两种模式本质就是两种消息捕获策略:

  • 图标上方滚轮(托盘区域模式):只接收托盘隐藏小窗口的滚轮消息;只有鼠标停留在托盘 EarTrumpet 图标上滚动,才响应调音量。依靠托盘通知图标绑定的隐藏 HWND 接收WM_MOUSEWHEEL。
  • 全局任意位置滚轮(RawInput 全局模式):程序注册RID_INPUT鼠标 RawInput 设备;无论鼠标在屏幕任何位置、哪个窗口上面滚动,硬件滚轮事件都会进入 EarTrumpet 进程,内部再做条件过滤(是否按下修饰键等),触发音量增减。

关键区分:

  • 托盘图标模式:窗口消息机制,不抢占硬件输入流;光标不在图标上,滚轮消息交给当前应用程序。
  • 全局滚轮模式:RawInput 原始输入捕获,硬件滚轮事件先拷贝一份给到 EarTrumpet;原始消息继续流向目标窗口,EarTrumpet 只做读取,不吞噬滚轮消息(默认配置)。

二、依赖文件

组件 文件 作用
Win32 输入 API user32.dll RegisterRawInputDevices、GetRawInputData、DefWindowProc;WM_MOUSEWHEEL消息定义;托盘通知图标 API
Shell 托盘 shell32.dll Shell_NotifyIcon托盘图标管理,创建托盘图标对应的隐藏消息窗口 HWND
WPF 互操作 PresentationCore.dll WPF HwndSource,创建隐藏消息窗口,接入 Win32 消息循环
EarTrumpet 内部 MouseWheelManager.cs 两种模式的业务分发、滚轮步长换算、修饰键判断、音量转换逻辑

两种模式共用同一套音量控制底层:Core‑Audio COM 接口 ISimpleAudioVolume。

三、依赖关系

3.1 图标上方滚轮(托盘图标模式)

  1. 必须依赖托盘通知图标有效:依赖explorer.exe资源管理器;Shell 崩溃重启后托盘 HWND 重建,需要重新绑定消息。
  2. 消息来源:Shell 把托盘图标区域的鼠标事件转发给 EarTrumpet 的隐藏消息窗口 HWND。
  3. 不需要注册 RawInput;不占用全局输入注册项。
  4. 权限:普通用户权限,无需管理员。
  5. 触发前置条件:鼠标光标坐标落在托盘图标矩形区域内,才会向该隐藏 HWND 发送WM_MOUSEWHEEL。

3.2 全局任意位置滚轮(RawInput 模式)

  1. 依赖user32.dll RawInput 子系统;系统输入服务正常运行。
  2. 进程启动时调用RegisterRawInputDevices注册鼠标设备,接收原始 HID 鼠标报告。
  3. 不依赖托盘窗口,不依赖鼠标光标位置;只要鼠标硬件产生滚轮旋转 HID 事件,就投递 RawInput 消息到 EarTrumpet 消息循环。
  4. 配置持久化:保存到 HKCU\Software\EarTrumpet(便携版) / Windows.Storage(MSIX 商店版)。
  5. 权限:普通用户即可注册 RawInput,不需要管理员权限。
  6. 注意:RawInput 只是监听副本,默认不拦截原始滚轮事件,其他软件依然收到滚轮;EarTrumpet 读取事件后只执行自身音量逻辑。

四、配套链

  1. 音量执行后端:两种模式最终都调用同一套 Core‑Audio COM,调节主音量 / 应用会话音量。
  2. 修饰键配套:两种模式都支持组合键(Ctrl/Shift/Win);可配置修饰键按下才响应滚轮,避免误触。
  3. 步长换算配套:解析滚轮WHEEL_DELTA;把滚轮旋转量映射为音量百分比增减;支持对数音量曲线选项。
  4. UI 设置配套:EarTrumpet 设置面板切换模式开关;设置变更后即时生效,无需重启程序;内部销毁旧的消息监听,建立新监听。
  5. 日志与异常配套:RawInput 注册失败会回退降级到「图标上方滚轮」模式;CHANGELOG 记录:虚拟化、远程桌面场景 RawInput 注册会失败。

五、逻辑链路

链路 1:图标上方滚轮(托盘图标模式)

鼠标滚轮滚动
  →系统判断鼠标光标位置
  if 光标坐标落在EarTrumpet托盘图标矩形内:
    shell32 发送 WM_MOUSEWHEEL 到EarTrumpet隐藏托盘消息窗口HWND
      →EarTrumpet消息循环收到消息
      →MouseWheelManager解析滚轮方向、步长、修饰键
      →调用Core‑Audio,执行音量±
  else:
    消息转发给光标下的应用窗口;EarTrumpet完全收不到事件,不做任何处理

链路 2:全局任意位置滚轮(RawInput 模式)

鼠标硬件产生滚轮HID报告
  →Windows输入栈生成RawInput事件
  →复制一份事件,投递给所有已经RegisterRawInputDevices注册鼠标的进程(含EarTrumpet)
  →EarTrumpet消息循环收到 `WM_INPUT` 消息
    →调用 GetRawInputData 读取原始HID数据包,解析滚轮增量、修饰键状态
    →MouseWheelManager业务逻辑:判断是否启用、修饰键条件
    if满足条件:
      执行音量增减(Core‑Audio COM调用)
    →**原始滚轮事件继续正常下发给鼠标悬停的窗口**,EarTrumpet不吞噬事件

重要:RawInput 只是多一份拷贝,不是 Hook 钩子;和 SetWindowsHookEx 鼠标钩子实现原理完全不一样。

模式切换执行链路:

用户设置面板切换滚轮模式
  →停止旧模式监听:
    如果旧模式是RawInput:调用`UnregisterRawInputDevices`注销鼠标原始输入
    如果旧模式是托盘模式:解绑托盘窗口WM_MOUSEWHEEL消息处理
  →启用新模式监听:
    全局模式:RegisterRawInputDevices注册鼠标设备
    托盘模式:仅保留托盘窗口消息处理
  →设置写入持久化存储,即时生效

六、边界(坑点、系统硬限制,来自 CHANGELOG)

🔹图标上方滚轮模式边界

  1. explorer.exe 崩溃重启:托盘隐藏 HWND 重建,短暂时间滚轮不响应;程序内部会重新绑定托盘消息。
  2. Win11 自动隐藏任务栏(ShyTaskbar):图标会自动隐藏,光标不在图标上就不会触发;触摸模式托盘行为变化。
  3. 多显示器、高 DPI 缩放:托盘图标矩形坐标计算错误,导致鼠标明明在图标上却不触发(历史版本修复过坐标换算 bug)。
  4. 优点:几乎不会和其他软件冲突;缺点:必须鼠标挪到托盘图标上才能调音量。

🔹全局任意位置滚轮(RawInput)模式边界

  1. 全屏独占游戏边界:部分游戏会使用独占 RawInput 模式,游戏接管鼠标硬件;此时 Windows 不再向其他进程转发 RawInput 拷贝,EarTrumpet 收不到滚轮事件,全局滚轮失效。这是系统硬限制,无法绕过。
  2. 远程桌面 / 虚拟机边界:部分虚拟化环境不会转发鼠标 HID 原始报告,RegisterRawInputDevices调用直接失败;EarTrumpet 会自动降级回托盘图标模式。
  3. 多软件同时注册 RawInput:系统会把事件副本分发给每一个注册进程;不会互相破坏,但会多个程序同时响应滚轮。
  4. 不吞噬消息,但存在交互冲突场景: 例:浏览器页面滚动,同时 EarTrumpet 收到滚轮事件,一边页面滚动,一边音量同步变化。所以 EarTrumpet 配套增加修饰键开关:要求必须按住 Ctrl/Win 才响应全局滚轮,规避误触。
  5. 设备插拔:鼠标热拔插后,RawInput 设备句柄失效;EarTrumpet 需要重新注册 RawInput;早期版本存在鼠标重新插上后全局滚轮失效 bug。
  6. 程序退出:必须调用UnregisterRawInputDevices;进程异常崩溃没机会执行注销,系统会自动清理注册项,不会永久残留。

两者共性边界

  1. 步长换算:不同鼠标硬件WHEEL_DELTA单位不一致;高分辨率滚轮(精确滚轮)会产生微小增量,需要做阈值过滤,防止音量频繁跳动。
  2. 音量执行层的边界:Core‑Audio 会话被独占模式音频占用时,音量调节调用可能返回失败。

Mermaid 对比时序

sequenceDiagram
    participant HW as 鼠标硬件
    participant Sys as Windows输入子系统(user32)
    participant Shell as shell32托盘
    participant ET as EarTrumpet
    participant App as 当前鼠标下应用

    Note over HW,Sys: 模式A:图标上方滚轮
    HW->>Sys: 滚轮旋转硬件事件
    Sys->>Sys: 判断鼠标光标位置
    alt 光标在托盘图标上
        Sys->>Shell: 转发WM_MOUSEWHEEL
        Shell->>ET: 发送消息到托盘隐藏HWND
        ET->>ET: 解析,调节音量
    else 光标不在图标
        Sys->>App: WM_MOUSEWHEEL发给当前应用
        Note over ET: ET收不到任何事件
    end

    Note over HW,Sys: 模式B:全局任意位置滚轮(RawInput)
    HW->>Sys: 滚轮旋转HID报告
    Sys->>ET: RawInput事件副本 WM_INPUT
    Sys->>App: 原始滚轮消息正常下发给应用
    ET->>ET: 解析原始输入;判断开关与修饰键
    alt 条件满足
        ET->>ET: 执行音量调节
    end

 


 

2.3.0.0

  • 添加了一个设置,允许在任何地方使用滚轮调整音量(感谢 @Tester798!)
  • 添加了一个设置,允许在鼠标悬停在 EarTrumpet 图标上时使用滚轮调整音量(感谢 @Tester798!)
  • 添加了新的社区设置区域
  • 添加了一个新的社区设置,允许启用/禁用使用对数音量刻度(感谢 @yonatan-mitmit!)
  • 在上下文菜单中添加了指向 [应用音量和设备偏好] / [音量混合器] 的传统快捷方式
  • 添加了在快捷键中使用 Windows 键的功能(感谢 @iamevn!)
  • 添加了音频设备的语言显示名称排序功能(感谢 @Tester798!)
  • 添加了 Windows 搜索(CortanaUI)显示默认资产(X)图标的解决方法
  • 修复了如果没有安装 Visual C++ 库包,通过 AppInstaller 安装 EarTrumpet 时会失败的问题
  • 修复了在 Windows 10 上滚动鼠标滚轮时 EarTrumpet 提示未实时更新的问题(感谢 @krlvm!)
  • 强制 EarTrumpet 以仅软件模式渲染,以避免使用高功耗 GPU。
  • 改进了弹出动画(感谢 @krlvm!)

2.2.2.0

  • 修复了在某些场景下滚动鼠标时音量变化的问题(例如虚拟现实)
  • 更新了日语翻译
  • 清理了旧的语言资源

2.2.1.0

  • 修复了启用“ShyTaskbar”时 Windows 11 设备上触摸上下文菜单的行为
  • 修复了启用浅色模式时 Windows 10 上的弹出窗口显示问题(感谢 @xmha97)
  • 修复了 Windows 10 和 Windows 11 上弹出动画未正确遵循系统设置的问题
  • 升级了 GIF 播放库,以减少内存使用(感谢 @rocksdanister)
  • 降低了对大多数 Windows 版本中 Acrylic 渲染性能问题的解决方法的使用(感谢 @krlvm)
  • 更新了来自 Crowdin 的翻译
  • 更新了 Microsoft Store 产品详情页元数据,修正了本地化问题

2.2.0.0

  • 添加了控制多个设备音量的快捷键(感谢 @Taknok!)
  • 调整了应用数据存储方式,以提高可靠性
  • 修复了在某些场景下切换弹出 Acrylic 时可能出现的崩溃问题
  • 修复了在 Windows 11 上弹出窗口过高的问题
  • 更新了日语、希腊语、克罗地亚语和俄语翻译(感谢 Crowdin 贡献者!)

2.1.10.0

  • 弹出窗口现在会记住在启动之间的展开/折叠状态(感谢 @Tester798!)
  • 修复了某些鼠标设备上弹出窗口打开动画行为不稳定的问题
  • 修复了某些设备缺少特定特征时会干扰静音和其他操作的问题
  • 修复了设备名称中包含下划线时显示不正确的问题
  • 修复了弹出窗口在某些情况下打开到工作区域外的问题
  • 调整了弹出窗口位置,从屏幕边缘调整为匹配 Windows 11 的外观
  • 删除了应用图标后面的纯色填充
  • 更新了芬兰语、德语等语言的翻译

2.1.9.0

  • 添加了对 Windows 11 的基本支持
  • 添加/更新了意大利语、匈牙利语、西班牙语、葡萄牙语、土耳其语、中文、挪威语、阿拉伯语、捷克语、波兰语、瑞典语、罗马尼亚语和俄语翻译
  • 修复了弹出窗口打开到工作区域外的问题
  • 修复了拖动窗口时移动缓慢的问题

2.1.8.0

  • 添加了匈牙利语、瑞典语、韩语和泰米尔语翻译
  • 更新了日语翻译
  • 添加了 Fluent 图标
  • 修复了捷克语和阿非利堪斯语翻译缺失的问题
  • 修复了打包桌面应用(如 Microsoft Flight Simulator)图标无法显示的问题
  • 修复了 [Windows Legacy > 声音设置] 菜单项打开错误面板的问题
  • 修复了通知区图标处理的问题
  • 修复了导致无法使用系统键的快捷键问题

2.1.7.0

  • 修复了在某些机器上获取 GDPR 合规性地区信息时导致的崩溃

2.1.6.0

  • 添加了启用/禁用崩溃报告的功能
  • 添加了缺失的翻译
  • 添加了隐私政策链接
  • 修复了基于 libmpv 的应用(如 Plex)图标显示问题
  • 修复了高 DPI 时使用鼠标操作音量滑块困难的问题
  • 恢复了 2.1.2.0 之前的托盘图标行为,直到我们解决图标重复问题

2.1.5.0

  • 修复了音量图标未显示的问题
  • 修复了上下文菜单子菜单意外消失的问题

2.1.4.0

  • 修复了设置中搜索文本框的各种问题
  • 修复了 Windows Shell 崩溃/重启时托盘图标消失的问题
  • 修复了静音时主音量滑块变暗的问题
  • 修复了浅色主题下弹出窗口轨迹颜色问题
  • 修复了音量为零时的静音图标问题
  • 添加了在存在大量音频设备时调整混音器窗口宽度的限制
  • 添加了斯洛文尼亚语语言支持
  • 为按钮添加了悬停状态
  • 其他崩溃修复

2.1.3.0

  • 修复了导致 EarTrumpet 启动时消失的崩溃
  • 修复了各种潜在的内存泄漏问题
  • 添加了帮助对话框,以帮助解决由于字体问题导致 EarTrumpet 无法启动的情况

2.1.2.0

  • 修复了导致崩溃的图标句柄泄漏
  • 修复了快捷键未正确注销的问题
  • 修复了箭头键改变默认设备音量的问题
  • 修复了高对比度主题颜色问题
  • 修复了最大化时设置窗口覆盖任务栏的问题
  • 托盘图标在更新后将保持在原位
  • 托盘和应用图标现在将正确缩放
  • 托盘图标支持滚动而不打开弹出窗口
  • 删除了不需要的遥测元数据

2.1.1.0

  • 修复了非英语系统解析数字时的崩溃

2.1.0.0

  • 添加了新的设置体验
  • 添加了对 Windows 浅色模式的支持
  • 添加了打开混音器和设置窗口的快捷键
  • 减少了上下文菜单中的杂乱内容
  • 修复了使用 RTL 写作系统时的各种显示问题
  • 更改了应用命名行为,以与 Windows 对齐
  • 在通知区图标上添加了静音文本
  • 在上下文菜单中添加了“打开声音设置”链接
  • 为通知区图标的工具提示添加了静音状态文本
  • 重新添加了弹出窗口阴影和边框
  • 添加了额外的遥测点
  • 移除了阿拉伯语、匈牙利语、韩语、挪威语博克马尔语、葡萄牙语、罗马尼亚语、土耳其语等语言,直到完成本地化
  • 其他修复

2.1.9.0

  • 增加了对 Windows 11 的基本支持
  • 增加/更新了意大利语、匈牙利语、西班牙语、葡萄牙语、土耳其语、中文、挪威语、阿拉伯语、捷克语、波兰语、瑞典语、罗马尼亚语和俄语的翻译
  • 修复了飞出菜单打开时超出工作区域的问题
  • 修复了拖动时窗口移动缓慢的问题

2.1.8.0

  • 增加了匈牙利语、瑞典语、韩语和泰米尔语的翻译
  • 更新了日语翻译
  • 增加了流畅图标
  • 修复了缺少捷克语和南非荷兰语翻译的问题
  • 修复了打包桌面应用程序(例如 Microsoft Flight Simulator)图标未出现的问题
  • 修复了[Windows Legacy > 声音设置]菜单项打开错误面板的问题
  • 修复了通知区域图标处理的问题
  • 修复了阻止在快捷键中使用系统键的问题

2.1.7.0

  • 修复了在某些机器上检索地区信息时导致的崩溃问题

2.1.6.0

  • 增加了启用/禁用崩溃报告的功能
  • 增加了缺失的翻译
  • 增加了隐私政策链接
  • 修复了基于 libmpv 的应用程序(例如 Plex)图标显示问题
  • 修复了高 DPI 下鼠标操作时音量滑块难以调整的问题
  • 恢复了 2.1.2.0 之前的托盘图标行为,直到解决图标重复问题

2.1.5.0

  • 修复了图标中线条不显示的问题
  • 修复了右键菜单子菜单意外消失的问题

2.1.4.0

  • 修复了设置中的搜索框的各种 bug
  • 修复了 Windows Shell 崩溃/重启时托盘图标消失的问题
  • 修复了静音时主音量滑块变暗的问题
  • 修复了浅色主题下飞出菜单的轨迹颜色问题
  • 修复了音量为零时的静音图标问题
  • 增加了在音频设备数量较多时,混音器窗口的宽度限制
  • 增加了斯洛文尼亚语支持
  • 增加了按钮的悬停状态
  • 其他崩溃修复

2.1.3.0

  • 修复了启动时导致 EarTrumpet 消失的崩溃问题
  • 修复了各种潜在的内存泄漏
  • 增加了帮助对话框,用于在由于字体损坏无法启动 EarTrumpet 时提供帮助

2.1.2.0

  • 修复了导致崩溃的图标句柄泄漏问题
  • 修复了快捷键未正确注销的问题
  • 修复了箭头键改变默认设备音量的问题
  • 修复了高对比度主题的颜色问题
  • 修复了设置窗口最大化时覆盖任务栏的问题
  • 托盘图标将保持不变,直到我们解决图标重复问题
  • 托盘和应用程序图标现在将正确缩放
  • 托盘图标支持滚动而无需打开飞出菜单
  • 删除了不必要的遥测元数据

2.1.1.0

  • 修复了在非英语系统上解析数字时的崩溃问题

2.1.0.0

  • 增加了新的设置体验
  • 增加了对 Windows 光模式的支持
  • 增加了打开混音器和设置窗口的快捷键
  • 减少了右键菜单中的杂乱内容
  • 修复了使用 RTL 写作系统时的各种显示问题
  • 更改了应用名称行为,使其与 Windows 保持一致
  • 在通知区域图标上增加了静音文本
  • 在右键菜单中增加了“打开声音设置”链接
  • 在通知区域图标工具提示中增加了静音状态的文本
  • 重新加入了飞出窗口的阴影和边框
  • 增加了额外的遥测点
  • 移除了阿拉伯语、匈牙利语、韩语、挪威语Bokmål、葡萄牙语、罗马尼亚语和土耳其语,直到完成本地化
  • 其他 bug 修复

2.0.8.0

  • 更改了分组行为,基于应用程序安装路径而非可执行文件名
  • 禁用了飞出窗口不在可见时的模糊效果,以确保它不会出现在任务切换器中
  • 修复了播放设备对话框中缺少增强选项卡的问题
  • 修复了任务栏配置为自动隐藏时飞出窗口过高的问题
  • 修复了禁用或未插拔设备意外出现的问题
  • 修复了当没有默认音频端点时的崩溃问题
  • 修复了在移动音频会话后右键点击导致的崩溃问题

2.0.7.0

  • 增加了对高对比度主题的额外支持
  • 增加了每个监视器 DPI 支持
  • 增加了内部诊断日志缓冲区限制
  • 禁用了飞出窗口的 Alt+Space 快捷键
  • 修复了 DPI 大于 100% 且设备数量多于飞出窗口可显示数量时的渲染问题
  • 修复了 DPI 大于 100% 时通知区域图标模糊的问题
  • 修复了“监听”模式下录音设备的图标和名称问题
  • 修复了通知区域图标的缩放问题
  • 修复了大于 100% DPI 时的飞出窗口溢出问题

2.0.6.0

  • 修复了影响非英语系统本地化的问题

2.0.5.0

  • 修复了 ARM64 上的系统声音图标
  • 更新了高对比度颜色
  • 增加了设备枚举失败时的调试信息收集

2.0.4.0

  • 将鼠标滚轮滚动限制为仅在通知区域图标上
  • 增加了对 RS3 的支持
  • 修复了在移除默认设备时,飞出窗口显示“看起来你没有播放设备”问题
  • 修复了添加/移除设备时的崩溃问题
  • 从遥测中删除了非致命错误

2.0.3.0

  • 修复了某些应用程序(例如《海盗之海》)显示不正确的问题
  • 增加了额外语言支持(阿拉伯语、西班牙语、匈牙利语、韩语、土耳其语和乌克兰语)

2.0.2.0

  • 对遥测做了更改

2.0.1.0

  • 修复了快速添加/移除设备时的崩溃问题
  • 修复了多进程音频会话的崩溃问题
  • 修复了启动网页链接时的崩溃问题
  • 修复了关闭 EarTrumpet 窗口时的崩溃问题
  • 修复了展开/收起主窗口时的崩溃问题
  • 修复了任务栏自动隐藏时的崩溃问题
  • 修复了注册表中无效个性化数据时的崩溃问题
  • 修复了调用应用程序数据存储 API 时的崩溃问题

2.0.0.0

  • 在通知区域图标上增加了中键点击静音功能
  • 增加了在窗口打开时使用鼠标滚轮调节设备音量的功能
  • 增加了多通道峰值计量功能
  • 增加了在设备之间移动应用程序的功能
  • 增加了查看多个设备的功能
  • 增加了音量混音器窗口
  • 增强了应用会话分组功能
  • 增强了键盘操作
  • 增加了打开飞出菜单的快捷键
  • 增加了对 Windows 浅色/深色模式的支持
  • 在右键菜单中增加了声音、录音等链接
  • 增强了动画和细节处理
  • 解决了 RTL、无图标应用程序和无障碍相关的更多问题

1.5.3.0

  • 提升了滑块性能
  • 修复了 Windows 10 1803 的 Acrylic Blur 兼容性问题

1.3.2.0
修复了在 Windows 10 (RS1) 中更改音频设备的问题

1.3.1.0
修复了 DWM 缩放问题,导致窗口显示位置错误
修复了找不到音频设备时的 UI 问题
修复了在 Windows 10 (TH1) 和 Windows 10 11 月更新 (TH2) 中更改音频设备的问题
修复了某些应用程序没有显示多个会话的问题
为任务管理器添加了公司元数据

1.3.0.0
修复了语音运行时显示问题
修复了启用任务栏自动隐藏时的位置问题
安装程序/卸载程序现在会检查应用程序是否正在运行
添加了更改默认音频设备的功能(右键点击托盘图标)
添加了静音应用程序/音频设备的功能
添加了默认音频设备主音量滑块

1.2.0.0
修复了使用后台音频服务时(例如 iHeartRadio)一些应用程序未出现在 Ear Trumpet 中的问题
修复了播放受保护媒体时(例如 Netflix)一些应用程序未出现在 Ear Trumpet 中的问题
修复了由于意外的图标路径导致应用程序未显示的问题(例如 Skype Translator)
为 Ear Trumpet 添加了基本本地化支持(目前默认使用英语——可以提交翻译作为拉取请求)

1.1.1.0

1.1.0.0
修复了 DPI 缩放问题
修复了任务栏位于不同位置或不在主显示器上时,Ear Trumpet 显示不正确的问题
初步修复了现代应用程序缺失提取图标的问题
Ear Trumpet 现在只允许打开一个实例
更新了 GitHub 自述文件,包含详细信息和最低版本要求
安装程序不再允许在 Windows 10 之前的 Windows 版本上安装
修复了 Windows 10 平板模式下的问题
修复了 Ear Trumpet 窗口没有正确的边框和投影阴影的问题

1.0.0.0
初始版本

 

posted @ 2025-05-16 15:49  suv789  阅读(198)  评论(0)    收藏  举报