2012-02-22 43 views
5

Tôi muốn nhận tần suất với công suất tối đa cho mọi thời điểm trong tệp wav. Vì vậy, tôi đã viết STFT bằng Python sử dụng fft từ scipy. Tôi đã sử dụng chức năng cửa sổ kaiser từ scipy. Mọi thứ trông tuyệt vời, nhưng đầu ra của tôi trông rất lạ. Nó có một số số rất nhỏ và một số rất cao.Thời gian ngắn Biến đổi Fourier trong python

đây là đầu ra cho một file wav: http://pastebin.com/5Ryd2uXj và đây là mã trong 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

Bạn đã thử kiểm tra nó với một dạng sóng đã biết như sóng sin để xem bạn có nhận được kết quả mong đợi không? – steve8918

+0

Tôi chỉ tìm thấy điều này: http://stackoverflow.com/questions/2459295/stft-and-istft-in-python Có vẻ tương tự và tôi thấy rằng trên cốt truyện của xoang là 2 dòng, không phải 1. Tôi có cùng trong đầu ra của tôi cho xoang. Tôi không biết tại sao ... – user1226419

Trả lời

5

FT thực tế của một sóng sin là một cặp hàm delta cách đều từ 0-tần số. Với chức năng rời rạc (mẫu), điều này được lặp lại mỗi fs (tốc độ lấy mẫu) trong miền tần số. Các lỗi nhỏ trong tính toán FFT sẽ có nghĩa là hai vùng đồng bằng (FT của sóng sin của bạn) sẽ không chính xác cùng chiều cao, do đó thuật toán của bạn chỉ đơn giản là chọn giá trị cao hơn.

Chức năng FFT scipy sẽ cung cấp cho bạn các thành phần tần số có miền [0, fs]. Vì (như tôi đã đề cập ở trên) đây là định kỳ, các giá trị này cũng có thể được ánh xạ lại dưới dạng [-fs/2, fs/2] bằng cách hoán đổi kết quả tại điểm giữa - xem xét sử dụng fftshift để thực hiện việc này. Có vẻ như bạn chỉ có thể quan tâm đến các tần số tích cực, do đó, bạn có thể chỉ cần loại bỏ nửa thứ hai của kết quả FFT của mình.

Từ những nốt nhạc của scipy.fftpack.fft:

Việc đóng gói của kết quả là “tiêu chuẩn”: Nếu A = FFT (a, n), sau đó A [0] chứa các hạn zero-tần số, A [ 1: n/2 + 1] chứa các cụm từ tần số dương và A [n/2 + 1:] chứa các cụm từ tần số âm, theo thứ tự tần số âm giảm dần. Vì vậy, đối với phép biến đổi 8 điểm, tần số của kết quả là [0, 1, 2, 3, 4, -3, -2, -1].

Các vấn đề liên quan