Saída de áudio para vários dispositivos de som simultaneamente

10

Gostaria que meu RasPi enviasse áudio para a porta de saída de áudio interna e também para a placa de saída digital (um Digif Hifiberry I2S). Isso deve ser possível com a ALSA. Eu tenho os drivers carregados e posso enviar para os dois dispositivos de som individualmente, mas combiná-los simplesmente não está funcionando. Existem vários posts explicando como fazer isso, mas não consigo fazer minha configuração funcionar.

O erro do 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

Saída de "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

Saída de "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`

Conteúdo do /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
}
Christi
fonte
Eu acho que você deveria procurar no pulseaudio. Mas eu posso estar errado aqui
Gerben
3
Eu olhei para o pulseaudio. Minha experiência foi que basicamente não funcionou.
Christi
Após uma investigação mais aprofundada (e uma segunda tentativa com o pulseaudio), acho que o problema é que esse tipo de recurso requer acesso compartilhado à memória da placa de som e / ou suporte ao mmap. O driver RasPi I2S não suporta isso. Realmente não posso confirmar isso, pois não há informações de depuração particularmente úteis da ALSA ou da PulseAudio - em geral, tudo funciona até você tentar envolver várias fontes de som. Não tenho certeza se isso será corrigido nos kernels RasPi ou não, mas tentar consertá-lo levaria mais tempo do que estou disposto a investir.
Christi
Só posso sugerir que o pulseaudio funcione , pois ele é capaz de fazer exatamente o que você deseja fazer (incluindo a extensão para outras placas de som na rede).
earthmeLon
Como mencionei acima, consegui o Pulseaudio funcionando. Ele funciona bem em cada dispositivo individual e falha quando você tenta criar um fluxo para várias saídas ao mesmo tempo. Acredito que a falta de mapeamento de memória no driver RasPi I2S seja a culpada, mas a depuração adicional envolveria essencialmente o aprendizado da estrutura interna do ALSA e / ou do Pulseaudio, que eu não tenho tempo ou disposição para fazer.
Christi

Respostas:

1

É um pouco hacky, mas você já considerou o teecomando? Leia mais sobre o StackExchange na re-direção do tee e consulte a seção de artigos da Wiki para obter mais exemplos. Estou pensando que, se você tem um comando que gera o nome do arquivo ou o link para o conteúdo da mídia, lstalvez, e use teepara chamar comandos para o seu media player preferido. Aqui está como eu script em torno do problema ...


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

Notas:

O código acima pode ser codificado para ter opções de manutenção para cada bifurcação de saída e a InputParcervariável deve ser editada se você planeja enviar um diretório ou link da web que contenha mais de um arquivo de mídia. Mas um arquivo de cada vez deveMediaOptions gerar saída para ambos se o 1/2 for codificado ou definido em cada execução. É um pouco hacky, você foi avisado.

... depois dos testes, eu provavelmente jogaria if [ ${#} < 4]; then echo "error"; fiperto do topo; editar o 4número de argumentos que senti que precisa estar lá. Executando como está, não se bash scripted_dule_player 'aplay <common_options>' '<options_output1>' '<options_output2>' '</full/file/path/to/mediafile>'esqueça de modificar para o seu sistema as opções e caminhos de arquivo que você deseja executar; as coisas entre <>.

Os problemas com o uso teesão que ele não é muito portável entre os tipos de Linux e pode causar problemas com o áudio não sendo reproduzido em sincronia entre as saídas. Em vez disso, sugiro usar omxplayer -o botha saída de som para dois dispositivos separados, mas como isso só foi testado em um RPi com saída HDMI e áudio conectada, não é exatamente a configuração usada pelo OP e pelo OP solicitado alsa.

Há também um bom blog sobre o assunto das configurações da alsa multi placa de som para vários usuários que você pode procurar; talvez você tenha um erro seu que fará com que meu código acima bloqueie um ponto discutível; apenas observe que o guia foi voltado para o Linux com sabor de Slaker e não para Raspbian.

S0AndS0
fonte