2010-12-13 47 views
8

Điều tôi đang cố gắng đạt được là: Tôi cần các giá trị tần số của tệp âm thanh (.wav) để phân tích. Tôi biết rất nhiều chương trình sẽ cung cấp cho một đồ thị trực quan (spectrogram) của các giá trị nhưng tôi cần phải dữ liệu thô. Tôi biết điều này có thể được thực hiện với FFT và nên được khá dễ dàng kịch bản trong python nhưng không chắc chắn làm thế nào để làm điều đó một cách chính xác. Vì vậy, giả sử rằng một tín hiệu trong một tệp dài 4 giây thì tôi muốn nhiều phép đo cho đầu ra như một mảng cho mỗi timepoint các biện pháp chương trình và giá trị (tần số) mà nó tìm thấy (và có thể là công suất (dB)). Điều phức tạp là tôi muốn phân tích các bài hát chim và chúng thường có các giai điệu hoặc tín hiệu vượt quá một dải tần số (ví dụ: 1000-2000 Hz). Tôi cũng muốn chương trình xuất thông tin này, vì điều này quan trọng đối với phân tích mà tôi muốn làm với dữ liệu :)Phát hiện tần số từ một tệp âm thanh

Bây giờ có một đoạn mã trông rất giống tôi muốn, nhưng tôi nghĩ rằng nó không cho tôi tất cả các giá trị tôi muốn .... (nhờ Justin Peel đăng bài này cho một câu hỏi khác :)) Vì vậy, tôi thu thập rằng tôi cần numpy và pyaudio nhưng tiếc là tôi không quen với python vì vậy tôi hy vọng rằng một chuyên gia Python có thể giúp tôi về điều này?

Mã Nguồn:

# Read in a WAV and find the freq's 
import pyaudio 
import wave 
import numpy as np 

chunk = 2048 

# open up a wave 
wf = wave.open('test-tones/440hz.wav', 'rb') 
swidth = wf.getsampwidth() 
RATE = wf.getframerate() 
# use a Blackman window 
window = np.blackman(chunk) 
# open stream 
p = pyaudio.PyAudio() 
stream = p.open(format = 
       p.get_format_from_width(wf.getsampwidth()), 
       channels = wf.getnchannels(), 
       rate = RATE, 
       output = True) 

# read some data 
data = wf.readframes(chunk) 
# play stream and find the frequency of each chunk 
while len(data) == chunk*swidth: 
    # write data out to the audio stream 
    stream.write(data) 
    # unpack the data and times by the hamming window 
    indata = np.array(wave.struct.unpack("%dh"%(len(data)/swidth),\ 
             data))*window 
    # Take the fft and square each value 
    fftData=abs(np.fft.rfft(indata))**2 
    # find the maximum 
    which = fftData[1:].argmax() + 1 
    # use quadratic interpolation around the max 
    if which != len(fftData)-1: 
     y0,y1,y2 = np.log(fftData[which-1:which+2:]) 
     x1 = (y2 - y0) * .5/(2 * y1 - y2 - y0) 
     # find the frequency and output it 
     thefreq = (which+x1)*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    else: 
     thefreq = which*RATE/chunk 
     print "The freq is %f Hz." % (thefreq) 
    # read some more data 
    data = wf.readframes(chunk) 
if data: 
    stream.write(data) 
stream.close() 
p.terminate() 
+3

Bạn đã thử "tìm kiếm" chưa? Câu hỏi này đã được hỏi. Ví dụ: http://stackoverflow.com/questions/2648151/python-frequency-detection. –

+1

Có, đây là lần thứ 5 câu hỏi này xuất hiện trên SO trong 2 tuần qua. – Brad

+0

Có, tôi đã tìm kiếm và nhìn xung quanh .. nhưng không tìm thấy câu trả lời chính xác mà tôi cần. Nhưng trong khi tìm kiếm thêm, tôi tìm thấy một chương trình thực hiện chính xác những gì tôi cần miễn phí :) phân tích âm thanh chuyên nghiệp nếu có ai khác đọc câu hỏi này và đang tìm cách để làm những việc tương tự. Bạn có thể lấy dữ liệu (tần số vv) với chương trình này được xuất sang Excel hoặc MATLAB! –

Trả lời

8

Tôi không chắc chắn nếu điều này là những gì bạn muốn, nếu bạn chỉ muốn FFT:

import scikits.audiolab, scipy 
x, fs, nbits = scikits.audiolab.wavread(filename) 
X = scipy.fft(x) 

Nếu bạn muốn phản ứng cường độ:

import pylab 
Xdb = 20*scipy.log10(scipy.absolute(X)) 
f = scipy.linspace(0, fs, len(Xdb)) 
pylab.plot(f, Xdb) 
pylab.show() 
+0

Tôi đã làm việc này nhưng chỉ trên các tệp âm thanh đơn sắc. Âm thanh stereo có vẻ là vấn đề –

+0

Sử dụng 'x [:, 0]' thay vì 'x'. –

+1

In giá trị X cho đầu ra này '[-1.15917969 + 0.j -0.06542969 + 0.j -0.06542969 + 0.j ..., -0.06542969 + 0.j -0.06542969 + 0.j -0.06542969 + 0 .j] 'Nhưng tôi chỉ nên có một tần số, đúng không? tần số – AQU

5

Tôi nghĩ rằng những gì bạn cần làm là Short-time Fourier Transform (STFT). Về cơ bản, bạn thực hiện nhiều FFT chồng chéo một phần và cộng chúng lại với nhau cho từng thời điểm. Sau đó, bạn sẽ tìm thấy đỉnh cho mỗi điểm trong thời gian. Tôi đã không làm điều này bản thân mình, nhưng tôi đã nhìn vào nó một số trong quá khứ và điều này chắc chắn là con đường để đi tiếp.

Có một số mã Python để thực hiện STFT herehere.

+0

Cảm ơn! Liên kết thứ hai chắc chắn trông giống như những gì tôi cần. Tôi sẽ thử cái này! –

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