这篇写什么?
上一篇讲了 MS12 声道与物理 I2S 怎么 remap。
更上游的分流逻辑见 MS12 解码后的 HAL 路由。
本机 Soundbar、无线音箱(高度声道)、无线低音炮组成 FlexConnect 拓扑后,本机与无线本应对齐。
Speaker Sync 实测发现无线高度声大约晚 20ms(48kHz 下约 960 frames),于是在 HAL 里只对本机 ch1–5 做延迟补偿。
这篇讲:偏差从哪来、为什么只补本机、ring buffer 怎么做、和校准里 recording_latency 怎么分工。
0. 一句话流程
1. 目标:本机喇叭与无线音箱同一时刻出声;
2. Speaker Sync:测出无线高度声比本机 ch1–5 大约晚 20ms(≈960 frames @48kHz);
3. 补偿:只把本机 ch1–5 往后推 ~20ms,让本机等无线追上;
4. 实现:写 ALSA 前对 ch1–5 做 ring buffer;ch0 / ch6 / ch7 直通。
1. 为什么测出来会差 20ms?
8 路 PCM 从 MS12 出来后,最终可以进 同一条 I2S,但到耳朵的 物理路径不同:
| 通道 | 内容 | 路径 |
|---|---|---|
| ch0 | LFE / Sub | 无线 RF → 低音炮 |
| ch1–5 | FC / FL / FR / LS / RS | 本机 Soundbar 功放(有线、几乎即时) |
| ch6–7 | TpFL / TpFR | 无线 RF → 无线音箱(卫星) |
本机 ch1–5 只经本地 DAC / 功放;无线音箱还要经 RF、对端解码与播放。
Speaker Sync 一类测试会量「两边样本是否齐」,结果常见是:无线侧整体晚约 20ms。
Dolby WLT-58 要求有线 vs 无线的样本误差落在较窄窗口内(约 -12 ~ +36 samples)。
不补偿时,人声从 Soundbar 先出、高度声从无线音箱后出——空间感会错位。
对策方向: 不是整包 8 路一起拖,而是 只把已经「跑太快」的本机 ch1–5 往后推,让它和无线 ch6/ch7(以及 ch0)对齐。
2. 补偿怎么做?
8ch PCM → 抽出 ch1-5 → ring buffer 推迟 N ms → 写回 → 整包送 ALSA
ch0 / ch6 / ch7 不动(无线侧保持原时序)
2.1 为什么不整包延迟?
| 方案 | 问题 |
|---|---|
| 整包 8ch 再拖 20ms | 无线通道也被拖慢,相对关系更乱 |
| 只延迟本机 ch1–5 | 本机晚出,无线保持原时序 · 正确做法 |
2.2 可调参数
默认约 20ms(产线可按实测微调):
vendor.media.audiohal.flexconnect.wired_delay_ms=20
运行时也可改,例如:
adb shell cmd media.audio_policy set_parameters "flexconnect_wired_delay_ms=18"
数值应对齐 Speaker Sync / RF 实测,不是拍脑袋写死「有线就该 20」。
3. 写 ALSA 前的位置
数据经多声道处理后,在 扬声器输出、且 FlexConnect 已 bypass TVSDX 时,才对本机 5 路做延迟。
(TVSDX bypass 的原因见 声道匹配篇:MS12 已输出最终高度声道,不能再折进 LFE。)
触发条件:
- 已走 FlexConnect FLAP 路径(bypass TVSDX)
- 是完整 8 声道布局
- 输出设备是本机喇叭,而不是 HDMI 透传等
每帧四步:pack ch1–5 → ring 延迟 → unpack 写回 → 整包写 ALSA。
4. Ring Buffer:为什么听起来像「固定晚 N ms」
4.1 FILLING(填满目标延迟)
- ring 里还不够 N ms 的数据
- 输出先填静音,同时把新样本写进 ring
- 20ms @ 48kHz、5 路:大约攒够 960 samples × 5 后进入稳态
- 刚开声那一瞬间,本机 ch1–5 可能短暂无声——这是填缓冲的正常现象
4.2 STEADY(稳态)
- 每来一帧:先写入新数据,再读出 N ms 之前 的旧数据
- 本机 ch1–5 相对输入 固定晚 N ms
- 无线 ch0 / ch6 / ch7 不进 这个 ring,不会被额外推迟
测延迟是否生效时,看日志里是否进入 STEADY、延迟毫秒数是否接近实测值即可。
5. 和 JSON recording_latency 别混
| 项目 | JSON recording_latency |
HAL wired_delay_ms |
|---|---|---|
| 用在哪 | 校准 / 录音回采算法 | 用户真正听播放时 |
| 干什么 | 校准时对齐 mic / 回采时间参考 | 让本机喇叭晚出,对齐无线音箱 |
| 典型量级 | 常约 -21ms(算法参考) | 默认约 20ms(播放补偿) |
分工:
recording_latency→ 校准 算位置wired_delay_ms→ 播放 听声音
Speaker Sync 发现问题 → 调 wired_delay_ms;校准收敛另看 recording_latency。
6. 和系列其它文章的关系
| 文章 | 侧重 |
|---|---|
| MS12 解码后 HAL 分流 | DAP / SEI / Master · 本篇上游 |
| MS12 声道与 I2S remap | 哪一路是哪个喇叭 |
| 本篇 | Speaker Sync 发现偏差后,本机 ch1–5 怎么补偿 |
| 不足 8ch dconf / Level Matching | 声道数不足时的 CTA 错位 |
| 从硬件 RF 到校准 | Bridge · 校准 App · JSON |
先 remap 对「哪一路是哪个喇叭」,再按实测补延迟,对「是否同时响」。
7. 排查清单
| 现象 | 优先想 |
|---|---|
| 人声明显早于高度声 | 补偿是否打开、是否仍约 20ms、是否进了 bypass 路径 |
| 开机瞬间本机短暂无声 | FILLING 正常;若一直无声再查 ring 是否卡死 |
| 补了仍不对 | 用 Speaker Sync / RF 再测真实偏差,微调 ms |
| 只有无线音箱怪 | ch6/ch7 不应进 ring;回头查 remap |
| 校准 OK 播放仍偏 | 分清 recording_latency(校准)与 wired_delay(播放) |
常用日志关键字:FlexConnect wired delay、STEADY、flexconnect_wired_delay_ms。
adb shell getprop vendor.media.audiohal.flexconnect.wired_delay_ms
基于 Amlogic Soundbar HAL FlexConnect 实践整理。20ms / 960 frames 来自 Speaker Sync 一类实测量级。
评论
还没有评论,来做第一个吧
有想法?直接在这说,不用跑留言板