百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

一文读懂回声消除(AEC)

bigegpt 2024-08-05 11:41 2 浏览

数字信号处理系列文章,理论+实践,持续更新,欢迎关注@平凡的兵 一起共成长


音频领域有3A问题,谓3A,是指声学回声消除(AEC, Acoustic Echo Cancel)、背景噪声抑制(ANS, Automatic Noise Suppression)、自动增益控制(AGC, Automatic Gain Control),今天聊一聊AEC。

什么是AEC

从通讯回音产生的原因看,可以分为声学回音(Acoustic Echo)和线路回音(Line Echo),相应的回声消除技术就叫声学回声消除(Acoustic Echo Cancellation,AEC)和线路回声消除(Line Echo Cancellation, LEC), 声学回音是由于在免提或者会议应用中,扬声器的声音多次反馈到麦克风引起的;线路回音是由于物理电子线路的二四线匹配耦合引起的,本讲只讨论声学回声(包括线性回声信号和非线性回声信号)

远端讲话者(A)的声音信号再传输给近端(B)后,在近端设备的扬声器播放出来,经过一系列声学反射,被近端设备的麦克风拾取,又传输给远端(A)的现象。声学回声将导致远端讲话者A在很短时间内,又听到了自己刚才的讲话声音。声学回声的产生过程如图所示。

使用 AEC 技术后,两端声音传输过程改变为如下图所示,进而从底层保证会议场景下声音的干净度。

数学化表示如下图。

远端信号x, 从听筒或喇叭spk播出,并经过空间传播,被麦克风mic接收,近端说话信号也进入麦克风mic,这样麦克风接收到的就是两个信号的叠加,即d。自适应滤波器w对x进行处理获得y(回声信号),d和y的差值作为误差e,传递给自适应滤波器,进行滤波器系数迭代更新。

AEC性能评价指标

指标1:ERLE(Echo Return Loss Enhancement,回声返回衰减增益):

ERLE值越大,则表明回声抵消效果越好。由于双讲或只有近端单讲时,e(n)中包含近端语音,导致很多情况下e(n)的能量远大于回声y(n)的能量,从而ERLE为负值,同时也无法衡量回声部分的消除情况。

对于优秀的回声消除器,ERLE增益必须不低于6dB。

指标2:SupperFactor(能量衰减因子)

? AEC后输出能量与对应远端麦克风信号能量的比值。

指标3:Cohde(输出信号e(n)与麦克风信号d(n)的频谱相关性)

? 该值越接近1,说明输出信号中保留的麦克风信号频谱越多。考虑到麦克风信号d(n)主要由回声信号y(n)和近端语音v(n)构成,因此只有近端单讲情况下cohde的值才能接近1,双讲情况下cohde的值在0.5~0.9(取决于回声信号在该帧的占比),当cohde接近0时说明输出信号几乎不包含任何近端语音和回声的频谱成分。其计算公式如下:

指标4:Cohxe(输出信号e(n)与远端参考信号x(n)的频谱相关性)

该值越接近0,说明输出信号中残留的远端参考信号频谱越少,回声消除越彻底,其计算公式如下:

不同通话状态对应的参数指标:

(1)近端单讲(最大程度保持输出与麦克风信号一致):

? Cohde:越接近1说明输出与麦克风信号越相似,越接近0说明两者差异越大,近端单讲时理想值为1。

? Cohxe:越接近1说明输出与远端参考信号越相似,越接近0说明两者差异越大,即残留的远端参考信号频谱成分越少,理想值为0。

? SuppFactor:越接近1说明输出与麦克风信号的能量越接近,越接近0说明AEC造成能量衰落越严重,近端单讲时理想值为1。

(2)远端单讲(最大程度抑制回声):

? ERLE:值越大越好,则表明残留回声的能量相对值越小,回声抵消效果越好。

? Cohde:越接近1说明输出与麦克风信号越相似,越接近0说明两者差异越大,远端单讲时理想值为0。

? Cohxe:越接近1说明输出与远端参考信号越相似,越接近0说明两者差异越大,即残留的远端参考信号频谱成分越少,理想值为0。

