热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

回声消除(AEC)初体验之matlab仿真

从代码传送门查看本博客所使用测试的源码。一个普通的音频系统结构如下图所示。假设结构中所有的增益都是1,则可以得到以下关系式。由上式可以看出来spk发出的信号,会被麦克

从代码传送门查看本博客所使用测试的源码。

一个普通的音频系统结构如下图所示。


假设结构中所有的增益都是1,则可以得到以下关系式。

由上式可以看出来spk发出的信号,会被麦克风采集到,然后又通过codec芯片重新播放出来,从而形成回声。为抑制这种现象提出回声消除算法


经过回声消除后的理想效果如以下公式,即从MIC传回codec芯片的信号仅仅包含信号源A的声音信号。

回声消除算法功能模块主要有两个:一个是检测声源信号的检测器;另一个是用来生成参考信号的滤波器。


自适应滤波算法用于自动跟踪输入的参考信号,根据MICin与REFin信号之间的相关性,生成随着输入信号变化的滤波器参数,从而生成预测的回声信号。现在主流的自适应滤波算法是最小均方(LMS-least mean square)算法,以及基于LMS算法衍生出来的一系列归一化最小均方(NLMS)算法、块最小均方误差(BLMS)算法、归一化块处理最小均方(NBLMS)算法、Filter-X LMS算法,另外还有递推最小二乘(RLS)算法、仿射投影滤波器(affine projection filter)算法等等。

app中算法相关的最佳参数搭配通过Filter.plot文件计算,如我想计算RLS滤波算法的参数length、ff可以执行如下代码。

clear all; 
[x,Fs] = audioread('handel.wav');  
[y,Fs1]=audioread('handel_echo.wav');


lOng=[2 4 8 16 32 64 128];
ff=(0.9:0.002:1);
co_lms=zeros(length(long),length(mu));
co_rls=zeros(length(long),length(ff));
t0=clock;
StartMatlabPool_fun(2);
for i=1:length(long)
    for j=1:length(ff)
       ha =dsp.RLSFilter('Length',long(i),'ForgettingFactor',ff(j));
        [res,e] = ha(x,y);
        co_rls(i,j)=corr(x,res);
    end
