1

我目前正在尝试计算 THD、本底噪声和其他音频测量(IMD,使用 Python 的频率响应)。为此,我将 wave 文件导入 numpy 数组,然后使用 scipy 模块计算 fft。为避免混叠,我需要在执行 fft 之前对数据进行窗口化。所以我尝试比较不同的窗口,这是一些结果(997 kHz 正弦波,32 位,192 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 是我的数据长度,可能很长。这非常耗时,有人可以帮我优化吗?

4

1 回答 1

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 点,它只会在大约 7 秒内为您节省 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 秒。

于 2014-07-18T09:56:34.003 回答