在Python中进行Fft窗口化,选择和优化

时间:2014-07-18 09:17:58

标签: python fft windowing

我目前正在尝试计算THD,本底噪声和其他音频测量(IMD,使用Python的频率响应)。为此,我将wave文件导入numpy数组,然后使用scipy模块计算fft。为了避免混叠,我需要在执行fft之前窗口化我的数据。所以我尝试比较不同的窗口,这里有一些结果(997 kHz正弦波,32位,192 ad kHz由adobe试听产生):

我正在寻找精确度:本底噪声应尽可能低,峰值以外的响应应尽可能平坦。所以我的问题是:Rife-Vincent是我最好的选择吗?我是否想念其他“秘密”窗口,我不知道并且没有测试过?

如果我决定保留Rife-Vincent窗口,问题就是时间计算!其他窗口在scipy模块中实现,并且计算速度非常快。我像这样计算Rife-Vincent系数:

w = np.empty(M,dtype=np.float64)
a = 2*np.pi/M
for i in np.arange(0, M):
    w[i] = (35 - 56*np.cos(a*i) + 28*np.cos(2*a*i) - 8*np.cos(3*a*i) + np.cos(4*a*i))/128

其中M是我的数据长度,可能很长。这非常耗时,任何人都可以帮我优化吗?

1 个答案:

答案 0 :(得分:0)

回答如何计算窗口:

a = 2*np.pi/M
x = np.arange(0, M)
w = (35 - 56 * np.cos(a * x) + 28 * np.cos(2 * a * x) - 8 * np.cos(3 * a * x) + np.cos(4 * a * x))/128

应该很快。你可以通过这样做来节省一些临时变量:

w = 35 - 56 * np.cos(a * x)
w +=  28 * np.cos(2 * a * x)
w -= 8 * np.cos(3 * a * x)
w += np.cos(4 * a * x)
w /= 128.

但是对于3e7分,它只能为你节省1秒左右。

如果你想要更快,你应该使用numexpr:

w = ne.evaluate('(35 - 56 * cos(a * x) + 28 * cos(2 * a * x) - 8 * cos(3 * a * x) + cos(4 * a * x))/128')

将并行编译和计算;在我的电脑上,时间从7秒到2秒。