高阶滤波器的级联双二阶部分如何工作?

信息处理 过滤器 过滤器设计 无限脉冲响应 双二阶
2022-01-10 00:30:20

我正在尝试实现一个 8 阶 IIR 滤波器,我读过的每一个应用笔记和教科书都说最好将任何超过 2 阶的滤波器实现为二阶部分。正如预期的那样,我tf2sos在 MATLAB 中使用了二阶部分的系数,这给了我 4 个二阶部分的 6x4 系数。在作为 SOS 实施之前,8 阶滤波器需要存储 7 个先前的样本值(以及输出值)。现在,当作为二阶部分实施时,流程如何从输入到输出,我是否只需要存储 2 个先前的样本值?或者第一个过滤器的输出是否像x_in第二个过滤器一样输入等等?

3个回答

这是您说的最后一件事(“或者第一个过滤器的输出是否作为 x_in 输入到第二个过滤器等等?”)。这个想法很简单:您将双二阶视为级联的单独二阶滤波器。第一个滤波器的输出是第二个滤波器的输入,依此类推,因此延迟线分布在滤波器之间。如果需要在内存受限的环境中优化结构,可以注意相邻的双二阶具有冗余延迟内存(即stage 1的最后几个输出样本与stage 2的最后几个输入样本相同,所以你不用不必像单独实现过滤器那样单独存储它们)。

实际上有两种方法可以实现二阶部分:并行和串行。在串行版本中,N 部分的输出是 N+1 部分的输入。在并行版本中,所有部分都具有相同的输入(并且只有一个实零而不是一对共轭复数零),并且每个部分的输出只是简单地相加。这两种方法通过 Z 域传递函数的部分分数展开相关联。警告:这是一个数值棘手的问题,标准的 Matlab 实现“residuez”对于极点接近单位圆的典型音频滤波器可能有非常大的数值误差。

这里有一些演示代码来说明为什么你最好级联二阶部分。

clc

sr = 44100;
order = 13;

[b,a] = butter(order,1000/(sr/2),'low');
[sos] = tf2sos(b,a);

x = [1; zeros(299,1)]; %impulse


% all in one
Y = filter(b,a,x);

% cascaded biquads
Z = x;
for nn = 1:size(sos,1);
    Z = filter(sos(nn,1:3),sos(nn,4:6), Z );
end


cla; plot(Y, 'k'); hold on; plot(Z,':r'); hold off

对于上面示例中给出的低通滤波器,大约 12 到 13 的数量级,数值误差会累积起来,从而为不使用级联双二阶的实现提供明显不同的脉冲响应。根据过滤器的不同,您的里程会有所不同。

订单 = 10

在此处输入图像描述

订单 = 13

在此处输入图像描述