21/09/2002 @21:42:09 ^22:48:16
RECORD_AUDIO & sleep 2h ; kill $!
This is how I recorded and encoded a two-hour show off the radio last night, using my linux box.
sox -t ossdsp -r 48000 -w -s -c2 /dev/dsp -t raw - | \ lame -r -x -s 48 - show.mp3 & sleep 2h ; kill $!
This is in three parts which will now be further explained:
sox -t ossdsp -r 48000 -w -s -c2 /dev/dsp -t raw - |
We use sox for the sound recording, as usual.
- -t ossdsp and /dev/dsp mean to record from the sound device /dev/dsp whose format is ossdsp (this is a pseudoformat to tell sox that it is using an OSS sound device)
- -r 48000: record at 48kHz (this could be slower, especially if you have a slower system, but it needs to be a frequency supported by the MP3 encoding format)
- -w -s -c2 specify to read 16 bit wide samples in "signed" format from two channels (i.e. in stereo)
- -t raw - means write the sample to standard output with no conversion to a file format
We want a raw output because rather than produce an intermediate file, we want to pipe the output directly into the encoder.
lame -r -x -s 48 - show.mp3
Again as usual we used lame for the encoding; one day I'll investigate Ogg Vorbis, but, you know...
- -r: tell lame to expect the input as raw unformatted data. You have to do this because we're reading from standard input.
- -x: I found it necessary to swap incoming data byte order for some reason... If you get static, take it out:)
- -s 48 Tell lame the sampling rate of the incoming data. It assumes 16 bit width and so on but you need sox's output rate and lame's input rate to match.
- - show.mp3 means encode standard input to a file called "show.mp3". Use whatever final filename you like. "test.mp3". "retard.mp3". Whatever.
You can specify whatever bitrate and/or quality of encoding you want, however it needs to be one that the computer is fast enough to do in real time. If it takes longer to encode a section of incoming sample data than it does to record, you'll get a bottleneck and bad things will happen. For similar reasons you don't want the computer doing too much else at the time.
& sleep 2h ; kill $!
The problem is getting sox to stop recording. Since /dev/dsp, when opened and read, will just give you raw sample data as many times as you ask for it, never producing an EOF, the process would continue until the disk gets filled! You have to interrupt it, and that's what this final part does.
The ampersand simply means to run the previous pipeline in its own child subprocess of the shell. After it has started the subprocess, sleep 2h is executed, which pauses the shell for two hours (surprise surprise!) After this time, kill $! sends a terminate signal to the last subprocess - that is, the recording. Hence it stops after two hours.
Anyway, that's what I did. "Your Mileage May Vary" and don't come crying to me if you experience data loss:) I also got the computer to power itself off five minutes after the recording was due to finish and next time I'll use a slightly higher encoding quality, I think the processor can handle it.
For a quick demonstration of "command & sleep time ; kill $!" try this. "yes text" will loop, printing text to standard output, until interrupted. So do "yes hello & sleep 5s ; kill $!". It'll stop after five seconds.