end
etime(clock,t0)
CloseMatlabPool_fun;
value=max(max(co_rls));
[row, col]=find(value==co_rls)
[L,F]=meshgrid(long,ff);
figure;
surf(L,F,co_rls');
title('Correlation Function of Filter Order and Stepsize');
xlabel('Filter Order'); ylabel('Stepsize'); zlabel('Correlation');

执行结果如下。

>> test_plot
Starting parallel pool (parpool) using the 'local' profile ...
connected to 2 workers.

ans =

  444.8310

Parallel pool using the 'local' profile is shutting down.

row =

     1


col =

    51


根据结果分析lOng=2(当ff=1时候,相关系数取值已经趋近于1,long取值对其影响已经可以忽略),ff=1

在echo_algo_hallelu.m文件中修改代码如下,然后执行。

clear all;  

[x,Fs] = audioread('handel.wav');  
[y,Fs1]=audioread('handel_echo.wav');

ha =dsp.RLSFilter(2, 'ForgettingFactor', 1);
[res,e] = ha(x,y);

%Regenerated Sound from Echoed Sound
sound(res,Fs);
audiowrite('handle Regenerated.wav',res,Fs)

%Original Signal
subplot(4,1,1); plot(x);
title('Original Signal');
xlabel('Time Index'); ylabel('Signal Value');

%Echoed Signal
subplot(4,1,2); plot(y);
title('Echoed Signal');
xlabel('Time Index'); ylabel('Signal Value');

%Regenerated Signal
subplot(4,1,3); plot(e);
title('Regenerated Signal');
xlabel('Time Index'); ylabel('Signal Value'); 
co=corr(x,res);
subplot(4,1,4); bar(co);

得到如下执行结果


或者在对应app中设置length=2,Fogettingfactor=1得到以下结果。


对于LMS滤波器参数寻优,则将代码改动如下。

clear all;  
[x,Fs] = audioread('handel.wav');  
[y,Fs1]=audioread('handel_echo.wav');


lOng=[2 4 8 16 32 64 128];
mu=(0.002:0.02:0.8);
ff=(0.9:0.002:1);
co_lms=zeros(length(long),length(mu));
co_rls=zeros(length(long),length(ff));
bar=waitbar(0,'参数寻优进度');
steps=length(long)*length(mu);
StartMatlabPool_fun(4);
for i=1:length(long)
    for j=1:length(mu)
       ha = dsp.LMSFilter('Length',long(i),'StepSize',mu(j));
        [res,e] = ha(x,y);
        co_lms(i,j)=corr(x,res);
    end
    waitbar((i*j)/steps);
end
CloseMatlabPool_fun;
close(bar);
value=max(max(co_lms));
[row, col]=find(value==co_lms);
length=long(row)
stepSize=mu(col)
[L,M]=meshgrid(long,mu);
figure;
surf(L,M,co_lms');
title('Correlation Function of Filter Order and Stepsize');
xlabel('Filter Order'); ylabel('Stepsize'); zlabel('Correlation');

执行结果如下。

test_plot
Starting parallel pool (parpool) using the 'local' profile ...
connected to 4 workers.
Parallel pool using the 'local' profile is shutting down.

length =

     2


stepSize =

    0.0220

同样在app中验证此组参数的效果。


在信噪比大于 60 dB 的理想信道中仿真自适应算法,LMS 和 NLMS 具有很好的收敛特性,回声可以有大比例的衰减。实际通信信道中,绝大多数近端场所(如会场)都有较大环境背景声音,回声比背景声电平只大 0~20 dB,在这样的系统中,LMS 和 NLMS 算法几乎无法收敛。AEC 算法要求 y(n)序列、x(n)序列保持严格同步(延时控制在100mS之内应该就可以,而且应该也可以提前获取固定延时量,然后在算法中做补偿),即有固定的小于预测窗的延迟时间,否则预测无法收敛。

回声检测只需要检测SPK是否有声音输出,如果输出就控制自适应算法模块生成回声预测信号,把MICin中所有关于SPK的部分全部滤掉,不用分近端远端。

滤波器一般用FIR或者IIR都可以。

集中列出app中不同的滤波器最优参数对应的回声消除效果对比。






在计算过程中,matlab通过matlabpool_open指令打开了并行计算模式。

并行计算模式启动打开指令如下(我电脑上最大允许开启四个核,默认的也是四个核)

StartMatlabPool_fun(4);
%%  此间放置需要进行并行计算的代码部分

CloseMatlabPool_fun;

实现函数代码如下

function StartMatlabPool_fun(size)
%====================================================================
%启动 MATLAB 并行运算(ling)
%StartMatlabPool(size)
%====================================================================
%输入参数:
%   [1] size 为 CPU 核心数量
p = gcp('nocreate'); 
if isempty(p)
    poolsize = 0;
else
    poolsize = p.NumWorkers;
end
if poolsize == 0
    if nargin == 0
        parpool('local');
    else
        try
            parpool('local',size);
        catch ce
            parpool;
            fail_p = gcp('nocreate');
            fail_size = fail_p.NumWorkers;
            display(ce.message);
            display(strcat('输入的size不正确,采用的默认配置size=',num2str(fail_size)));
        end
    end
else
    disp('parpool start');
    if poolsize ~= size
        closematlabpool();
        startmatlabpool(size);
    end
end

我对比了使用四核并行计算和两核并行计算之间的速度,以下是加速的效果,可以看出节省了12秒钟≈3%的时间节约,但考虑到Matlab重复运行相同的程序速度回一次比一次快的特点,这12秒钟时间是不是并行计算省出来的真不好说。

>> test_plot
parpool start

ans =

  426.6580

Parallel pool using the 'local' profile is shutting down.
>> test_plot
Starting parallel pool (parpool) using the 'local' profile ...
connected to 2 workers.

ans =

  438.2910

Parallel pool using the 'local' profile is shutting down.



推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文介绍了如何在Jquery中通过元素的样式值获取元素,并将其赋值给一个变量。提供了5种解决方案供参考。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
author-avatar
手机用户2602913901
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有