15、常见问题:回声残留、近端语音失真、双讲时发散、啸叫问题
做音频回声消除这么多年,我踩过的坑真不少。今天聊的这四个问题——回声残留、近端语音失真、双讲时发散、啸叫——几乎是每个AEC工程师都会遇到的“老朋友”。
说白了,这些问题不是理论上的“会不会发生”,而是实际项目中“什么时候发生、怎么解决”。我个人的习惯是,先把问题分类,再对症下药。咱们一个一个来看。
15.1 回声残留:最让人头疼的“尾巴”
回声残留,就是远端声音明明已经消掉了,但还能听到一点点“尾巴”。
为什么会这样?
原因其实不复杂。自适应滤波器收敛得不够干净,或者非线性失真没处理好。我在项目中遇到过一种情况:扬声器音量开得很大,AEC算法明明收敛了,但每次说话停顿的间隙,总能听到一丝丝回声。
排查下来,是扬声器的谐波失真导致的。线性滤波器只能处理线性回声,非线性部分它管不了。
- 滤波器收敛不充分(步长太小或初始值不对)
- 非线性失真(扬声器饱和、功放过载)
- 双讲检测误判(把近端语音当回声处理了)
- 延迟估计不准(参考信号和麦克风信号没对齐)
15.2 近端语音失真:消了回声,也伤了人声
这个更常见。你想想看,AEC算法为了把回声消干净,结果把近端说话人的声音也削掉了一部分。听起来就像人声变闷、变窄,甚至有点“水底说话”的感觉。
失真主要来自两个地方:
- 双讲检测太激进:一旦检测到双讲,立刻冻结滤波器更新,甚至强行衰减信号。结果近端语音被“误伤”。
- 后处理滤波器过度:有些AEC会在后端加一个中心削波器或噪声抑制器,参数调得太狠,人声的高频细节就没了。
我记得有一次做车载免提,客户反馈“声音像从罐子里传出来的”。我一看,后处理的抑制深度设到了-30dB,近端语音的高频部分几乎全被干掉了。调回-18dB,问题解决。
15.3 双讲时发散:算法“懵了”
双讲,就是远端和近端同时说话。这时候AEC算法最容易出问题。
发散的表现是什么?
本来消得好好的回声,突然“嘭”一下冒出来了,甚至比原来还大。这是因为双讲时,近端语音对自适应滤波器来说是个“干扰信号”,滤波器会误以为这是新的回声路径,开始胡乱调整系数。
我见过最夸张的一次,双讲持续了3秒,滤波器系数直接发散到正无穷,整个音频通道都爆了。
怎么防?
- 双讲检测要准:不能太敏感,也不能太迟钝。我个人习惯用能量比+相关性检测结合的方式。
- 滤波器更新要“刹车”:检测到双讲,立刻冻结滤波器更新,或者把步长降到接近0。
- 加一个发散检测机制:如果发现回声反而变大了,强制重置滤波器。
15.4 啸叫问题:最“刺耳”的故障
啸叫,说白了就是声学正反馈。扬声器放出来的声音被麦克风重新拾取,再放大、再拾取,循环下去,就变成了刺耳的尖叫声。
啸叫和AEC有什么关系?
关系大了。AEC如果没把回声消干净,残留的回声被再次放大,就可能引发啸叫。尤其是在免提通话、会议系统中,扬声器和麦克风距离近,更容易出现。
啸叫的典型场景:
- 扬声器音量开得很大
- 麦克风灵敏度太高
- AEC收敛速度跟不上回声路径变化
- 设备摆放位置形成“声短路”
15.5 知识体系总览
下面这张图,是我自己整理的问题分类和解决思路。你可以把它当成一个“排查地图”。
15.6 实际排查步骤
如果你在项目中遇到了上述问题,我建议按这个顺序排查:
- 先确认延迟对齐:用测试信号打一下,看看参考信号和麦克风信号的时间差。不对齐的话,后面全白搭。
- 检查双讲检测:录一段双讲场景的log,看看检测标志位是不是频繁误判。
- 看滤波器收敛曲线:如果ERLE(回声衰减量)一直上不去,说明滤波器没收敛好。
- 听一下后处理效果:把后处理关掉,只留线性AEC,听听还有没有残留。如果有,是线性部分的问题;如果没有,是后处理的问题。
- 最后看物理环境:扬声器音量、麦克风位置、设备摆放,这些往往被忽略,但往往是根源。
好了,这一章的内容就到这里。希望这些经验能帮你少走弯路。