4、前端信号处理降噪:VAD、AEC、AGC 原理与调优

各位好,我是老张。今天聊前端信号处理的三板斧——VAD、AEC、AGC。这三个东西,说白了就是语音识别系统的「守门员」。你想想看,麦克风收进来的信号要是乱七八糟的,后端模型再强也白搭。我在项目里见过太多这种情况:模型精度明明有 95%,一上真实环境直接掉到 70%。查到最后,问题全出在前端信号处理上。

所以这一章,咱们就把这三个模块的原理和调优讲透。我会结合自己踩过的坑,告诉你哪些参数是「命门」,哪些地方容易翻车。

4.1 VAD(语音活动检测)—— 别让静音浪费算力

VAD 的任务很简单:判断当前这段音频里有没有人说话。有,就往后送;没有,就扔掉。听起来容易,做起来全是细节。

4.1.1 原理:能量检测 + 过零率 + 谱熵

我习惯把 VAD 分成三层:

  1. 能量检测:计算短时能量。安静环境下,能量低于阈值就是静音。但噪声大了就不准。
  2. 过零率:语音的过零率通常比噪声低。清音(如 /s/、/f/)过零率高,浊音低。结合能量能筛掉一部分突发噪声。
  3. 谱熵:语音的频谱分布不均匀,熵值低;白噪声的频谱平坦,熵值高。这是对付平稳噪声的利器。

实际产品里,我一般用 能量 + 谱熵 的组合。过零率在安静场景有用,但嘈杂环境下容易误判。

核心公式(简化版):

VAD_decision = (Energy > E_th) AND (SpectralEntropy < H_th)

两个条件同时满足,才判定为语音。

4.1.2 调优实战:阈值怎么设?

我调 VAD 有个习惯:先录一段「纯噪声 + 语音」的混合音频,然后画能量和熵的分布图。阈值就设在两个分布的交界处,再往噪声侧偏 2-3 dB 作为安全余量。

参数 推荐范围 我的经验
能量阈值 -30 dB ~ -20 dB 办公室环境用 -25 dB,工厂环境要降到 -18 dB
谱熵阈值 0.5 ~ 0.7 0.6 是个不错的起点,噪声大时调到 0.7
最小语音长度 50 ms ~ 200 ms 我习惯设 100 ms,太短容易把咔嗒声当语音
挂起时间 200 ms ~ 500 ms 300 ms 能避免说话间隙被切断

我曾经踩过的坑:有一次在车载环境,VAD 把空调风声当成了语音。查了半天,发现是谱熵阈值设得太低。空调风声虽然能量低,但频谱平坦,熵值高。把阈值从 0.5 调到 0.65 就解决了。

4.2 AEC(回声消除)—— 别让扬声器「污染」麦克风

AEC 解决的是「自己说话自己听」的问题。扬声器放出来的声音被麦克风重新采集,形成回声。如果不消除,语音识别会收到两遍同样的内容——一遍是近端说话人,一遍是远端回声。

4.2.1 原理:自适应滤波器 + 双端检测

AEC 的核心是 自适应滤波器。它模拟回声路径,从麦克风信号里减去估计的回声。我画个图帮你理解:

AEC 回声消除流程 扬声器 麦克风 自适应滤波器 减法器 输出信号 参考信号 估计回声 含回声信号 关键:自适应滤波器不断更新系数,跟踪回声路径的变化 双端检测(DTD)在双方同时说话时冻结滤波器更新,防止发散

这里有个关键点:双端检测(DTD)。当近端和远端同时说话时,自适应滤波器必须停止更新。否则滤波器会发散,产生更严重的回声。我见过不少团队忽略 DTD,结果 AEC 越消越糟。

4.2.2 调优实战:收敛速度 vs 稳定性

AEC 调优的核心矛盾是:收敛速度 vs 稳定性。收敛太快,容易受噪声干扰;收敛太慢,回声消除不干净。

参数 作用 我的建议
滤波器长度 决定能消除多长的回声 一般 512~2048 点(16kHz 采样率对应 32~128 ms)
步长因子 控制收敛速度 0.1~0.5,我习惯从 0.2 开始调
DTD 阈值 判断是否双端说话 能量比法:近端能量 / 远端能量 > 2 时冻结
非线性处理 消除残余回声 中心削波 + 舒适噪声,削波阈值 -40 dB

我个人习惯:先录一段远端信号,让滤波器充分收敛。然后加入近端语音,观察 ERLE(回声返回损耗增强)指标。ERLE 达到 30 dB 以上才算合格。如果达不到,先检查滤波器长度是否够,再调步长。

4.3 AGC(自动增益控制)—— 让音量「刚刚好」

AGC 解决的是音量不一致的问题。有人说话声音大,有人声音小;有人离麦克风近,有人离得远。AGC 把这些信号统一拉到目标电平,保证语音识别后端收到的信号幅度稳定。

4.3.1 原理:目标电平 + 增益计算 + 平滑

AGC 的流程很简单:

  1. 计算当前帧的 RMS(均方根)电平
  2. 和目标电平比较,算出需要的增益
  3. 对增益做平滑处理,避免突变
  4. 应用增益到信号

但这里有个陷阱:增益不能无限放大。背景噪声也会被放大。所以 AGC 必须和 VAD 配合——只在语音段放大,静音段保持原样或降低增益。

4.3.2 调优实战:目标电平设多少?

我一般把目标电平设在 -26 dBFS ~ -22 dBFS 之间。这个范围既能保证语音清晰,又不会削波。

场景 目标电平 最大增益 攻击时间 释放时间
安静办公室 -24 dBFS 20 dB 10 ms 100 ms
嘈杂街道 -22 dBFS 15 dB 5 ms 50 ms
远场拾音(3米) -26 dBFS 30 dB 20 ms 200 ms

我曾经翻过车:有一次在智能音箱项目里,AGC 把增益设到了 30 dB。结果用户离得远时,空调噪声被放大了 30 dB,语音识别率直接崩了。后来加了 VAD 门控,只在语音段应用 AGC,噪声段保持原增益,问题才解决。

4.4 三者的协同工作

VAD、AEC、AGC 不是各自为战的。我习惯把它们串成一条流水线:

  1. AEC 先上:消除回声,避免回声干扰 VAD 和 AGC 的判断
  2. VAD 判断:标记哪些是语音段,哪些是噪声段
  3. AGC 调整:只在语音段应用增益,噪声段保持原样

这个顺序不能乱。如果先做 VAD 再做 AEC,回声会干扰 VAD 的判决,导致语音段被误判为噪声。

一句话总结:

  • VAD 决定「什么时候处理」
  • AEC 决定「消除什么」
  • AGC 决定「放大多少」

三者配合好了,语音识别率能提升 5~10 个百分点。

4.5 避坑指南

最后,分享几个我踩过的坑:

  • VAD 阈值太死板:不同噪声环境用同一套阈值,结果要么漏检要么误检。我建议做自适应阈值,根据噪声底噪动态调整。
  • AEC 滤波器长度不够:在会议室这种大空间,回声路径长,滤波器长度不够就消不干净。我一般设 1024 点起步。
  • AGC 增益突变:增益变化太快会产生「呼吸效应」,听起来很不自然。攻击时间和释放时间要调得平滑一些。
  • 忽略双端检测:AEC 没有 DTD,双方同时说话时滤波器发散,回声反而变大。这个坑我至少见过三次。