Как обновить семпл Sounddevice?

Я использую sd.Stream для вывода звука и записи с микрофона одновременно. Мне нужно иметь возможность получать вход и выход одновременно для обработки аудио в реальном времени, поэтому я использую Stream. Если я использую все файлы, которые используют одну и ту же частоту дискретизации, это работает нормально. Если у меня есть несколько аудиофайлов, которые не имеют одинаковую частоту дискретизации, я должен иметь возможность изменить частоту дискретизации, используемую Stream.

try:
    stream = sd.Stream(device=(args.input_device, args.output_device),
                        samplerate=args.samplerate, blocksize=args.blocksize,
                        dtype='float32', latency=(0, 0),
                        channels=len(args.channels), callback=callback, finished_callback=finished_callback)
    with stream:
        ani = FuncAnimation(fig, update_plot, interval=args.interval, blit=False, init_func=plot_init)
        plt.show()

Моя первая попытка закрыть поток в done_callback:

def finished_callback():
    global stream
    print "just closed"
    stream.close()

и затем снова откройте поток в update_plot:

if stream.closed and callback.fs_mismatch:
    args.samplerate = callback.new_fs
    callback.fs_mismatch = 0
    stream = sd.Stream(device=(args.input_device, args.output_device),
                       samplerate=args.samplerate, blocksize=args.blocksize,
                       dtype='float32', latency=(0, 0),
                       channels=len(args.channels), callback=callback, finished_callback=finished_callback)
    print "stopped stream and fs mismatch!\n"

Повторное открытие потока, кажется, не имеет никакого эффекта вообще. Я считаю, что причина этого в том, что у меня нет ничего блокирующего после нового потока, как я использую ранее (plt.show). У меня не может быть ничего блокирующего в этом разделе, потому что именно здесь я обновляю свой сюжет. Есть ли способ изменить частоту дискретизации потока после того, как он уже открыт, или есть другой способ выполнить то, что я пытаюсь сделать?

1 ответ

Прежде всего, если у вас есть файлы с разной частотой дискретизации, вам следует рассмотреть возможность повторной выборки (также известной как преобразование частоты выборки). Это то, что обычно делается для решения вашей проблемы.

Во-вторых, PortAudio (библиотека C за sounddevice модуль) не поддерживает изменение частоты дискретизации существующего потока. Существуют и другие звуковые платформы, которые теоретически поддерживают это (например, JACK), если вам это действительно нужно.

В-третьих, если вам действительно нужны потоки с разной частотой дискретизации, вы, конечно, можете закрыть один поток и открыть другой с другой частотой дискретизации. На некоторых платформах вы можете даже иметь несколько потоков (с потенциально разными настройками) одновременно.

Вы не должны закрывать поток в finished_callbackна самом деле вы не должны вызывать функции из sounddevice модуль там.

Вероятно, не очень хорошая идея создавать поток в update_plot обратный вызов, потому что он будет уничтожен, когда переменная выйдет из области видимости (что происходит очень быстро, потому что функция, как правило, очень короткая).

Возможно, вам следует создать отдельный поток для построения графика и обработки остановки и перезапуска аудиопотоков в основном потоке (или наоборот).

Другие вопросы по тегам