2012-02-22 216 views
5

我想獲得wav文件中每個時刻最大功率的頻率。 所以我用Python從scipy編寫了STFT。我使用scipy的kaiser窗口函數。一切看起來不錯,但我的輸出看起來很奇怪。它有一些非常小的數字和一些非常高的。Python中的短時傅里葉變換

這裏是一個wav文件的輸出:http://pastebin.com/5Ryd2uXj 這裏是在Python代碼:

import scipy, pylab 
import wave 
import struct 
import sys 

def stft(data, cp, do, hop): 
    dos = int(do*cp) 
    w = scipy.kaiser(dos,12) //12 is very high for kaiser window 
    temp=[] 
    wyn=[] 
    for i in range(0, len(data)-dos, hop): 
     temp=scipy.fft(w*data[i:i+dos]) 
     max=-1 
     for j in range(0, len(temp),1): 
      licz=temp[j].real**2+temp[j].imag**2 
      if(licz>max): 
       max = licz 
       maxj = j 
     wyn.append(maxj) 
    #wyn = scipy.array([scipy.fft(w*data[i:i+dos]) 
     #for i in range(0, len(data)-dos, 1)]) 
    return wyn 

file = wave.open(sys.argv[1]) 
bity = file.readframes(file.getnframes()) 
data=struct.unpack('{n}h'.format(n=file.getnframes()), bity) 
file.close() 

cp=44100 #sampling frequency 
do=0.05 #window size 
hop = 5 

wyn=stft(data,cp,do,hop) 
print len(wyn) 
for i in range(0, len(wyn), 1): 
    print wyn[i] 
+2

你有沒有試過用像正弦波這樣的已知波形來測試它,看看你是否能得到預期的輸出? – steve8918 2012-02-22 17:13:34

+0

我剛剛發現這個:http://stackoverflow.com/questions/2459295/stft-and-istft-in-python 它看起來相似,我看到在竇的情節是2行,不是1.我有同樣的在我的輸出爲竇。我不知道爲什麼...... – user1226419 2012-02-22 19:01:41

回答

5

正弦波的實際FT是一對從0頻率等距離δ函數。對於離散函數(採樣),在頻域中每隔fs(採樣率)重複一次。 FFT計算中的小錯誤將意味着這兩個增量(正弦波的FT)不會完全相同,因此您的算法只是選擇較高的一個。

scipy FFT函數會爲您提供帶域[0, fs]的頻率分量。由於(正如我上面提到的)這是週期性的,所以這些值也可以通過交換中心點處的結果重新映射爲[-fs/2, fs/2] - 查看使用fftshift來執行此操作。 這聽起來像你可能只對正數頻率感興趣,但是,所以你可以簡單地丟棄FFT的後半部分。

scipy.fftpack.fft調:

結果的填料是「標準」:如果A = FFT(A,N),則A [0]包含零頻率項,A [ 1:n/2 + 1]包含正頻率項,而A [n/2 + 1:]包含負頻率項,按負頻率遞減。因此,對於8點變換,結果的頻率是[0,1,2,3,4,-3,-2,-1]。