在实时音频互动场景中,除了咱们上一篇讲到的编解码会影响音质与体验,在端上,降噪、回声消除、自动增益模块一样起着重要做用。在本篇内容中咱们将主要围绕回声消除和降噪模块,讲讲实时互动场景下的技术挑战,以及咱们的解决思路与实践。前端
在语音通讯系统中,回声消除(Echo Cancellation)一直扮演着核心算法的角色。通常来讲,回声消除的效果受诸多因素的影响,包括: 声学环境,包括反射,混响等;算法
通话设备自己声学设计,包括音腔设计以及器件的非线性失真等;数据库
系统性能,处理器的计算能力以及操做系统线程调度的能力。数组
声网回声消除算法在设计之初,就将算法性能、鲁棒性和普适性做为最终的优化目标,这一点对于一个优秀的音视频 SDK 来讲相当重要。markdown
首先,回声是怎么产生的?简单来说,就是你的声音从对方的扬声器发出,这个声音又被他的麦克风给收录了进去,这个被麦克风收录的声音又传回到你这一端,你就听到了回声。为了消除回声,咱们就要设计一个算法将这个声音信号从麦克风信号中去除掉。网络
那么声学回声消除模块(AEC, Acoustic Echo Cancellation)是如何消除回声的呢?具体的步骤见以下简图所示:函数
第一步须要找到参考信号/扬声器信号(蓝色折线)跟麦克风信号(红色折线)之间的延迟,也就是图中的 delay=T。post
第二步根据参考信号估计出麦克风信号中的线性回声成分,并将其从麦克风信号中减去,获得残差信号(黑色折线)。性能
第三步经过非线性的处理将残差信号中的残余回声给完全抑制掉。测试
与以上的三个步骤相对应,回声消除也由三个大的算法模块组成:
延迟估计(Delay Estimation)
线性自适应滤波器(Linear Adaptive Filter)
非线性处理(Nonlinear Processing)
其中「延迟估计」决定了AEC的下限,「线性自适应滤波器」决定了 AEC 的上限,「非线性处理」决定了最终的通话体验,特别是回声抑制跟双讲之间的平衡。
注:双讲是指在交互场景中,互动双方或多方同时讲话,其中一方的声音会受到抑制,从而出现断断续续的状况。这是因为回声消除算法“矫枉过正”,消除了部分不应去除的音频信号。
接下来,咱们先围绕这三个算法模块,分别讲讲其中的技术挑战与优化思路。
受具体系统实现的影响,当把参考信号与麦克风信号分别送入 AEC 模块进行处理之时,它们所存入的数据 buffer 之间存在一个时间上的延迟,即咱们在上图中看到的“delay=T”。假设这个产生回声的设备是一部手机,那么声音从它的扬声器发出后,一部分会通过设备内部传导到麦克风,也可能会通过外部环境传回到麦克风中。因此这个延迟就包含了设备采集播放 buffer 的长度,声音在空气中传输的时间,也包含了播放线程与采集线程开始工做的时间差。正是因为影响延迟的因素不少,所以这个延迟的值在不一样系统,不一样设备,不一样 SDK 底层实现上都各不相同。 它在通话过程当中也许是一个定值,也有可能会中途变化(所谓的 overrun 和 underrun)。这也是为何一个 AEC 算法在设备 A 上可能起做用,但换到另外一个设备上可能效果会变差。延迟估计的精确性是 AEC 可以工做的先决条件,过大的估计误差会致使 AEC 的性能急剧降低,甚至没法工做,而没法快速跟踪时延变化是出现偶现回声的重要因素。
加强延迟估计算法鲁棒性
传统算法一般经过计算参考信号跟麦克风信号之间的相关性来决定延迟。相关性的计算能够放在频域上,典型的就是 Binary Spectrum 的方法,经过计算单频点上的信号能量是否超过必定门限值,实际将参考信号跟麦克风信号映射成了两维的0/1数组,而后经过不断移动数组偏移来找到延迟。最新的 WebRTC AEC3 算法经过并行的多个NLMS线性滤波器来寻找延迟,这个方法在检测速度及鲁棒性方面都取得了不错的效果,可是计算量很是大。当在时域上计算两个信号的互相关时,一个明显的问题是语音信号包含大量的谐波成分而且具备时变特性,它的相关信号经常呈现出多峰值的特征,有的峰值并不表明真正的延迟,而且算法容易受到噪声干扰。
声网延迟估计算法经过下降信号之间的相关性(de-correlate),可以有效抑制 local maxima 的值以大大加强算法的鲁棒性。以下图所示,左边是原始信号之间的互相关,右边是声网SDK处理后的互相关,可见信号的预处理大大加强了延迟估计的鲁棒性:
算法自适应,下降计算量
一般延迟估计算法为了下降计算量的须要,会预先假设回声信号出如今某个较低的频段内,这样就能够将信号作完下采样以后再送入延迟估计模块,下降算法的计算复杂度。然而面对市面上数以万计的设备及各类路由,以上的假设每每并不成立。下图是 VivoX20 在耳机模式下麦克风信号的频谱图,可见回声都集中在 4kHz 以上的频段内,传统的算法针对这些 case 都会致使回声消除模块的失效。声网延迟估计算法会在全频段内搜索回声出现的区域,并自适应地选择该区域计算延迟,确保算法在任何设备,路由下都有精确的延迟估计输出。
动态更新音频算法库,提高设备覆盖率
为了确保算法的持续迭代改进,声网维护了一个音频算法的数据库。咱们使用大量不一样测试设备,在不一样声学环境下采集到了各类参考信号和麦克风信号的组合,而它们之间的延迟所有经过离线处理的方式进行标定。除了真实采集的数据,数据库中也包含了大量仿真的数据,包括不一样的说话人,不一样的混响强度,不一样的底噪水平,以及不一样的非线性失真类型。为了衡量延迟估计算法的性能,参考信号与麦克风信号之间的延迟能够随机的变化,用以观察算法对突发延迟变化的响应。
因此判断一个延迟估计算法的优劣,还须要考察:
适应尽可能多的设备、声学环境,且在尽可能短的时间内根据设备、声学环境的因素匹配合适的算法;
在突发随机的延迟变化后,能及时动态调整算法策略。
如下是声网 SDK 与友商之间的延迟估计性能对比,总共使用了数据库中 8640 组测试数据。从图中数据能够看出,声网 SDK 能够在更短的时间内找到大多数测试数据的初始时延。在 96% 的测试数据中,声网 SDK 能在 1s 以内找到它们正确的延迟,而友商这一比例为 89%。
第二个测试的是在通话过程当中出现随机的延迟抖动,测试延迟估计算法要在尽可能短的时间内找到精确的延迟值。如图中所示,声网 SDK 在 71% 的测试数据中能在 3s 以内从新找到变化后的精确延迟值,而友商这个比例为 44%。
对于线性滤波器,已有大量的文献介绍其原理及实践。当应用于回声消除的应用场景,主要考虑的指标包含收敛速度(convergence rate),稳态失调(steady-state misalignment)及跟踪性能(tracking capability)。这些指标之间每每也有冲突,譬如较大的步长能够改善收敛速度,可是会致使较大的失调。这个就是自适应滤波器中的没有免费的午饭定理(No Free Lunch Theorem)。
对于自适应滤波器的类型,除了最为经常使用的 NLMS 滤波器(Model Independent),还可使用 RLS 滤波器(Least Squares Model)或 Kalman 滤波器(State-Space Model)。除了各自理论推导中的各类假设,近似,优化,这些滤波器的性能最终都归结到如何计算最佳的步长因子(在卡尔曼滤波器里面步长因子合并到 Kalman Gain 的计算里面)。在滤波器还没有收敛或是环境传输函数突变的情形下,步长因子须要足够大以跟踪环境变化,当滤波器收敛及环境传递函数变化缓慢的时间段,步长因子应尽可能减少以达到尽量小的稳态失调。对于步长因子的计算,须要考虑自适应滤波器后残余回声跟残差信号间的能量比值,建模为系统的 leakage coefficients。这个变量经常等价于求滤波器系数跟真实传递函数之间的差(Kalman 滤波器里面称为状态空间状态向量偏差),这也是整个估计算法中的难点。除此以外,双讲阶段的滤波器发散问题也是一个须要考虑的点,通常来讲这个问题能够经过调整滤波器结构,使用 two echo path models 来解决。
声网自适应滤波器算法并不使用单一的滤波器类型,而是兼顾了不一样滤波器之间的优势,同时搭配自适应算法计算最优的步长因子。此外,算法经过线性滤波器系数实时估计环境的传递函数,自动修正滤波器长度,以覆盖通讯设备链接 HDMI 外设等高混响,强回声的场景。以下是一个例子,在声网办公室的一个中型会议室中(面积约 20m2,三面玻璃墙),使用 Macbook Pro 经过 HDMI 链接小米电视,图中是线性滤波器时域信号的变化趋势,算法能自动计算并匹配实际环境传递函数的长度(在第 1400 帧左右自动检测出了强混响环境),以优化线性滤波器的性能。
一样的,咱们也使用数据库中大量测试数据进行声网 SDK 与友商之间的性能对比,对比的指标包括稳态失调(滤波器收敛以后对回声的抑制程度)以及收敛速度(滤波器达到收敛状态须要的时长)。第一张图表明自适应滤波器的稳态失调,声网SDK在 47%的测试数据中能达到超过 20dB 的回声抑制,而友商的比例为 39%。
下图显示的是自适应滤波器的收敛速度,声网 SDK 在 51% 的测试样本中能在通话前 3s 以内收敛到稳态,而友商的比例为13%。
非线性处理旨在抑制线性滤波器所没有预测出的回声成分,一般经过计算参考信号,麦克风信号,线性回声以及残差信号间的相关性,或是将相关性直接映射到抑制增益上,或是经过相关性估计出残留回声的功率谱,进一步经过维纳滤波器等传统降噪的算法抑制残留回声。
做为回声消除算法的最后一个模块,除了抑制残留回声以外,非线性处理单元也肩负着监控整个系统是否正常工做的重任,譬如线性滤波器是否由于延迟抖动而没法正常工做?在声网 SDK 回声消除以前是否存在硬件回声消除未能处理的残余回声?
下面是一个简单的例子,经过自适应滤波器估计出的回声能量等内部参数,可以更快的发现延迟变化的现象,而且提示 NLP 采起相应的动做:
随着声网 SDK 覆盖的场景愈来愈广,针对音乐信号的传输成为了一个重要的场景。声网 SDK 针对音乐信号的回声消除体验作了大量的优化,一个典型场景是温馨噪声的估计算法改进。传统算法使用基于 Minimum Statistics 的算法原理对信号中的底噪进行估计,当把这个算法应用于音乐信号时,由于音乐信号比之语音信号更为平稳,所以会太高的估计噪声功率,反映到回声消除中会致使处理后有回声时段与无回声时段间的底噪(背景噪声)不平稳,体验极差。声网 SDK经过信号分类以及模块融合的方式,完全解决了 CNG 估计致使的底噪起伏现象。
除此以外,声网 SDK 还针对全部可能碰到的极端状况,包括非因果系统,设备频率偏移,采集信号溢出,声卡包含系统信号处理等等,都进行了大量的优化,确保算法可以工做在全部的通讯场景中。
降噪对信号音质的影响大于回声消除模块,这一点源自于在降噪算法的设计之初,咱们先验的假设底噪都是平稳信号(至少是短时平稳的),而根据这个假设,音乐跟底噪的区分度明显弱于语音跟底噪的区分度。
声网 SDK 在降噪模块的前端预置了信号分类模块,可以精确的检测出信号的类型,并根据信号的类型调整降噪算法的类型及参数,常见的信号类型包括通常语音、清唱、音乐信号等。下图所示是两个降噪算法处理的信号片断,其中第一个是语音与音乐的混合信号,前15秒为含噪的语音信号,以后是40s是音乐信号,再以后是10s的含噪语音,语谱图从上到下分别是原始信号、友商处理结果、声网SDK处理结果。结果显示在语音段信号降噪性能差很少的前提下,竞品处理过信号中的音乐部分受到了严重的损伤,而声网SDK的处理并无下降音乐的音质。
在第二个例子中,使用的音频是歌手的清唱,清唱中歌手反复发出“啊”的声音。在下图的语谱图中,从上到下分别是原始信号、友商的处理结果、声网 SDK 处理结果。结果显示,友商的降噪处理严重的损伤了原语音的频谱成分,而声网 SDK 完整的保留了原语音的谐波成分,保证了歌手清唱时候的音质体验。
自1967年贝尔实验室的M. M. Sondhi开创性的提出以自适应滤波器的方法来消除回声为开端,无数的研究和实践都投入到了这个语音通讯的最基本问题上。要完美的解决回声问题,除了要有强大的算法做为基础,也须要在工程优化领域作不少优化。声网会持续不断的改进回声消除在各个不一样应用场景下的体验。
在本系列的下一篇内容中,咱们将随着音频信号,从设备端进入现实的网络环境,一边实地环行上海,一边聊聊音频互动场景下的延时、抖动,以及丢包对抗背后的优化策略。(以一张图来简单剧透,敬请期待)