在实时音频互动场景中,回声消除、降噪、自动增益(即 3A 算法)是直接影响音质和体验的重要环节之一。如何降低计算量,提升处理效率,如何兼容更多的设备、环境等,让3A 算法可以适应更多场景等一系列问题是我们做实时音视频开发中必须要解决的难点。
回声消除的三大算法模块优化
在语音通信系统中,回声消除(Echo Cancellation)一直扮演着核心算法的角色。一般来说,回声消除的效果受诸多因素的影响,包括:
- 声学环境,包括反射,混响等;
- 通话设备本身声学设计,包括音腔设计以及器件的非线性失真等;
- 系统性能,处理器的计算能力以及操作系统线程调度的能力。
声网回声消除算法在设计之初,就将算法性能、鲁棒性和普适性作为最终的优化目标,这一点对于一个优秀的音视频 SDK 来说至关重要。
首先,回声是怎么产生的?简单来讲,就是你的声音从对方的扬声器发出,这个声音又被他的麦克风给收录了进去,这个被麦克风收录的声音又传回到你这一端,你就听到了回声。为了消除回声,我们就要设计一个算法将这个声音信号从麦克风信号中去除掉。
那么声学回声消除模块(AEC, Acoustic Echo Cancellation)是如何消除回声的呢?具体的步骤见如下简图所示:
- 第一步需要找到参考信号/扬声器信号(蓝色折线)跟麦克风信号(红色折线)之间的延迟,也就是图中的 delay=T。
- 第二步根据参考信号估计出麦克风信号中的线性回声成分,并将其从麦克风信号中减去,得到残差信号(黑色折线)。
- 第三步通过非线性的处理将残差信号中的残余回声给彻底抑制掉。
与以上的三个步骤相对应,回声消除也由三个大的算法模块组成:
- 延迟估计(Delay Estimation)
- 线性自适应滤波器(Linear Adaptive Filter)
- 非线性处理(Nonlinear Processing)
其中「延迟估计」决定了AEC的下限,「线性自适应滤波器」决定了 AEC 的上限,「非线性处理」决定了最终的通话体验,特别是回声抑制跟双讲之间的平衡。
注:双讲是指在交互场景中,互动双方或多方同时讲话,其中一方的声音会受到抑制,从而出现断断续续的情况。这是由于回声消除算法“矫枉过正”,消除了部分不该去除的音频信号。
接下来,我们就要围绕这三个算法模块,来进行优化。那么其中存在一些挑战:
一、延迟估计
受具体系统实现的影响,当把参考信号与麦克风信号分别送入 AEC 模块进行处理之时,它们所存入的数据 buffer 之间存在一个时间上的延迟,即我们在上图中看到的“delay=T”。假设这个产生回声的设备是一部手机,那么声音从它的扬声器发出后,一部分会经过设备内部传导到麦克风,也可能会经过外部环境传回到麦克风中。所以这个延迟就包含了设备采集播放 buffer 的长度,声音在空气中传输的时间,也包含了播放线程与采集线程开始工作的时间差。正是由于影响延迟的因素很多,因此这个延迟的值在不同系统,不同设备,不同实时音视频系统底层实现上都各不相同。它在通话过程中也许是一个定值,也有可能会中途变化(所谓的 overrun 和 underrun)。这也是为什么一个 AEC 算法在设备 A 上可能起作用,但换到另一个设备上可能效果会变差。延迟估计的精确性是 AEC 能够工作的先决条件,过大的估计偏差会导致 AEC 的性能急剧下降,甚至无法工作,而无法快速跟踪时延变化是出现偶现回声的重要因素。在这方面你会遇到这些问题:
- 怎么增强估计算法鲁棒性?
- 如何降低计算量,又不影响效果?
- 怎么覆盖更多设备?
- 等等