跳转至

说明

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 级联把问题分解为多个二阶子系统,每节极点独立可控。