2. 时域滤波技术:从FIR到维纳滤波器

时域滤波,说白了就是在时间轴上直接对音频信号做手脚。你想想看,麦克风采集到的噪声和语音混在一起,我们得想办法把噪声"滤"掉。这一章我会把四种核心的时域滤波器讲透——FIR、IIR、自适应滤波器、维纳滤波器。每个我都踩过坑,有些经验希望能帮你少走弯路。

核心观点:时域滤波是降噪的基石。频域方法再花哨,最终都要回到时域实现。理解这四种滤波器,你就掌握了降噪的"内功"。

2.1 FIR滤波器:稳定但代价高

FIR(有限脉冲响应)滤波器,我个人的最爱。为什么?因为它天生稳定,相位线性,不会出现振荡。在音频降噪里,相位失真比幅度失真更让人头疼——你想想,人耳对相位变化其实很敏感。

FIR的核心公式很简单:

y[n] = b₀·x[n] + b₁·x[n-1] + ... + b_N·x[n-N]

说白了就是加权平均。每个输出样本是过去N个输入样本的线性组合。系数b就是滤波器的"记忆"。

设计方法:窗函数法

我在项目中常用的方法是窗函数法。步骤很简单:

  1. 确定理想频率响应(比如低通,截止频率3kHz)
  2. 做逆傅里叶变换得到无限长脉冲响应
  3. 加窗截断(汉明窗、布莱克曼窗等)

举个例子,设计一个64阶的低通FIR:

// 伪代码示例
float h[65]; // 滤波器系数
float fc = 0.3; // 归一化截止频率
for (int n = 0; n <= 64; n++) {
    if (n == 32) {
        h[n] = 2 * fc;
    } else {
        h[n] = sin(2 * PI * fc * (n - 32)) / (PI * (n - 32));
    }
    // 加汉明窗
    h[n] *= 0.54 - 0.46 * cos(2 * PI * n / 64);
}

我的经验:阶数越高,过渡带越陡,但延迟也越大。在实时降噪中,我一般控制在128阶以内。超过这个数,延迟就超过10ms了,通话场景会明显感觉到"回声"。

2.2 IIR滤波器:高效但需小心

IIR(无限脉冲响应)滤波器,效率高得吓人。同样的滤波效果,IIR可能只需要FIR十分之一的阶数。但代价是什么?不稳定、相位非线性。

IIR的差分方程:

y[n] = b₀·x[n] + b₁·x[n-1] + ... - a₁·y[n-1] - a₂·y[n-2] - ...

注意那个负号。输出不仅依赖输入,还依赖过去的输出。这就是"反馈"——也是不稳定的根源。

设计方法:双线性变换

我习惯用双线性变换把模拟滤波器映射到数字域。步骤:

  1. 设计模拟滤波器(巴特沃斯、切比雪夫等)
  2. 用双线性变换 s = (2/T)·(1-z⁻¹)/(1+z⁻¹) 转换
  3. 预畸变补偿频率偏移
滤波器类型 通带特性 阻带特性 我常用的场景
巴特沃斯 最平坦 单调下降 语音降噪(相位失真小)
切比雪夫I型 等波纹 单调下降 需要陡峭过渡带时
椭圆 等波纹 等波纹 极端陡峭需求(慎用)

避坑指南:我曾经在一个车载免提项目中用了椭圆IIR滤波器,过渡带确实陡,但相位失真导致语音听起来"金属感"很强。后来换成巴特沃斯,虽然过渡带宽了点,但听感自然多了。记住:降噪不是越狠越好,听感才是王道。

2.3 自适应滤波器:LMS与NLMS

固定系数的滤波器有个致命问题——噪声环境变了怎么办?自适应滤波器就是干这个的。它能根据输入信号自动调整系数。

LMS(最小均方)算法,我入行时学的第一个自适应算法。核心思想:

// LMS算法核心
error = desired - output;
for (i = 0; i < N; i++) {
    w[i] += 2 * mu * error * x[i];
}

mu是步长因子。mu太大,收敛快但不稳定;mu太小,稳定但收敛慢。这个平衡我调了无数次。

NLMS:归一化版本

NLMS(归一化LMS)解决了LMS对输入信号幅度敏感的问题。说白了就是根据输入功率动态调整步长:

// NLMS算法核心
error = desired - output;
power = 0;
for (i = 0; i < N; i++) {
    power += x[i] * x[i];
}
mu_normalized = mu / (power + epsilon);
for (i = 0; i < N; i++) {
    w[i] += 2 * mu_normalized * error * x[i];
}

我的经验:epsilon取1e-6就够了,防止除零。mu值我一般从0.1开始调,如果发散就减半。在回声消除场景中,NLMS比LMS好用得多——因为语音信号的动态范围太大了。

2.4 维纳滤波器:理论最优

维纳滤波器,理论上的最优线性滤波器。它假设信号和噪声都是平稳随机过程,目标是让输出与期望信号的均方误差最小。

频域表达式很优雅:

H(ω) = P_s(ω) / [P_s(ω) + P_n(ω)]

其中P_s是信号功率谱,P_n是噪声功率谱。你看,当信噪比高时,H接近1,信号通过;信噪比低时,H接近0,噪声被抑制。

但实际应用中,我们不知道P_s和P_n。所以需要估计。常用的方法:

  • 噪声估计:用语音活动检测(VAD)在静音段更新噪声谱
  • 先验信噪比估计:用决策导向法(Decision-Directed)
  • 后验信噪比:直接用当前帧计算

关键点:维纳滤波器在平稳噪声下效果极好。但实际噪声往往是非平稳的——比如突然的关门声、键盘敲击声。这时候维纳滤波器就力不从心了,需要结合其他方法。

2.5 四种滤波器对比

特性 FIR IIR LMS/NLMS 维纳
稳定性 绝对稳定 可能不稳定 条件稳定 取决于估计
相位特性 线性相位 非线性 非线性 非线性
计算量 高 低 中等 高(需FFT)
自适应能力 无 无 强 弱(需重估计)
适用场景 要求线性相位 资源受限 回声消除、主动降噪 平稳噪声降噪

2.6 知识体系图

下面这张图展示了四种时域滤波器的关系和应用场景:

时域滤波技术知识体系 时域滤波技术知识体系 时域滤波 FIR滤波器 IIR滤波器 自适应滤波器 维纳滤波器 线性相位 绝对稳定 计算量大 非线性相位 可能不稳定 计算量小 自适应能力强 收敛需时间 适合非平稳 理论最优 需噪声估计 适合平稳噪声 选择原则: 线性相位→FIR | 资源受限→IIR | 环境变化→自适应 | 平稳噪声→维纳

2.7 实际项目中的选择建议

说了这么多理论,到底怎么选?我根据实际项目经验给几个建议:

  • 通话降噪:首选FIR+自适应组合。FIR保证线性相位,自适应处理残留噪声。我在一个蓝牙耳机项目中就是这么做的,效果不错。
  • 主动降噪(ANC):必须用自适应滤波器。因为噪声环境时刻在变,固定滤波器根本扛不住。NLMS是主流选择。
  • 后处理降噪:维纳滤波器很合适。录音完成后处理,不要求实时,可以慢慢算。
  • 资源受限的嵌入式设备:IIR是无奈之选。但一定要做稳定性检查——我吃过这个亏,滤波器在特定频率自激了,整个系统啸叫。

重要提醒:不要迷信"最优"理论。维纳滤波器理论上最优,但实际中噪声估计不准,效果可能还不如一个调好的FIR。我见过太多工程师花几周调维纳,最后换回FIR两天搞定。理论是指导,实践才是检验标准。