2012-02-22 12 views
5

私はwavファイルのあらゆる瞬間に最大パワーで周波数を取得したいと思います。 私はscftからfftを使ってPythonでSTFTを書いた。私はscipyからカイザーウィンドウ関数を使用しました。すべてが素晴らしく見えますが、私の出力は奇妙に見えます。いくつかの非常に小さな数字と非常に高い数字があります。ここで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

+0

私はちょうどこれを見つけた:http://stackoverflow.com/questions/2459295/stft-and-istft-in-python それは似ていると私は副鼻腔のプロットで2行、1ではないことを参照してください。私は同じ私の洞結石の出力ではどうしてか分かりません... – user1226419

答えて

5

正弦波の実際のFTは、0周波数から等距離デルタ関数のペアです。離散関数(サンプル)では、これは周波数領域でfs(サンプリングレート)ごとに繰り返されます。 FFT計算での小さな誤差は、これらの2つのデルタ(正弦波のFT)が正確に同じ高さにならないことを意味するので、アルゴリズムは単により大きなものを選んでいるだけです。

scipy FFT関数は、ドメイン[0, fs]を持つ周波数コンポーネントを提供します。上記のようにこれは周期的であるため、これらの値は[-fs/2, fs/2]として再マップすることもできます。これを行うにはfftshiftを使用してください。 ポジティブなの周波数にのみ興味があるようですが、FFTの結果の後半を単に破棄することができます。 scipy.fftpack.fftのNotesから

結果のパッキングが「標準」である:A = FFT(n)は、次に[0]はゼロ周波数項、Aが含まれている場合は[ 1:n/2 + 1]は正の周波数項を含み、A [n/2 + 1:]は負の周波数項を含む。したがって、8点変換では、結果の周波数は[0,1,2,3,4,3 -2、-1]となります。

関連する問題