Command line audio - piping for simultaneous playback and recording

5,497

You can use tee(1) to multiplex the stream, e.g.

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

You might also be interested in soxs' synth effect, which can produce most tones and sweeps, e.g.

sox -n -r 44100 test.wav synth 4 sine 100:1000
Share:
5,497

Related videos on Youtube

sdaau
Author by

sdaau

Updated on September 18, 2022

Comments

  • sdaau
    sdaau over 1 year

    I am trying to generate sound data, convert it and store it to a WAV format. I'm almost there - except I'd like to hear the generated sound while it is being "recorded".

    This command just generates data and plays it back:

    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
    

    (Note that if you press Ctrl-C here after sound stops playing, aplay may segfault)

    Using sox and mplayer, I can record fine - but I can hear no sound at the same time:

    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
    

    Note here that play test.wav (where play is from sox package, not alsa's aplay) will state "Duration: 00:00:03.00" for the test.wav file. Also, this process seems to run faster than realtime, i.e. completes in (apparently) less than 3 secs.

    By trying to cheat by using tee to capture the stream to disk,

    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
    

    Here apparently I get to hear the sound as it is generated - and test.wav is playable as well, however, play test.wav will report "Duration: unknown".

    So I'd like to ask - is it possible to do something like the above "one-liner" command, to both generate, play and record a sound at the same time - however, without the need to install jack?

    PS: some relevant links: