The description in the official documentation:

This filter has some handy utilities to manage stereo signals, for converting M/S stereo recordings to L/R signal while having control over the parameters or spreading the stereo image of master track.

[me@host: ~]$ # Convert M/S signal to L/R
[me@host: ~]$ ffplay snd.wav -af "stereotools=mode=ms>lr"
[me@host: ~]$ # Apply karaoke like effect
[me@host: ~]$ ffplay snd.wav -af "stereotools=mlev=0.015625"

Note that this filter affects the (ffmpeg-utils)2.8. Syntax | Channel Layout, but on the other hand “it doesn’t pay attention to the channel layout”. That is, the input is unconditionally converted to 2-channel stereo, which becomes the output channel layout as it is:

[me@host: ~]$ ffprobe -hide_banner mono.wav 2>&1 | grep Audio
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 1 channels, s16, 768 kb/s
[me@host: ~]$ ffmpeg -y -i mono.wav -af "stereotools" mono_stt.wav
[me@host: ~]$ ffprobe -hide_banner mono_stt.wav 2>&1 | grep Audio
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 2 channels, s16, 1536 kb/s
[me@host: ~]$ ffprobe -hide_banner 21ch.wav 2>&1 | grep Audio
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2.1, s16, 2116 kb/s
[me@host: ~]$ ffmpeg -y -i 21ch.wav -af "stereotools" 21ch_stt.wav
[me@host: ~]$ ffprobe -hide_banner 21ch_stt.wav 2>&1 | grep Audio
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s

This is the same for other stereo filters such as stereowiden, extrastereo, and so on, but for this filter, this fact can confuse you. Actually I did.

“mid / side” appears in the description and in the description of mode. These are, indeed, completely unrelated to the (ffmpeg-utils)2.8. Syntax | Channel Layout, but it is the encoding of the signal in each channel. It simply means if mode is “lr>ms”:

l = L * min(1., 2. - sbal);
r = R * min(1., sbal);
L = 0.5 * (l + r) * mlev;  /* left out */
R = 0.5 * (l - r) * slev;  /* right out */

and if mode is “ms>lr”:

l = L * mlev * min(1., 2. - mpan) + R * slev * min(1., 2. - sbal);
r = L * mlev * min(1., mpan)      - R * slev * min(1., sbal);
L = l;  /* left out */
R = r;  /* right out */

In essence, what this filter does is pretty straightforward, and if you can read the C language to some extent, I think it’s best to refer the source code (af_stereotools.c).

It has many parameters and can be controlled in various ways. this filter has the flexibility to swap left and right channels, for example. However, in the end, this filter is based on “M/S recording conversion tool”, so, unless you want to input or output audio related to “M/S recording” this filter, it is not particularly easy to use.

It is convenient to use it occasionally, so it is good to put it in one corner of the head, but usually you will probably feel the pan filter, aeval, etc. more convenient.

see also

pan, aeval