【中科蓝讯】TWS音量是怎样同步的

这篇梳理音乐音量在应用层的处理:手机下发的音量怎样换算为本地等级,左右耳怎样同时生效,以及耳机按键调节后怎样同步手机音量条。通话音量只作区分,不展开 HFP 细节。 一、手机调节音量后的主流程 一次音量调节要对应下面四处状态: %%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%% flowchart LR N0["手机音量条"] N1["耳机内部音量级"] N2["左右耳同步状态"] N3["DAC 实际输出音量"] N0 --> N1 N1 --> N2 N2 --> N3 class N0,N1,N2,N3 blue; classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px; classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px; classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px; 手机和耳机的音量范围并不相同。AVRCP 绝对音量是 0~127,SDK 内部可配置为 16 级或 32 级,最后还要通过音量表转换为 DAC 使用的数字音量。 因此,手机显示 50% 不等于把数值 50 直接写入 DAC,而是先换算、再查表。 这里的“绝对音量”指手机音量条和耳机媒体音量相互对应:任一侧调节,另一侧都要更新。 手机调节音乐音量后,协议栈将新的媒体音量交给应用层,主线如下: %%{init: {"flowchart": {"htmlLabels": true, "wrappingWidth": 1000, "rankSpacing": 30}, "themeVariables": {"lineColor": "#71829a"}}}%% flowchart TB subgraph R0["① 接收与换算"] direction LR R0N0["收到手机设置的媒体音量"] R0N1["把 0~127<br/>换算为本地音量级"] R0N2["发起 TWS 定时音量请求"] R0N0 --> R0N1 --> R0N2 end class R0N0,R0N1,R0N2 blue; style R0 fill:#f1f6fd,stroke:#b8cfe8,color:#23456b subgraph R1["② 定时执行与保存"] direction LR R1N0["左右耳在约定时间设置 DAC"] R1N1["更新当前音量<br/>后续再延时保存"] R1N0 --> R1N1 end class R1N0,R1N1 green; style R1 fill:#f0f8f3,stroke:#b9d7c4,color:#24563a R0 --> R1 classDef blue fill:#e8f2ff,stroke:#7ba4d8,color:#23456b,stroke-width:1.5px; classDef green fill:#e7f4ec,stroke:#78aa8b,color:#24563a,stroke-width:1.5px; classDef amber fill:#fff3df,stroke:#d5a25b,color:#72501e,stroke-width:1.5px; TWS 路径不会在当前回调里直接设置 DAC,而是先发起定时请求;到达定时点后,左右耳再一起设置实际音量。 ...

【中科蓝讯】TWS 耳机音量问题单复盘

写在开始 这篇文章整理项目中比较有代表性的音量问题单。只保留已经写明原因和处理方向的内容,并按音量控制链路归为三类。 排查音量问题时,可以先确认四个结果: 1. 收到的目标音量是否正确 ↓ 2. 左右耳保存的音量是否一致 ↓ 3. 两耳应用音量的时间是否一致 ↓ 4. 实际写入硬件的音量是否正确 本文围绕下面三类问题,整理对应的现象和排查思路: 回连后的初始音量不对 ; 快速调节时双耳音量不同步 ; 出盒恢复时单耳突然变大 。 一、回连后的初始音量不对 问题现象 1 耳机重新组队并连接手机后,预期使用耳机的默认音量,实际却变成手机之前保存的最大音量。 排查思路 1 按时间确认三个值:重新组队后恢复的默认音量、手机首次下发的历史音量,以及最终实际生效的音量。若默认值恢复正确,但最终值变成手机历史值,说明问题出在手机下发后的覆盖。 耳机重新组队后已恢复到默认音量,但手机连接时下发的历史音量又覆盖了本地值。如果要求重新组队后采用耳机默认音量,可以在首次连接的短暂保护窗口内忽略手机下发的音量,使用耳机的默认音量,同时将默认音量写回给 App。 问题现象 2 一拖二场景下,设备 A 已连接耳机且音量调到最大;设备 B 的音量较小,在播放音乐时抢连耳机。抢连成功后,音乐开始时仍按设备 A 的最大音量播放,随后才突然降到设备 B 的低音量。 排查思路 2 检查抢连后耳机采用的是哪台设备的音量,以及 A2DP 开始播放前硬件音量是否已经更新。 已有问题中,设备 B 抢连成功后,硬件音量设置晚于音乐开始,导致开始播放时仍保留设备 A 的最大音量。处理时要在 A2DP 出声前,按设备 B 的音量设置好硬件音量。 二、快速调节时双耳音量不同步 问题现象 1 长按手机音量键或快速滑动音量条时,声音会短暂偏向一边;从最大音量降到静音时,一只耳机比另一只更晚无声。反复在最大和最小音量之间切换时,还可能出现音量跳变。 排查思路 1 先看手机下发音量后,主从耳是不是在 alarm 到点前就各自更新了本地媒体音量;再对比 alarm 回调里两边实际采用的目标值。 已有问题中,主从耳在 alarm 到点前更新本地媒体音量的路径不同。快速滑动时,虽然两边在同一时刻进入 alarm 回调,但取到的音量基准已经不一致,所以会出现一边先变大、先变小或更晚静音。 ...