2013-01-07 37 views
0

我試圖理解PyAudio中看到的內容。我試圖採取200毫秒的音頻採樣,等待幾秒鐘,然後再採取三個200毫秒的音頻採樣。考慮以下代碼:如果我運行此「原樣」(即time.sleep()註釋掉)time.sleep中的PyAudio行爲()

import pyaudio 
import time 

p = pyaudio.PyAudio() 
chunk = 1024 
FORMAT = pyaudio.paInt16 
CHANNELS = 1 #chan 
RATE = 11025 
stream = p.open(format = FORMAT, 
      channels = CHANNELS, 
      rate = RATE, 
      input = True, 
      output = False, 
      frames_per_buffer = chunk, 
      input_device_index = 0, 
      output_device_index = 0) 

def record(seconds): 
all = [] 
for i in range(0, int(RATE/chunk * seconds)): 
    data = stream.read(chunk) 

    all.append(data) 
data = ''.join(all) 
return data 

#record 200ms of sound 
print "pre-record 1 " + str(time.time()) 
data = record(.2) 
print "post-record 1 " + str(time.time()) 

#sleep for one second 
#time.sleep(1) 

#record 200ms of sound 
print "pre-record 2 " + str(time.time()) 
data = record(.2) 
print "post-record 2 " + str(time.time()) 

print "pre-record 3 " + str(time.time()) 
data = record(.2) 
print "post-record 3 " + str(time.time()) 

print "pre-record 4 " + str(time.time()) 
data = record(.2) 
print "post-record 4 " + str(time.time()) 

,我得到這個,這是有道理的:

pre-record 1 1357526364.46 
post-record 1 1357526364.67 
pre-record 2 1357526364.67 
post-record 2 1357526364.86 
pre-record 3 1357526364.86 
post-record 3 1357526365.03 
pre-record 4 1357526365.03 
post-record 4 1357526365.22 

如果我再取消註釋的時間。睡眠()線到第一和第二記錄之間增加一週秒鐘後,我得到這個:

pre-record 1 1357525897.09 
post-record 1 1357525897.28 
pre-record 2 1357525898.28 
post-record 2 1357525898.28 
pre-record 3 1357525898.28 
post-record 3 1357525898.28 
pre-record 4 1357525898.28 
post-record 4 1357525898.47 

注意,雖然在第一和第二錄音,療法之間的時間戳一秒鐘的延遲e在記錄2和記錄3之間沒有任何延遲,並且它們看起來是在零時間內(儘管它們實際上包含200ms的數據)。記錄四似乎花費了200毫秒纔得到,但是與記錄2和3同時開始。

如果我將time.sleep(1)替換爲record(1)(並且不保存/使用1秒記錄中的數據),則程序的行爲如我所料:

pre-record 1 1357526802.57 
post-record 1 1357526802.77 
pre-record 2 1357526803.69 
post-record 2 1357526803.88 
pre-record 3 1357526803.88 
post-record 3 1357526804.06 
pre-record 4 1357526804.06 
post-record 4 1357526804.25 

所以這樣看來,即使在time.sleep(1),緩衝的地方仍然被送入音頻,當我的睡眠後調用記錄功能,它抓住從緩衝區中的音頻,這不是我想要的音頻。我需要睡眠後的音頻,而不是在睡眠期間。有人可以幫助我瞭解PyAudio與任何緩衝區的交互情況嗎?有什麼方法可以更好地瞭解我的音頻什麼時候被實際捕獲?

回答

0

音頻設備會每秒向緩衝區添加RATE樣本,並從此緩衝區讀取您的代碼。

因此,如果不從緩衝區讀取數據,就無法入睡(1)。你可以寫一些代碼來跳過樣本:

def skip(seconds): 
    samples = int(seconds * RATE) 
    count = 0 
    while count < samples: 
     stream.read(chunk) 
     count += chunk 
     time.sleep(0.01) 
+0

謝謝,這是非常有幫助的。你知道緩衝區是否有一定的大小?如果你看看上面的第二個例子,看起來記錄4實際上需要200ms才能完成,這似乎表明緩衝區在這個RATE可能只能保存大約400ms的數據? – aaknitt

+1

爲了部分回答我自己的問題,在這裏有一個很好的緩衝區大小的討論:http://www.portaudio.com/docs/latency.html它看起來像有一個PortAudio函數'Pa_GetMinNumBuffers(int framesPerBuffer,double sampleRate )'會返回緩衝區大小,但我還沒有在PyAudio中找到。但是,通過調用'get_read_available()'函數,我可以瞭解緩衝區的行爲。 – aaknitt

+0

此外,似乎在time.sleep(1)之前調用'stream.stop_stream()'將停止音頻設備添加到緩衝區,然後在重新啓動睡眠之後調用'stream.start_stream()'添加到緩衝區。時機似乎通過這樣做成功。 – aaknitt