Использование звукового устройства Python для многоканального захвата на двух устройствах

Я пытаюсь вывести до 4 каналов звука с моей звуковой карты RME Fireface UCX и получить 16 каналов аудиоданных на моем 16-канальном массиве miniDSP. В настоящее время, если я использую комбинацию перечисленных устройств из команды query_devices, я могу получить работающую систему с 16 входами /2 выходами, но я не могу увеличить количество выходных каналов.

Из списка устройств:

0 name:Microsoft Sound Mapper - Input input ch:2 out ch:0
1 name:ADAT (7+8) (RME Fireface UCX) input ch:2 out ch:0
2 name:Line (miniDSP micArray Multi-ch input ch:2 out ch:0
...
46 name:ASIO Fireface USB input ch:18 out ch:18
47 name:ASIO4ALL v2 input ch:2 out ch:2
48 name:miniDSP ASIO Driver input ch:16 out ch:2
...
60 name:Line (miniDSP micArray Multi-channels) input ch:16 out ch:0
72 name:Line (nanoSHARC micArray16 UAC2.0) input ch:16 out ch:0
73 name:Analog (1+2) (Fireface Analog (1+2)) input ch:0 out ch:8
74 name:Analog (1+2) (Fireface Analog (1+2)) input ch:2 out ch:0
...

Поэтому, если у меня есть x (который представляет собой массив с 44100*5 строками на три столбца, чтобы представить 5 секунд 3-канальных данных, отобранных на частоте 44,1 кГц (=fs)), я могу сделать:

sd.default.device = [46, 46]
rx_data = sd.playrec(x, samplerate=fs, channels=8)

и это одновременно воспроизводит 3 канала вывода на мои динамики и получает 8 каналов на входе моей звуковой карты RME. Точно так же, если я делаю:

duration = 5
sd.default.device = [48, 48]
sd.rec(int(duration * fs), samplerate=fs, channels=16)

Я могу заставить свой miniDSP записывать 16 каналов звука в течение 5 секунд. Кроме того, если я сделаю:

sd.default.device = [60, 73]
rx_data = sd.playrec(x, samplerate=fs, channels=16)

Я могу заставить miniDSP работать в режиме реального времени для получения 16 каналов звука, в то время как RME выводит только 2 канала (да, только 2 канала, несмотря на то, что массив содержит 3 столбца и список устройств говорит, что устройство может выводить 8 каналов?). Это нормально, но, как я уже сказал, мне бы хотелось 3 или 4 выходных аудиоканала.

Я думал о комбинировании устройств ASIO, т.е.

sd.default.device = [48, 46]
rx_data = sd.playrec(x, samplerate=fs, channels=16)

But this (not unsurprisingly) results in the PortAudioError -9993 Illegal combination of I/O devices.

So I have considered using InputStreams and OutputStreams, but I didn't quite follow some of the example code in the sounddevice docs. But maybe this is the way forward on this problem?

1 ответ

Решение

Библиотека PortAudio (которая используется в sounddevice модуль) на самом деле не позволяет поток с различными устройствами ввода и вывода (аппаратные). Он может работать для некоторых хост-API и некоторых комбинаций устройств, но официально не поддерживается.

См. Также https://github.com/spatialaudio/python-sounddevice/issues/154.

Возможно, вы сможете объединить несколько устройств в "виртуальное устройство" на уровне операционной системы, но я не знаю, работает ли это как в Windows (это может работать в Linux/ALSA с файлом конфигурации .asoundrc и в macOS путем определения "агрегатных устройств").

Если это не вариант, вы можете использовать разные потоки для ввода и вывода (как вы упомянули в своем вопросе). В этом случае синхронизация блоков ввода и вывода, как правило, не совпадает, поэтому не следует пытаться обрабатывать входы и выходы синхронно. Вы должны скорее использовать что-то вроде queue.Queue для переноса аудиоданных из входного обратного вызова в выходной обратный вызов.

В документации действительно нет примеров для этого. Но вы можете попытаться объединить rec_unlimited.py(для обратного вызова ввода) с play_long_file.py(для обратного вызова вывода).

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