2

我一直致力于音频数字信号处理。我想设计一个数字滤波器。我附上了截图。当然,我可以使用 FIR/IIR 滤波器设计带通或带阻滤波器,但这个滤波器的特别之处在于它可以控制低频、中频和高频。所以我的问题是,如何在 python 中在此处输入图像描述手动设计这样的过滤器,如图所示。请帮忙。我不知道如何将过滤器限制为这些值。

另一种选择可能是在 MATLAB 的 filterdesigner 工具中使用此类滤波器并将系数导出到 python。但同样,我不知道如何在那里设计这样的过滤器。所以请帮忙。

4

1 回答 1

1

与简单的低通/带通/带阻/高通分类相比,有许多设计选项可以匹配更多的任意频段规范。最常见的是:

前两个很容易从scipy.signalasscipy.firlsscipy.remez分别获得,而第三个可以通过对采样的频率响应曲线进行逆 FFT 来完成。

使用最小二乘法的示例实现:

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

bands = [0, fL1, fL2, fH1, fH2, fs/2]
desired = [Bl, Bl, 1, 1, Bh, Bh]
y = signal.firls(numtaps, bands, desired, fs=fs)
f,h = signal.freqz(y, fs=fs)

plt.plot(bands, desired, 'k', linewidth=2)
plt.plot(f, np.abs(h), 'r')

使用 Parks-McClellan 算法的示例实现:

from scipy import signal
import matplotlib.pyplot as plt
import numpy as np

bands = [0, fL1, fL2, fH1, fH2, fs/2]
desired = [Bl, 1, Bh]
y = signal.remez(numtaps, bands, desired, fs=fs)
f,h = signal.freqz(y, fs=fs)

plt.plot(bands, desired, 'k', linewidth=2)
plt.plot(f, np.abs(h), 'b')

使用频率采样方法的示例实现:

from scipy import interpolate, fft
import matplotlib.pyplot as plt
import numpy as np

# interpolate desired response at equally spaced frequency points
interpolator = interpolate.interp1d(bands, desired)
N = 1024
fsampling = np.linspace(0, fs/2, N)
sampled = interpolator(fsampling)
# take the inverse FFT
y = fft.fftshift(fft.irfft(sampled))
# truncate response to keep numtaps coefficients
n1 = N-numtaps//2
n2 = n1 + numtaps
y = y[n1:n2]

为了便于说明,使用以下一组参数

numtaps = 19
fL1 = 100
fL2 = 200
fH1 = 500
fH2 = 600
fs  = 1600
Bl  = 2
Bh  = 2.3

将产生相应的设计:

使用最小二乘法、Parks-McClellan 和频率采样设计方法的频率响应

请注意,如果您的频率规格曲线是不超过值(而不是标称值),您仍然可以在每次调整bandsdesired参数时以迭代方式使用上述方法,直到收敛到可接受的响应。使用上面的初始参数集,使用最小二乘法,您最终可能会得到调整后的参数,例如

bands   = [0, 100, 180, 520, 600, fs/2]
desired = [1.966,1.966,0.980,0.980,2.225,2.225]

与相应的响应:

在此处输入图像描述

于 2021-12-03T15:39:29.787 回答