参考
"On Adjusting the Learning Rate in Frequency Domain Echo Cancellation With Double-Talk"
"Multidelay Block Frequency Domain Adaptive Filter"
"Echo Canceler with Two Echo Path Models "
注:由于包含很多LaTeX公式,可能需要多次刷新或者使用google浏览器
大纲
包括小节:1 信号模型、2 迭代公式推导、3 最优学习率、4 量的估计、5 双讲分析、6 代码解析
speexdsp AEC 的三个主要设计:
1)Multi-delay frequency domain adaptive filter,好处是:a)用来进行低延迟自适应,b)可以为每个频点单独使用学习率
2)Two path model,好处是:a)双滤波器切换,避免双讲时发散
3)Optimal learning rate under noise:a)噪声环境下能更好地控制学习率,b)避免双讲发散,对近端语音快速响应
下面对“On Adjusting the Learning Rate in Frequency Domain Echo Cancellation With Double-Talk”这篇论文(也就是上面的第三点)进行解析,并挑一些代码中的技术点进行梳理。
噪声环境下最优NLMS学习率
1 信号模型
则,系统的误差公式如下:
基于 NLMS 的迭代公式如下:
代入(1)式有:
记为第次迭代后,滤波器权重第个系数的估计误差;并且,对于理想滤波器有:。
将的表达式代入(3)式中,并考虑到理想滤波器系数(声学路径)并不随着时间发生较大变化,可以认为,得到:
接着定义在第 n 次迭代时,滤波器失配度:
2 滤波器失配度的迭代公式推导
由失配度的定义和迭代公式(4)可得,在第 n+1 次迭代时,滤波器的失配度为:
若我们作一个强假设:远端信号和 近端语音是互不相关的白噪声,假设给定的条件下的条件分布为,则对关于分布求期望得:
其中:是近端语音信号得方差 。
我们需要对(6)式做一些推导:(为了简洁,将时间 n 略去)
先直接对绝对值的平方进行展开:
其中:显然就是时刻 n 的滤波器失配度,中有关的一次项式的部分,在其取期望后为 0,即:
余下的部分,重新整理得:
再一次,在上式中,对得一次项取期望后为 0;
再对上式中子式进行处理,其分子如下化简:
其中 “交叉项” 为 0,因为假设(远端)语音是白噪,因此不相关;为远端语音信号得方差。
再对中的分母改写为:
又,全部代入子式得:
同理,对子式使用同样得处理可得:
提取公因子,就得到了论文中的公式(6)。
3 最优学习率
接下来,我们寻找在新的一轮迭代中,使得 滤波器失配度达到最小的学习率;由于上式是一个关于学习率的二次函数,因而容易得到最小值点,求导并令其为 0 得:
解方程得:
Observation:当没有近端语音时,即,此时(8)式退化成 NLMS 对应的学习率。
虽然我们得到了噪声环境中的最优学习率(8)式,但是其中的失配度无法计算,因此我们需要进一步将其变为可估计的量。
3.1 得到可估计的学习率公式
继续分析(8)式中的这一项,其中左半边为滤波器的失配度,右半边显然是远端信号能量的估计;因此,这一整项似乎与 AEC 滤波后的远端信号残留能量相关的某个量;下面我们证明,它的确就是远端信号的残留能量的估计,推导过程如下:
其中:由语音是白噪声这一假设可知 “交叉项” 为 0。
进而有:
这里又用到了 残差信号 与 远端残留信号 的不相关性,得到总误差的能量就等于 组成误差的两个分量的能量和 。
结论:在以上的假设下,理论上的最优学习率 近似等于 残留回声 与 总误差信号 的能量比。
在实际操作中,迭代第 n 步有:(其中分别是在第 n 步得估计)
4 量的估计
4.1 残留回声估计的上限
当条件满足时,我就达到了统计意义上的收敛(此时,滤波器在整体上达到了平稳状态,但系数之间或有细微变化),在公式中,令,并用远端信号得方差替代其估计后,可解得:
因此,如果当前滤波器失配度满足上式(11),则在统计意义下,使用最优学习率,将不再能改善滤波器失配度。最优学习率为代入(11)式中,考虑到误差信号得方差可以估计得很准确,因此我们直接使用它得期望值代入,而残留回声方差则用估计值代入,即将作为学习率代入(11)式得:
上式继续整理,得到如下方程:
所以,残差得 估计值 和 期望值 应满足:
因此,在达到平稳后,残留回声的估计方差,不应该大于 2 倍的真实方差,即不能高估这个方差超过 2 倍(3 dB)。
显然,前面对近端语音和远端语音的白噪声假设是不合理的;但是,我们可以到频域进行估计,理由是:
a. 经观察,同一个频点沿着时间轴上的相关性 比 时域数据的相关性要低,这使得我们的假设在频域更加可靠。
b. 在频域,我们可以对每个频点单独计算最优学习率:
4.2 残留回声的估计
a. 假设滤波器有一个和频率无关的泄露系数,则可以通过下式来对 残留回声的方差 进行估计:
下面我们来证明(15)式的合理性, 显然根据的白噪假设,有:
由前面关于残留回声功率的结论,并代入上式有:
在上式中,我们记;我们注意到 的分子和分母都是和滤波器权重的整体相关的一个值,是关于 echo path 以及 echo path change 的一个量;而在实际中回声路径被认为是缓慢变化的,所以我们可以认为 是一个缓慢变化的量。而另一项是语音的能量,因而是变化迅速的。
该过程同样也能说明频域的学习率也能分成这两个部分。
虽然在上式中对残留回声方差的估计,包含了不可计算的滤波器失配度,但是从式子来看,的确可是视为滤波器的 ERLE。并且作者给出了下图,说明的倒数 与 ERLE近似程度。
使用上式来估计残留回声有两个好处:
1)将残留回声的估计转为对两个量的估计,一个是变化缓慢 但不易估计的泄露系数,另一个是变化快速 但容易估计的回声功率。
2)在 double-talk 到来时,可以迅速做出反应:如下式的最优学习率,我们使用回声的瞬时功率作为它的方差,同样使用 误差信号的瞬时功率作为误差信号的方差:
如此,就将 学习率的自适应 解耦成泄露系数 和 回声功率与误差功率之比 这两部分,正是后者提供了对 double-talk 的快速反应能力。(而泄露系数需要较长时间才能迭代到目标值)
另外,系统初始化时,滤波器系数为 0,所以 也是 0,因此最优学习率总是 0;为了解决这个问题,考虑在初始化后使用固定的学习率(代码中是0.25)进行自适应滤波,等到滤波器系数收敛到一定程度时,再使用这里提出的自适应学习率算法。
4.3 泄露系数的估计
综上,我们就将 残留回声方差估计的问题,转为对 泄露系数的估计问题:
1)利用信号的非平稳性
2)利用估计的回声信号 和 误差信号 之间的线性回归值 来估计
3)基于的事实是:残留的回声 与 估计的回声 是高度相关的, 且估计的回声 与 误差信号中的噪声 是无关的。
SpeexDSP 代码中的计算过程:
1)先使用一阶去 DC 滤波器 去除 估计的回声功率 和 误差功率谱 的 DC分量,得到 零均值的,代码中使用递归平均来估计均值,然后分别减去均值)
2)再使用下式计算平滑的相关:
其中,是一个动态的平滑系数,用于估计泄露系数,如下计算:
,其中 是一个基础平滑系数
在 Speex 代码中,和前面的学习率一样,使用瞬时功率 代替估计式中的方差。
当远端没有信号时,有 beta = 0, 所以 和保持不变,即泄露系数保持不变,这样到下一次远端有语音(回声)过来时,能有一个合理的初始值。
3)最后将所有的频点上的相关性加起来,得到频点无关的泄露系数的估计:
5 双讲分析
分析前面的最优学习率公式,可以发现该系统能够处理 double-talk 场景:
a. 当近端语音突然出现时, 公式(16)中的分母(瞬时功率)会陡然增大,从而使得学习率变得很小;这会持续到 double-talk 结束;
b. 假设近端没有语音,但是有平稳噪声,则(16)中的分母保持不变,此时学习率收到 回声功率 和 泄露系数的影响:
i)当回声功率增大时,学习率变大,使得收敛迅速;
ii)当滤波器系数收敛时,泄露系数 变小,从而学习率变小,使得收敛过程更平稳;
c. double-talk 时,残留回声 与 误差的相关性 很小,从而保持学习率很小,不会造成滤波器发散;
d. Echo-path 发生变化时,滤波器系数完全失效,残留回声 与 误差有很大的相关性,从而使得学习率 迅速达到 1,从而加快收敛。
6 代码解析
6.1 循环卷积到线性卷积
在代码实现时,使用FFT计算卷积,会产生循环卷机效应。为了看懂代码,非电子、信息、通信专业的工程师还是要搞清楚这一点,才能理解代码,下面先来分析一下为什么出现循环卷积:
其中:为傅立叶变换,为某一帧数据,为该时刻的滤波器权重。
期望使用卷积定理的等价形式来计算时域卷积运算(可参考任一本dsp方面的书籍),对于离散傅立叶变换的特殊情况,我们将其展开:
其中等比数列计算为:
因此,只有当时,才包含有效的计算,上式为:
,这是一个循环卷积!见下面简单示例:
例如:当时,我们计算的值有,如下图所示与的对齐情况:
这是一个非因果运算,显然我们的滤波器不允许这种情况发生,为了避免循环卷积,可以拼接前后两帧数据,并将权重的后半段置为 0 即可,多出来的 0 将不会产生有效的计算,如下图所示,产生的过程:
注意:利用计算卷积,实际上的计算过程永远都是循环卷积,只不过在这里,我们通过将权重的后半段强行置 0 后,只有后半段的在进行有效的计算,而此时得到的结果恰好就是线性卷积的结果。
(TODO)