一、回声消除算法模型

  先来分析下自适应回声消除的主要组成部分,大体上可以把回声消除模型分为两个部分

  1. 横向滤波器结构
  2. 滤波器系数自适应与步长控制

  横向滤波器用脉冲响应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实现,可以有哪些改进的思路。本人水平有限,这里先分享出来,欢迎各位朋友批评指正不足之处!

  1. 最优初始值问题,Speex虽然采用了MDF做为长延时滤波,但本质上仍然是时域滤波原理,只是在频域做罢了。那么为了尽可能的在启动时快速收敛,滤波器权向量的初始值问题就不好简单的用0来初始化。
  2. 回声对每个频点的影响是不同的,不能用一个泄露因子来表示,如果在频域进行分段处理,每段采用不同的泄露因子,应是可行的一个思路
  3. 没有考虑不同扬声器到麦克风回声路径的非线性差异。这个差异在手机端效果效果很明显,如果对远端参考信号做非线性处理,可以弱化这个影响。

LMS、NLMS最优步长理论分析与Speex回声消除可能的改进想法的更多相关文章

  1. speex 回声消除的用法

    speex 回声消除的用法 分类: speex AEC 回声消除 2012-11-13 11:24 1336人阅读 评论(0) 收藏 举报 speex的回声消息 就是speex_echo_cancel ...

  2. Speex回声消除代码分析

    先说明下,这里的代码流程是修改过的Speex流程,但与Speex代码差异不大,应该不影响阅读.   (1)用RemoveDCoffset函数进行去直流 (2)远端信号预加重后放入x[i+frame_s ...

  3. Speex回声消除原理深度解析

    这里假设读者具有自适应滤波器的基础知识.Speex的AEC是以NLMS为基础,用MDF频域实现,最终推导出最优步长估计:残余回声与误差之比.最优步长等于残余回声方差与误差信号方差之比,这个结论可以记下 ...

  4. Speex Acoustic Echo Cancellation (AEC) 回声消除模块的使用

    背景:回声与啸叫的产生  http://blog.csdn.net/u011202336/article/details/9238397 参考资料:  http://www.speex.org/doc ...

  5. 回声消除中的LMS和NLMS算法与MATLAB实现

    自适应滤波是数字信号处理的核心技术之一,在科学和工业上有着广泛的应用领域.自适应滤波技术应用广泛,包括回波抵消.自适应均衡.自适应噪声抵消和自适应波束形成.回声对消是当今通信系统中普遍存在的现象.声回 ...

  6. speex与webrtc回声消除小结

    回声消除AEC包含:   延时估计对齐+线性自适应滤波器+NLP(双讲检测.处理)+舒适噪声CNG 一.speex aec 1.没有NLP 2.只考虑实时DSP系统,即是没有延时对齐等 3.自适应滤波 ...

  7. 回声消除(AEC)原理

    一.前言 因为工作的关系,笔者从2004年开始接触回声消除(Echo Cancellation)技术,而后一直在某大型通讯企业从事与回声消除技术相关的工作,对回声消除这个看似神秘.高端和难以理解的技术 ...

  8. 声学回声消除(Acoustic Echo Cancellation)

    回声就是声音信号经过一系列反射之后,又听到了自己讲话的声音,这就是回声.一些回声是必要的,比如剧院里的音乐回声以及延迟时间较短的房间回声:而大多数回声会造成负面影响,比如在有线或者无线通信时重复听到自 ...

  9. Flex Flash Player回声消除的最佳方法

    Adobe Flash Player 已经成为音频和视频播放的非常流行的工具.实际上,目前大多数因特网视频均使用 Flash Player观看. Flash Player 通过将许多技术进行组合可以提 ...

随机推荐

  1. Day 11 文件和异常

    文件和异常 在实际开发中,常常需要对程序中的数据进行持久化操作,而实现数据持久化最直接简单的方式就是将数据保存到文件中.说到“文件”这个词,可能需要先科普一下关于文件系统的知识,对于这个概念,维基百科 ...

  2. 1、DataGridView

    DataGridView赋值后 通过RowPostPaint事件绘制行号 private void AddXh() { DataGridViewTextBoxColumn col = new Data ...

  3. c3p0 连接池配置

    C3P0 可使用properties 配置文件方式,将c3p0.properties放在classpath目录下,如果为WEB应用,放在WEB-INF\classes下 c3p0.properties ...

  4. php第十六节课

    分页 <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 private $ ...

  5. C++实现双人枪战游戏

    //单机版枪战游戏,喜欢就拿走,把赞留下//by floatiy #include<iostream> #include<cstdio> #include<windows ...

  6. uva 524(Prime Ring Problem UVA - 524 )

    dfs练习题,我素数打表的时候j=i了,一直没发现实际上是j=i*i,以后可记住了.还有最后一行不能有空格...昏迷了半天 我的代码(紫书上的算法) #include <bits/stdc++. ...

  7. [LUOGU]4932 浏览器

    \(\_\_stdcall\)大佬出的题\(Orz\) 我们惊奇地发现,加入\(\_\_popcount(x)\)和\(\_\_popcount(y)\)的奇偶数性相同,那么\(\_\_popcoun ...

  8. dubbo服务telnet命令的使用

    转自:https://www.cnblogs.com/feiqihang/p/4387330.html dubbo服务发布之后,我们可以利用telnet命令进行调试.管理.Dubbo2.0.5以上版本 ...

  9. opencv图像阈值设置的三种方法

    1.简单阈值设置   像素值高于阈值时,给这个像素赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色).这个函数就是 cv2.threshhold().这个函数的第一个参数就是原图像 ...

  10. Android传递Bitmap的两种简单方式及其缺陷

    Android传递Bitmap的几种简单方式 一,通过Intent的Bundle. 比如有两个activity,A,B,从A进入B.先在A中将Bitmap写进去: Resources res=getR ...