Detectar quando apenas o silêncio está sendo tocado

3

Meu PC está conectado a um amplificador de áudio que eu posso ligar ou desligar na rede. Eu gostaria de configurar tudo para desativá-lo automaticamente depois que nenhum áudio estiver sendo reproduzido por 10 minutos.

Eu encontrei algumas perguntas semelhantes aqui que aconselham olhar para /proc/asound/card*/pcm*/sub*/status para verificar a palavra RUNNING que indica que o áudio está sendo produzido, no entanto, muitos programas parecem deixar o áudio em execução mesmo quando não estão fazendo nenhum ruído, apenas produzindo silêncio. Tenho notado que alguns programas em Python fazem isso, assim como o Firefox quando executado através de apulse .

Isso significa que não consigo detectar via /proc/asound/ quando não há áudio saindo dos alto-falantes, pois é permanentemente RUNNING .

Existe outra maneira de detectar quando o único sinal de áudio sendo tocado é o silêncio? Existe alguma maneira de gravar ou interceptar a saída ALSA, mesmo quando um dispositivo hw é o usado?

    
por Malvineous 06.08.2017 / 14:52

1 resposta

1

Esta é uma demonstração de prova de conceito usando apenas alsa, o módulo alsa loopback, e sox para detectar o silêncio. O módulo de loopback fornece um dispositivo de saída no qual você pode reproduzir o som e, em seguida, registra-se a partir dele. Por exemplo, você poderia direcionar mplayer para usar o loopback para a saída de som e, em seguida, executar sox para gravar a partir do loopback, detectar o silêncio e a saída para o dispositivo de saída de hardware original.

Carregue o módulo com

sudo modprobe snd-aloop

(Estava na minha lista de módulos do kernel disponíveis). aplay -l agora listará um novo cartão com dois dispositivos. O dispositivo 0 deve ser reproduzido no dispositivo 1 para gravar. Existem 8 canais "subdevice" independentes, e é mais fácil usar o número 0, pois ele pode ser omitido. (Encontrei aplay no pacote alsa-utils ).

$ aplay -l
...
card 1: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
...
  Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
...
  Subdevice #7: subdevice #7

Agora você pode usar outro utilitário do pacote para gerar um tom contínuo no dispositivo de loopback 0 (subdevice 0):

speaker-test -t sine -D hw:Loopback

ou por exemplo, diga mplayer para usar o dispositivo com a opção -ao alsa:device=hw=Loopback

Você não ouvirá nada até executar sox para ler o outro lado do dispositivo e gravá-lo no hardware real, supondo que este seja o cartão 0:

sox -q  -t alsa hw:Loopback,1  -t alsa hw:0  silence 0 1 10.0 2%

(Eu vi alguns avisos sox WARN alsa: under-run ). Se você parar o teste de alto-falante, após 10 segundos de silêncio, o comando sox será interrompido. Observe que, se você silenciar mplayer , ficará em silêncio, mas isso parece ser independente do nível de dados (que você pode visualizar se remover o -q de sox ). Você precisa pausar ou diminuir o nível de som de mplayer para que o silêncio seja detectado. sox também pode introduzir um segundo ou dois de atraso no áudio. Você deve ser capaz de configurar o alsa para tornar o dispositivo Loopback o padrão em vez do seu cartão 0.

Uma solução mais satisfatória é permitir que os drivers de som do kernel manipulem o áudio em tempo real, e use sox apenas para detectar o silêncio, jogando fora sua saída. Isso parece ser possível, mas com apenas alsa também é um pouco complicado e precisa de conhecimento que eu não tenho, embora você possa encontrar exemplos de duplicação de som para dois dispositivos, sua placa de áudio original e um dispositivo virtual que sox pode então ler.

Uma solução mais simples usando pulseaudio para permitir o monitoramento é possível, usando pactl load-module module-combine-sink , o que provavelmente irei investigar.

    
por 10.08.2017 / 20:03

Tags