一、回声消除算法模型
先来分析下自适应回声消除的主要组成部分,大体上可以把回声消除模型分为两个部分
- 横向滤波器结构
- 滤波器系数自适应与步长控制
横向滤波器用脉冲响应w(n)【有的地方也称为回声路径】与远端说话者信号u(n)卷积得到回声估计,并用y(n)表示该估计。麦克风输出信号做为期望响应d(n),从期望响应d(n)中减去滤波器的”合成回声”,得到误差信号e(n)。通过不断的调整滤波器系数w(n)使误差信号的均方值最小化,其结果就是:误差信号为本地语音提供了一个近似的估计。这就是为什么这样的结构能去掉回声的原因。
二、LMS算法最优步长分析
下面我们重点说一下LMS滤波器系数自适应更新中的步长控制问题,也就是如何获得最优步长的问题。我们首先把期望响应用向量的形式表示如下:
\[d(n) = {w^H}u(n) + v(n)\]
上式中,w是横向滤波器的未知参数向量,v(n)为加性干扰噪声。通过LMS滤波器计算得到的抽头权向量是对w的估计,它们之间的失配用加权误差向量
\[\varepsilon (n + 1) = w - \hat w(n)\]
来衡量,由横向滤波器系数的的自适应更新机制
\[\hat w(n + 1) = \hat w(n) + \mu u(n)e(n)\]
可得
\[\varepsilon (n + 1) = \varepsilon (n) - \mu u(n)e(n)\]
如果我们对抽头权向量n次迭代到n+1次迭代的抽头权向量的增量变化最小为准则来选择最优步长,即使
\[E\{ |\varepsilon (n + 1){|^2}\} - E\{ |\varepsilon (n){|^2}\} \]
达到最小,为求最优步长,将其展开,得到
\[E\{ |\varepsilon (n + 1){|^2}\} - E\{ |\varepsilon (n){|^2}\} = {\mu ^2}E\{ {e^2}(n)|u(n){|^2}\} - 2\mu E\{ e(n){\varepsilon ^T}(n)u(n)\} \]
设额外误差向量(有的地方也称为无干扰误差,即假设没有噪声情况下的系数输出误差)与滤波器权值误差向量之间的关系为
\[\xi (n) = {\varepsilon ^T}(n)u(n)\]
则
\[E\{ |\varepsilon (n + 1){|^2}\} - E\{ |\varepsilon (n){|^2}\} = {\mu ^2}E\{ {e^2}(n)|u(n){|^2}\} - 2\mu E\{ e(n)\xi (n)\} \]
对上式两边求导,并置导数为0,很容易就可以得到最优步长为
\[{\mu _{opt}}(n) = \frac{{E\{ e(n)\xi (n)\} }}{{E\{ {e^2}(n)|u(n){|^2}\} }}\]
又因为额外误差可以视为系统输出误差与加性干扰噪声之差
\[\xi (n) = e(n) - v(n)\]
再假设加性干扰噪声信号与额外误差信号相关独立,则最优步长可以写为
\[{\mu _{opt}}(n) \approx \frac{{E\{ e(n)\xi (n)\} }}{{|u(n){|^2}E\{ {e^2}(n)\} }} = \frac{{E\{ {e^2}(n)\} - E\{ {v^2}(n)\} }}{{|u(n){|^2}E\{ {e^2}(n)\} }}\]
可以看出,当噪声信号不存在时,LMS算法的最优步长等于固定步长的NLMS算法
三、NLMS算法最优步长分析
下面再分析下NLMS滤波器的最优步长,NLMS横向滤波器系数的的自适应更新机制为
\[w(n + 1) = w(n) + \frac{\mu }{{|u(n){|^2}}}u(n)e(n)\]
两边减去w,整理可得
\[\varepsilon (n + 1) = \varepsilon (n) - \frac{\mu }{{|u(n){|^2}}}u(n)e(n)\]
我们同样对抽头权向量n次迭代到n+1次迭代的抽头权向量的增量变化最小为准则来选择最优步长,即使
\[E\{ |\varepsilon (n + 1){|^2}\} - E\{ |\varepsilon (n){|^2}\} = {\mu ^2}E\left\{ {\frac{{|e(n){|^2}}}{{|u(n){|^2}}}} \right\} - 2\mu E\left\{ {\frac{{e(n)\xi (n)}}{{|u(n){|^2}}}} \right\}\]
最小,按上面分析LMS滤波器时的思路进行求导并整理,最终得到NLMS的最优步长为
\[{\mu _{opt}} = \frac{{E\{ e(n)\xi (n)/|u(n){|^2}\} }}{{E\{ |e(n){|^2}/|u(n){|^2}\} }}\]
为了简化最优步长的计算,我们假设从一次迭代到下一次迭代的输入信号能量的波动足够小,以满足以下近似
\[E\{ e(n)\xi (n)/|u(n){|^2}\} = E\{ e(n)\xi (n)\} /E\{ |u(n){|^2}\} \]
和
\[E\{ |e(n){|^2}/|u(n){|^2}\} = E\{ |e(n){|^2}\} /E\{ |u(n){|^2}\} \]
则最优步长可以重写为
\[{\mu _{opt}} = \frac{{E\{ e(n)\xi (n)\} }}{{E\{ |e(n){|^2}\} }}\]
又因为加性干扰噪声信号与额外误差信号相关独立,再次重写最优步长
\[{\mu _{opt}} = \frac{{E\{ e(n)\xi (n)\} }}{{E\{ |e(n){|^2}\} }} = \frac{{E\{ [\xi (n) + v(n)]\xi (n)\} }}{{E\{ |e(n){|^2}\} }} = \frac{{E\{ |\xi (n){|^2}\} }}{{E\{ |e(n){|^2}\} }} = \frac{{E\{ |{\varepsilon ^T}(n)u(n){|^2}\} }}{{E\{ |e(n){|^2}\} }}\]
如果我们接下来假设输入信号u(n)的频谱中,每个频点分别对加权误差向量频谱的对应频点的影响都是相同的,那么
\[E\{ |{\varepsilon ^T}(n)u(n){|^2}\} \approx E\{ |{\varepsilon ^T}(n){|^2}\} E\{ |u(n){|^2}\} \]
最终得到的最优步长可以近似为
\[{\mu _{opt}} = \frac{{E\{ |{\varepsilon ^T}(n)u(n){|^2}\} }}{{E\{ |e(n){|^2}\} }} \approx \frac{{E\{ |{\varepsilon ^T}(n){|^2}\} E\{ |u(n){|^2}\} }}{{E\{ |e(n){|^2}\} }}\]
细心的朋友可能已经看出来了,这个结论与Speex回声消除原理深度解析一文中的最优步长结论意义上可以认为是相同的(采用的符号表示不同,不影响理解),这说明无论从哪个角度分析,在抽头权向量均方偏差最小的约束准则下,得到的最优步长的结论都是一样的。
四、改进思路
既然原理已经分析清楚了,现在再来看看,针对这个原理的Speex实现,可以有哪些改进的思路。本人水平有限,这里先分享出来,欢迎各位朋友批评指正不足之处!
- 最优初始值问题,Speex虽然采用了MDF做为长延时滤波,但本质上仍然是时域滤波原理,只是在频域做罢了。那么为了尽可能的在启动时快速收敛,滤波器权向量的初始值问题就不好简单的用0来初始化。
- 回声对每个频点的影响是不同的,不能用一个泄露因子来表示,如果在频域进行分段处理,每段采用不同的泄露因子,应是可行的一个思路
- 没有考虑不同扬声器到麦克风回声路径的非线性差异。这个差异在手机端效果效果很明显,如果对远端参考信号做非线性处理,可以弱化这个影响。