2010-04-15 76 views
29

好吧即時嘗試做的是一種音頻處理軟件,可以檢測到流行的頻率,如果頻率播放足夠長的時間(幾毫秒),我知道我得到了積極的匹配。我知道我需要使用FFT或simiral的東西,但在這個數學領域我吮吸,我沒有搜索互聯網,但沒有找到一個只能做到這一點的代碼。Python頻率檢測

即時通訊的目標是讓自己成爲一種通過聲音發送數據的自定義協議,每秒需要非常低的比特率(5-10bps),但即時通訊在發送端也非常有限,所以接收軟件需要能夠定製(不能使用實際的硬件/軟件調制解調器)也我希望這只是軟件(沒有額外的硬件,除了聲卡)

非常感謝幫助。

+1

這可能有幫助(請務必閱讀回覆):http://www.keyongtech.com/5003865-frequency-analysis-without-numpy – ChristopheD 2010-04-15 19:07:49

回答

37

aubio庫已被SWIG封裝,因此可以被Python使用。其衆多功能包括音調檢測/估計的幾種方法,包括YIN算法和一些諧波梳理算法。然而,如果你想要簡單些,我前段時間爲音高估計編寫了一些代碼,你可以拿它或者離開它。它不會像在aubio中使用算法一樣準確,但它可能足夠滿足您的需求。我基本上只是把數據的FFT乘以一個窗口(在這種情況下是一個Blackman窗口),FFT值的平方,找到具有最高值的bin,並且使用最大值的對數在峯值附近使用二次插值和它的兩個相鄰值來找到基頻。我從我發現的一些論文中得到的二次插值。

它在測試音調上運行得很好,但它不會像上面提到的其他方法那樣穩健或不精確。通過增加塊大小(或通過減小塊大小)可以提高精度。塊大小應該是2的倍數以充分利用FFT。另外,我只確定每個塊的基本音高,沒有重疊。我用PyAudio在寫出估計音高時播放聲音。

源代碼:

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

哇,非常感謝,這看起來像現在我會得到一個數字如何從音頻實時讀取音頻輸入(麥克風) – MatijaG 2010-04-15 23:56:37

+2

進入PyAudio站點http://people.csail.mit.edu/hubert/pyaudio/並向下滾動頁面到示例,你會看到一些從麥克風輸入的信息。 – 2010-04-16 00:13:35

+0

uhm can you help me figure爲什麼會發生此錯誤: 「需要多於0個值才能在以下行上解壓縮「 」 「y0,y1,y2 = np。log(fftData [which-1:which + 2:])「 – MatijaG 2010-04-16 14:51:49

0

雖然我之前還沒有嘗試過使用Python進行音頻處理,但也許您可以根據SciPy(或其子項目NumPy)構建一個有效的科學/工程數值計算框架?您可以從查看scipy.fftpack開始查看FFT。

+1

好的,我發現這個http://www.swharden.com/博客/ 2010-03-05 - 實時-fft-graph-of-audio-wav-file-or-microphone-input-with-python-scipy-and -wckgraph/tho現在我想知道我將如何找到頻率範圍是在最高的(也是SciPy幫助了一下,謝謝 – MatijaG 2010-04-15 19:40:18

+0

所以你想怎麼做? – 2017-12-05 18:10:20