我一直在尝试使用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数据)。我该怎么做呢?
答案 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')
请记住,波形文件中可能包含不同的数据类型和多个通道,因此在解压缩时请注意这一点。