我一直致力于音频数字信号处理。我想设计一个数字滤波器。我附上了截图。当然,我可以使用 FIR/IIR 滤波器设计带通或带阻滤波器,但这个滤波器的特别之处在于它可以控制低频、中频和高频。所以我的问题是,如何在 python 中手动设计这样的过滤器,如图所示。请帮忙。我不知道如何将过滤器限制为这些值。
另一种选择可能是在 MATLAB 的 filterdesigner 工具中使用此类滤波器并将系数导出到 python。但同样,我不知道如何在那里设计这样的过滤器。所以请帮忙。
与简单的低通/带通/带阻/高通分类相比,有许多设计选项可以匹配更多的任意频段规范。最常见的是:
前两个很容易从scipy.signal
asscipy.firls
和scipy.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
将产生相应的设计:
请注意,如果您的频率规格曲线是不超过值(而不是标称值),您仍然可以在每次调整bands
和desired
参数时以迭代方式使用上述方法,直到收敛到可接受的响应。使用上面的初始参数集,使用最小二乘法,您最终可能会得到调整后的参数,例如
bands = [0, 100, 180, 520, 600, fs/2]
desired = [1.966,1.966,0.980,0.980,2.225,2.225]
与相应的响应: