View Full Version : ffmpeg downmix 7.1 -> 5.1
tebasuna51
15th July 2020, 01:02
The simple way to do the downmix 7.1 -> 5.1 is:
ffmpeg -i INPUT71 -af "pan=5.1(side)|FL=FL|FR=FR|FC=FC|LFE=LFE|SL=0.5*BL+0.5*SL|SR=0.5*BR+0.5*SR" OUT51.wav
But I want preserve the volume balance between front and surround channels, like BeHappy/MeGUI can do in AviSynth, with a controlled gain by 2 without clip.
Then I make a separated chain for the surround channels with:
ffmpeg -i INPUT71 -filter_complex "asplit [f][s]; \
[f] pan=4c|c0=c0|c1=c1|c2=c2|c3=c3 [r]; \
[s] pan=2c|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7, \
acontrast=2, aformat=sample_fmts=s16:channel_layouts=stereo [d]; \
[r][d] amerge=inputs=2,pan=5.1(side) [a]" -map "[a]" OUT51.wav
I tried other functions like 'compand' instead 'acontrast', other formats in 'aformat', 'join' instead 'amerge', ... and always obtain errors in formats, channels layouts, ...
Only the previous command work without errors, the output wav have the format, length, ... correct, but is empty. I only obtain silence.
Please, there are some ffmpeg guru than can help me.
richardpl
15th July 2020, 16:18
Why you do not use pan + alimiter instead of whatever you want to do? Your acontrast filtergraph (it does not do what you think it do) is giving silence because of missing last pan filter options.
tebasuna51
15th July 2020, 21:48
Why you do not use pan + alimiter instead of whatever you want to do?
But to apply the filter only to the surround channels I need split in two chains like I do. Or I'm wrong?
Your acontrast filtergraph (it does not do what you think it do)
Is very simple but yes do the job that I want.
The alimiter don't work for me, distort very much the signal.
The best, for me, is:
compand=attacks=0:decays=0:points=-90/-84|-10/-4|-6/-2|-0/-0.3
is giving silence because of missing last pan filter options.
Arggg!!!
Thanks, only adding the obvious:
|c0=c0|c1=c1|c2=c2|c3=c3|c4=c4|c5=c5
work now.
One more question:
Input #0, dtshd, from '8v341.dts':
Stream #0:0: Audio: dts (DTS-HD MA), 48000 Hz, 7.1, s32p (24 bit)
Stream mapping:
Stream #0:0 (dca) -> asplit
pan -> Stream #0:0 (pcm_s16le)
How can preserve the input bitdepth (a DTS-MA 24 bits).
For what is downsampled to 16 bits?
The filters can't work with more precission?
Richard1485
16th July 2020, 07:26
For what is downsampled to 16 bits?
I think that it's simply because 16-bit is the default for wav in ffmpeg, which in my experience uses certain settings for a given extension regardless of other considerations.
richardpl
16th July 2020, 10:00
How can preserve the input bitdepth (a DTS-MA 24 bits).
For what is downsampled to 16 bits?
The filters can't work with more precission?
pan filter works with first audio sample format it founds.
As compand works with dblp sample format only you could use aformat=dblp prior to calling pan.
For outputing 24bit sample format use pcm_s24be/le codec.
tebasuna51
16th July 2020, 18:47
With this command line:
FFMPEG -i 8v341.dts -filter_complex "aformat=sample_fmts=dblp, asplit [f][s]; \
[f] pan=3.1|c0=c0|c1=c1|c2=c2|c3=c3 [r]; \
[s] pan=stereo|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7, \
compand=attacks=0:decays=0:points=-90/-84|-10/-4|-6/-2|-0/-0.3, \
aformat=channel_layouts=stereo [d]; [r][d] amerge [a]" -map "[a]" zz51.wav
I obtain:
Input #0, dtshd, from '8v341.dts':
...
Stream #0:0: Audio: dts (DTS-HD MA), 48000 Hz, 7.1, s32p (24 bit)
Stream mapping:
Stream #0:0 (dca) -> aformat
amerge -> Stream #0:0 (pcm_s16le)
...
[Parsed_amerge_6 @ 0000017be0953500] Input channel layouts overlap: output layout will be determined by the number of distinct input channels
[Parsed_pan_2 @ 0000017be0940480] Pure channel mapping detected: 0 1 2 3
Output #0, wav, to 'zz51.wav':
...
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 5.1, s16, 4608 kb/s
1) The output is pcm_s16le when the source is s32p (24 bit) and I force aformat=sample_fmts=dblp
Any comments?
2) Without aformat=channel_layouts=stereo
I obtain:
[Parsed_amerge_4 @ 0000019ec0321a80] No channel layout for input 2
Last message repeated 1 times
[AVFilterGraph @ 0000019ec02b6480] The following filters could not choose their formats: Parsed_amerge_4
Consider inserting the (a)format filter near their input or output.
Error reinitializing filters!
Failed to inject frame into filter network: I/O error
Error while processing the decoded data for stream #0:0
Conversion failed!
The channel_layouts=stereo is already defined in previous pan, the 'compand' delete the channel layout?
richardpl
16th July 2020, 19:06
The channel_layouts=stereo is already defined in previous pan, the 'compand' delete the channel layout?
Nope, amerge is causing that.
Let me repeat again you need to specify pcm_s24le/be encoder to get 24bit output. Otherwise default encoder is 16 bit PCM.
tebasuna51
16th July 2020, 20:21
Nope, amerge is causing that.
I don't understand what is the problem, but we can live with that.
Let me repeat again you need to specify pcm_s24le/be encoder to get 24bit output.
Sorry, I checked (the four first channels are bitidentical between the 7.1 and the 5.1 obtained) than the final output preserve the precission from the source adding at the end -c:a pcm_s24le
Otherwise default encoder is 16 bit PCM.
That's is my problem, I can't understand for what the default is downsample.
But ok, that is my final command line recommended to downsample 7.1 -> 5.1 with ffmpeg:
FFMPEG -i 8v341.dts -filter_complex "asplit [f][s]; \
[f] pan=3.1|c0=c0|c1=c1|c2=c2|c3=c3 [r]; \
[s] pan=stereo|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7, \
compand=attacks=0:decays=0:points=-90/-84|-10/-4|-6/-2|-0/-0.3, \
aformat=channel_layouts=stereo [d]; \
[r][d] amerge [a]" -map "[a]" -c:a pcm_s24le zz51.wav
Of course the output can be other format (FLAC, AAC, EAC3, AC3,...)
Richard1485
16th July 2020, 20:29
That's is my problem, I can't understand for what the default is downsample.
I don't understand ffmpeg's logic either. AFAIK, if you specify .wav, you get 16-bit simply because it's the default for wav (regardless of context). It's not like eac3to, which attempts to adopt logical behavior based on the nature of the conversion. With ffmpeg, you have to specify everything; otherwise, you get the defaults.
junh1024
14th January 2021, 11:46
"But I want preserve the volume balance between front and surround channels,"
Do you mean preserve the positioning between front/side/back? Traditionally, Side is just mixed 100% into back for 71>51. But you want to change this.
## Pan law
If you want to do this, you might typically go 0.5*side into front & back so that 0.5+0.5=1. However, the perceived volume will be reduced by 3dB since 1 mono source is played into 2 speakers. The correct coefficients for equal power, is 0.7*side into front & back. 0.7+0.7=1.4. It looks wrong, but sounds correct in 5.1. When you then downmix this to stereo, the side will sound too loud since 0.7+0.7=1.4. But if you did 0.5, it will sound correct. This is the dilemma.
You can now see why Traditionally, Side is just mixed 100% into back. The positioning is not preserved, but the volume for the side will be correct regardless if you do successive downmixing 71>51>20. Alternatively, you can use the compromise coefficient of 0.6
## Implementation
Instead of using FFMPEG to make a file, mpv supports FFMPEG filters. Or you can use the matrix mixer in AC3filter.
tebasuna51
14th January 2021, 22:04
Traditionally, Side is just mixed 100% into back for 71>51. But you want to change this.
Nope, I try to mix the 100% most the time, but in peaks we can't do so because the sound is clipped.
The mix is 50% + 50% to avoid clip but the compand amplify by 2 most the time without clip.
fa1rid
23rd June 2024, 03:47
So can you please summarize what is the proper way to downmix 7.1 to 5.1?
As I understood you used this:
FFMPEG -i 8v341.dts -filter_complex "asplit [f][s]; \
[f] pan=3.1|c0=c0|c1=c1|c2=c2|c3=c3 [r]; \
[s] pan=stereo|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7, \
compand=attacks=0:decays=0:points=-90/-84|-10/-4|-6/-2|-0/-0.3, \
aformat=channel_layouts=stereo [d]; \
[r][d] amerge [a]" -map "[a]" -c:a pcm_s24le zz51.wav
Can you please explain the "compand" option and based on what these points were chosen "-90/-84|-10/-4|-6/-2|-0/-0.3"
Thanks
tebasuna51
23rd June 2024, 10:46
1) First question to understand: with 6 speakers we can't listen the same peak level volume than using 8 speakers.
Then, when downmix, we need reduce the volume to avoid clips (distort), we can reduce it in all channels (standard downmix) or only in surround channels (BL-BR-SL-SR -> SL'-SR')
2) Like volume in BL-BR-SL-SR is normally low I suggest let the same volume in front channels (FL-FR-FC-LFE) and do the downmix only in surround channels:
pan=stereo|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7
3) With that option, without clip, the volume level in SL'-SR' is half than using BL-BR-SL-SR.
Like normally the volume is low we can amplify if by 2 to obtain the same volume level than using 4 speakers.
But we need a protection to avoid clip in the rare cases of high volume in surround channels, for that I use the compand filter.
4) That compand filter provide a gain of 2 for low levels and limit the volume to 1 in high levels like you can see in the image:
https://forum.doom9.org/attachment.php?attachmentid=17534&stc=1&d=1603721482
The users can select the curve or make another one.
That provide the same volume level with 2 speakers and only some peaks are reduced.
fa1rid
27th June 2024, 18:13
Could you please clarify further your answer?
You mentioned that you reduced the sound level by 50% right? and you added a gain of 2, you mean 2db? and limit the volume to 1, what does that mean?
So as I understood, the surround channels will NOT be as loud as the originals after the downmix even though we added the gain?
Also how is it different than using -ac 6 ?
Thanks for the clarification.
tebasuna51
28th June 2024, 21:09
A gain of 2 is +6 dB like show the transfer curve. In the blue one the gain of 2 go until the point -8, -2.
Of course the 2 surround speakers sound as loud the 4 originals most the time, but can't go until high peaks volumes.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.