Как изящно остановить Python SoundDevice из обратного вызова
Я использую Python SoundDevice и PySoundFile для воспроизведения звука "трудным путем", то есть с использованием неблокирующего обратного вызова. (Подсказка для Matthias и команды - эти пакеты просты в использовании и делают все, что мне нужно.) Примечание: использовать sd.play() гораздо проще, но я Я выбрал этот патк, потому что в моей окончательной версии я хочу выполнить дополнительную обработку в методе обратного вызова.
Я могу определить, когда я достиг конца звукового файла, но не ясно, как сказать звуковому устройству остановиться после того, как оно воспроизводит последний буфер в очереди.
Вот пример обратного вызова, который НЕ РАБОТАЕТ: он воспроизводит весь звуковой файл, но не останавливается после обработки последнего буфера. В обратном звонке поднимаю sd.CallbackStop()
, но статус потока никогда не становится stopped
:
def callback(outdata, frame_count, time, status):
view = sf.read(frame_count, dtype='float32', out=outdata)
if (view.size != outdata.size): # this was the last buffer.
print('stopping')
sd.CallbackStop()
with sd.OutpuStream(samplerate=sf.samplerate,
channels=sf.channels,
dtype=np.float32,
callback=callback) as ss:
while (ss.active):
time.sleep(0.1)
1 ответ
Doh! Исключения не работают очень хорошо, если вы не raise
их!! Правильный код для обратного вызова:
def callback(outdata, frame_count, time, status):
view = sf.read(frame_count, dtype='float32', out=outdata)
if (view.size != outdata.size): # this was the last buffer.
# zero the part of outdata not written into by sf.read()
outdata[view.shape[0]:,:].fill(0.0)
print('stopping')
raise sd.CallbackStop()
... и он работает просто отлично, играя до конца и останавливаясь после того, как последний буфер был воспроизведен.