Page head image

Stereo to 2.1 "upmix" on Linux - part 2

(1 comment)

How to construct a 2.1 signal from a stereo signal? We are going to encode it as AC3 ("Dolby Digital"), with the original stereo channels left and right mapped to front left and right, center and rear channels being muted, and bass getting the sum of half of the level of left and right channel. Strictly speaking, we should run the the bass signal through a low pass, but it is not necessary for my speaker system, as the active bass box has a built in low pass with an adjustable cutoff frequency.

As a first attempt, let us just create such a signal. We're going to do this the Unix way: with pipes. Since sox has some issues with WAV streams on non-seekable input such as pipes, and it does not come with ffmpeg bindings on openSUSE for legal reasons, let's first create a PCM stream from anything with ffmpeg:

ffmpeg -i - -ar 48k -f s16le -

It'll take anything from stdin and convert it to an 48 KHz sampling rate 16 bit signed little endian integer PCM stream. Thinking about it, it probably should only take the first two channels from the input, but let's ignore that for now. Now pipe that to sox to create a six channel WAV stream according to above mapping:

ffmpeg -i - -ar 48k -f s16le - | \
sox -t s16 -L -c 2 -r 48k - -t wav - remix 1 2 0 1,2 0 0

If you are wondering about the channel order for surround sound in WAV files (and thus expected by the AC3 encoder): it is front left, front right, front center, lfe (bass), rear left, rear right as defined by Microsoft. The channel order for AC3 is even weirder (ATSC A/52 standard, section, table 5.8), fortunately the encoder is taking care of this.

Talking about encoding, we need to convert it to AC3 with ffmpeg next:

ffmpeg -i - -ar 48k -f s16le - | \
sox -t s16 -L -c 2 -r 48k - -t wav - remix 1 2 0 1,2 0 0 | \
ffmpeg -i - -ab 192k -ac 6 -f ac3 -

Now we just need something to actually write the stream to the audio device. Mplayer can do this for us, however don't ask how long it took me to find all the options:

ffmpeg -i - -ar 48k -f s16le - | \
sox -t s16 -L -c 2 -r 48k - -t wav - remix 1 2 0 1,2 0 0 | \
ffmpeg -i - -ab 192k -ac 6 -f ac3 - | \
mplayer -rawaudio format=0x2000 -demuxer rawaudio -ao alsa:device=iec958 -ac hwac3 -really-quiet -

Let's try that and 'cat' an MP3 file to this pipe... Yes, we have sound! A quick test with Daft Punk — Tron Legacy Soundtrack: oomph oomph!!

The latency is even bearable.

Unfortunately, using the pipe as the output to VLC results in mplayer complaining about underruns frequently. Also, other applications don't even allow piping their audio output. But the approach is still good to play single files and experiment a bit without having to confuse the whole audio setup of the system.


There are currently no comments

New Comment


required (not published)