webrtc AEC 线性滤波 PBFDAF(均匀分块频域自适应滤波)介绍

计算一个脉冲响应和输入信号的卷积,除了使用原始的时域卷积以外,还有如下方法:

  1. FFT卷积的方法:对输入信号(长度M)和脉冲响应(长度N)分别补零到K(K>M+N-1),然后分别计算FFT,然后相乘,最后反FFT,取前M+N-1个元素作为最终的卷积结果
  2. 输入信号很长时,将输入信号分成一帧一帧,使用overlap-add或者overlap-save的方法
  3. 当脉冲信号和输入信号都很长时,可使用均匀分块卷积

均匀分块卷积

        均匀分块卷积与频域自适应滤波(FDAF)结合,就是WebRTC AEC中线性滤波处理中的算法核心。

在介绍PBFDAF之前,我们来看一下均匀分块卷积的计算流程图:

我们分几个部分讲解上图的计算流程:

1、脉冲响应分块

        如上图红色矩形部分,将脉冲响应分成P个等长的不重叠的小块,每小块的长度为B,我们把这些小块叫做子滤波器(filter part 1,2...P),将每个小块后面补B个零,分别构成2B长度的序列,然后进行实数FFT。我们知道实数序列的FFT结果具有对称性,因此实数FFT返回B+1个点(类似numpy的rfft.fft)

2、将输入信号分块

        如上图红色线框内的部分,将输入信号分成不重叠的等长的分块(帧),分块长度为B,通过一个buffer构造重叠长度为B,这样输入buffer的长度为2B,将输入buffer进行实数FFT,得到B+1个复数结果。然后将fft结果存入一个长度为P的队列,队列进口处存储最新的输入buffer fft结果,旧的输入buffer的fft结果从队列的出口扔掉。这个队列有个名字叫Frequency-domain delay line。

3、频域相乘相加和反变换

        第三部分如上图红色矩形内,将第一部分准备的P个分块脉冲响应的FFT结果分别与第二部分形成的输入buffer fft结果的队列分别相乘,然后沿着P的方向求和。得到B+1长度的FFT结果,然后在进行复数到实数的IFFT(如numpy.rfft.ifft),输出是2B个实数序列,取后B个元素作为输入block对于的输出。

WebRTC AEC中的分块卷积

    % FD block method% ----------------------   Organize dataxk = rrin(pos:pos+N-1);dk = ssin(pos:pos+N-1);xx = [xo;xk];xo = xk;tmp = fft(xx); XX = tmp(1:N+1);% ----------------------   Filtering   XFm(:,1) = XX;for mm=0:(M-1)m=mm+1;  YFb(:,m) = XFm(:,m) .* WFb(:,m);endyfk = sum(YFb,2);tmp = [yfk ; flipud(conj(yfk(2:N)))];ykt = real(ifft(tmp));ykfb = ykt(end-N+1:end); 

xk是近端麦克风输入信号,要对近端信号进行线性滤波,得到估计的回声信号。

xx就是输入buffer,xk是输入的N个样本点,xo是上一次的输入N个样本点。对输入buffer进行傅里叶变换的到XX,将XX存入XFm,XFm就是频域的那个队列

然后将队列中各个输入buffer的fft结果与WFb进行相乘相加。WFb就是存放脉冲响应分块傅里叶变换的结果,因为这是自适应滤波,所以WFb矩阵的初始值的元素全部是0。M与上文中的P对应,N与上文中的B对应

WebRTC AEC中的PBFDAF

