KunSpace
返回博客

FlexConnect:Speaker Sync 测出 20ms 偏差,再给本机喇叭做补偿

2026年7月25日
9 次阅读

读完了?别空手走啊 😏

读都读完了,不点个赞说不过去吧

写评论

有想法?直接在这说,不用跑留言板

这篇写什么?

上一篇讲了 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 → 无线音箱(卫星)
图1 8 路 I2S 物理路径差异:本机 ch1–5 比无线 ch6/ch7 快约 20ms图1 8 路 I2S 物理路径差异:本机 ch1–5 比无线 ch6/ch7 快约 20ms

本机 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 前的位置

图2 写 ALSA 前延迟 ch1–5 的完整数据流图2 写 ALSA 前延迟 ch1–5 的完整数据流

数据经多声道处理后,在 扬声器输出、且 FlexConnect 已 bypass TVSDX 时,才对本机 5 路做延迟。
(TVSDX bypass 的原因见 声道匹配篇:MS12 已输出最终高度声道,不能再折进 LFE。)

触发条件:

  1. 已走 FlexConnect FLAP 路径(bypass TVSDX)
  2. 是完整 8 声道布局
  3. 输出设备是本机喇叭,而不是 HDMI 透传等

每帧四步:pack ch1–5 → ring 延迟 → unpack 写回 → 整包写 ALSA

图3 pack / delay / unpack:只动 ch1–5,ch0/ch6/ch7 直通图3 pack / delay / unpack:只动 ch1–5,ch0/ch6/ch7 直通

4. Ring Buffer:为什么听起来像「固定晚 N ms」

图4 Ring Buffer FILLING → STEADY 两阶段图4 Ring Buffer FILLING → STEADY 两阶段

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 别混

图5 recording_latency 与 wired_delay_ms 的分工图5 recording_latency 与 wired_delay_ms 的分工
项目 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 delaySTEADYflexconnect_wired_delay_ms

adb shell getprop vendor.media.audiohal.flexconnect.wired_delay_ms

基于 Amlogic Soundbar HAL FlexConnect 实践整理。20ms / 960 frames 来自 Speaker Sync 一类实测量级。

评论

还没有评论,来做第一个吧

有想法?直接在这说,不用跑留言板