How to use the Linux arecord command to generate multiple FLAC files?
Olivia Zamora
I would like to use the Linux arecord command to record and save multiple FLAC type files using the file time flag or similar:
--max-file-time For a wav file it is fairly straight forward to save multiple files using the --max-file-time flag. In the example below a new wav file is stored every 10 seconds of 6 channel audio:
arecord -t raw -f S16_LE -r 44100 --max-file-time 10 -D ac108 -c 6 --use-strftime listen-%H-%M-%v.wavIn this answer a contributor showed how to record to a FLAC file by piping the audio data to the flac program for output in flac formatfile, as demonstrated below:
arecord -t raw -f S16_LE -r 44100 -D ac108 -c 6 | flac - -f --endian little --sign signed --channels 6 --bps 16 --sample-rate 44100 -s -o listen.flacMy question is simply how to construct a Linux command that can record to multiple FLAC files where each file is similar in size?
01 Answer
Let's take advantage from these properties of raw format your arecord generates:
- there is no header, no metadata;
- each full sample is 6 (number of channels) times 2 bytes (i.e. 16 bits), so exactly 12 bytes;
- there are exactly 44100 samples in each second.
So each second takes 44100 × 12 = 529200 bytes. To get 10 seconds you need 5292000 bytes. Note you cannot take a random chunk of 5292000 consecutive bytes from the stream, you need to make sure you don't start mid-sample. But the first 5292000 bytes will contain an integer number of samples for sure (strictly 44100 samples), then the next 5292000 bytes, then the next, and so on.
This is what split command can do: it can split the stream into pieces of a given size. The real magic comes from its --filter= option.
arecord -t raw -f S16_LE -r 44100 -D ac108 -c 6 \
| split -d -b 5292000 --filter='
flac - -f --endian little --sign signed --channels 6 --bps 16 --sample-rate 44100 -s -o "${FILE}.flac"
'In the above pipeline split will run flac for each piece of data.
Notes:
--filteris not required by POSIX; yoursplitmay or may not support it.- See
man 1 splitto learn options that affect what${FILE}expands to. I used just-d, so in my case it'sx00,x01,x02, … - This is a pipeline, so Ctrl+C will send SIGINT to both
arecordandsplit. In my tests this makes the last flac file truncated (splitterminatesflacin a hard way?), so I getERROR while decoding data,state = FLAC__STREAM_DECODER_END_OF_STREAMwhile decoding the file later. Sending SIGINT toarecordonly (e.g.killall arecord) allowssplitand (most importantly)flacto finish gracefully. The command takes multiple lines for readability, but logically it's a one-liner in the following form:
arecord … | split … --filter='flac …'