WebRtc AEC核心算法之一:频域自适应滤波

7 篇文章 1 订阅
5 篇文章 6 订阅

WebRtc AEC核心算法之一:频域自适应滤波

WebRtc和Speex作为目前开源的语音增强平台,给非科班出身的工程师一探究竟的机会,本文接下来以WebRtc的Aec模块为主线,研究一下比较核心的算法和实现。
一直以来在心目中AEC就是利用自适应滤波器求解梯度的迭代过程,时域的LMS/RLS经典算法在教科书和主流文章中都有介绍,但频域的介绍的就不多了,恰恰两个流行的平台都选用了频域自适应滤波器,首先是因为频域方法避免了时域FIR滤波器抽头太多,计算复杂度较大的缺点,另外就是最近二三十年频域滤波的发展迅速,很多优秀的算法已经产品化,只是我们接触的少不知道而已。在《Acoustic MIMO Signal Processing》第五章 Frequency-Domain Adaptive Filters,有以下介绍:相比于时域方法,频域分块处理的计算复杂度显著的降低了。FFT的运用,令输入信号的时移属性非常适合Toeplitz矩阵结构,意味着设计一个频域自适应滤波算法仅仅是通过被显式的Toeplitz和循环矩阵重写时域的误差尺度而已。(说的真轻松!)据这本书介绍,最早是1978年Dentino等在《Adaptive filtering in the frequency domain》提出了频域滤波器,紧接着Ferrara在1980年的《Fast implementations of LMS adaptive filters》提出了频域最小均方差方法使得频域地维纳解实现了快速收敛。Mansour和Gray在1982年提出了《Unconstrained frequency-domain adaptive filter》,以及后来MDF(Multi delay filter is selected by speex)的提出和应用,这些基本奠定了频域自适应滤波器的基础。《An adaptive filtering algorithm using an orthogonal projection to an affine subspace and its properties》还介绍了 affine project方法,也是热门的话题。

自适应滤波器-从时域到频域

经典的LMS自适应滤波器是采用时域实现的,标准的权重因子 w ( n ) w(n) w(n)迭代表达如下:
y ( n ) = w H ( n ) u ( n ) e ( n ) = d ( n ) − y ( n ) w ( n + 1 ) = w ( n ) + μ u ( n ) e ( n ) y(n)=w^H(n)u(n)\\ e(n)=d(n)-y(n)\\ w(n+1)=w(n)+\mu u(n)e(n) y(n)=wH(n)u(n)e(n)=d(n)y(n)w(n+1)=w(n)+μu(n)e(n)
u ( n ) u(n) u(n)是输入矢量, d ( n ) d(n) d(n)是期望的相应, w ( n ) w(n) w(n)是FIR滤波器抽头, μ \mu μ是收敛因子。普通LMS的收敛因子是常数,而NLMS是对 μ \mu μ做了归一化处理,加速收敛速度的变形。但是实际实现过程遇到了两个挑战:

  1. 应用于回声消除等延时比较敏感的场景下,FIR的抽头(阶数)数量可观,意味需要较大的存储空间来存放权重因子,更为烦恼的是高阶卷积的运算量巨大,算法复杂度、稳定性等等都会遇到极大的挑战
  2. 收敛速度和稳定性一直是自适应滤波器需要追求的一种平衡,能否在频域发现更加优秀的算法取得收敛速度和稳定性的统一考量。
    因此,频域自适应滤波(FDAF)、正交自适应滤波和子带自适应滤波被提出来,有书中归纳为块自适应滤波,因为输入信号序列 u ( n ) u(n) u(n)被分成 L L L点的数据块来处理,自适应过程是以块为单位来更新,这区别原始的以采样点为更新基础的算法。
    在进行分块自适应讨论之前,我们先将上面的式子展开,便于理解,假设滤波器抽头为N:
    [ w 0 ( k + 1 ) w 1 ( k + 1 ) . . . . w N − 1 ( k + 1 ) ] = [ w 0 ( k ) w 1 ( k ) . . . . w N − 1 ( k ) ] + μ [ u ( k ) u ( k − 1 ) . . . . u ( k − N + 1 ) ] e ( n ) = [ w 0 ( k ) w 1 ( k ) . . . . w N − 1 ( k ) ] + μ [ u ( k ) u ( k − 1 ) . . . . u ( k − N + 1 ) ] [ d ( n ) − y ( n ) ] \begin{aligned} \begin{bmatrix} w_0(k+1) \\ w_1(k+1)\\ ....\\ w_{N-1}(k+1)\\ \end{bmatrix}&=\begin{bmatrix} w_0(k) \\ w_1(k)\\ ....\\ w_{N-1}(k)\\ \end{bmatrix}+\mu\begin{bmatrix} u(k) \\ u(k-1)\\ ....\\ u(k-N+1)\\ \end{bmatrix}e(n)\\ &=\begin{bmatrix} w_0(k) \\ w_1(k)\\ ....\\ w_{N-1}(k)\\ \end{bmatrix}+\mu\begin{bmatrix} u(k) \\ u(k-1)\\ ....\\ u(k-N+1)\\ \end{bmatrix}[d(n)-y(n)]\\ \end{aligned} w0(k+1)w1(k+1)....wN1(k+1)=w0(k)w1(k)....wN1(k)+μu(k)u(k1)....u(kN+1)e(n)=w0(k)w1(k)....wN1(k)+μu(k)u(k1)....u(kN+1)[d(n)y(n)]
    从这个公式很容易得出,每计算出一个滤波器输出 y ( n ) y(n) y(n),都需要更新权重因子,如果处理一帧数据是L个samples,那么随着输出更新L次,权重因子也更新L次,计算量是客观的。

