webrtc 的回声抵消(aec、aecm)算法简介
webrtc 的回声抵消(aec、aecm)算法主要包括以下几个重要模块:1.回声时延估计 2.NLMS(归一化最小均方自适应算法) 3.NLP(非线性滤波) 4.CNG(舒适噪声产生),一般经典aec算法还应包括双端检测(DT)。考虑到webrtc使用的NLMS、NLP和CNG都属于经典算法范畴,故只做简略介绍,本文重点介绍webrtc的回声时延估计算法,这也是webrtc回声抵消算法区别一般算法(如视频会议中的算法)比较有特色的地方。
1) 回声时延估计
回声延时长短对回声抵消器的性能有比较大的影响(此处不考虑pc上的线程同步的问题),过长的滤波器抽头也无法实际应用,因此时延估计算法就显得比较重要了。常用且容易想到的估计算法是基于相关的时延估计算法(学过通信原理的应该不会陌生),另外相关算法在语音编码中也得到广泛的应用,如 amr系列,G.729系列 ,G.718等编码器。在语音信号自相关求基音周期时,由于编码器一般按帧处理,帧长度一般是10或20ms,在该时延范围内搜索基音周期运算量较小,然而对于回声抵消的应用场合,延时搜索范围比较大,带来很高的运算复杂度。在手持终端设备上,我们需要考虑移动环境的变化对算法性能的影响,比如时延是否随机变化,反射路径线性还是非线性,以及运算量(电池)是否符合要求,则更为复杂。
回到webrtc的回声时延估计,它采用的是gips首席科学家Bastiaan的算法。下面介绍一下该算法的主要思想:
设1表示有说话音,0表示无说话音(静音或者很弱的声音),参考端(远端)信号x(t)和接收端(近端)信号y(t)可能的组合方式有以下几种:(0,0),(0,1),(1,0),(1,1),
(0,0)表示远端和近端都是比较弱的声音,(1,1)表示远端和近端都是比较强的声音,webrt的c代码默认其它两种情况是不可能发生的。设在时间间隔p上,即p=1,2,…,P, 频带q,q=1,2,…,Q上,输入信号x加窗(如汉宁窗)后的功率谱用Xw(p,q)来表示,对每个频带中的功率谱设定一个门限Xw(p,q)_threshold,
如果 Xw(p,q) >= Xw(p,q)_threshold , 则Xw(p,q) =1;
如果 Xw(p,q) < Xw(p,q)_threshold , 则Xw(p,q) =0;
同理,对于信号y(t),加窗信号功率谱Yw(p,q)和门限Yw(p,q)_threshold,
如果 Yw(p,q) >= Yw(p,q)_threshold , 则Yw(p,q) =1;
如果 Yw(p,q) < Yw(p,q)_threshold , 则Yw(p,q) =0;
考虑到实际处理的方便,在webrtc的c代码中,将经过fft变换后的频域功率谱分为32个子带,这样每个特定子带 Xw(p,q)的值可以用1个比特来表示,总共需要32个比特,只用一个32位数据类型就可以表示了。
webrtc对参考信号定义了75个32位binary_far_history的数组存放历史远端参考信号,定义了16个32位binary_near_history的数组存放历史近端参考信号,最近的值都放在下标为0的数组中,使用
binary_near_history[15]的32位bit与binary_far_history数组中75个32位bit分别按位异或,得到75个32位比特数据,32位bit的物理意义是近似地使用功率谱来统计两帧信号的相关性。统计32位结果中的1的个数存于bit_counts中,接下来用对bit_counts进行平滑防止延时突变,得到mean_bit_count,可以看出 mean_bit_count 越小,则表明近端数据与该帧的远端数据越吻合,两者的时延越接近所需要的延时数值,用value_best_candidate表示。剩下的工作是对边界数值进行保护,如果value_best_candidate接近最差延时(预设),则表明数值不可靠,这时不更新延时数据;如果数据可靠,则进一步使用一阶markvo模型,比照上一次时延数据确定本次最终的更新时延last_delay.