如何理解音频频率分析中的傅里叶变换结果
我正在用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 个回答
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.])
傅里叶变换会返回一个复杂数字的数组,这些数字表示不同频率的幅度和相位。如果你只关心幅度,我使用了 np.abs
来获取每个频率的大小,并用 np.round(__, 0)
将其四舍五入到最接近的整数。你可以看到在索引 1
处有一个尖峰,这表明找到了一个周期等于样本数量的正弦波。
现在让波形变得复杂一些
>>> 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 和 5 处看到了尖峰,这些尖峰对应于我们的输入。它们分别代表周期为 n
、n/3
和 n/5
的正弦波(其中 n 是输入样本的数量)。
编辑
这里有一个关于傅里叶变换的很好的概念解释: http://betterexplained.com/articles/an-interactive-guide-to-the-fourier-transform/