? SuppFactor:越接近1说明输出与麦克风信号的能量越接近,越接近0说明AEC造成能量衰落越严重,远端单讲时理想值为0。

(3)双讲(尽量抑制回声同时保留近端语音)

? Cohde:越接近1说明输出与麦克风信号越相似,保留的近端语音频谱成分也越多;越接近0说明两者差异越大,保留的近端语音频谱成分也越少,双讲时理想值为0.5~0.9(取决于回声信号在该帧的占比)。

? Cohxe:越接近1说明输出与远端参考信号越相似,越接近0说明两者差异越大,即残留的远端参考信号频谱成分越少,双讲时理想值为0。

? SuppFactor:越接近1说明输出与麦克风信号的能量越接近,越接近0说明AEC造成能量衰落越严重,双讲时理想值为1。


AEC技术原理

典型回声消除技术框架如下图。


远端信号x从听筒或喇叭spk播出,并经过空间传播,被麦克风mic接收,近端说话信号也进入麦克风mic,这样麦克风接收到的就是两个信号的叠加,即d。自适应滤波器w对x进行处理获得y(回声信号),d和y的差值作为误差,传递给自适应滤波器,进行滤波器系数迭代更新。




远端参考信号(上图far-end signal)经过自适应滤波器w


远端参考信号经过空间传播(即经过Room Impulse Response)得到x'

目标误差




其实,自适应滤波器的作用就是来抵消房间冲击响应对x的影响,以误差最小为目标。

?

具体算法:

(1)LMS(least mean square)

LMS是最广泛应用的自适应滤波算法,以MSE误差为目标函数,以梯度下降为优化算法。NLMS是使用输入的功率对步长进行归一化的方法,可以取得更好的收敛性能。

算法复杂度:

LMS: (2M+1次乘法和2M次加法) * 序列长度

NLMS: (3M+1次乘法和3M次加法) * 序列长度

(2)Block LMS

LMS算法对输入数据是串行处理的,可以通过将输入数据分段并行处理,类似深度学习领域的mini-batch操作, 并且利用频域FFT来做快速卷积,大大减少计算复杂度。

首先需要将串行的LMS算法转变为分块处理,也就是Block LMS(BLMS)。 每次迭代,输入数据被分成长度为L的块进行处理。和LMS使用瞬时梯度来进行滤波器参数更新不同,BLMS使用L点的平均梯度来进行参数更新。 对第k块数据,BLMS算法递推公式为:

(3)Fast Block LMS

思想是利用FFT进行助攻加速,称作Fast Block LMS,或Frequency Domain Adaptive Filter。对于长度为M的滤波器,一般采用2M点的FFT(M点补零),且使用overlap-and-save的快速卷积方法。

算法复杂度

10MlogM +26M

(4)Partitioned Fast Block LMS

对滤波器的时长进行分割,达到降低时延的目的。又称Multidelay block filter(MDF)。

如果将长度为M的滤波器等分成长度为B的小段,M=P*B。则卷积的结果可以分解为个P卷积叠加。


双讲检测

存在远近端同时讲话场景,针对该场景,要进行双讲检查。

自适应滤波器有三种工作模式(通过DTD双讲检测):

  • 远端语音存在,近端语音不存在:滤波、自适应滤波器系数更新
  • 远端语音存在,近端语音存在:滤波
  • 远端语音不存在:什么都不用做

Webrtc中的回声消除模块,已包含:双讲检测技术(语音活动检测,区分希腊佛中是否存在双端讲话)、自适应滤波技术(主要性能指标:跟踪性能、抗冲激性、鲁棒性和计算复杂性)、后处理(消除自适应滤波器的输出误差)。

双滤波器结构与双讲检测:

Speex 除了使用MDF作自适应滤波,还是用了双滤波器结构(Two-Path Method)。 双滤波器结构包括一个迭代更新的自适应Background Filter, 和一个非自适应的Foreground Filter。在自适应滤波器性能变坏、甚至发散时, AEC使用Foreground Filter的结果,并且重置Background Filter。 在Background Filter 性能变好时,将其参数下载到Foregound Filter。

这种双滤波器结构,可以实现隐式的双讲检测。 在双讲的情况下,Background Filter无法收敛,其更新结果不会保存下来,也就实现了区分双讲和非双讲的目标。