块自适应滤波-block adaptive filtering[5]

假设输入数据块为向量表达:
u ( n ) = [ u ( n ) , u ( n − 1 ) , . . . , u ( n − N + 1 ) ] T u(n)=[u(n),u(n-1),...,u(n-N+1)]^T u(n)=[u(n),u(n1),...,u(nN+1)]T
此时的权重因子向量为:
w ^ ( n ) = [ w 0 ^ ( n ) , w 1 ^ ( n ) , . . . , w ^ M − 1 ( n ) ] T \hat{w}(n)=[\hat{w_0}(n),\hat{w_1}(n),...,\hat{w}_{M-1}(n)]^T w^(n)=[w0^(n),w1^(n),...,w^M1(n)]T
对于 n n n进一步的用如下定义来分解:
n = k L + i , i = 0 , 1 , . . . L − 1 , k = 1 , 2 , . . . , \begin{aligned} n=kL+i,\quad &i=0,1,...L-1,\\ &k=1,2,..., \end{aligned} n=kL+i,i=0,1,...L1,k=1,2,...,
L L L表示块长度,这样对于输入数据第 k k k块,可以定义为:
A T ( k ) = u ( k L + i ) i = 0 L − 1 = [ u ( k L ) , u ( k L + 1 ) , . . . , u ( k L + L − 1 ) ] \begin{aligned} \bold{A}^T(k)&={u(kL+i)}_{i=0}^{L-1}\\ &=[u(kL),u(kL+1),...,u(kL+L-1)] \end{aligned} AT(k)=u(kL+i)i=0L1=[u(kL),u(kL+1),...,u(kL+L1)]
这个时候容易瞢,回头看看 u ( n ) u(n) u(n)可是 M M M维数组,所以 A ( k ) A(k) A(k)是一个矩阵,假设 M = 6 , L = 4 M=6,L=4 M=6L=4,矩阵的格式如下
在这里插入图片描述再举一例,由此我们得到 y ( n ) y(n) y(n)的更新过程如下图 ( M = 3 , L = 3 ) (M=3,L=3) (M=3L=3)
在这里插入图片描述这里很明显的看出 A ( k ) A(k) A(k)是Toeplitz矩阵,主对角线以及平行主对角线的元素均相等。
block adaptive filtering权重因子更新算法是显著区别于经典算法的,下面只列出结果,有兴趣的同学可以参考[4][5]文献的介绍。
w ( k + 1 ) = w ( k ) + μ ∑ i = 0 L − 1 u ( k L + i ) e ( k L + i ) = w ( k ) + A T ( k ) e ( k ) \begin{aligned} w(k+1)&=w(k)+\mu \sum_{i=0}^{L-1}\bold{u}(kL+i)e(kL+i)\\ &=w(k)+\bold{A}^T(k)e(k) \\ \end{aligned} w(k+1)=w(k)+μi=0L1u(kL+i)e(kL+i)=w(k)+AT(k)e(k)
这里的k是表示第k*L个模块,和之前时域的k不一样了。也就是每个L个samples算一次,我们可以把上式得矩阵表示进一步展开:
[ w 0 ( k + 1 ) w 1 ( k + 1 ) . . . . w N − 1 ( k + 1 ) ] = [ w 0 ( k ) w 1 ( k ) . . . . w N − 1 ( k ) ] + μ [ u ( k L ) x ( k L − 1 ) . . . . x ( k L − N + 1 ) ] e ( k L ) + μ [ u ( k L + 1 ) x ( k L ) . . . . x ( k L − N + 2 ) + ] e ( k L + 1 ) + . . . + μ [ u ( k L + L − 1 ) x ( k L + L − 2 ) . . . . x ( k L − N + L ) ] e ( k L + L − 1 ) \begin{aligned} \begin{bmatrix} w_0(k+1) \\ w_1(k+1)\\ ....\\ w_{N-1}(k+1)\\ \end{bmatrix}&=\begin{bmatrix} w_0(k) \\ w_1(k)\\ ....\\ w_{N-1}(k)\\ \end{bmatrix}+\mu\begin{bmatrix} u(kL) \\ x(kL-1)\\ ....\\ x(kL-N+1)\\ \end{bmatrix}e(kL)+\mu\begin{bmatrix} u(kL+1) \\ x(kL)\\ ....\\ x(kL-N+2)\\ +\end{bmatrix}e(kL+1)+\\&...+\mu\begin{bmatrix} u(kL+L-1) \\ x(kL+L-2)\\ ....\\ x(kL-N+L)\\ \end{bmatrix}e(kL+L-1) \end{aligned} w0(k+1)w1(k+1)....wN1(k+1)=w0(k)w1(k)....wN1(k)+μu(kL)x(kL1)....x(kLN+1)e(kL)+μu(kL+1)x(kL)....x(kLN+2)+e(kL+1)+...+μu(kL+L1)x(kL+L2)....x(kLN+L)e(kL+L1)
这样只需每个块L算一次,并且对这个块内的e(n)做了平滑处理。最后提一下,实际应用中往往采用M(N)=L,这是综合考量计算复杂度等因素,对理解算法也有帮助,上文的第二个例子就说明了当M(N)=L之后,很容易设计出 A ( k ) A(k) A(k)的Toeplitz矩阵形式,尤其下面引入频域和傅立叶变换之后。

