Numpy fft 冻结更长的样本

Posted

技术标签:

【中文标题】Numpy fft 冻结更长的样本【英文标题】:Numpy fft freezes for longer samples 【发布时间】:2014-05-07 20:03:31 【问题描述】:

我目前正在使用 numpy.fft 库。我有 200 个带有单个音符的 .wav 文件,每个大约 4 秒长。我为每一个运行 numpy.fft ,但对于 4.5 秒或更长的样本 numpy.fft 冻结。我不明白为什么会这样?此外,如果我明确指定 fft 的长度,该函数可以正常工作,但它会检测到错误的频率(它会检测到频率偏移高一到两个半音)。

这是我的代码:

(framerate, sample) = wav.read(wav_file)
monoChannel = sample.mean(axis=1)
fft_length = int(duration * framerate)     # duration is usually around 4sec long
FFT = numpy.fft(monoChannel, n=fft_length)

对于 fft_length 小于 216090 的样本,numpy.fft 可以正常工作,对于更长的 fft,算法会挂起,但在我在终端中按 ctrl+C 后它会继续。

我正在使用 python 2.7.3

我是 FFT 的新手,我真的很想了解这里发生了什么。

【问题讨论】:

【参考方案1】:

np.fft 中使用的 FFT 算法在输入长度有很多小的素因数时表现非常好(意味着 O(n log n)),而在输入大小是一个素数。查看 2 次幂和下一个最小素数的一些示例时序:

In [69]: a = np.random.rand(1024)
In [70]: b = np.random.rand(1031)

In [71]: %timeit np.fft.fft(a)
10000 loops, best of 3: 20.8 µs per loop

In [72]: %timeit np.fft.fft(b)
100 loops, best of 3: 2.09 ms per loop

In [73]: a = np.random.rand(65536)
In [74]: b = np.random.rand(65537)

In [75]: %timeit np.fft.fft(a)
100 loops, best of 3: 3.16 ms per loop

In [76]: %timeit np.fft.fft(b)
1 loops, best of 3: 11.8 s per loop

对于您的特定情况,请注意:

216090 = 2 * 3**2 * 5 * 7**4
216091 = 216091 (prime)
216092 = 2**2 * 89 * 607

因此:

In [77]: %timeit np.fft.fft(np.random.rand(216090))
10 loops, best of 3: 37.1 ms per loop

In [78]: %timeit np.fft.fft(np.random.rand(216092))
10 loops, best of 3: 149 ms per loop

In [79]: %timeit np.fft.fft(np.random.rand(216091))
# Got bored and killed it before it finished, should take ~2 min
# based on the other results for prime numbers

【讨论】:

以上是关于Numpy fft 冻结更长的样本的主要内容,如果未能解决你的问题,请参考以下文章

将 FFT 应用于 1024 个样本的每个块

Numpy FFT错误 - 带信封的梳状滤波器

采样率和可变长度输入样本与固定大小的 FFT 输入有何关系?

来自 portAudio 流的样本的 FFT

fft 在 matlab 中的音频文件样本上

如何在加载的样本上使用 FFTW?