Python中的FFT及其解释

3

我有一个WAV文件,我想在频率域中对其进行可视化。接下来,我想编写一个简单的脚本,该脚本接收一个WAV文件并输出是否某个特定频率"F"上的能量超过阈值"Z"(即该WAV文件是否具有强烈的音调存在)。网上有很多代码片段展示如何在Python中绘制FFT谱,但我不理解其中很多步骤。

  1. 我知道wavfile.read(myfile)返回采样率(fs)和数据数组(data),但当我对其运行FFT(y = numpy.fft.fft(data))时,y的单位是什么?
  2. 为了获取x轴的频率数组,一些帖子做了这个操作,其中n = len(data):

    X = numpy.linspace(0.0, 1.0 /(2.0 * T),n / 2)

    而其他人则这样做:

    X = numpy.fft.fftfreq(n) * fs)[range(n/2)]

    这两种方法之间有区别吗?是否有好的在线说明文档解释它们的概念?

  3. 一些关于FFT的在线教程提到了窗口函数,但是很少有帖子在其代码片段中使用窗口函数。我知道numpy有一个numpy.hamming(N)函数,但是我应该以什么作为该函数的输入,并如何将其输出窗口“应用”于我的FFT数组?
  4. 对于我的阈值计算,是否正确查找X中最接近所需音调/频率的频率,并检查Y中相应元素(相同索引)的幅度是否大于阈值?
1个回答

1
  1. FFT数据的单位是归一化频率,其中第一个点是0 Hz,而最后一个点则是fs Hz。您可以使用linspace(0.0, (1.0 - 1.0/n)*fs, n)创建自己的频率轴。您也可以使用fftfreq,但组件将为负数。

  2. 如果n是偶数,则它们是相同的。我认为您也可以使用rfftfreq。请注意,这仅是您频率的“正半部分”,这可能是您对音频(实值)想要的。请注意,您可以使用rfft仅生成频谱的正半部分,然后使用rfftfreq(n,1.0/fs)获取频率。

  3. 窗函数会降低旁瓣级别,代价是扩大任何存在的频率的主瓣。 N是信号的长度,您将信号乘以窗口。但是,如果您正在查看长信号,则可能希望将其“切成片段”,对它们进行窗口处理,然后添加其频谱的绝对值。

  4. “是否正确”很难回答。简单的方法就像您所说的那样,找到最接近您频率的bin并检查其幅度。


所有的FFT都是默认进行窗函数处理的。如果你没有显式地应用窗函数,那么结果就是一个方窗口。 - marko
没错,但这是以最严谨的方式来说的——一个宽度为信号宽度的矩形窗口只是一个全为1的信号。 - rlbond

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接