Áudio de linha de comando - tubulação para reprodução e gravação simultâneas

Áudio de linha de comando - tubulação para reprodução e gravação simultâneas

Estou tentando gerar dados de som, convertê-los e armazená-los no formato WAV. Estou quase lá - só que gostaria de ouvir o som geradoenquantoestá sendo "gravado".

Este comando apenas gera dados e os reproduz:

perl -e 'for ($c=0; $c<4*44100; $c++) {
             $k=1*sin((1500+$c/16e1)*$c*22e-6); print pack "f", $k;
         } ' |
aplay -t raw -c 1 -r 44100 -f FLOAT_LE

(Observe que se você pressionar Ctrl-C aqui depois que o som parar de tocar, aplaypoderá ocorrer uma falha de segmentação)

Usando soxe mplayer, posso gravar bem - mas não consigo ouvir nenhum som ao mesmo tempo:

perl -e 'for ($c=0; $c<4*44100; $c++) {
             $k=1*sin((1500+$c/16e1)*$c*22e-6); print pack "f", $k;
         } ' |
sox -V -r 44100 -c 1 -b 32 -e floating-point -t raw - \
    -c 2 -b 16 -t wav - trim 0 3 gain -1 dither |
mplayer - -cache 8092 -endpos 3 -vo null -ao pcm:waveheader:file=test.wav

Observe aqui que play test.wav(onde playé do soxpacote, não alsado aplay) indicará "Duração: 00:00:03.00" para o test.wavarquivo. Além disso, esse processo parece ser executado mais rápido que o tempo real, ou seja, é concluído em (aparentemente) menos de 3 segundos.

Ao tentar trapacear usando teepara capturar o fluxo para o disco,

perl -e 'for ($c=0; $c<4*44100; $c++) {
             $k=1*sin((1500+$c/16e1)*$c*22e-6); print pack "f", $k;
         } ' |
sox -V -r 44100 -c 1 -b 32 -e floating-point -t raw - \
    -c 2 -b 16 -t wav - trim 0 3 gain -1 dither |
tee test.wav |
aplay

Aqui, aparentemente, consigo ouvir o som conforme ele é gerado - e test.wavtambém pode ser reproduzido, no entanto, play test.wavreportará "Duração: desconhecida".

Então, eu gostaria de perguntar - é possível fazer algo como o comando "one-liner" acima, para gerar, reproduzir e gravar um somao mesmo tempo- no entanto,sema necessidade de instalar jack?

PS: alguns links relevantes:

Responder1

Você pode usar tee(1) para multiplexar o fluxo, por exemplo

perl -e 'for ($c=0; $c<4*44100; $c++) {
  $k=1*sin((1500+$c/16e1)*$c*22e-6); print pack "f", $k;
}' | tee >(sox -c1 -r44100 -t f32 - test.wav) \
         >(sox -c1 -r44100 -t f32 - -d) > /dev/null

Você também pode estar interessado no efeito de sintetizador do Soxs, que pode produzir a maioria dos tons e varreduras, por exemplo

sox -n -r 44100 test.wav synth 4 sine 100:1000

informação relacionada