Why does ffmpeg's conversion from mono to stereo lower the volume?

12

3

We start with this mono file: test.wav

In audacity it looks like this:

mono

Then we convert it to stereo with this command:

ffmpeg -i test.wav -ac 2 out.wav

Now it looks like this:

stereo

Notice that the amplitude changed!

Finally, we convert the stereo back to mono:

ffmpeg -i out.wav -ac 1 back.wav

We should get the same file from which we started. But in audacity we get the following picture:

sine wave with different phase and amplitude from original

The questions are:

1) Why did the amplitude change when converting to stereo?

2) Why did the amplitude not change back when converting to mono?

3) how can I make the amplitude change back when converting to mono?

Igor Liferenko

Posted 2018-01-15T07:01:09.483

Reputation: 223

Answers

21

1 - It seems that FFmpeg attempts to respect a common pan law (when routing a centered mono track to a stereo track, lower the mono signal by - 3 dB on each channel of the stereo track). The goal is that the perceived loudness remains coherent.

EDIT

As mentioned by @Mulvya, you can use the pan filter to keep input file level untouched :

ffmpeg -i test.wav -af "pan=stereo|c0=c0|c1=c0" out.wav

END EDIT

2 - It seems that FFmpeg attempts to lower each of the contributing mono signals to prevent the sum to be over maximum level in the destination track.

I couldn't find a definitive description of the processes involved when using the -ac option, but on the AudioChannelManipulation page, you can find the following sentence :

ffmpeg integrates a default down-mix (and up-mix) system that should be preferred (the -ac option) over the pan filter unless you have very specific needs.

3 - For a 2 channel input to a 1 channel output, it seems that :

ffmpeg -i out.wav -filter:a "volume=3dB" -ac 1 back.wav

restores the original level. That should be used with care in the general case for the reasons mentionned above (prevent overloading).

audionuma

Posted 2018-01-15T07:01:09.483

Reputation: 2 449

6Use ffmpeg -i test.wav -af "pan=stereo|c0=c0|c1=c0" out.wav for mono-to-stereo step to keep channel as-is. – Gyan – 2018-01-15T09:35:55.803

I'm curious if the same happens "behind the scenes" in alsa or pulseaudio when we play mono file on a stereo sound card. – Igor Liferenko – 2018-01-16T06:19:08.467

That would be another question. But this question is related to the actual player software more than the underlying OS audio architecture. When playing a mono file, some players do not apply the pan law and put the untouched mono channel to L and R output channels. – audionuma – 2018-01-18T10:38:51.690

@audionuma @Gyan when converting stereo to mono, same volume lowering happens. How can we use the same pan filter in that case? – Riz – 2020-07-28T00:29:07.260