Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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 line 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 line, to both generate, play and record a sound "at the same time" - however, without the need to install jack?

PS: some relevant links:

share|improve this question

1 Answer 1

up vote 1 down vote accepted

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|improve this answer
    
Many thanks for the answer, @ThorAndreassen - looks good! Cheers! –  sdaau Apr 13 '12 at 7:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.