pan¶
Watch on youtube.com- see also
The description in the official documentation:
Mix channels with specific gain levels. The filter accepts the output channel layout followed by a set of channels definitions.
This filter is also designed to efficiently remap the channels of an audio stream.
The filter accepts parameters of the form:
l|outdef|outdef|...
l:
output channel layout or number of channels
outdef:
output channel specification, of the form:
out_name=[gain*]in_name[(+-)[gain*]in_name...]
out_name:
output channel to define, either a channel name (FL, FR, etc.) or a channel number (c0, c1, etc.)
gain:
multiplicative coefficient for the channel, 1 leaving the volume unchanged
in_name:
input channel to use, see out_name for details;
Warning
it is not possible to mix named and numbered input channels
If the `=’ in a channel specification is replaced by `<’, then the gains for that specification will be renormalized so that the total is 1, thus avoiding clipping noise.
For example:
[me@host: ~]$ # swapping LR
[me@host: ~]$ ffmpeg -y -i 2chstereo.wav -filter_complex "
> [0:a]pan='stereo|FL=FR|FR=FL'" out.wav
[me@host: ~]$ # both the inputs have 2 channels stereo,
[me@host: ~]$ # so the result of "amerge" has 4 channels.
[me@host: ~]$ ffmpeg -y -i audio1.wav -i audio2.wav -filter_complex "
> [0:a][1:a]
> amerge
> ,pan='stereo|
> c0 < 0.5 * c0 + 0.5 * c2 |
> c1 < 0.5 * c1 + 0.5 * c3'
> " out.wav
In the uplodaed video, I did:
[me@host: ~]$ # Applying "pan" filter. In this case, it decreases
[me@host: ~]$ # the left and right channel volumes separately.
[me@host: ~]$ ffplay -f lavfi "
> amovie=wolframtones_02.wav
> ,pan='stereo| c0 = 0.1 * c0 | c1 = 0.9 * c1'
> ,asplit=3
> [out1][oa1][oa2];
> [oa1]showfreqs=s=960x270:fscale=log:cmode=separate[v1];
> [oa2]showvolume,scale=960:270[v2];
> [v1][v2]vstack[out0]"
[me@host: ~]$ # After separating LFE components and others,
[me@host: ~]$ # let's "amerge"" them.
[me@host: ~]$ # The resulting channel layout will be 4 channels
[me@host: ~]$ # (FL | FR | FC | BC) (probably not what you want).
[me@host: ~]$ ffplay -f lavfi "
> amovie=wolframtones_02.wav
> ,asplit[a1][a2];
> [a1]bandreject=f=192:w=64,aformat=channel_layouts=stereo[rest];
> [a2]bandpass=f=192:w=64,aformat=channel_layouts=stereo[lfe];
> [rest][lfe]amerge
> ,asplit=3
> [out1][oa1][oa2];
> [oa1]showfreqs=s=960x270:fscale=log:cmode=separate[v1];
> [oa2]showvolume,scale=960:270[v2];
> [v1][v2]vstack[out0]"
[me@host: ~]$ # Using "pan" to make this into "FL | FR | LFE"
[me@host: ~]$ # 2.1 channel.
[me@host: ~]$ ffplay -f lavfi "
> amovie=wolframtones_02.wav
> ,asplit[a1][a2];
> [a1]bandreject=f=192:w=64,aformat=channel_layouts=stereo[rest];
> [a2]bandpass=f=192:w=64,aformat=channel_layouts=stereo[lfe];
> [rest][lfe]amerge
> ,pan='2.1| FL=FL | FR=FR | LFE=FC+BC'
> ,asplit=3
> [out1][oa1][oa2];
> [oa1]showfreqs=s=960x270:fscale=log:cmode=separate[v1];
> [oa2]showvolume,scale=960:270[v2];
> [v1][v2]vstack[out0]"
[me@host: ~]$ # It just outputs the output to a file instead of
[me@host: ~]$ # real-time playback.
[me@host: ~]$ ffmpeg -filter_complex "
> amovie=wolframtones_02.wav
> ,asplit[a1][a2];
> [a1]bandreject=f=192:w=64,aformat=channel_layouts=stereo[rest];
> [a2]bandpass=f=192:w=64,aformat=channel_layouts=stereo[lfe];
> [rest][lfe]amerge
> ,pan='2.1| FL=FL | FR=FR | LFE=FC+BC'
> ,asplit=3
> [out1][oa1][oa2];
> [oa1]showfreqs=s=960x270:fscale=log:cmode=separate[v1];
> [oa2]showvolume,scale=960:270[v2];
> [v1][v2]vstack[out0]" -map '[out0]' -map '[out1]' out_2.1.mp4
[me@host: ~]$ # Probably, there isn't much that you try to
[me@host: ~]$ # convert from 2ch stereo to 2.1ch as in the
[me@host: ~]$ # previous example. Rather, most people want to
[me@host: ~]$ # convert 2.1ch audio received from someone to
[me@host: ~]$ # 2ch stereo to avoid problems in the playback
[me@host: ~]$ # environment.
[me@host: ~]$ ffplay out_2.1.mp4 -af "pan='stereo|FL<FL+LFE|FR<FR+LFE'"
[me@host: ~]$ ffplay -f lavfi "
> amovie=out_2.1.mp4,pan='stereo|FL<FL+LFE|FR<FR+LFE',asplit[out1][a];
> [a]showvolume,scale=800:-1[out0]"
Note
Saying “form specification” may feel flexible, but not at all. For example, the following examples are all illegal and rejected.
[me@host: ~]$ # layout "stereo " is invalid (extra space)
[me@host: ~]$ ffmpeg -y -i 2chstereo.wav -filter_complex "
> [0:a]pan='stereo |FL=FR|FR=FL'" out.wav
[me@host: ~]$ # you cannot use calculation
[me@host: ~]$ ffplay 2chstereo.wav -af "
> pan='stereo|FL=(1/2)*FR|FR=FL'"
[me@host: ~]$ # recall: you cannot use calculation
[me@host: ~]$ ffplay -f lavfi "
> amovie=2chstereo.wav,pan='stereo|c0=0.5*(c0+c1)|c1=c1'"
[me@host: ~]$ # must be "gain*in_name", not "in_name*gain"
[me@host: ~]$ ffmpeg -y -i 2chstereo.wav -filter_complex "
> [0:a]pan='stereo|c0=c0*0.5|c1=c1'" out.wav
[me@host: ~]$ # can not mix named and numbered channels
[me@host: ~]$ ffmpeg -y -i 2chstereo.wav -filter_complex "
> [0:a]pan='stereo|c0=0.5*FR|c1=c1'" out.wav
[me@host: ~]$ # can not mix named and numbered channels
[me@host: ~]$ ffmpeg -y -i 2chstereo.wav -filter_complex "
> [0:a]pan='stereo|FL=0.5*c0|c1=c1'" out.wav
changing the mixing amount for each frequency band¶
If you want to understand the behavior of filters that are frequency-based and operate on multiple channels, you may want to split the left and right channels by frequency band. The following example is changing the mixing amount for each frequency band:
[me@host: ~]$ # "acrossover" can be used in ffmpeg 4.1+.
[me@host: ~]$ ffmpeg411="/c/Program Files/ffmpeg-4.1.1-win64-shared/bin/ffmpeg"
[me@host: ~]$ "${ffmpeg411}" -y -filter_complex "
> amovie=input.wav
> ,acrossover=split='55|110|220|1500'[ab0_0][ab1_0][ab2_0][ab3_0][ab4_0];
> [ab0_0]aformat=channel_layouts=stereo[ab0];
> [ab1_0]aformat=channel_layouts=stereo[ab1];
> [ab2_0]aformat=channel_layouts=stereo[ab2];
> [ab3_0]aformat=channel_layouts=stereo[ab3];
> [ab4_0]aformat=channel_layouts=stereo[ab4];
> [ab0][ab1][ab2][ab3][ab4]amerge=5[sm];
> [sm]pan='stereo|
> c0 < 0.0 * c0 + 3.0 * c2 + 0.0 * c4 + 3.0 * c6 + 1.0 * c8
> |
> c1 < 4.0 * c1 + 0.0 * c3 + 4.0 * c5 + 0.0 * c7 + 1.0 * c9'
> ,volume=3
> ,asplit=2[out1],channelsplit[a1][a2];
> [a1]showcqt=s=1920x540,setsar=1[v1];
> [a2]showcqt=s=1920x540,setsar=1,vflip[v2];
> [v1][v2]vstack
> [out0]
> " -map '[out0]' -map '[out1]' output.mp4