回声问题 · 为什么你会听到自己

不用耳机开免提,对方会听到自己的声音延迟传回——这就是声学回声。这一章讲清回声怎么产生(扬声器→房间→麦克风)、为什么这条声学路径难以捉摸、以及「双讲」为什么让回声消除难上加难。为下一章的 AEC3 算法铺垫。

作者 David更新于 第 72 篇(共 112 篇)

回声问题 · 为什么你会听到自己

APM 处理链里最难的一环是回声消除。在讲它怎么消之前,先把“回声”这个问题本身讲透——它比想象中刁钻。

回声怎么产生

不戴耳机、开着免提时:你的扬声器播出对方的声音 → 这声音在房间里传播 → 被你的麦克风又采了回去** → 混进你要发出的音频 → 传回对方 → 对方听到了自己的声音,延迟了一段——这就是回声。** 整个链条:对方说话 → 你的扬声器播 → 房间声学传播 → 你的麦克风采集(连你的话 + 漏进来的对方声) → 编码发回 → 对方听到自己延迟的回声。延迟来自“网络往返 + 两端的缓冲处理”,通常几百毫秒——足够让人清楚地听到“自己说的话过一会儿又回来了”,极其烦人,严重时还会啸叫。

戴耳机就没这问题——因为扬声器(耳机)的声音不会被麦克风采到,链条断了。所以回声是免提 / 外放场景特有的。而移动时代大家越来越多用外放,回声消除就越发重要。

难点一:声学路径看不见、还在变

要消回声,核心是知道“麦克风采的音里,哪部分是扬声器漏回来的”。这需要知道声学路径——声音从扬声器到麦克风,经过了怎样的衰减、延迟、反射。但:

扬声器到麦克风的声学路径,看不见、极复杂、还时刻在变——这是回声消除最根本的难点。 这条路径取决于:扬声器和麦克风的距离、音量、房间大小和形状、墙壁的反射(混响)、以及你有没有动(手机拿起放下、人走动,路径立刻变)。它不是一条简单的“延迟 + 衰减”,而是一个复杂的声学冲激响应(包含直达声 + 无数次反射的叠加),可能长达几百毫秒。

更糟的是它动态变化:你说话时手机凑近嘴边、说完放到桌上,声学路径就完全变了。所以回声消除不能预先测好路径一劳永逸,必须实时地、持续地估计这条不断变化的路径——这是一个自适应滤波问题,也是 AEC3 复杂的根源。

难点二:双讲

即便估准了路径,还有一个更刁钻的情况——双讲(double-talk):

当两个人同时说话时,麦克风采的音里,你的话和对方的回声混在一起——既要消掉对方的回声,又不能削掉你的话,这个“同时”让回声消除难上加难。 单讲(只有一方说)时好办:麦克风采的几乎全是回声(对方在说、你在听),放心消;但双讲时,麦克风采的是“你的话 + 对方的回声”的叠加,消回声的算法一不小心就会把你的话也当回声消掉(对方听你声音发闷、断续),或者漏消回声(对方还是听到自己)。

所以 AEC3 必须有双讲检测:识别出“现在是不是双讲”,双讲时谨慎行事(别激进地消,以免误伤近端语音),单讲时放心消。在“消干净回声”和“不伤害近端语音”之间的这个动态平衡,是回声消除算法水平的试金石。一个好的 AEC,双讲时你和对方能自然地“抢话”,而不会互相把对方消没了。

为什么 WebRTC 自己做 AEC

有人问:操作系统 / 硬件不是常自带回声消除吗?为什么 WebRTC 还要 AEC3?因为平台的 AEC 质量参差不齐——有的设备好、有的很烂,还有的根本没有。WebRTC 要在所有平台上都保证音质,就得有一个自己的、软件的、高质量回声消除器,作为兜底或首选(它也能用平台 AEC,但自带一个高水准的更稳妥)。AEC3 就是这个“自带的好 AEC”——Google 打磨多年的成果。

小结与下一章

回声是免提场景特有:扬声器播对方的声 → 房间传播 → 麦克风采回 → 传回 → 对方听到自己延迟的回声(几百毫秒,烦人)。戴耳机则无。难点一:声学路径看不见、极复杂(混响)、还随你移动实时变,须自适应估计。难点二:双讲——两人同时说,回声和近端语音混叠,消回声时别误伤自己的话,须双讲检测。WebRTC 自带 AEC3 以在所有平台保证音质。

问题讲清了,下一章看 AEC3 怎么消——自适应滤波估计回声、再减掉。👉 AEC3 回声消除内核。

参考资料

  • [1] libwebrtc 源码.modules/audio_processing/aec3/(AEC3 实现)。
  • [2] 声学回声消除(AEC)—— 自适应信号处理经典问题。
  • [3] 关联APM 总览、ProcessReverseStream(远端参考)。

本页目录