常用音频DSP算法:FIR与IIR滤波器、FFT与IFFT、卷积与相关、重采样算法

这一章,我们聊聊音频DSP里最常用的几类算法。说实话,这些算法就像工具箱里的螺丝刀和扳手——你未必天天用,但真遇到活儿的时候,少了哪一把都别扭。

我个人习惯把音频DSP算法分成四类:滤波、变换、运算、重采样。下面我们逐个拆开看。

核心观点:这四类算法覆盖了90%以上的音频处理场景。理解它们的计算模式和瓶颈,是性能优化的起点。

4.1 FIR与IIR滤波器

滤波器是音频DSP的看家本领。不管是EQ、去噪、还是分频,背后都是滤波器在干活。

4.1.1 FIR滤波器

FIR(有限冲激响应)滤波器,说白了就是一组加权求和。它的公式很简单:

y[n] = b0 * x[n] + b1 * x[n-1] + ... + bN * x[n-N]

每个输出样本,是当前输入和过去N个输入的加权和。N就是滤波器的阶数。

FIR的优点:

  • 绝对稳定——没有反馈,不会炸
  • 可以做到严格的线性相位——这对音频很重要
  • 实现简单,适合SIMD优化

FIR的缺点:

  • 要达到陡峭的截止特性,阶数往往很高
  • 延迟大——阶数越高,延迟越大
  • 计算量大——每个样本要做N次乘加

我的经验:在嵌入式平台上,我一般把FIR阶数控制在128以内。超过这个数,延迟和计算量都开始变得棘手。如果非要高阶,我会考虑用FFT加速卷积。

4.1.2 IIR滤波器

IIR(无限冲激响应)滤波器引入了反馈。它的差分方程长这样:

y[n] = b0*x[n] + b1*x[n-1] + b2*x[n-2] - a1*y[n-1] - a2*y[n-2]

IIR可以用很低的阶数实现陡峭的截止特性。一个二阶IIR(双二阶滤波器)就能做很多事。

IIR的优点:

  • 计算量小——二阶IIR只需要5次乘法和4次加法
  • 延迟低——几乎没有群延迟
  • 频率选择性好——阶数低,过渡带窄

IIR的缺点:

  • 可能不稳定——反馈系数搞不好就炸了
  • 非线性相位——对某些应用是硬伤
  • 定点实现时容易有精度问题

避坑指南:我曾经在定点DSP上实现IIR滤波器,系数量化后直接自激振荡。后来我养成了一个习惯:每次改系数,先用双精度仿真跑一遍,再量化到定点,最后在目标板上用正弦扫频验证稳定性。

4.1.3 FIR vs IIR 对比

特性 FIR IIR
稳定性 绝对稳定 可能不稳定
相位特性 线性相位 非线性相位
计算量 大(高阶) 小(低阶)
延迟 大 小
频率选择性 需高阶才能陡峭 低阶即可陡峭
定点实现 容易 容易出问题

4.2 FFT与IFFT

FFT(快速傅里叶变换)是音频DSP的瑞士军刀。它把时域信号变到频域,让我们能看到声音的“频谱”。

你想想看,如果没有FFT,我们怎么分析一段音频的频率成分?只能靠耳朵听,或者用滤波器组一个个扫。FFT一次搞定。

4.2.1 FFT的核心思想

FFT是DFT(离散傅里叶变换)的快速算法。DFT的公式是:

X[k] = Σ x[n] * e^(-j*2π*k*n/N), n=0..N-1

直接算DFT,复杂度是O(N²)。FFT利用旋转因子的对称性和周期性,把复杂度降到O(N log N)。

常用的FFT算法有:

  • 基-2 FFT:最经典,要求N是2的幂
  • 基-4 FFT:比基-2少一些乘法,但实现更复杂
  • 分裂基FFT:混合基-2和基-4,效率更高
  • 实序列FFT:利用实序列的对称性,可以省一半计算

我的习惯:在ARM Cortex-M上,我常用基-2 FFT,因为CMSIS-DSP库已经优化好了。在x86上,我会用FFTW或者Intel IPP。别自己手写FFT——除非你想练手,或者平台太特殊。

4.2.2 FFT在音频中的应用

FFT在音频里能干的事太多了:

  • 频谱分析:显示均衡器、VU表、频谱图
  • 快速卷积:用FFT加速长卷积(后面会讲)
  • 频域滤波:在频域直接修改幅度和相位
  • 音高检测:找频谱峰值对应的频率
  • 音频编解码:MP3、AAC都用MDCT(基于FFT)

