【发布时间】:2021-03-10 16:46:57
【问题描述】:
Scipy 的 firwin2 函数接受大于 1.0 的增益值,这会导致相应频率的放大。我已经对此进行了测试,它似乎按预期工作。但是,我在网上找到的所有示例都只使用了 0.0 到 1.0 之间的增益值。这让我想知道:用 firwin2 函数制作和放大滤波器是不是一个坏主意?
【问题讨论】:
Scipy 的 firwin2 函数接受大于 1.0 的增益值,这会导致相应频率的放大。我已经对此进行了测试,它似乎按预期工作。但是,我在网上找到的所有示例都只使用了 0.0 到 1.0 之间的增益值。这让我想知道:用 firwin2 函数制作和放大滤波器是不是一个坏主意?
【问题讨论】:
这根本不是一个坏主意!与其他基于窗口的设计一样,您需要确保您的 numtaps(也就是滤波器的阶数)足以代表您想要的频率响应。
您看到 gain=[0,1] 的伪标准是因为在大多数情况下,相对于不使用它(在相反,放大可能会引入削波)。为了提高信噪比和信干比,您需要摆脱噪声或干扰。如果噪声和干扰的频率与您想要的信号不同,您可以通过过滤它们来衰减它们。在这种情况下,您的信号频率将保持 1.0 的增益,而您不需要的部分将保持 0.0 的增益。
但是, 有时您希望放大某些频率,同时不理会其他频率或衰减它们。这方面的一个例子是音频均衡器。假设您有一个基于计算机的音频均衡器。用户会看到一系列不同频率的滑块,并根据需要向上或向下调整它们。你的车里可能有其中之一。您可以轻松地使用 firwin2 创建相应的 FIR 系数,只需传入频率向量和相应的增益向量即可。如果用户调高低音而将所有其他频率保持在 0 dB(即单位增益),您将在您设计的低音频率处获得增益,而在所有其他频率处获得 1.0。
以下是使用增益作为音频均衡器的示例。我为Equalizer extension for Google Chrome找到了这张图片:
要使用 firwin2 实现这一点,我可以使用以下脚本:
from scipy import signal
import numpy as np
import matplotlib.pyplot as plt;
Fs = 44100
order = 4096+1
freqs = [0, 32, 64, 125, 250, 500, 1000, 2000, 4000, 8000, 16000, Fs/2]
gains_dB = [4.0, 4.0, 2.3, 1.0, 0.3, -0.3, -1.2, 0.1, 1.6, 3.1, 3.3, 3.3]
gains = 10.**(np.asarray(gains_dB)/10.)
h = signal.firwin2(order, freqs, gains, fs=Fs)
plt.semilogx(np.fft.rfftfreq(len(h))*Fs, 10*np.log10(abs(np.fft.rfft(h))))
plt.title('Equalizer Example')
plt.xlabel('Frequency, Hz')
plt.ylabel('Filter Magnitude Response, dB')
plt.grid(True,which='both')
plt.show()
一些注意事项:
firwin2 接受线性单位的增益,而不是分贝,因此需要进行转换。firwin2 需要频率表示为 0 和 Fs/2,因此我将它们添加进去并使其与它们的邻居相等。【讨论】:
firwin 不接受增益因子,只接受 numtaps 和
firwin(numtaps, cutoff, width=None, window='hamming', pass_zero=True,
scale=True, nyq=None, fs=None)
要么我理解错了你的问题,要么你把cutoff 与增益混淆了。
截止点表示cutoff freqeuncy。
如果您想应用增益,请将返回的过滤器乘以您的增益。
from scipy import signal
numtaps = 3
f = 0.1
gain = 5;
h = gain * signal.firwin(numtaps, f)
您可以按如下方式绘制过滤器的响应
import numpy as np;
import matplotlib.pyplot as plt;
h1 = signal.firwin(256, 0.1)
h2 = signal.firwin(256, 0.3)
plt.plot(np.fft.rfftfreq(len(h1)), abs(np.fft.rfft(h1)))
plt.plot(np.fft.rfftfreq(len(h2)), abs(np.fft.rfft(h2)))
plt.xlabel('F / Fs')
plt.ylabel('Filter gain')
编辑:关于 firwin2 的问题
函数firwin2(freq, gain) 返回一个滤波器,该滤波器由频域中的插值构成,后跟一个窗口(标量乘法)。该操作在增益阵列上是线性的。即firwin2(freq, A*gain) = A*firwin2(freq, gain)。所以有gain < 1这样的限制。
您可以通过
确认这一点from scipy import signal
import numpy as np
taps1 = signal.firwin2(150, [0.0, 0.5, 1.0], [1.0, 1.0, 0.0]) * 2
taps2 = signal.firwin2(150, [0.0, 0.5, 1.0], [2.0, 2.0, 0.0])
assert(np.allclose(taps1, taps2))
【讨论】:
firwin2。
firwin2 线性依赖于增益。 firwin(freq, gain*A) = A*firwin(freq, gain) 所以你可以合成一个任意增益的滤波器。