% Partitioned block frequency domain adaptive filtering NLMS and 
% standard time-domain sample-based NLMS 
%fid=fopen('aecFar-samsung.pcm', 'rb'); % Load far end
fid=fopen('aecFar.pcm', 'rb'); % Load far end
%fid=fopen(farFile, 'rb'); % Load far end
rrin=fread(fid,inf,'int16');
fclose(fid); 
%rrin=loadsl('data/far_me2.pcm'); % Load far end
%fid=fopen('aecNear-samsung.pcm', 'rb'); % Load near end
fid=fopen('aecNear.pcm', 'rb'); % Load near end
%fid=fopen(nearFile, 'rb'); % Load near end
ssin=fread(fid,inf,'int16');
%ssin = [zeros(1024,1) ; ssin(1:end-1024)];
fclose(fid);
rand('state',13);
fs=16000;
mult=fs/8000;
%rrin=rrin(fs*0+1:round(fs*120));
%ssin=ssin(fs*0+1:round(fs*120));% Flags
NLPon=0;  % NLP
CNon=0; % Comfort noise
PLTon=1;  % Plotting
M = 16; % Number of partitions
N = 64; % Partition length
L = M*N; % Filter length 
if fs == 8000mufb = 0.6;
elsemufb = 0.5;  
end
%mufb=1;  alp = 0.1; % Power estimation factor alc = 0.1; % Coherence estimation factorlen=length(ssin);
w=zeros(L,1); % Sample-based TD NLMS 
WFb=zeros(N+1,M); % Block-based FD NLMS
WFbOld=zeros(N+1,M); % Block-based FD NLMS
YFb=zeros(N+1,M);
erfb=zeros(len,1);zm=zeros(N,1);
XFm=zeros(N+1,M);pn0=10*ones(N+1,1);
pn=zeros(N+1,1);
NN=len;
Nb=floor(NN/N)-M;start=1;
xo=zeros(N,1);
do=xo;
eo=xo;for kk=1:Nbpos = N * (kk-1) + start;% FD block method% ----------------------   Organize dataxk = rrin(pos:pos+N-1);dk = ssin(pos:pos+N-1);xx = [xo;xk];xo = xk;tmp = fft(xx); XX = tmp(1:N+1);% ------------------------  Power estimationpn0 = (1 - alp) * pn0 + alp * real(XX.* conj(XX));pn = pn0;%pn = (1 - alp) * pn + alp * M * pn0;% ----------------------   Filtering   XFm(:,1) = XX;for mm=0:(M-1)m=mm+1;  YFb(:,m) = XFm(:,m) .* WFb(:,m);endyfk = sum(YFb,2);tmp = [yfk ; flipud(conj(yfk(2:N)))];ykt = real(ifft(tmp));ykfb = ykt(end-N+1:end); % ----------------------   Error estimation ekfb = dk - ykfb; erfb(pos:pos+N-1) = ekfb; tmp = fft([zm;ekfb]);      % FD version for cancelling part (overlap-save)Ek = tmp(1:N+1);% ------------------------  Adaptation  Ek2 = Ek ./(M*pn + 0.001); % Normalized errorabsEf = max(abs(Ek2), threshold);absEf = ones(N+1,1)*threshold./absEf;Ek2 = Ek2.*absEf; % 让EK2限定到thresholdmEk = mufb.*Ek2;PP = conj(XFm).*(ones(M,1) * mEk')';  %计算线性相关tmp = [PP ; flipud(conj(PP(2:N,:)))];IFPP = real(ifft(tmp));PH = IFPP(1:N,:);tmp = fft([PH;zeros(N,M)]);FPH = tmp(1:N+1,:);WFb = WFb + FPH;XFm(:,2:end) = XFm(:,1:end-1);endaudiowrite('aec_out.wav', erfb/32768, fs);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/216898.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring aop核心原理概念

目录 概述aop核心概念解析Target(目标对象)Joinpoint(连接点)Advice(通知/增加)Pointcut(切入点)Aspect(切面)Advisor(通知器)Weaving(织入)Proxy(代理)Introduction(引介) 结束 概述 aop核心概念解析 Target(目标对象) 代理的目标对象 目标对象(Target)的确立,是…

微信公众号对接获取用户openid预约项目心路全历程

公众号对接获取openid全历程 一、背景二、选型三、开始修改若依框架四、自己搭后端框架五、前端框架uni-app修改六、对接获取公众号登录用户openId七、总结 一、背景 老板接了朋友的一个公众号需求,要求做一个简单的疫苗预约系统。功能是获取当前登录用户&#xff0…

系列十五、BeanDefinition

一、BeanDefinition 1.1、概述 BeanDefinition是一个接口,主要负责存储bean的定义信息,决定bean的生产方式,类似于说明书。后续BeanFactory就可以根据这些信息生产bean了。比如实例化:可以通过反射得到实例对象;比如&…

【版本管理 | Git 】Git最佳实践系列(一) —— LFS .gitignore 最佳实践,确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

【腾讯云云上实验室-向量数据库】用向量数据库——实现高效文本检索功能

文章目录 前言Tencent Cloud VectorDB 简介Tencent Cloud VectorDB 使用实战申请腾讯云向量数据库腾讯云向量数据库使用步骤腾讯云向量数据库实现文本检索 结论和建议 前言 想必各位开发者一定使用过关系型数据库MySQL去存储我们的项目的数据,也有部分人使用过非关…

Kafka配置SASL认证密码登录

​​​​​​1、修改config/server.properties,添加如下内容 listenersSASL_PLAINTEXT://内网ip:9092 advertised.listenersSASL_PLAINTEXT://外网ip:9092 security.inter.broker.protocolSASL_PLAINTEXT sasl.mechanism.inter.broker.protocolPLAIN sasl.enabled.…

Vue解析器

解析器本质上是一个状态机。但我们也曾提到,正则表达式其实也是一个状态机。因此在编写 parser 的时候,利用正则表达式能够让我们少写不少代码。本章我们将更多地利用正则表达式来实现 HTML 解析器。另外,一个完善的 HTML 解析器远比想象的要…

高性能Mysql第三版学习(一)

学习目标: 高性能Mysql第3版 学习内容: MySQL架构与历史Mysql基座测试服务器性能Schema与数据类型优化创建高性能的索引查询性能优化Mysql高级特性Explain 学习时间: 周一至周五晚上 9点—晚上10点周六晚上9点-10点周日晚上9 点-10点 学习…

鸿蒙开发-ArkTS 语言-基础语法

1. 初识 ArkTS 语言 ArkTS 是 HarmonyOS 优选主力开发语言。ArkTS 是基于 TypeScript (TS) 扩展的一门语言,继承了 TS 的所有特性,是TS的超集。 主要是扩展了以下几个方面: 声明式UI描述和自定义组件: ArkTS使用声明式的方式描述用…

java计算下一个整10分钟时间点

最近工作上遇到需要固定在整10分钟一个周期调度某个任务,所以需要这样一个功能,记录下 package org.example;import com.google.gson.Gson; import org.apache.commons.lang3.time.DateUtils;import java.io.InputStream; import java.util.Calendar; i…

JWT和Token之间的区别

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏:每天一个知识点 ✨特色专栏&#xff1a…

鸿蒙开发之android开发人员指南《基础知识》

基于华为鸿蒙未来可能不再兼容android应用,推出鸿蒙开发系列文档,帮助android开发人员快速上手鸿蒙应用开发。 1. 鸿蒙使用什么基础语言开发? ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript(简称TS)基本语法风…