这篇写什么?
Soundbar 一边大声播影音,一边还要远场喊「OK Google」。原生方案里,回声消除(AEC)在 Google Assistant 应用层,且往往只有 2 路麦 + 2 路参考(Ref)。多麦阵列、多扬声器的空间信息用不上,大音量时回声淹没人声,唤醒率会掉得很厉害。
本文对比 Google 原生远场架构 与一种常见优化思路:
舍弃对原生 AEC 的依赖,把自研多通道 AEC+NS 下沉到 Audio HAL;向上仍按标准接口送「干净 2ch 麦 + 静音 Ref」,让原生 AEC 因没有有效参考而不再二次改写语音。
一句话:
痛点:2×2 AEC + APP 层处理 → 大音量回声消不干净 → 唤醒差
做法:HAL 吃满 4mic + 6ref → 自研 AEC+NS → 上传干净 2ch
+ Ref 送全零 → 原生 AEC「空转」
目标:多声道路径建全、大音量仍可远场唤醒,且不改 Google 应用代码
相关:Mic + Ref 采集、多路唤醒占麦、喇叭 THD。
一、技术方案概述
| 维度 | 原生 | 优化 |
|---|---|---|
| AEC 位置 | Google Assistant APP 层 | Audio HAL(Native) |
| Mic | 常为 2ch | HAL 内用满 4ch(示例) |
| Ref | 常为 2ch | HAL 内用满 6ch(示例) |
| 向上交付 | 脏麦 + 真实 Ref,交给原生 AEC | 干净 2ch 麦 + 静音 Ref |
| Google 代码 | AEC 真正干活 | 不改应用;原生 AEC 因静音 Ref 几乎不改写 |
通道数因项目而异(有的是 2mic+2ref、有的是 4+6);关键是:在 HAL 用完整多通道做 AEC,再收敛成 Assistant 仍认识的 2ch 接口。
二、Google 原生远场架构
2.1 层级示意

自上而下大致是:
云端 Google ASR
↑↓
APP:Google Assistant(内含 AEC → 唤醒)
↑ 两路 AudioRecord(约 2ch mic / 2ch ref)
Audio Framework(flinger / policy / effect)
↑↓
Audio HAL:AudioRecord-mic / AudioRecord-ref;播放侧 MS12 等
↑↓
Kernel ALSA:PDM IN、LoopBack、TDM out
↑↓
硬件:麦克风阵列 / 喇叭
2.2 工作流程
- 采集:PDM 采麦;LoopBack 取本机播放作 Ref
- 上传:HAL 分别把 mic / ref 送到 Framework
- APP:Assistant 开两个
AudioRecord——一路脏麦(人声+回声+噪声),一路播放参考 - AEC:在 APP 内用 Ref 消回声
- 唤醒:对消后结果做热词检测
- 识别:唤醒后走云端 ASR 等
播放路径则是 Netflix / YouTube / Assistant → AudioTrack → Framework → HAL(如 MS12)→ TDM → 喇叭。
2.3 三大痛点
痛点 1:AEC 通道数不够
- 原生 AEC 常见上限:2 mic + 2 ref
- Soundbar 往往是 4+ 麦、6+ 扬声器单元
- 阵列空间信息、各单元独立 Ref 都用不上
痛点 2:大音量回声消不动
- 认证/设计余量下,本机播放可能只按约 70 dB @ 1.5 m 一类条件考虑
- 客厅 Soundbar 实际常到 80~90 dB
- 残余回声盖住人声 → 唤醒词检测失败
痛点 3:处理层级偏上
- 数据要穿过 Framework 才到 APP,延迟更大
- 上传过程中易被混音、降采样、通道合并,原始多通道已丢
- APP 层跑不动复杂的多通道自适应滤波
三、优化方案架构
3.1 层级示意

