Intereting Posts
Clang, Microsoft linker и стандартная библиотека Почему не возвращает 0x80000000 из функции, которая возвращает int32_t, вызывают предупреждение? C99 не по умолчанию C-версия для GCC? HTTP-сервер не отправляет полный файл в WGET, Firefox. Сброс соединения с помощью одноранговой сети? Самый тщательный способ конкатенации строк в C Правильные fork () и pipe () используют для одного родителя, имеющего несколько дочерних элементов. Как мне это сделать правильно? Запись DLL для использования с rundll32.exe Должен ли я отключить предупреждение о несогласованности с помощью компилятора C? Как отсоединить процесс из объекта JobObject Внедрение mergesort в связанном списке Печать двоичного числа, дающего странные результаты Является ли чтение из нераспределенной памяти безопасным? Список файлов в C (.LST) Абсурдное состояние в самой длинной растущей подпоследовательности Как использовать «% f» для заполнения двойного значения в строке с правильной точностью

ALSA Api: Как играть в два волновых файла одновременно?

Какая требуемая конфигурация / вызов API для воспроизведения двух независимых волновых файлов перекрывается? Я попытался сделать это, я получаю ошибку загрузки ресурсов. Некоторые указатели для решения проблемы будут очень полезными.

Ниже приведено сообщение об ошибке из snd_pcm_prepare() второго волнового файла

 "Device or resource busy" 

ALSA не обеспечивает микшер. Если вам нужно одновременно воспроизводить несколько аудиоstreamов, вам необходимо их смешать самостоятельно.

Самый простой способ сделать это – декодировать WAV-файлы, чтобы float образцы, добавлять их и обрезать их при преобразовании их обратно в целые образцы.

В качестве альтернативы вы можете попытаться открыть звуковое устройство по умолчаниюне аппаратное устройство типа «hw: 0») несколько раз, один раз для каждого streamа, который вы хотите воспроизвести, и надеяться, что плагин dmix ALSA будет загружен и обеспечит смешивание функциональность.

Вы можете настроить плагин dmix ALSA, чтобы позволить нескольким приложениям совместно использовать устройства ввода / вывода.

Ниже приведен пример конфигурации:

 pcm.dmixed { type dmix ipc_key 1024 ipc_key_add_uid 0 slave.pcm "hw:0,0" } pcm.dsnooped { type dsnoop ipc_key 1025 slave.pcm "hw:0,0" } pcm.duplex { type asym playback.pcm "dmixed" capture.pcm "dsnooped" } # Instruct ALSA to use pcm.duplex as the default device pcm.!default { type plug slave.pcm "duplex" } ctl.!default { type hw card 0 } 

Это делает следующее:

  • создает новое устройство с использованием плагина dmix , который позволяет нескольким приложениям совместно использовать выходной stream
  • создает другое, используя dsnoop который делает то же самое для входного streamа
  • объединяет их в новое duplex устройство, которое будет поддерживать ввод и вывод с использованием плагина asym
  • сообщить ALSA использовать новое устройство duplex печати в качестве устройства по умолчанию
  • скажите ALSA, чтобы использовать hw:0 для управления устройством по умолчанию (alsamixer и т. д.),

Вставьте это в ~/.asoundrc или /etc/asound.conf и вам должно быть хорошо идти.

Для получения дополнительной информации см. http://www.alsa-project.org/main/index.php/Asoundrc#Software_mixing .

Вы также можете использовать эту конфигурацию

  pcm.dmix_stream { type dmix ipc_key 321456 ipc_key_add_uid true slave.pcm "hw:0,0" } pcm.mix_stream { type plug slave.pcm dmix_stream } 

Обновите его в ~ / .asoundrc или /etc/asound.conf.

Вы можете использовать команду

Для wav-файла

aplay -D mix_stream “filename”

Для raw или pcmfile

aplay -D mix_stream -c “channels” -r “rate” -f “format” “filename”

Введите значение для каналов, скорости, формата и имени файла в соответствии с вашим аудиофайлом

следующее – очень упрощенное многопоточное решение воспроизведения (предполагая, что оба файла имеют одинаковый формат выборки, один и тот же номер канала и ту же частоту):

  1. начальный stream на основе буфера для каждого декодирования файла (необходимо сделать этот код 2 раза – для file1 и для file2 ):

     import wave import threading periodsize = 160 f = wave.open(file1Wave, 'rb') file1Alive = True file1Thread = threading.Thread(target=_playFile1) file1Thread.daemon = True file1Thread.start() 
  2. сам файл декодирования (также должен быть определен дважды – для file1 и для file2 ):

     def _playFile1(): # Read data from RIFF while file1Alive: if file1dataReady: time.sleep(.001) else: data1 = f.readframes(periodsize) if not data1: file1Alive = False f.close() else: file1dataReady == True 
  3. начало слияния streamов (aka funnel ) для объединения файловых декодирования

     import alsaaudio import threading sink = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, device="hw:CARD=default") sinkformat = 2 funnelalive = True funnelThread = threading.Thread(target=self._funnelLoop) funnelThread.daemon = True funnelThread.start() 
  4. слияние и воспроизведение (aka funnel ) thread

     def _funnelLoop(): # Reading all Inputs while funnelalive: # if nothing to play - time to selfdestruct if not file1Alive and not file2Alive: funnelalive = False sink.close() else: if file1dataReady and file2dataReady: # merging data from others but first datamerged = audioop.add(data2, data2, sinkformat) file1dataReady = False file2dataReady = False sink.write(datamerged) time.sleep(.001)