2012-02-22 20 views
5

Wav dosyasında her an için maksimum güçle frekans almak istiyorum. Bu yüzden Python'da STFT'yi scipy'den fft kullanarak yazdım. Scipy'den kaiser pencere işlevini kullandım. Her şey harika görünüyor, ama çıkarım garip görünüyor. Bazı çok küçük sayılara sahip ve bazıları çok yüksek. Burada Python'da Kısa Süreli Fourier Dönüşümü

bir WAV dosyası için çıktıdır: http://pastebin.com/5Ryd2uXj burada python kodudur:

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

Beklenen çıktıyı alıp almadığınızı görmek için, bunu bir sinüs dalgası gibi bilinen bir dalga biçimine karşı test etmeyi denediniz mi? – steve8918

+0

Ben sadece şunu buldum: http://stackoverflow.com/questions/2459295/stft-and-istft-in-python Benzer görünüyor ve ben sinüs arsa üzerinde değil 2 satır, 1 olduğunu görüyorum. Ben aynı sinüs için benim çıkışımda. Bilmiyorum neden ... – user1226419

cevap

5

bir sinüs dalgası gerçek FT 0 frekanslı eşit uzaklıkta delta fonksiyonunun bir çift. Ayrık bir işlevle (örnekler), bu, frekans alanında her fs (örnekleme oranı) tekrarlanır. FFT hesaplamasındaki küçük hatalar, bu iki delta (sinüs dalganın FT'si) tam olarak aynı yükseklikte olmayacağı anlamına gelir, bu yüzden algoritmanız sadece uzun olanı seçer.

Scipy FFT işlevi, [0, fs] etki alanına sahip frekans bileşenleri sağlar. (Yukarıda bahsettiğim gibi) bu periyodik olduğundan, bu değerler sonucu merkezi noktada değiştirerek [-fs/2, fs/2] olarak yeniden eşleştirilebilir - bunu yapmak için fftshift'u kullanın. Sadece pozitif frekanslarıyla ilgilenebileceğiniz gibi, FFT'nizin sonucunun ikinci yarısını atabilirsiniz. scipy.fftpack.fft notları kaynaktan

:

sonucun ambalaj “standart”: A = FFT (a, n), A [0], sıfır frekans terimi, bir [içeriyorsa 1: n/2 + 1], pozitif-frekans terimlerini içerir ve A [n/2 + 1:], negatif frekans sırasına göre negatif frekans terimlerini içerir. Dolayısıyla 8 noktalı bir dönüşüm için sonucun frekansları [0, 1, 2, 3, 4, -3, -2, -1].

İlgili konular