Fast Block LMS Algorithm & FDAF

回顾上一节的滤波器输出,用公式来表示:
y ( k L + i ) = w ^ T ( k ) u ( k L + i ) = ∑ j = 0 M − 1 w ^ j ( k ) u ( k L + i − j ) , i = 0 , 1 , . . , L − 1. \begin{aligned} y(kL+i)&=\hat{w}^T(k)\bold{u}(kL+i)\\ &=\sum_{j=0}^{M-1}\hat{w}_j(k)u(kL+i-j), \quad i=0,1,..,L-1. \end{aligned} y(kL+i)=w^T(k)u(kL+i)=j=0M1w^j(k)u(kL+ij),i=0,1,..,L1.
以及 ϕ ( k ) \phi(k) ϕ(k)的定义:
ϕ ( k ) = ∑ i = 0 L − 1 u ( k L + i ) e ( k L + i ) = A T ( k ) e ( k ) \begin{aligned} \phi(k)&=\sum_{i=0}^{L-1}\bold{u}(kL+i)e(kL+i)\\ &=\bold{A}^T(k)e(k) \end{aligned} ϕ(k)=i=0L1u(kL+i)e(kL+i)=AT(k)e(k)
这两个公式可以用线性卷积结构实现,而FFT经过特殊的处理就可以满足线性卷积的处理需求,即50%重叠存储法,如果M个抽头的滤波器,补充M个0,构建一个N=2M长度的FFT:
W ^ ( k ) = F F T [ w ^ ( k ) 0 ] \hat{W}(k)=FFT\begin{bmatrix} \hat{w}(k) \\ 0 \\ \end{bmatrix} W^(k)=FFT[w^(k)0]
构建频域对角阵
U ( k ) = d i a g { F F T [ u ( k M − M ) , . . . , u ( k M − 1 ) , ⎵ ( k − 1 ) t h b l o c k u ( k M ) , . . . , u ( k M + M − 1 ) , ⎵ ( k ) t h b l o c k ] } \bold{U}(k)=diag\lbrace FFT[\underbrace{u(kM-M),...,u(kM-1),}_{(k-1)th\quad block}\underbrace{u(kM),...,u(kM+M-1),}_{(k)th\quad block}]\rbrace U(k)=diag{FFT[(k1)thblock u(kMM),...,u(kM1),(k)thblock u(kM),...,u(kM+M1),]}
最后可以得到:
y T = [ y ( k M ) , y ( k M + 1 ) , . . . , y ( k M + M − 1 ) ] = l a s t   M   e l e m e n t s   o f   I F F T [ U ( k ) W ^ ( k ) ] \begin{aligned} y^T&=[y(kM),y(kM+1),...,y(kM+M-1)]\\ &=last\space M\space elements\space of\space IFFT [\bold{U}(k)\hat{\bold{W}}(k)] \end{aligned} yT=[y(kM),y(kM+1),...,y(kM+M1)]=last M elements of IFFT[U(k)W^(k)]
而前M个元素被扔掉了。
定义一维期望信号向量和误差向量为:
d ( k ) = [ d ( k M ) , d ( k M + 1 ) , . . . , d ( k M + M − 1 ) ] T e ( k ) = [ e ( k M ) , e ( k M + 1 ) , . . . , e ( k M + M − 1 ) ] T = d ( k ) − y ( k ) \begin{aligned} d(k)&=[d(kM),d(kM+1),...,d(kM+M-1)]^T\\ e(k)&=[e(kM),e(kM+1),...,e(kM+M-1)]^T\\ &=\bold{d}(k)-\bold{y}(k) \end{aligned} d(k)e(k)=[d(kM),d(kM+1),...,d(kM+M1)]T=[e(kM),e(kM+1),...,e(kM+M1)]T=d(k)y(k)
与输出向量的定义过程类似,定义一个2M维向量,但前M个用0填充:
E ( k ) = F F T [ 0 e ( k ) ] E(k)=FFT\begin{bmatrix} 0 \\ \bold{e}(k) \\ \end{bmatrix} E(k)=FFT[0e(k)]
将重叠保存的方法应用于线性相关,求得 ϕ ( k ) \phi(k) ϕ(k)
ϕ ( k ) = f i r s t   M   e l e m e n t s   o f   I F F T [ U H ( k ) E ( k ) ] \phi(k)=first\space M\space elements\space of\space IFFT[U^H(k)E(k)] ϕ(k)=first M elements of IFFT[UH(k)E(k)]
而权重因子的频域更新公式如下:
W ^ ( k + 1 ) = W ^ ( k ) + μ F F T [ ϕ ( k ) 0 ] \hat{W}(k+1)=\hat{W}(k) + \mu FFT \begin{bmatrix} \phi(k) \\ 0 \\ \end{bmatrix} W^(k+1)=W^(k)+μFFT[ϕ(k)0]
频域实现的基本数学过程大致如此。相比较Ns算法中利用谱减规则对频域功率谱分析的侧重点,此处FFT更多的是为了算法效率上的考虑。

参考文献

[1]:《Acoustic MIMO Signal Processing》Yiteng Huang etc. Springer
[2]:《频域自适应滤波算法及应用》华南理工大学-本科毕业设计
[3]:《频域块 LMS 自适应滤波算法的研究》田超 西安理工大学 - 硕士毕业论文
[4]:《Frequency Domain and MutiRate Adaptive Filtering》 John J. shynk. IEEE Digital Signal Process Magzine.
[5]:《Adaptive Filter Theory》Fifth Edition Simon Haykin.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值