上图就是典型的双滤波器AEC结构,其核心就是将Background Filter下载到Foregound Filter的判决标准。一般而言,可以有着几方面的考虑:

Speex AEC使用的判决准则,可以从代码里面提炼出来,跟以上提到的几点不完全一样,是用Foreground Filter和Background Filter输出的残留功率之差来进行判别,

其中是Foreground Filter与麦克风信号之差的功率,是Background Filter与麦克风信号之差的功率, Dbf是两个Filter输出信号之差的平方。 于是判别公式可以写成

代码地址:https://github.com/wavesaudio/Speex-AEC-matlab/blob/master/speex_mdf.m

% Logic for updating the foreground filter */
    
% For two time windows, compute the mean of the energy difference, 
as well as the variance */
VAR1_UPDATE = .5;
VAR2_UPDATE = .25;
VAR_BACKTRACK = 4;
MIN_LEAK = .005;

st.Davg1 = .6*st.Davg1 + .4*(Sff-See);
st.Davg2 = .85*st.Davg2 + .15*(Sff-See);
st.Dvar1 = .36*st.Dvar1 + .16*Sff*Dbf;
st.Dvar2 = .7225*st.Dvar2 + .0225*Sff*Dbf;

update_foreground = 0;

% Check if we have a statistically significant reduction in the residual echo */
% Note that this is *not* Gaussian, so we need to be careful about the longer tail */
if (Sff-See)*abs(Sff-See) > (Sff*Dbf)
update_foreground = 1;
elseif (st.Davg1* abs(st.Davg1) > (VAR1_UPDATE*st.Dvar1))
update_foreground = 1;
elseif (st.Davg2* abs(st.Davg2) > (VAR2_UPDATE*(st.Dvar2)))
update_foreground = 1;
end

如果Background Filter过于发散,则应该重置,可将其重置为Foreground Filter。 其MATLAB代码如下:

 % Do we update? */
if (update_foreground)

st.Davg1 = 0;
st.Davg2 = 0;
st.Dvar1 = 0;
st.Dvar2 = 0;
st.foreground = st.W;
% Apply a smooth transition so as to not introduce blocking artifacts */
for chan = 1:C
st.e(st.frame_size+1:N, chan) = (st.window(st.frame_size+1:N) .* st.e(st.frame_size+1:N, chan)) + (st.window(1:st.frame_size) .* st.y(st.frame_size+1:N, chan));
end
else
reset_background=0;
% Otherwise, check if the background filter is significantly worse */

if (-(Sff-See)*abs(Sff-See)> VAR_BACKTRACK*(Sff*Dbf))
reset_background = 1;
end
if ((-st.Davg1 * abs(st.Davg1))> (VAR_BACKTRACK*st.Dvar1))
reset_background = 1;
end
if ((-st.Davg2* abs(st.Davg2))> (VAR_BACKTRACK*st.Dvar2))
reset_background = 1;
end

if (reset_background)

% Copy foreground filter to background filter */
st.W = st.foreground;

% We also need to copy the output so as to get correct adaptation */
for chan = 1:C
st.y(st.frame_size+1:N, chan) = st.e(st.frame_size+1:N, chan);
st.e(1:st.frame_size, chan) = st.input(:, chan) - st.y(st.frame_size+1:N, chan);
end

See = Sff;
st.Davg1 = 0;
st.Davg2 = 0;
st.Dvar1 = 0;
st.Dvar2 = 0;
end
end


自适应滤波器步长优化

上述讲解的滤波器步长固定,其实也可以将步长作为参数,把固定步长优化成可变步长,并且通过当前的各段信号,推导出最优步长。

主要是基于论文On Adjusting the Learning Rate in Frequency Domain Echo Cancellation With Double-Talk.

下面摘录其中的主要结论。 最优步长等于残余回声方差与误差信号方差之比

为了计算残留回声的功率,定义泄漏因子, 取值在0~1之间

泄漏因子通过递归平均更新:

残留回声消除 Residual Echo Cancellation

