我无法使用您的系数获得稳定的滤波器。您没有说明,但我假设这是一个低通滤波器。在这里使用计算器,我得到:
coeffs = dict(
a0=0.0010232172047183973,
a1=0.0020464344094367946,
a2=0.0010232172047183973,
b1=-1.9075008174364765,
b2=0.91159368625535,
)
过滤器代码:
我重铸为转置直接形式 2(不是必需的,但通常推荐用于浮点)为:
def filter_process(input_data):
zb = [0., 0.]
output_data = []
for data in input_data:
output_data.append(coeffs['a0'] * data + zb[0])
zb[0] = zb[1] + coeffs['a1'] * data - coeffs['b1'] * output_data[-1]
zb[1] = coeffs['a2'] * data - coeffs['b2'] * output_data[-1]
return output_data
测试代码:
import matplotlib.pyplot as plt
import numpy as np
def plot_f(f):
Fs = 44000
sample = 1000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
out_y = np.array(filter_process(y))
plt.plot(x, out_y)
for freq in (200, 500, 1000):
plot_f(freq)
plt.show()
结果:
来自评论的更新:
如果输入和输出缓冲区实际上是同一个缓冲区,那肯定会有问题。当前组织的传递函数在完成将其用作输入之前将新输出写入缓冲区。但这很容易解决:
void Filter::process(int size, double *in, double *out)
{
double xb[2] = { 0, 0 };
double yb[2] = { 0, 0 };
for (int n = 0; n < size; n++)
{
double in_n = in[n]
out[n] = (coeffs->a0 * in_n) + (coeffs->a1 * xb[0])
+ (coeffs->a2 * xb[1]) - (coeffs->b1 * yb[0])
- (coeffs->b2 * yb[1]);
xb[1] = xb[0];
xb[0] = in_n;
yb[1] = yb[0];
yb[0] = out[n];
}
}