相对原生,关键变化在 Audio HAL:
Kernel:4ch Mic(PDM)+ 6ch Ref(LoopBack ← TDM 播放)
→ HAL:自研多通道 AEC + NS
→ 输出干净 2ch mic
→ Framework → Assistant:Record-2ch-mic → 唤醒
播放仍走:App → Track → Framework → MS12 → TDM → 喇叭
Assistant 侧仍做唤醒;重活的回声消除已在 HAL 做完。
3.2 创新点一:自研 AEC 替代原生,并下沉 HAL
为什么不用原生 AEC?
它面向通用 2×2 场景;Soundbar 多喇叭形成的复杂回声场,在通道上限内原理上就很难拿到足够抑制量。
为什么放在 HAL?
- 直接拿原始多通道:对接 ALSA,4ch mic + 6ch ref 不先被 Framework 捏扁
- 少一层损失:少混音 / 重采样 / 通道合并
- 延迟更低:自适应滤波更好跟回声路径变化
- 算力更合适:Native C/C++ 更适合多通道自适应算法
3.3 创新点二:4mic × 6ref 联合建模
| 原生(示意) | 优化(示意) | |
|---|---|---|
| Mic | 2ch | 4ch 阵列 |
| Ref | 2ch(常已混成立体声) | 6ch 各单元参考 |
| 回声路径模型数 | 2×2 = 4 | 6×4 = 24 |
回声路径数 ≈ 扬声器单元数 × 麦克风数:每个喇叭到每个麦都是一条独立路径,AEC 最好为每条路径建滤波器。
4 麦:波束形成增强目标方向人声,多通道相关估计噪声,收敛更稳。
6 Ref:低音/中高/环绕等单元信号不同;只给混好的 2ch Ref,等于丢掉「谁在响」的细节,大音量时尤其吃亏。
再加上 NS,消回声后继续压环境噪声,给唤醒更干净的 2ch。
3.4 创新点三:静音 Ref 旁路(不改 Google 代码)
问题:HAL 已经输出「干净麦」了,但 Assistant 仍会跑自带 AEC。若再送入真实 Ref,等于对已消干净的语音做 二次 AEC,容易发干、失真、丢信息。

做法:
送给 Google Assistant:
├── mic 通道:HAL AEC+NS 后的干净 2ch
└── ref 通道:全零静音
原生 AEC 看不到有效参考,就 几乎不会改写 mic——既遵守双路接口习惯,又让自研 AEC 真正接管回声消除。这是一种 无侵入旁路,不是去改 Assistant 源码。
四、为什么大音量时原生唤醒会崩?
约 3 m 距离的能量对比(量级示意):
| 成分 | 约 |
|---|---|
| 用户语音到麦 | 68~70 dB |
| 本机播放回声到麦 | 80~90 dB+ |
| 「语音相对回声」 | 约 −20 dB(人声被淹) |
要听得见唤醒词,AEC 往往需要把回声压低 20~30 dB 量级甚至更多。原生 2×2 + APP 层在信息不完整时很难稳定做到。
原生大约只有四成量级唤醒(视测试集而定)的常见原因:
- Ref 不完整 → 路径模型不准
- 只有 4 条路径模型,盖不住 Soundbar 声学
- 滤波器难收敛
- 大音量非线性失真,纯线性 2ch AEC 更吃力
优化后能明显抬升(项目实测可到约九成量级,视场景与认证集而定)的常见原因:
- 6ch Ref → 路径更准 → 抑制量可到约 30~40 dB 量级
- 4ch 阵列 → 波束形成约再给数 dB 语音优势
- HAL 原始信号 → 处理更准
- AEC+NS 联合 → 输出 SNR 更好
具体百分比请以你们实验室报表为准;不同距离、音量、语料差会很大。
五、三条创新点收束
- 自研多通道 AEC+NS 替代原生 AEC,部署在 HAL — 突破 2×2 与 APP 层瓶颈。
- 4mic × 6ref ≈ 24 条路径建模 — 信息量相对 2×2 有数量级提升(示例配置)。
- 静音 Ref 旁路 — 不改 Google 应用,避免二次 AEC,接口仍兼容。
六、和邻近主题怎么串?
| 主题 | 关系 |
|---|---|
| Mic+Ref 怎么采 | HAL AEC 的「原料」从哪来 |
| Loopback 抗混叠 | 16 kHz 参考/麦别先混叠脏掉 |
| 喇叭 THD | 播放太脏,再强的 AEC 也难 |
| 多路唤醒占麦 | 远场与自研助手如何同时开麦 |
建议顺序:硬件麦/喇叭合格 → loopback 数据干净 → HAL 多通道 AEC → 再谈唤醒率曲线。
总结
Google 远场在 Soundbar 上的瓶颈,往往不是「不会唤醒」,而是 AEC 通道与层级配不上多扬声器大音量场景。
把多通道 AEC+NS 放到 HAL,用满 mic×ref 路径,再用 静音 Ref 让原生 AEC 空转,可以在 不改 Assistant 的前提下大幅改善大音量远场唤醒——前提是底层 Mic/Ref 采得齐、采得稳、放音别先严重失真。
相关阅读
评论
还没有评论,来做第一个吧
赞同、吐槽、提问都行,评论区开放