音频分析中如何理解傅立叶变换结果

时间:2014-05-12 03:57:27

标签: python numpy fft frequency-analysis audio-analysis

我正在使用Python进行音频分析。我的最终目标是获取频率列表及其各自的卷,例如{ frequency : volume (0.0 - 1.0) }

我将音频数据作为值列在-1.0+1.0之间的帧列表。我在这个列表中使用了numpy的傅里叶变换 - numpy.fftpack.fft()。但结果数据对我来说毫无意义。

我确实理解傅立叶变换从时域变换到频域,但不完全是数学上如何工作。这就是为什么我不太了解结果。

  • numpy.fftpack.fft()返回的列表中的值是什么意思?我该如何使用它/解释它?
  • 如上所述在列表上执行的傅立叶变换的最大/最小值是多少?
  • 如何以{ frequency : volume (0.0 - 1.0) }
  • 的形式实现字典的最终目标

谢谢。对不起,如果我对傅里叶变换缺乏了解,那么你将面临一些问题。

1 个答案:

答案 0 :(得分:4)

考虑单个正弦波周期的FFT:

>>> t = np.linspace(0, 2*np.pi, 100)
>>> x = np.sin(t)
>>> f = np.fft.rfft(x)
>>> np.round(np.abs(f), 0)
array([  0.,  50.,   1.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.])

FFT返回一个复数数组,给出频率的幅度和相位。假设您只对幅度感兴趣,我使用np.abs来获取每个频率的幅度,并使用np.round(__, 0)将其四舍五入为最接近的整数。您可以在索引1处看到尖峰,表示周期等于找到样本数的sin波。

现在让波浪变得更复杂

>>> x = np.sin(t) + np.sin(3*t) + np.sin(5*t)
>>> f = np.fft.rfft(x)
>>> np.round(np.abs(f), 0)
array([  0.,  50.,   1.,  50.,   0.,  48.,   4.,   2.,   2.,   1.,   1.,
         1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
         0.,   0.,   0.,   0.,   0.,   0.,   0.])

我们现在看到第1,3和3号标记出现尖峰。 5对应我们的输入。正弦波的周期为nn/3n/5(其中n为输入样本数)。

修改

以下是傅里叶变换的一个很好的概念性解释:http://betterexplained.com/articles/an-interactive-guide-to-the-fourier-transform/