先说明下,这里的代码流程是修改过的Speex流程,但与Speex代码差异不大,应该不影响阅读。
 
(1)用RemoveDCoffset函数进行去直流
(2)远端信号预加重后放入x[i+frame_size],近端信号预加重后放入input缓冲区
(3)前M-1帧的远端频域信号移位,为当前帧频域信号腾出空间
(4)用spx_fft函数进行FFT变换,变换后的系数存在X中
(5)计算当前远端信号当前帧的方差Sxx。(去直流操作后,意味着均值可以视为零
(6)当前远端时域信号移位,x[i] = x[i+frame_size],50%交叠处理
(7)先用前景滤波器进行滤波
(8)将滤器后的输出进行反变换
(9)再用近端信号(麦克风语音)减去滤波输出得到前景滤波器的语差信号
(10)再用mdf_inner_prod计算前景滤后器的时域误差总功率
(11)使用mdf_adjust_prop计算背景滤波器的P步长,结果存放在prop中
(12)用weighted_spectral_mul_conj函数计算背景滤波器频域系数需要调整多少量,(其思想为LMS:步长乘以W*E)
power_1 最优步长因子,具体可以参考Mader算法,与prop相乘得到最化步长
prop   为归一化后的背景滤波器各频率的系数幅度。与power_1相乘
X 为转换到频域后的远端信号
E       为转换到频域后的误差信号
PHI     输出结果:背景滤波器频域系数需要调整的量
(13)背景滤波器频域系数调整:W[j*N+i] = W[j*N+i]+ PHI[i]
(14)防止循环卷积处理(重叠保留法变循环卷积为线性卷积,把相关块的FFT系数中的后半部分置为零)
(15)根据调整后的背景滤波器对远端信号再进行频域滤波处理
(16)滤波后的输出进行反变换,存到y
(17)在时域计算两次滤波之间的误差及两次滤波之间误差的功率Dbf
(18)在时域计算背景滤波器滤波后的误差和背景滤波器滤波后误差的方差See。至此我们得到:
Sff 前景滤波后的方差
See 背景滤波后的方差
Dbf 前景滤波与背景滤波之间方差
(19)利用Sff、See、Dbf来计算是否需要更新前景滤波器(总的来说,当Dbf值比较大时需要更新前景滤波器系数)
(20)如果需要更新前景滤波器系数则把背景滤波器系数给前景滤波器,并平滑背景滤波后的时域误差(前景滤波时域语差加上背景滤波器的时域输出),得到总误差,存在e[i+frame_size],这里的总误差,就是总的远端信号回声。
(21)根据总的远端信号回声,计算回声消除后的语音信号,并进行预加重处理,存在out输出缓冲区中(这个步骤是我自己调的)
(22)误差缓冲区移动,为下一帧处理做好准备
(23)计算背景滤波器输出与误差的互相关Sey、背景滤波器的自相关Syy
(24)再把语差信号与输出信号(前面都置为0)都是变换到频域
(25)再计算变换后的E、Y、X的功率谱,对应的分别是Rf、Xf、Xf
(26)通过Xf平滑得到远端信号功率谱power
power[j] = (ss_1*power[j]) + 1 + (ss*Xf[j]);
(27)当(前一帧的)泄露系数小于一个阀值(0.5)时,重新估算远端信号功率谱power
(28)计算ey协方差,得到e和y的相关系数 Pey,标准差 Pyy。(Pey为相关系数:ey协方差/y标准差)
(29)计算远端信号泄露系数
参考论文:On Adjusting the Learning Rate in Frequency Domain Echo Cancellation With Double-Talk
先计算递归平均系数:
alpha = beta0*Syy/See; 这里beta0为泄露估计的学习速率
alpha_1 = 1-alpha;
  再递归计算相关系数Pey和标准差Pyy
  最后得到泄露系数:leak_estimate = Pey/Pyy
(30)计算残余回声与误差的比率,并做上下限处理。
RER = (0.0001*Sxx + 3.0f*leak_estimate*Syy) / See; 
  下限:Sey*Sey/(1+See*Syy)
  上限:0.5
(31)判断收敛条件:sum_adapt > M 且leak_estimate > 0.03
如果滤波器收敛:
r = 0.7*leak_estimate*Yf + 0.3*RER*(RF+1) // 计算残余回声的功率
// 计算最优步长因子,具体可以参考Mader算法,或者到本文作者那里寻求帮助
power_1[i] = r / (e*(power[i]+10)); 
如果没有收敛
当Sxx > N*1000时,按如下计算adapt,否则adapt_rate值为0
adapt_rate = 0.25f*Sxx/See;
sum_adapt += adapt_rate
(32)把残余回声保存在last_y,这是为了语音增强时去掉回声的影响

Speex回声消除代码分析的更多相关文章

  1. LMS、NLMS最优步长理论分析与Speex回声消除可能的改进想法

    一.回声消除算法模型 先来分析下自适应回声消除的主要组成部分,大体上可以把回声消除模型分为两个部分 横向滤波器结构 滤波器系数自适应与步长控制 横向滤波器用脉冲响应w(n)[有的地方也称为回声路径]与 ...

  2. speex 回声消除的用法

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

  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. 基于深度学习的回声消除系统与Pytorch实现

    文章作者:凌逆战 文章代码(pytorch实现):https://github.com/LXP-Never/AEC_DeepModel 文章地址(转载请指明出处):https://www.cnblog ...

  6. speex与webrtc回声消除小结

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

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

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

  8. Flex回声消除的最佳方法

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

  9. 音频算法speex中的aec分析以及解析

    算法原理: Speex的AEC是以NLMS(Normalized Least Mean Square)为基础,用MDF(multidelay block frequency domain)频域实现,最 ...

随机推荐

  1. js 原型模型重写1

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  2. php 扩展 redis

    1.通过phpinfo 查看php的版本(  要注意php 是nts 还是ts 通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabl ...

  3. Cocos2d-x利用CCHttpRequest获取网络图片并显示

    利用CCHttpRequest获取网上http地址的图片并缓存到本地生成CCSprite用于显示 //图片结构class imgstruct : public CCObject { public: i ...

  4. Flex坐标

    flash和flex针对不同的目的,提供了3种不同的坐标系. 全局的就是(stage级别的) 本地坐标系(组件级别的) 内容坐标系(相对于本地坐标系说的) 这些坐标系的点是可以转换的,并且有相应的方法 ...

  5. IDA Script: Remove empty auto labels

    http://simeonpilgrim.com/blog/2010/03/25/ida-script-remove-empty-auto-labels/ #include <idc.idc&g ...

  6. iOS设置某个界面强制横屏,进入就横屏

    最近有一个项目,例如:A界面跳转到B界面,A界面是竖屏的,B界面进入就要横屏. 花了半天的时间在网上搜索解决方案,有些论坛的大牛也就贴两行代码,具体实现也没有,对我们这种菜鸟造成一万点真实伤害.为了避 ...

  7. JDBC-ODBC桥乱码问题解决方案

    按照网上提供的ODBC连接数据库的相关资料编写代码,成功编译后运行发现,非中文字段显示正确,而中文字段却是每个汉字以?显示.关于这方面的错误baidu或google下可以找到很多解答方案,我也尝试过其 ...

  8. 微软停服 XP系统到底伤害了谁?

    http://majihua.baijia.baidu.com/article/10386 微软现在成了招人恨的角色,因为其史上最成功的操作系统WINDOWS XP在4月8日就将停止服务,而社会上对X ...

  9. 数据结构复习:直接插入排序与二分插入排序的C++实现

    1.直接插入排序 直接插入排序的过程可以理解为一个固定长度的数组被分为两个集合,即已排序集合和未排序. 开始时已排序集合为空,而未排序集合即为整个数组.当排序开始后插入一个对象,已排序集合元素数目加1 ...

  10. Owin管道与asp.net管道模型

    ------2016.3.6 更新 文中提到没有Microsoft.Owin.Host.SystemWeb 这个dll 便不会加载Startup.Configuration,因为这个dll 其中有个O ...