Вывод звука на несколько звуковых устройств одновременно

10

Я бы хотел, чтобы мой RasPi отправлял аудио на мой встроенный аудиовыход, а также на мою карту цифрового выхода (I2S Hifiberry Digi). Это должно быть возможно с ALSA. Я загрузил драйверы и могу отправлять оба звуковых устройства по отдельности, но объединение их просто не работает. Есть несколько сообщений, объясняющих, как это сделать, но я не могу заставить мой конфиг работать.

Ошибка из aplay:

Playing WAVE 'sin1000_48khz.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
ALSA lib pcm_params.c:2162:(snd1_pcm_hw_refine_slave) Slave PCM not usable
aplay: set_params:1059: Broken configuration for this PCM: no configurations available

Вывод "aplay -l"

**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_digi], device 0: HifiBerry Digi HiFi wm8804-spdif-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Вывод "aplay -L"

null
   Discard all samples (playback) or generate zero samples (capture)
sysdefault:CARD=sndrpihifiberry
    snd_rpi_hifiberry_digi,
    Default Audio Device
sysdefault:CARD=ALSA
    bcm2835 ALSA, bcm2835 ALSA
    Default Audio Device`

Содержимое /etc/asound.conf

pcm.both {
    type route
    slave.pcm {
        type multi    
        slaves.a.pcm "hw:0,0"
        slaves.b.pcm "hw:1,0"
        slaves.a.channels 2
        slaves.b.channels 2

        bindings.0.slave a
        bindings.0.channel 0    
        bindings.1.slave a
        bindings.1.channel 1

        bindings.2.slave b
        bindings.2.channel 0
        bindings.3.slave b
        bindings.3.channel 1
    }

    ttable.0.0 1
    ttable.1.1 1

    ttable.0.2 1
    ttable.1.3 1
}

ctl.both {
    type hw
    card sndrpihifiberry
    device 0
}

pcm.hifiberry {
    type hw    
    card sndrpihifiberry
    device 0
}

ctl.hifiberry {
    type hw
    card sndrpihifiberry
    device 0
}

pcm.audioout {
    type hw
    card ALSA
    device 0
}

ctl.audioout {
    type hw
    card ALSA
    device 0
}

pcm.!default {
    type plug
    slave {
        pcm both
    }
}

#pcm.!default {    
#    type hw
#    card sndrpihifiberry
#    device 0
#}

ctl.!default {
    type hw
    card sndrpihifiberry
    device 0
}
Кристи
источник
Я думаю, что вы должны смотреть на Pulseaudio. Но я могу ошибаться здесь
Гербен,
3
Я посмотрел в pulseaudio. Мой опыт состоял в том, что это в основном не работало.
Кристи
После дальнейшего исследования (и второй попытки с pulseaudio), я думаю, что проблема заключается в том, что этот тип функции требует общего доступа к памяти звуковой карты и / или поддержки mmap. Драйвер RasPi I2S не поддерживает это. Я не могу подтвердить это, так как нет никакой особенно полезной информации отладки ни от ALSA, ни от PulseAudio - в общем, все работает, пока вы не попытаетесь задействовать несколько источников звука. Я не уверен, будет ли это исправлено в ядрах RasPi или нет, но попытка исправить это потребует больше времени, чем я готов инвестировать.
Кристи
Я могу только предложить попробовать заставить Pulseaudio работать , так как он способен делать именно то, что вы хотите делать (в том числе распространяться на другие звуковые карты в сети).
earthmeLon
Как я упоминал выше, я заставил Pulseaudio работать. Он отлично работает на каждом отдельном устройстве, а затем завершается ошибкой при попытке создать поток для нескольких выходов одновременно. Я полагаю, что причиной является недостаток отображения памяти в драйвере RasPi I2S, но дальнейшая отладка, по сути, потребует изучения внутренней структуры ALSA и / или Pulseaudio, на что у меня нет времени или желания делать это.
Кристи

Ответы:

1

Это немного глупо, но вы рассматривали teeкоманду? Читайте больше на StackExchange о переадресации и смотрите Wiki Artical для большего количества примеров. Я думаю, что если у вас есть команда, которая выводит имя файла или ссылку на медиа-контент, lsвозможно, и использовать teeдля вызова команд на ваш предпочтительный медиа-плеер. Вот как я мог бы решить эту проблему ...


#!/bin/bash
MediaPlayer="$1"
MediaOptions1="$2"
MediaOptions2="$3"
InputParcer="ls $4"
${InputParcer} | tee >(${MediaPlayer} ${MediaOptions1}) >(${MediaPlayer} ${MediaOptions2}) || echo 'Exiting baddly'

Заметки:

Вышеприведенное может быть жестко запрограммировано, чтобы иметь несколько вариантов обслуживания для каждого разветвления, и InputParcerпеременная должна быть отредактирована, если вы планируете предоставить каталог или веб-ссылку, которая содержит более одного медиа-файла. Но один файл за раз должен выводить оба файла, если MediaOptions1/2 либо жестко заданы, либо установлены при каждом запуске. Это немного глупо, вы были предупреждены.

... после тестирования и тому подобного я бы, скорее всего, бросился бы if [ ${#} < 4]; then echo "error"; fiближе к вершине; редактирование 4для того, сколько аргументов я чувствовал, должен быть там. Работая как есть, вы bash scripted_dule_player 'aplay <common_options>' '<options_output1>' '<options_output2>' '</full/file/path/to/mediafile>'обязательно измените для вашей системы параметры и пути к файлам, которые вы хотите запустить; вещи между <>.

Проблемы с использованием tee- то, что это не очень переносимо между версиями Linux, и это может вызвать проблемы с аудио, не играющим в синхронизации между выходами. Вместо этого я бы предложил использовать omxplayer -o bothдля вывода звука на два отдельных устройства, но так как это было протестировано только на RPi, к которому подключен HDMI и аудио выход, не совсем то, что используется OP, и OP запросил что-то для alsa.

Есть также хороший блог на тему многопользовательских конфигураций alsa multi sound card, которые вы можете просмотреть; возможно, у вас есть ошибка, из-за которой приведенный выше код блокирует спорный вопрос; просто обратите внимание, что руководство было ориентировано на Slaker со вкусом Linux, а не Raspbian.

S0AndS0
источник