一阶递归滤波器的截止频率

信息处理 过滤器 低通滤波器 无限脉冲响应 C
2022-02-14 21:25:05

我使用以下算法在 c 中实现了一个非常简单的一阶递归低通滤波器:

double a, b, prevOutput;

double lowPassFilter(double input)
{
    double output = a * input + b * prevOutput;
    prevOutput = output; 
    return output;
}

在哪里:

a = 1.0 - b

根据 The Scientist and Engineer's Guide to Digital Signal Processing,滤波器的截止频率由以下关系定义:

b=e2πfc

fc是作为采样频率一部分的 -3db 截止频率。使用fc=0.25,我计算出b=0.20788(大约)并将其插入我的过滤器。我想验证我的过滤器,所以我通过它传递了一个脉冲函数并记录了输出:

double result[128];
for (int i = 0; i < 128; ++i)
{
    if (0 == i) result[i] = lowPassFilter(1.0);
    else result[i] = lowPassFilter(0.0);
}

然后我对结果执行 FFT 以找到频率响应:

complex_t fftResult* = fft(result);
for (int i = 0; i < 65; ++i)
{
    double amplitude = fftResult[i].real * fftResult[i].real;
    amplitude += fftResult[i].img * fftResult[i].img;
    amplitude = sqrt(magnitude);
    printf("f = %.3f: %f\n", i / 128.0, amplitude );
}

我看到的结果在某种程度上是预期的,但也不完全是我的预期。在 DC bin ( f=0 ) 中,我看到一个非常接近 1 的幅度,并且我看到幅度在接近 0.5 时衰减。但是,我还预计在f=0.25时,幅度应该在0.70795左右(即 -3db)。但幅度却在0.775左右:

lp滤波器的频率响应

 ...
f = 0.242: 0.782501
f = 0.250: 0.774971
f = 0.258: 0.767380
 ...

除了效率低下的代码之外,我用来获取频率响应的方法是否有问题,或者我是否错误地解释了截止频率关系或其他原因?

1个回答

截止频率的公式是一个非常不准确的近似值。这个答案中,我推导出了一阶递归平均滤波器的系数与其 3-dB 截止频率之间的确切关系。请注意,在引用的答案中,我使用了常量从该答案中的公式我们得到系数α=1b(3)b

(1)b=2cos(ωc)(2cos(ωc))21)

使用我们得到的值ωc=2πfcfc=0.25b=0.26795

滤波器的频率响应由下式给出

(2)H(ejω)=1b1bejω

下图显示幅度响应的选择值可以实现所需的截止频率|H(ejω)|b

在此处输入图像描述

请注意,上面引用的答案的“编辑”部分也解释了截止频率的不准确公式的来源。和使用近似值时,滤波器的最终截止频率作为所需截止频率的函数:(1)

在此处输入图像描述

显然,近似值非常糟糕,它只适用于非常小的截止频率。我认为根本没有理由使用它。