自适应滤波器不能百分百消除回声,AEC的输出信号含有残留的回声信号,这个时候就需要一个Post-Filter,进行残留回声消除(Residual Echo Cancellation)。可以采用信号处理方法,也可以采用深度学习方法。


参考资料

[1] https://www.sohu.com/a/645659372_120122487

[2] https://blog.csdn.net/qq_44085437/article/details/123504211

[3] Speex回声消除,简书

相关推荐

程序员请收好:10个非常有用的 Visual Studio Code 插件

一个插件列表,可以让你的程序员生活变得轻松许多。作者|Daan译者|Elle出品|CSDN(ID:CSDNnews)以下为译文:无论你是经验丰富的开发人员还是刚刚开始第一份工作的初级开发人...

PADS在WIN10系统中菜单显示不全的解决方法

决定由AD转PADS,打开发现菜单显示不正常,如下图所示:这个是由于系统的默认字体不合适导致,修改一下系统默认字体即可,修改方法如下:打开开始菜单-->所有程序-->Windows系统--...

一文讲解Web前端开发基础环境配置

先从基本的HTML语言开始学习。一个网页的所有内容都是基于HTML,为了学好HTML,不使用任何集成工具,而用一个文本编辑器,直接从最简单的HTML开始编写HTML。先在网上下载notepad++文...

TCP/IP协议栈在Linux内核中的运行时序分析

本文主要是讲解TCP/IP协议栈在Linux内核中的运行时序,文章较长,里面有配套的视频讲解,建议收藏观看。1Linux概述  1.1Linux操作系统架构简介Linux操作系统总体上由Linux...

从 Angular Route 中提前获取数据

#头条创作挑战赛#介绍提前获取意味着在数据呈现在屏幕之前获取到数据。本文中,你将学到,在路由更改前怎么获取到数据。通过本文,你将学会使用resolver,在AngularApp中应用re...

边做游戏边划水: 基于浅水方程的水面交互、河道交互模拟方法

以下文章来源于腾讯游戏学堂,作者Byreave篇一:基于浅水方程的水面交互本文主要介绍一种基于浅水方程的水体交互算法,在基本保持水体交互效果的前提下,实现了一种极简的水面模拟和物体交互方法。真实感的...

Nacos介绍及使用

一、Nacos介绍Nacos是SpringCloudAlibaba架构中最重要的组件。Nacos是一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台,提供注册中心、配置中心和动态DNS...

Spring 中@Autowired,@Resource,@Inject 注解实现原理

使用案例前置条件:现在有一个Vehicle接口,它有两个实现类Bus和Car,现在还有一个类VehicleService需要注入一个Vehicle类型的Bean:publicinte...

一文带你搞懂Vue3 底层源码

作者:妹红大大转发链接:https://mp.weixin.qq.com/s/D_PRIMAD6i225Pn-a_lzPA前言vue3出来有一段时间了。今天正式开始记录一下梗vue3.0.0-be...

一线开发大牛带你深度解析探讨模板解释器,解释器的生成

解释器生成解释器的机器代码片段都是在TemplateInterpreterGenerator::generate_all()中生成的,下面将分小节详细展示该函数的具体细节,以及解释器某个组件的机器代码...

Nacos源码—9.Nacos升级gRPC分析五

大纲10.gRPC客户端初始化分析11.gRPC客户端的心跳机制(健康检查)12.gRPC服务端如何处理客户端的建立连接请求13.gRPC服务端如何映射各种请求与对应的Handler处理类14.gRP...

聊聊Spring AI的Tool Calling

序本文主要研究一下SpringAI的ToolCallingToolCallbackorg/springframework/ai/tool/ToolCallback.javapublicinter...

「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作

一、概述作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,在部署集群时采用了默认的dockers...

在MySQL登录时出现Access denied for user ~~ (using password: YES)

Windows~~~在MySQL登录时出现Accessdeniedforuser‘root‘@‘localhost‘(usingpassword:YES),并修改MySQL密码目录适用...

mysql 8.0多实例批量部署script

背景最近一个项目上,客户需要把阿里云的rdsformysql数据库同步至线下,用作数据的灾备,需要在线下的服务器上部署mysql8.0多实例,为了加快部署的速度,写了一个脚本。解决方案#!/bi...