2011-08-07 106 views
6

這是我想要做的。我希望在每個說出1毫秒的.wav文件中找到.wav文件的音頻和幅度,並將其保存到文件中。我已經繪製了頻率與振幅的關係曲線,並繪製了隨時間變化的振幅,但我無法確定頻率超時。我的最終目標是能夠讀取文件並使用它們幅度來調整變量和頻率以觸發正在使用的變量,這似乎是很容易的部分。我一直在使用numpy,audiolab,matplotlib等......使用FFT,但我無法弄清楚這一點,任何幫助表示讚賞!謝謝!Python隨着時間的推移發現音頻和振幅

+2

聲音文件不只是在任何時候單一的「頻率」,除非它只是一個純正弦波音的記錄。您可能需要做的是定期捕獲*功率譜*並存儲該信息,或者可能對功率譜做一些處理,例如識別最大的N個峯值並存儲這些峯值。 –

+0

http://stackoverflow.com/questions/604453/analyze-audio-using-fast-fourier-transform – sylvanaar

回答

7

使用帶重疊窗口的STFT來估計光譜圖。爲了節省自己滾動的麻煩,您可以使用Matplotlib的mlab的specgram method。重要的是要使用足夠小的窗口,使音頻大致靜止,並且緩衝區大小應該是2的冪以有效地使用共同的基數2 fft。 512個採樣(48 ksps時約爲10.67 ms;或每個bin爲93.75 Hz)就足夠了。對於48ksps的採樣率,重疊464個採樣以每1ms估計一個滑動窗口(即移位48個採樣)。

編輯:

下面是在具有每秒1音調從2kHz到16kHz的8秒信號使用mlab.specgram一個例子。請注意瞬態響應。我放大了4秒,以更詳細地顯示響應。頻率恰好在4秒鐘處移動,但需要緩衝區長度(512個採樣;大約+/- 5 ms)才能使瞬態通過。這說明了當非平穩過渡通過緩衝區時所引起的光譜/時間拖尾。另外,您可以看到,即使信號處於靜止狀態,也存在數據窗口化造成的頻譜泄漏問題。 Hamming window function被用於最小化泄漏的旁瓣,但是這也擴大了主瓣。

spectrogram

import numpy as np 
from matplotlib import mlab, pyplot 

#Python 2.x: 
#from __future__ import division 

Fs = 48000 
N = 512 
f = np.arange(1, 9) * 2000 
t = np.arange(8 * Fs)/Fs 
x = np.empty(t.shape) 
for i in range(8): 
    x[i*Fs:(i+1)*Fs] = np.cos(2*np.pi * f[i] * t[i*Fs:(i+1)*Fs]) 

w = np.hamming(N) 
ov = N - Fs // 1000 # e.g. 512 - 48000 // 1000 == 464 
Pxx, freqs, bins = mlab.specgram(x, NFFT=N, Fs=Fs, window=w, 
           noverlap=ov) 

#plot the spectrogram in dB 

Pxx_dB = np.log10(Pxx) 
pyplot.subplots_adjust(hspace=0.4) 

pyplot.subplot(211) 
ex1 = bins[0], bins[-1], freqs[0], freqs[-1] 
pyplot.imshow(np.flipud(Pxx_dB), extent=ex1) 
pyplot.axis('auto') 
pyplot.axis(ex1) 
pyplot.xlabel('time (s)') 
pyplot.ylabel('freq (Hz)') 

#zoom in at t=4s to show transient 

pyplot.subplot(212) 
n1, n2 = int(3.991/8*len(bins)), int(4.009/8*len(bins)) 
ex2 = bins[n1], bins[n2], freqs[0], freqs[-1] 
pyplot.imshow(np.flipud(Pxx_dB[:,n1:n2]), extent=ex2) 
pyplot.axis('auto') 
pyplot.axis(ex2) 
pyplot.xlabel('time (s)') 
pyplot.ylabel('freq (Hz)') 

pyplot.show()