说明¶
IIR — 无限脉冲响应滤波器
带反馈的递归滤波器。用更少的阶数达到陡峭过渡带,代价是非线性相位和潜在不稳定。
算法原理¶
设计流程(双线性变换法)¶
\[ \text{模拟原型} \xrightarrow{\text{预扭曲}} \xrightarrow{\text{双线性变换}} H(z) \xrightarrow{\text{Biquad 分解}} \text{二阶节级联} \]
Step 1 — 选择模拟原型
-
Butterworth
通带最平坦
过渡带较宽
无通带波纹 -
Chebyshev I
通带有波纹
过渡带更陡
允许通带波纹换取陡降
Step 2 — 频率预扭曲(补偿双线性变换的频率弯曲)
\[ \omegaa = \frac{2}{T} \tan\left(\frac{\omegad T}{2}\right) \]
边界频率(通带/阻带截止)都要预扭曲。
Step 3 — 双线性变换
\[ s = \frac{2}{T} \cdot \frac{1 - z^{-1}}{1 + z^{-1}} \]
将模拟 \(H(s)\) 映射为数字 \(H(z)\)。
无混叠
双线性变换是一一映射,不会像脉冲响应不变法那样产生频谱混叠。代价是频率弯曲——已被预扭曲补偿。
Step 4 — Biquad 级联
高阶 \(H(z)\) 分解为二阶节的乘积,每个 Biquad 独立稳定,对系数量化不敏感。
滤波结构(直接 II 型转置)¶
每输入一个样本,每个 Biquad 节执行:
\[ \begin{aligned} w[n] &= x[n] + b1 \cdot w[n-1] + b2 \cdot w[n-2] \\ y[n] &= a0 \cdot w[n] + a1 \cdot w[n-1] + a_2 \cdot w[n-2] \end{aligned} \]
IIR vs FIR
| FIR | IIR | |
|---|---|---|
| 稳定性 | 始终稳定 | 需检查极点 |
| 相位 | 可线性 | 非线性 |
| 阶数 | 高 | 低(同样指标 5-10× 更少) |
| 量化敏感 | 低 | 高(Biquad 级联缓解) |
| 适合 | 相位关键 | 实时、低延迟、低资源 |
API 参考¶
滤波器设计¶
// 低通 / 高通 / 带通 / 带阻 IIR 设计函数
int tiny_iir_design_lowpass(float *coeffs_b, float *coeffs_a,
int max_order, float cutoff_norm,
tiny_iir_type_t type, tiny_iir_design_t method);
参数:cutoff_norm = 归一化截止频率 [0, 1](1 = Nyquist)
批量滤波¶
tiny_error_t tiny_iir_filter_f32(const float *input, int len,
const float *coeffs_b, const float *coeffs_a,
int order, float *output);
实时滤波¶
typedef struct { /* ... */ } tiny_iir_state_t;
tiny_error_t tiny_iir_init(tiny_iir_state_t *state,
const float *coeffs_b, const float *coeffs_a, int order);
tiny_error_t tiny_iir_deinit(tiny_iir_state_t *state);
float tiny_iir_process_sample(tiny_iir_state_t *state, float input);
void tiny_iir_reset(tiny_iir_state_t *state);
注意事项¶
极点在单位圆外 → 不稳定
IIR 极点必须在单位圆内。设计后可通过 abs(pole) < 1 检查稳定性。
双线性变换的频率弯曲
高频区弯曲更严重。若关心高频响应,预扭曲必须正确。
Biquad 级联优于直接型
高阶直接型对系数量化非常敏感。Biquad 级联把问题分解为多个二阶子系统,每节极点独立可控。