4.2.3 IFFT

IFFT(逆FFT)就是把频域变回时域。公式和FFT几乎一样,只是指数符号相反,最后除以N。

很多音频处理流程是:时域 → FFT → 频域处理 → IFFT → 时域。比如噪声抑制、混响、变调,都是这个套路。

注意:FFT和IFFT的缩放因子怎么放,不同库不一样。有的库在FFT里放1/N,有的在IFFT里放,有的各放1/√N。用之前一定要看清楚文档,否则信号幅度会不对。

4.3 卷积与相关

卷积和相关,听起来像数学概念,但在音频里非常实用。

4.3.1 卷积

卷积的公式:

y[n] = Σ x[k] * h[n-k], k=-∞..∞

说白了,卷积就是输入信号x和冲激响应h的“加权叠加”。在音频里,卷积可以用来:

  • 模拟混响:用真实空间的冲激响应和干信号卷积
  • 实现FIR滤波器:FIR滤波就是卷积
  • 模拟音箱/话筒特性:用测得的冲激响应卷积

直接卷积的复杂度是O(N*M),N和M分别是信号长度和冲激响应长度。如果M很大(比如混响的IR有几十万点),直接算就太慢了。

快速卷积:用FFT加速。把信号分块,每块和IR做FFT → 频域相乘 → IFFT。复杂度降到O(N log N)。

我常用的方法:对于短IR(几百点以内),直接卷积更快。对于长IR(几千点以上),用重叠保留法(Overlap-Save)做快速卷积。中间那个区间,两种方法都可以,看平台。

4.3.2 相关

相关分两种:自相关和互相关。

  • 自相关:信号和自身的延迟版本做相关。用于音高检测、周期估计。
  • 互相关:两个不同信号做相关。用于时延估计、信号匹配、模式识别。

相关的计算和卷积很像,也可以用FFT加速。我记得有一次做麦克风阵列的声源定位,就是用互相关估计各通道之间的时延差,然后算角度。

4.4 重采样算法

重采样,就是把音频从一个采样率变到另一个。比如44.1kHz转48kHz,或者48kHz转16kHz。

重采样的核心是:先插值,再滤波,再抽取。

4.4.1 重采样的基本流程

  1. 插值(上采样):在样本之间插零,提高采样率
  2. 低通滤波:滤掉镜像频率
  3. 抽取(下采样):每隔M个点取一个,降低采样率

举个例子:48kHz转44.1kHz。先上采样到48*441=21168kHz(插零),然后低通滤波(截止频率22.05kHz),再下采样441倍,得到44.1kHz。

当然,实际不会这么暴力。一般用多相滤波器实现,一次搞定。

4.4.2 常用重采样算法

算法 质量 计算量 适用场景
最近邻插值 差 极低 实时预览、低质量需求
线性插值 一般 低 简单应用、嵌入式
三次样条 好 中等 通用音频处理
Sinc插值 极好 高 高保真音频、专业软件
多相滤波器 好~极好 中等 固定比例重采样

避坑指南:我曾经在重采样时没注意抗混叠滤波,结果高频出现了严重的混叠失真。后来我学乖了:不管上采样还是下采样,低通滤波的截止频率一定要小于min(原采样率/2, 目标采样率/2)。

4.5 本章知识体系

下面这张图,把这四类算法的关系串起来了。你可以看到,它们不是孤立的——FFT可以用来加速卷积,卷积可以用来实现FIR滤波,重采样里也离不开滤波。

音频DSP常用算法知识体系 FIR / IIR 滤波器 时域滤波 FFT / IFFT 时频变换 卷积 / 相关 运算操作 重采样算法 采样率转换 线性相位 / 稳定性 低阶高效 / 定点风险 O(N log N) 快速算法 频谱分析 / 频域处理 直接 / 快速卷积 自相关 / 互相关 插值 + 滤波 + 抽取 多相滤波器 / Sinc FFT加速卷积 滤波用于重采样抗混叠 核心:理解每种算法的计算模式和瓶颈 是后续性能优化的基础

4.6 小结

这一章我们聊了四类核心算法:

  • FIR/IIR滤波器:时域滤波的两种思路,各有优劣
  • FFT/IFFT:时频变换的利器,很多高级处理的基础
  • 卷积/相关:运算操作,混响、匹配、估计都靠它
  • 重采样:采样率转换,插值和滤波的组合拳

这些算法不是孤立的。FFT加速卷积,卷积实现FIR,滤波用于重采样——它们互相交织,构成了音频DSP的骨架。