簡體   English   中英

從聲音文件中檢測頻率

[英]Frequency detection from a sound file

我想要實現的目標如下:我需要聲音文件(.wav)的頻率值進行分析。 我知道很多程序會給出值的可視圖(譜圖),但我需要原始數據。 我知道這可以通過FFT完成,並且應該在python中相當容易編寫腳本但不確定如何完全執行它。 因此,假設文件中的信號長度為.4s,那么我希望多次測量,為程序測量的每個時間點以及它找到的值(頻率)(以及可能的功率(dB))提供輸出作為數組。 復雜的是我想分析鳥歌,它們經常有諧波或信號超出頻率范圍(例如1000-2000赫茲)。 我希望程序也能輸出這些信息,因為這對於我想對數據做的分析非常重要:)

現在有一段看起來非常像我想要的代碼,但我認為它並沒有給我所有我想要的價值......(感謝Justin Peel將這個問題發布到另一個問題:))所以我聚集在一起我需要numpy和pyaudio但不幸的是我不熟悉python所以我希望Python專家可以幫助我嗎?

源代碼:

# 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()

如果您只是想要FFT,我不確定這是否是您想要的:

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

如果你想要幅度響應:

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

我認為您需要做的是短時傅里葉變換 (STFT)。 基本上,您可以執行多個部分重疊的FFT,並將它們一起添加到每個時間點。 然后你會找到每個時間點的峰值。 我自己並沒有這樣做,但我過去一直在研究它,這絕對是前進的方法。

這里這里有一些用於執行STFT的Python代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM