【问题标题】:Design audio digital filter设计音频数字滤波器
【发布时间】:2022-01-07 01:54:33
【问题描述】:

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

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

【问题讨论】:

    标签: python audio signal-processing acoustics digital-filter


    【解决方案1】:

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

    前两个可从scipy.signal 轻松获得,分别为scipy.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
    

    会产生相应的设计:

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

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

    有相应的回应:

    【讨论】:

    • 感谢您的详细解答。我希望在等式中实现这个过滤器。例如,我有方程( B'(k)*B(k) ),其中 ' 是例如共轭的,并且 B(k) 高于为 k 在范围(0,4096)中计算的过滤器(假设为 4096 点 FFT) .你能告诉我,我将如何使用你刚刚回答的上述过滤器在 python 中实现这个?
    • 您可以尝试使用numpy.conjugatenumpy.multiply...
    猜你喜欢
    • 2011-06-02
    • 2014-11-18
    • 2010-12-24
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多