如何优化归一化滤波器系数?

信息处理 过滤器设计 C 双二阶
2022-02-04 12:45:56

我在 Matlab 中设计了一个 IIR 滤波器,其中包含以下双二阶

0.244   0.002   0.244   1   -1.432  0.543
0.244   -0.345  0.244   1   -1.555  0.777
0.244   -0.388  0.244   1   -1.652  0.943

我想在 16 位 DSP 中实现这个过滤器。因此,在将系数转换为 short int 之前,我通过将所有系数除以矩阵中存在的最大幅度(在本例中为 1.652)来对它们进行归一化。这导致

b0      b1      b2      a0       a1     a2
0.147   0.001   0.147   0.605   -0.866  0.328
0.147   -0.208  0.147   0.605   -0.941  0.470
0.147   -0.235  0.147   0.605   -1      0.570

然后我将这些系数转换为 16 位值,范围从 +32767 到 -32768。我使用Transposed Direct Form II实现了过滤器

在此处输入图像描述

我意识到增益非常低,尽管在 Matlab 中测试时滤波器在通带中显示为 0 dB。算法如下。它遍历所有双二阶并根据需要将它们的输出重新引入下一个。

for (k = 0; k < N_sos; k++) {

    y_n = (short) ((s1[k][1] + b[k][0] * x_n) >> 15);

    s1[k][0] = s2[k][1] + b[k][1] * x_n - a[k][1] * y_n;

    s2[k][0] = b[k][2] * x_n - a[k][2] * y_n;

    s1[k][1] = s1[k][0];

    s2[k][1] = s2[k][0];

    x_n = y_n;
}

IIR_out = y_n;

请注意,我没有考虑 a0 系数。因为它通常是 1,所以没关系。但我想知道丢失的增益是否是由这个丢失的系数引起的。我尝试通过交换将 y_n 与它相乘

y_n = (short) ((s1[k][1] + b[k][0] * x_n) >> 15);

y_n = (short) a[k][0] * ((s1[k][1] + b[k][0] * x_n) >> 15);

但这严重扭曲了信号。

1个回答

OP 应首先使用浮点实现过滤器以确认所有规范和结构。一旦确认没有“最佳”,因为解决方案是在所需精度和结果所需精度之间进行权衡,但通常设计方法是使用比数据路径中使用的系数多 2 位的精度;相应地缩放所有系数,让滤波器使用扩展精度累加器增大信号(这样在输入设置为最大可能信号时不会发生削波),然后将输出缩放回数据路径精度。

在最近发布的这个答案中查看我的更多详细信息:

RRC 滤波器的正确增益是多少?