尝试使用FFT分析Python中的音频信号

时间:2012-03-13 19:06:17

标签: python audio signal-processing

我一直在尝试使用FFT来获取信号的频率,而且我在处理它时遇到了一些麻烦。我找到了一个网站,谈论使用FFT来分析和绘制信号:

http://macdevcenter.com/pub/a/python/2001/01/31/numerically.html?page=2

但是我遇到了用Python 2.7实现它的问题。编辑我用改进的版本更新了代码。实际上,这个可以工作,并将波形(有点慢)绘制到图表上。我想知道这是否是读取帧的正确方法 - 我读到偶数编号的数组索引是针对左声道的(因此奇数编号将是右边的,我想)。

所以,我想我应该阅读很多帧,但是将它除以样本宽度,然后如果它是立体声则对每个其他偶数帧进行采样,是吗?

import scipy
import wave
import struct
import numpy
import pylab

fp = wave.open('./music.wav', 'rb')

samplerate = fp.getframerate()
totalsamples = fp.getnframes()
fft_length = 256 # Guess
num_fft = (totalsamples / fft_length) - 2

#print (samplerate)

temp = numpy.zeros((num_fft, fft_length), float)

leftchannel = numpy.zeros((num_fft, fft_length), float)
rightchannel = numpy.zeros((num_fft, fft_length), float)

for i in range(num_fft):

tempb = fp.readframes(fft_length / fp.getnchannels() / fp.getsampwidth());

up = (struct.unpack("%dB"%(fft_length), tempb))

temp[i,:] = numpy.array(up, float) - 128.0

temp = temp * numpy.hamming(fft_length)

temp.shape = (-1, fp.getnchannels())

fftd = numpy.fft.fft(temp)

pylab.plot(abs(fftd[:,1]))

pylab.show()

我加载的音乐是我自己制作的音乐。

编辑:现在,我通过读取帧来读取音频文件,并将当前数字除以通道数和每帧位数来读取。我这样做会丢失任何数据吗?这是我可以获取任何数据的唯一方法 - 否则文件处理程序读取struct.unpack函数的数据太多。此外,我正在尝试将左声道与右声道分开(获取每个声道的FFT数据)。我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

我很长一段时间没有使用scipy的numpy / numarray版本,但是找出函数frombuffer。使用它比通过struct.unpack重新调整所有数据要容易得多。使用numpy读取数据的示例:

fp = wave.open('./music.wav', 'rb')
assert fp.getnchannels() == 1, "Assumed 1 channel"
assert fp.getsampwidth() == 2, "Assuming int16 data"
numpy.frombuffer(fp.getnframes(fp.readframes()), 'i2')

请记住,波形文件中可能包含不同的数据类型和多个通道,因此在解压缩时请注意这一点。