我正在使用pyaudio來錄製我想然後以塊(例如,每5秒)處理的音頻。我在回調模式下使用pyaudio,並且每調用一次錄製的1500個音頻樣本就會調用一個回調函數,並在該函數內將這些樣本添加到隊列中。我還將樣本保存到一個wav文件中,以便驗證它們是否符合預期。在回調模式下使用python與pyaudio的線程問題
q = Queue.Queue()
flag = False
waveFile = wave.open('recording.wav', 'wb')
waveFile.setnchannels(1)
waveFile.setsampwidth(2)
waveFile.setframerate(RATE)
def callback(in_data, frame_count, time_info, status):
silent = is_silent(in_data)
if silent == False:
numpydata = np.fromstring(in_data, dtype=np.int16)
waveFile.writeframes(in_data)
q.put(numpydata)
callback_flag = pyaudio.paContinue
elif silent == True and flag == True:
numpydata = np.fromstring(in_data, dtype=np.int16)
if len(numpydata) != 0:
waveFile.writeframes(in_data)
q.put(numpydata)
waveFile.close()
callback_flag = pyaudio.paComplete
else:
callback_flag = pyaudio.paContinue
return (in_data, callback_flag)
p=pyaudio.PyAudio() # start the PyAudio class
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True,frames_per_buffer=1500, stream_callback = callback) #uses default input device
一旦隊列不再是空的,我進入while循環,其從該隊列,以一個單獨的緩衝器添加數據,然後每當已添加音頻5秒處理在該緩衝器中的數據。
while q.empty() == True:
if q.empty() == False:
break
buf = []
while 1:
flag = True
try:
snd_data = q.get(True,timeout = 4)
buf.extend(snd_data)
if len(buf) >= 220500:
process audio...
except Queue.Empty:
我的問題是,我在音頻信號中注意到奇怪的意想不到的毛刺,彷彿節目短暫停止錄製了幾樣,然後再次啓動備份。我可以通過在Audacity中打開錄製的wav文件並放大信號來看到這一點。我認爲這是因爲pyaudio每1500個樣本在一個單獨的線程中調用回調函數,有時它可能會嘗試調用回調函數,但前一個回調函數的線程仍處於打開狀態,並且此回調函數尚未完成,數據是仍然被添加到隊列等(道歉,如果這是一個不連貫的解釋,我不太確定使用什麼術語)。
有誰知道我該如何解決這個問題?是否有一種同步方法,以便每個回調函數只有在前一個回調函數完成處理後纔會調用?
感謝您提供的內容豐富的回覆,我似乎通過處理回調函數中的音頻來擺脫問題(無論如何我都這樣認爲),但我會看看您的腳本,並嘗試將其適用於我的目的。 – CJF