Log in

View Full Version : Encode to 7.1 eac3 for free and volume adjustment


hellgauss
21st March 2025, 09:20
I'm trying to find a way to encode to 7.1 eac3 using free tools, so I tryed to reorganize the info available in this thread https://forum.doom9.org/showthread.php?t=177346.

Note: for the analysis, I refer to the doc here: https://www.atsc.org/atsc-documents/a522012-digital-audio-compression-ac-3-e-ac-3-standard-12172012/

PROCEDURE DESCRIPTION (WINDOWS 10/11)

- Go to Plex Website-->Download (up on the right)-->For Desktop

- Choose Plex (NOT Plex Media Server) and download the .exe setup

- That .exe is a self-extracting installer. You can install it but it is not mandatory. If you have 7zip, you can right-click on it and select "extract to folder..."

- Make a new folder e.g. on Desktop and copy
- Plex Transcoder.exe
- avfilter-8.dll
- avcodec-59.dll
- avformat-59.dll
- swresample-4.dll
- swscale-6.dll
- avutil-57.dll
- libc++.dll
- libunwind.dll

- The old Plex folder is no longer needed. You can delete it after checking this procedure is ok

- Rename Plex Transcoder.exe in Plex_Transcoder.exe, just to remove annoying spaces

- Download from https://forum.doom9.org/showthread.php?t=177346&page=10 , Balling message of 13 September 2022, EasyAudioEncoder.exe and modify it, or download the already modified version from github (they only differs for those two bytes). Put it together with the other files.

- Plex Transcoder is somewhat an old version of ffmpeg which can interact with eae to produce eac3 output. It is poor in decoding, so feed it with pcm stuff (wav or w64)

- Create this .bat and launch it

start easyaudioencoder
timeout /t 2
Plex_Transcoder.exe -y -bitexact -i input71.w64 -c:a eac3_eae -eae_root . -bitexact output.eac3
rem close EasyAudioEncoder manually
pause


EDIT: there are some errors in eae but the output seems to be ok.

OUTPUT ANALYSIS
General
Complete name : .\output.eac3
Format : E-AC-3
Format/Info : Enhanced AC-3
Commercial name : Dolby Digital Plus
File size : 1.34 MiB
Duration : 11 s 8 ms
Overall bit rate mode : Constant
Overall bit rate : 1 024 kb/s

Audio
Format : E-AC-3
Format/Info : Enhanced AC-3
Commercial name : Dolby Digital Plus
Duration : 11 s 8 ms
Bit rate mode : Constant
Bit rate : 1 024 kb/s
Channel(s) : 8 channels / 6 channels
Channel layout : L R C LFE Ls Rs Lb Rb / L R C LFE Ls Rs
Sampling rate : 48.0 kHz
Frame rate : 31.250 FPS (1536 SPF)
Compression mode : Lossy
Stream size : 1.34 MiB (100%)
Service kind : Complete Main
Dialog Normalization : -31 dB
compr : -0.28 dB
dialnorm_Average : -31 dB
dialnorm_Minimum : -31 dB
dialnorm_Maximum : -31 dB

ReportBy : MediaInfoLib - v24.12
- The bitrate is 1024k and it cannot be setted, or I'm not able to set it.
- The output file seems to be ok but a little low on volume, but more than 0.28dB. I can restore the volume via ffmpeg decoding to pcm with drc_scale 0. Is it fault of the compr field? Reading the forum, it seems to be a problem of the dee encoder too.
- Checking for 0B 77 occurrence with an hex editor, it seems that there are two interleaved streams with fixed size frames. The first one is about 576kbps (2292 B/frame) and the second is 448kbps (1804 B/frames)
For reference, here the first two packets

0B 77 04 79 3F 67 FF E0 04 00 ... 00 00 00 03 A1 54 83 E1
0B 77 43 85 3A 67 FF F1 A0 00 ... 00 00 00 00 00 00 4C CA
0B 77 04 79 ...

Probably 83E1 and 4CCA are crc, but the auxdata field seems to be strange. Also, there are a lot of wasted 00 at the end of each packet, probably for padding at fixed size frame. Are they necessary for eac3? Can they be removed except for the suggested 16-bit word-padding?

- It is worth trying to remove, or set to zero, the compr field? I could try to do that following Tebasuna scripts for adjusting DN. Has anybody tried it?
- As a (very) long term goal I would like to create a 7.1 eac3 with 5.1 embedded ac3 from 7.1 input with backward compatibility. Is there any reference and examples on how to do that practically? I've seen that you can specify mix option in the secondary stream.

TR-7970X
21st March 2025, 13:48
I'm trying to find a way to encode to 7.1 eac3 using free tools, so I tryed to reorganize the info available in this thread https://forum.doom9.org/showthread.php?t=177346.

Note: for the analysis, I refer to the doc here: https://www.atsc.org/atsc-documents/a522012-digital-audio-compression-ac-3-e-ac-3-standard-12172012/

That sounds VERY interesting, but this can also do it (and so much more) for free, too :)

https://forum.doom9.org/showthread.php?p=1997616#post1997616

hellgauss
21st March 2025, 14:06
Thanks for you answer, did not know that. It seems that he is using the same method. However Plex installation is not needed, and you can keep only a few files.

https://github.com/R3S3t9999/DoVi_Scripts/blob/main/TOOLS%20%26%20INSTALLATION

tebasuna51
21st March 2025, 15:08
Thanks, the DoVi method don't work for me at all, with your method I need extract also:

libssl-3-x64.dll
libcrypto-3-x64.dll
libwinpthread-1.dll

And now work fine (with some errors like you say)

The output info is:
File: C:\Portablz\Eac3Plex\output.eac3
Size: 2691072 bytes
----------------------------------------- First Frame Info
StrmTyp .....................: 0 (0=Ind, 1=Dep, 2=AC3)
SubStreamID .................: 0
FrameSize....................: 2292 bytes (573 Kb/s)
SampleRate ..................: 0 (48000 Hz)
NumBlksCod ..................: 3 (6 Blocks)
Audio coding mode (acmod) ...: 7 (3/2 - L, C, R, SL, SR)
Low frequency effects channel: 1 (Present)
Version (bsid) ..............: 12 (Other sintax)
Dialogue normalization ......: -31 dB
Dynamic Range gain ..........: -0.27 dB
Mixing metadata .............: 0 (Not exist)
Informational metadata ......: 0 (Not exist)
Additional Bsi ..............: 0 (Not exist)
----------------------------------------- Revised EAC3 Info
Dyn. Range min/max : -12.04/3.34 dB
Frames Tot/Ind/AC3.: 1314 / 657 / 0
Bitrate average... : 1024 Kb/s
Duration ..........: 21024 ms (0 h. 0 m. 21.024 s.)
------------------------------------------------- End Info
Then there are 657 Independent frames at 573 Kb/s and 657 Dependent frames with extra channels (over 5.1) info.
Not exist AC3 frames then this eac3 is not compatible with BD specs.

I don't know if the encoder admit some parameters to modify the encode.

Also that encoder ignore the channelmask of the wav input (the actual ffmpeg encoder read it and preserve it to the output) and the output is 7.1 when the input is 5.1.2 (3D). So that encoder is usseless for me.

[EDIT]From the Plex_Transcoder.exe -h encoder=eac3_eae :
Encoder eac3_eae [EAE E-AC-3 encoder]:
General capabilities: delay
Threading capabilities: none
Supported sample rates: 48000
Supported sample formats: flt s16
Supported channel layouts: 5.1(side) 7.1

eae_eac3_enc AVOptions:
-eae_root <string> ED..A...... EAE root path (default "")
-eae_prefix <string> ED..A...... EAE file prefix (default "frame-")
-eae_batch_frames <int> ED..A...... EAE number of frames for each pass (from 0 to 1000) (default 0)
-eae_max_files <int> ED..A...... EAE number of files on disk (from 1 to 4) (default 2)
-downmix <channel_layout> ED..A...... Request a specific channel layout from the decoder
But using -downmix FL+FR+FC+LFE+BL+BR+TFL+TFR
don't show a error but still output standard 7.1

And seems we can't modify other parameters, the encoder always use eac3 core (never ac3 core like required by BD specs) and always DN -31 (the -dialnorm parameter is not accepted) then low volume is not a encoder but decoder problem.

Also the bitrate is accepted but ignored:

Plex_Transcoder.exe -y -bitexact -i 8w512.wav -c:a eac3_eae -eae_root . -bitexact -ab 768k -downmix FL+FR+FC+LFE+BL+BR+TFL+TFR out3D.eac3
...
Guessed Channel Layout for Input Stream #0.0 : 7.1 [1]
Input #0, wav, from '8w512.wav':
Duration: 00:00:21.00, bitrate: 6144 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 7.1, s16, 6144 kb/s [1]
...
Output #0, eac3, to 'out3D.eac3':
Stream #0:0: Audio: eac3, 48000 Hz, 7.1, s16, 768 kb/s [2]
Metadata:
encoder : Lavc eac3_eae
size= 2628kB time=00:00:21.02 bitrate=1024.0kbits/s [2] speed=19.3x

[1] Ignore the ChannelMask of input file and the included in the parameter
[2] Read fine the desired bitrate but the output is always 1024 even if is not needed (Trailing 0's) like with my simple channel test.

The same file encoded to flac by ffmpeg:

ffmpeg -i 8w512.wav 8w512.flac
...
Input #0, wav, from '8w512.wav':
Duration: 00:00:21.00, bitrate: 6144 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 5.1.2, s16, 6144 kb/s
...
Output #0, flac, to '8w512.flac':
...
WAVEFORMATEXTENSIBLE_CHANNEL_MASK: 0x503f
Stream #0:0: Audio: flac, 48000 Hz, 5.1.2, s16, 128 kb/s
...
size= 476KiB time=00:00:21.00 bitrate= 185.5kbits/s speed= 383x
The ChannelMask is read and traslated to flac and only 186 Kb is needed.

hellgauss
21st March 2025, 19:16
A fast reverse engineering on the two streams headers using hex editor and online hex-->bit converter (I hope I did not got misaligned)

Independent
00 strmtype
000 substreamid
10001111001 frmsize
00 fscod
11 numblkscod
111 acmod
1 lfeon
01100 bsid
11111 dialnorm
1 compre
11111111 compr [I need to change this to 00001111]
0 chanmape
0 mixmdate
0 infomdate
0 addbsie
(47 bits)
[data]
Dependent
01 strmtype
000 substreamid
01110000101 frmsize
00 fscod
11 numblkscod
101 acmod ["complete" 7.1 eac3 is also redundant!]
0 lfeon
01100 bsid
11111 dialnorm
1 compre
11111111 compr
1 chanmape
0001 1010 0000 0000 chanmap [see Tab.E2.5, you need to change this]
0 mixmdate
0 infomdate
0 addbsie
(63 bit)
[data]

Probably and hopefully audfrm audblk do not contains extra metadata and can be left untouched

I do not have time now for a bitwriter and crc, but it should not be difficult. Perhaps it can be done encoding two streams with ffmpeg and a cpp small program, without plex. And perhaps it can also be done for ac3+eac3 for blu-ray compatibility.

tebasuna51
21st March 2025, 20:10
The Dynamic Range gain (compr) can be cancelled using the -drc_scale 0 at decoding time, it's not a problem.
But I doubt you can easily obtain a BD compliant eac3 using the ffmpeg encoder. Good luck!

hellgauss
22nd March 2025, 00:30
The ChannelMask is read and traslated to flac and only 186 Kb is needed.

Yes, that's a test file. I also noticed that the output.eac3 can be heavily compressed by .7z. This do not happen with regular movies. However, even in regular movies, there are some wasted 0 bytes at the end of each frame.

In a far future I think I will try the ffmpeg road, at least with eac3+eac3, so that I can tune bitrate. Probably the independent 5.1 stream can be copy-pasted from ffmpeg. For the independent 4.0 output stream I will try the following way:

1) Insert 16 bit channel map
2) Change some flags (strmtype, chanmape, etc)
3) Increase frmsize by 1 (16 bit more, 0.5kbps more at 48khz)
4) Recalculate crc

Other thing to do for the raw input to ffmpeg:
- be careful with normalization and 5.1 downmix coefficients for independent stream
- Guess channel order for the dependent stream

tebasuna51
22nd March 2025, 09:34
Please tell me if you are successful.

About the ChannelMask I can suply the same file encoded by Audition like FL+FR+FC+LFE+BL+BR+TFL+TFR and FL+FR+FC+LFE+BL+BR+SL+SR, if can help you.
And encoded by DDE like core EAC3 (standard) and core AC3 (Bluray compliant).

hellgauss
22nd March 2025, 14:53
Thanks, that would help, a few seconds sample is sufficient. But I do not know when I will start.

PS: I will steal from your scripts the crc functions :)

tebasuna51
22nd March 2025, 19:31
PS: I will steal from your scripts the crc functions :)

They are not mine, I copied them from the old DelayCut by jsoto (https://download.videohelp.com/jsoto/audiotools.htm)

Link for the samples: https://www.sendspace.com/file/jdu9yw

Source FL+FR+FC+LFE+BL+BR+SL+SR

8w341_a3D.eac3 Audition like FL+FR+FC+LFE+BL+BR+TFL+TFR
8w341_an.eac3 Both Audition encodes have a delay of 5.333 ms -> 1 more frame
8w341_db.eac3 Dolby Encoder Engine like Bluray compliant (core Ac3)
8w341_dn.eac3 Dolby Encoder Engine standard (core EAC3)

I can't use 'None' for DRC in DEE then I use 'music light', but DN -31 and bitrate 768 Kb/s (minimum for 7.1). In Audition I use the same parameters.

hellgauss
31st March 2025, 12:45
Some minor updates:

1) It seems that compr field should not be set to 0x0F but to 0x00 (I'll do more test)

2) To customize output, the core stream can be left untouched. In the second dependent stream I have been able to set channel mask (standard 7.1, or whatever 5.1.2 etc...) , dialn=31, compr. Just replace the bits (without adding any field) and recalculate crc. There are also 6 values of dynrng which change the volume. They are difficult to parse since they are in the middle of audio blocks.

3) Most interestingly, the independent core stream can be replaced with a different bitrate and different engine (e.g. ffmpeg). It can be even ac3 for blu-ray compliance.

4) The road to hack ffmpeg and change some headers seems not to be feasible. The coding algorithm has some differences for independent vs dependent stream. ffmpeg has no options to set the eac3 coding as "dependent".

I'll reorganize my code into an usable script, which can mux/demux independent and dependent streams and set compr, chanmask and dialn. For dynrng setting it seems to be too difficult/time consuming. Stay tuned...

tebasuna51
1st April 2025, 07:26
1) It seems that compr field should not be set to 0x0F but to 0x00 (I'll do more test)
Yes, from specs: "The compr field in the AC-3 data stream is 8-bits in length..."

The first four bits indicate gain changes in 6.02 dB, where (Table):
0000 => Gain 6.02 dB

The following four bits (ABCD) indicate linear gain changes, where:
ABCD => Gain 0.1ABCD (base 2)
Then 0000 => Gain 0.10000 (base 2) = 1/2 = - 6.02 dB

Then compr = 0000 0000 => 6.02 dB - 6.02 dB = 0 dB

2) To customize output, the core stream can be left untouched. In the second dependent stream I have been able to set channel mask (standard 7.1, or whatever 5.1.2 etc...) , dialn=31, compr. Just replace the bits (without adding any field) and recalculate crc.

Please let me know how change the channel mask from 7.1 to 5.1.2 and recalculate the crc in the second dependent frame. Maybe I can use DDE instead Audition for my 5.1.2 encodes.

There are also 6 values of dynrng which change the volume. They are difficult to parse since they are in the middle of audio blocks.
It's difficult to parse but easy of correct:
"The bit code of ‘0000 0000’ indicates 0 dB (unity) gain."

3) Most interestingly, the independent core stream can be replaced with a different bitrate and different engine (e.g. ffmpeg). It can be even ac3 for blu-ray compliance.
Good news, but not for me, I'm not interested in burn BD's.

4) The road to hack ffmpeg and change some headers seems not to be feasible. The coding algorithm has some differences for independent vs dependent stream. ffmpeg has no options to set the eac3 coding as "dependent".
Thats can be the big problem.

I'll reorganize my code into an usable script, which can mux/demux independent and dependent streams and set compr, chanmask and dialn. For dynrng setting it seems to be too difficult/time consuming. Stay tuned...
You can let the dynrng for a second step and see if the decoders with drc = 0 can solve the problem. Let me know please.

hellgauss
4th April 2025, 17:41
Here a first version of the script, probably buggy :)

https://github.com/HG3112/md71

It is a little bit complicated to use at first sight, but there are some examples in the readme

I have two questions:

1) Some years ago, perhaps, I read that there were some problems in muxing eac3 with ac3 core into .mkv container, e.g. with mkvmerge. Is this still an issue? I performed two test with mkv, one with 7.1 with ac3 core, the second as full .eac3 and get no problems on both on my tv. However I only have a 5.1 hardware. Is such stream playable if no DD+ support is available in the TV?

2) Assuming that channel 1-4 are untouched (coefficient=1.0) and that there is no overflow, what is the correct 7.1-->5.1 downmix coefficients for surround in a "basic" downmix?

A) Here ( https://www.audiokinetic.com/en/library/edge/?source=Help&id=downmix_tables ) it is suggested
Surround=1.0*side + 1.0*back

B) My mathematical theory, which can be wrong, says
Surround=0.707*side + 0.707*back

C) ffmpeg default with -ac 6 is
Surround=1.0*side + 0.707*back (???)

D) Tebasuna ( https://forum.doom9.org/showthread.php?t=181635&highlight=downmix ) suggests
Surround=0.5*side + 0.5*back

SeeMoreDigital
4th April 2025, 22:25
Here a first version of the script, probably buggy :)

1) Some years ago, perhaps, I read that there were some problems in muxing eac3 with ac3 core into .mkv container, e.g. with mkvmerge. Is this still an issue? I performed two test with mkv, one with 7.1 with ac3 core, the second as full .eac3 and get no problems on both on my tv. However I only have a 5.1 hardware. Is such stream playable if no DD+ support is available in the TV?

If you provide some samples I can test them on various hardware SoC devices...

tebasuna51
4th April 2025, 22:47
Questions:

1) I don't read problems about the core AC3/EAC3, maybe about EAC3 with Atmos data.

2) A,B,C are wrong because Surround values must be in the range -1 to 1. To preserve the max volume without clip we need limit (and distort) only the peaks.
See images in https://forum.doom9.org/showthread.php?p=2017241#post2017241
A downmix using ffmpeg can be:

ffmpeg.exe -i input71.eac3 -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|-8/-2|-6/-1|-0/-0.1, aformat=channel_layouts=stereo [d]; [r][d] amerge [a]" -map "[a]" output51.ac3

j7n
4th April 2025, 23:06
If you have four speakers in 7.1, they would be louder than two in 5.1. The most straightforward is to just add them together (A). I don't think it follows that you need to divide the level of side surround by 2 (B). Maybe the back speakers can be quieter by 3 dB to account for them being behind and to avoid widening the image too much (C).

Potential clipping shouldn't be addressed in the downmix matrix. There is usually ample headroom because surrounds typically have low level, and you can use a limiter if needed.

mannequin80
5th April 2025, 01:41
1) I don't read problems about the core AC3/EAC3, maybe about EAC3 with Atmos data.


i was excited for a second when i saw this thread - thought there's a chance we would be able to change/remove dialn and compr values without breaking the Atmos JOC data :(

@hellgauss
tried with a random eac3 file to change dialn and compr values and getting this error: ERROR: Unexpected EOF found in inputB

tebasuna51
5th April 2025, 07:44
If you have four speakers in 7.1, they would be louder than two in 5.1.
Of course.
The most straightforward is to just add them together (A)...
There is usually ample headroom because surrounds typically have low level, and you can use a limiter if needed.

Like I do with my method:

1) First a mix at 50% to obtain normalized values:
pan=stereo|c0=0.5*c4+0.5*c6|c1=0.5*c5+0.5*c7
Or (the same):
pan=stereo|c0<c4+c6|c1<c5+c7

2) And after a gain of 2 for low levels and decrease the gain for high levels (see image (https://forum.doom9.org/showthread.php?p=1926777#post1926777))
compand=attacks=0:decays=0:points=-90/-84|-8/-2|-6/-1|-0/-0.1

We obtain the same volume with 2 speakers in 5.1 than 4 in 7.1 most the time, only on peaks we can't.

tebasuna51
5th April 2025, 08:20
Here a first version of the script, probably buggy :)

https://github.com/HG3112/md71

It is a little bit complicated to use at first sight, but there are some examples in the readme

Work fine for me when I try change dialn_value compr_flags chanmap_flags.

With a 7.1 encoded with dde I do:

md71 8w341_.eac3 : 8341_3D.eac3 : 31 00 1810

where 1810 hex = 1100000010000 bin = (table E2.5) Left Surround, Right Surround, Vhl/Vhr pair

Seems work fine the changes but my 5.1.2 Denon play a mix of channels, I need to do more test.

tebasuna51
5th April 2025, 09:44
i was excited for a second when i saw this thread - thought there's a chance we would be able to change/remove dialn and compr values without breaking the Atmos JOC data...

I run without error this:

md71 audiosphere.eac3 : audiosphere_.eac3 : 31 00

audiosphere.eac3 from https://www.demolandia.net/es/cine/trailers-de-demostracion-dolby/pagina-9.html

And the:
Dialogue normalization ......: -23 dB
RF atenuattion ..............: 0.53 dB
are converted to:
Dialogue normalization ......: -31 dB
RF atenuattion ..............: 0.00 dB

But my Denon don't recognize the audiosphere_.eac3 like Atmos, only dd+.
"They are some kind of unknown checksum (32+8 bits) at the end of the embedded Atmos data" (https://forum.doom9.org/showthread.php?p=2010410#post2010410)

hellgauss
5th April 2025, 10:51
@tebasuna
a) Perhaps I will begin with 0.9 Side + 0.8 back for simplicity, and thanks for the advanced command, I will study it!

b) In the samples you send me some posts above the 3d file has chanmap A010 (fornt channels replaced)

c) Sorry for atmos... no free specs=no free tools. I write md71 with the main goal to mux/demux 7.1 streams from plex+eae , at this moment it is the only encoder I have, and change what is easy to modify (compr, dialn, chanmap)

@mannequin
Probably you are using the core+dependent mode with a single file with an odd number of frames. Which command line gives the error? Try tebasuna command line:

md71 input.eac3 : output.eac3 : 31 00

With this you are telling md71 to consider the input as only one stream, and it also works with 7.1

@SeeMoreDigital
There are some .thd 7.1 mkv video for testing around the internet. They are free to download but I do not know if they are freely redistributable/re-encodable. I'll ask them for permission, or try to reconvert them with command line only, and provide source_link + script. Thank you.

tebasuna51
5th April 2025, 12:59
@tebasuna
a) Perhaps I will begin with 0.9 Side + 0.8 back for simplicity, and thanks for the advanced command, I will study it!

Seems you want replace the 5.1 EAC3 core with a new 5.1 AC3 encode, and add after the dependent frames to obtain a BD compliant.

Then the downmix to encode must be equivalent to the downmix in the 5.1 EAC3 core. Decoding my channel test seems the downmix used is:

pan=5.1|c0=c0|c1=c1|c2=c2|c3=c3|c4=0.871*c4+0.49*c5+1.0*c6|c5=0.49*c4+0.871*c5+1.0*c7

I don't know how the surround channels aren't normalized.

b) In the samples you send me some posts above the 3d file has chanmap A010 (fornt channels replaced)

Thanks, that make sense because the downmix core EAC3 have the front channels mixed with the Vhl/Vhr pair.

But also don't work with my Denon. I must remain with the Audition encoder.

hellgauss
5th April 2025, 13:24
Then the downmix to encode must be equivalent to the downmix in the 5.1 EAC3 core. Decoding my channel test seems the downmix used is:

pan=5.1|c0=c0|c1=c1|c2=c2|c3=c3|c4=0.871*c4+0.49*c5+1.0*c6|c5=0.49*c4+0.871*c5+1.0*c7

I do not think it is necessary. As far as i understand, for DD+ decoder c4 and c5 will be replaced by the channels in the dependent stream. For DD decoder, the dependent stream is skipped.

But also don't work with my Denon. I must remain with the Audition encoder.

Did not precisely understand what is the problem, but you could try this last road. Perhaps your alternative_encoder encodes c0-c5 in core, and c4-c7 in dependent. If you need to replace front channels you should perform two encodes, the first normal (demux core with md71), the second with front and surround swapped (demux dependent with md71), so that front channels goes in dependent. Then mux core and dependent with md71, changing flags to A010.

SeeMoreDigital
5th April 2025, 14:38
Indeed, in order for a Dolby Digital Plus (or Dolby TrueHD) stream to be fully Blu-ray disc compliant it must include a lossy 5.1 Dolby Digital (or Dolby Digital EX) encoded 'core' (or whatever people prefer to call it).

hellgauss
6th April 2025, 10:30
I have some good news and some bad news...

First the good news:
I did it!! Free 7.1 with ffmpeg. Zero compression, dialn=31... no dynrng! And also no plex (so that I can easily open anything and use pipe, and set any bitrate).
I open the 7.1 output with audacity and the wave form have the same exact amplitude as the source!

Now the bad news...
You have to compile your own version of ffmpeg (I do not know if I can redistribute it)

If you are a newbie like me, I suggest the excellent tutorial here (https://www.youtube.com/watch?v=OIYGjzmJ2GI). Follow EVERY step, it works perfectly, except that before compiling you have to replace the option --enable-yasm with --enable-x86asm

You need to modify ac3enc.c and eac3enc.c in the libavcodec folder as follows:

In ac3enc:

- In the "snr offset" block (https://github.com/FFmpeg/FFmpeg/blob/ccf073e772d72b83e5973c62c4c4112cfa545a9c/libavcodec/ac3enc.c#L1833) remove the "else" block, so that the "no converter snr offset" bit (convsnroffste in specs) is not inserted

In eac3enc:

A) Replace this line (https://github.com/FFmpeg/FFmpeg/blob/ccf073e772d72b83e5973c62c4c4112cfa545a9c/libavcodec/eac3enc.c#L141) with

put_bits(pb, 2, 1); /* stream type = 01 = dependent */

B) A few lines after, set the compression gain flag (compre) to 1, and add the fields compr, chanmape and chanmap:

put_bits(pb, 1, 1); /* yes compression gain */
put_bits(pb, 8, 0); /* set compression gain to 0 */
put_bits(pb, 1, 1); /* chanmap exists */
put_bits(pb, 16, 0x1a00); /* set channel map */
/* mixing metadata*/

Note that according to Section E3.8.5 of specs, the compr field is mandatory in the dependent stream, just set it to 0x00.

C) Remove all the lines from the comment (https://github.com/FFmpeg/FFmpeg/blob/ccf073e772d72b83e5973c62c4c4112cfa545a9c/libavcodec/eac3enc.c#L234C8-L234C50) "E-AC-3 to AC-3 converter exponent strategy" up to to "snr offsets" (convexpstre bit)

Compile ffmpeg, then rename e.g. to ffmpeg_eac371.exe and put in your working folder or in path. We will use this build to encode the dependent stream.

You can use the following script. Check if channel order is ok for surround, I do not know if it is the same for all .wav and pcm stream. If not labeled, the encoder wants channels in the same order as in Table E2.5.

rem write the command in one line I do not know if I can CR inside strings
rem the board has bad formatting for long code
ffmpeg -y -bitexact -i "input71.wav" -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|-8/-2|-6/-1|-0/-0.1,
aformat=channel_layouts=stereo [d]; [r][d] amerge [a]" -map "[a]"
-c:a ac3 -b:a 640k -bitexact tmp_51.ac3

ffmpeg_eac371 -y -bitexact -i "input71.wav" -af "pan=quad|c0=c6|c1=c7|c2=c4|c3=c5" -c:a eac3 -b:a 384k -bitexact tmp_40.eac3

md71 tmp_51.ac3 tmp_40.eac3 out71.eac3 out71.eac3

TODO in ffmpeg (I'm not able to do that, or to submit commits to the team)
- CLI to set stream type to dependent
- CLI to enable and set compr
- CLI to enable and set chanmap
- Maybe an option to mux the two streams without external tools

SeeMoreDigital
6th April 2025, 10:39
Can you provide a sample of your 7.1 DD+ encode?

tebasuna51
6th April 2025, 13:41
You have to compile your own version of ffmpeg (I do not know if I can redistribute it)
I'm not a lawyer but everybody can redistribute ffmpeg versions if the included libraries aren't protected by law.

... before compiling you have to replace the option --enable-yasm with --enable-x86asm
I don't know if the library x86asm is protected or not, but I don't thik so.

You need to modify ac3enc.c and eac3enc.c in the libavcodec folder as follows:
But you can improve free libraries without problem.

There are links to ffmpeg versions with some protected libraries than maybe can be used in some countries with less law restritions.

SeeMoreDigital
6th April 2025, 13:52
Hi hellgauss,

As mentioned in my PM, I'm happy to report that both of your 7.1 channel DD+.mkv encodes work perfectly on my OPPO UDP-203 4K UHD disc player and on my LG OLED65C44LA television.

The only odd thing I have to mention is that UsEac3To v1.3.3 reports that your '7.1 DD+ 640kbps with 5.1 DD 0kbps core.mkv' sample has a 640kbps core. But TSmuxer GUI reports that everything is correct.

I also muxed both .mkv samples into .m2ts files and created short Blu-ray disc compatible file/folder sets for each sample, and my OPPO could play both files correctly too.

A few people on the forum have wanted to be able to create 7.1 DD+ streams from 7.1 TrueHD sources for years. And now we have televisions that can support 7.1 DD+ streams this is good news. Very well done.

hellgauss
6th April 2025, 17:09
@tebasuna
I'm not a lawyer but everybody can redistribute ffmpeg versions if the included libraries aren't protected by law.

That's not so simple. For example if in the tutorial i remove --enable-libx264 or remove --enable-gpl the compiling does not work. I can only remove --enable-nonfree without problems. However here (https://www.ffmpeg.org/legal.html) it is suggested to be very carefull with gpl stuff.

Considering that "someone" will be very unhappy about this thread since it allows free and clean 7.1 encode, I prefer to be 100% safe.

I share attached the modified sources, I think that there are no problems with that. Be carefull, with further versions of ffmpeg the files can be no longer compatible, it is better to edit the few modificatons yourself.

@seemoredigital
Thanks for your test. If I find a royalty free 7.1 test video without any DD logo I will publish here.

Both files I sent you are indeed eac3, with 640k core +384k dependent, either ac3-core like my previous script or eac3-core (just change some flags in that script). With ac3 you are limited to discrete values of bitrate up to 640k, with eac3 you have more freedom and can set higher bitrate.

SeeMoreDigital
6th April 2025, 17:22
Here's a link to where you can download an '8-channel ID.wav' sample: -

https://www.mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html

Take note of the channel assignment information.


Cheers

hellgauss
6th April 2025, 17:49
It is a strange file. Audacity open it as 8ch but mediainfo says it is 6ch. However i converted with the following 2 scripts

Script1 (ac3core)
set "source=8_Channel_ID.wav"

ffmpeg -y -bitexact -i "%source%" -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|-8/-2|-6/-1|-0/-0.1, aformat=channel_layouts=stereo [d]; [r][d] amerge [a]"^
-map "[a]" -c:a ac3 -b:a 640k -bitexact tmp_51.ac3

ffmpeg_eac371 -y -bitexact -i "%source%" -af "pan=quad|c0=c6|c1=c7|c2=c4|c3=c5" -c:a eac3 -b:a 384k -bitexact tmp_40.eac3

md71 tmp_51.ac3 tmp_40.eac3 out71_ac3core.eac3 out71_ac3core.eac3

Script2 (eac3core)

set "source=8_Channel_ID.wav"

ffmpeg -y -bitexact -i "%source%" -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|-8/-2|-6/-1|-0/-0.1, aformat=channel_layouts=stereo [d]; [r][d] amerge [a]"^
-map "[a]" -c:a eac3 -b:a 640k -bitexact tmp_51.eac3

ffmpeg_eac371 -y -bitexact -i "%source%" -af "pan=quad|c0=c6|c1=c7|c2=c4|c3=c5" -c:a eac3 -b:a 384k -bitexact tmp_40.eac3

md71 tmp_51.eac3 tmp_40.eac3 out71_eac3core.eac3 out71_eac3core.eac3

Link:
https://easyupload.io/944b0t

tebasuna51
6th April 2025, 21:16
It is a strange file.
Have a buggy MaskChannels 63 (FL FR FC LF BL BR - - ERROR: don't match with NumChan 8), but if ffmpeg accept it, no problem.

A correct 7.1 must have MaskChannels : 1599 (FL FR FC LF BL BR SL SR)
The "Back Left/Right" must be at 120º (Surround 5.1) until 135º (in 7.1)
The "Auxiliary Left/Right" must be replaced with "Side Left/Right" (90-100º)

Link:
https://easyupload.io/944b0t
Don't work for me.

hellgauss
6th April 2025, 22:07
The link or the files? Both plays well on my 5.1 setup, except that I cannot recognize back vs auxiliary.

Here another link
https://limewire.com/d/xUsWp#p1zP4ueEdw

tebasuna51
6th April 2025, 23:47
Thanks, now I can download the samples. And the eac3 are perfect.

The only odd thing I have to mention is that UsEac3To v1.3.3 reports that your '7.1 DD+ 640kbps with 5.1 DD 0kbps core.mkv' sample has a 640kbps core.

The extracted eac3 from the samples are reported ok with UsEac3To v1.3.4 and eac3to v3.52 (improved to manage eac3):

E-AC3, 7.1 channels, 0:01:34, 1024kbps, 48kHz, dialnorm: -31dB
(core: AC3, 5.1 channels, 0:01:34, 640kbps, 48kHz, dialnorm: -31dB)

and

E-AC3, 7.1 channels, 0:01:34, 1024kbps, 48kHz, dialnorm: -31dB
(core: E-AC3, 5.1 channels, 0:01:34, 640kbps, 48kHz, dialnorm: -31dB)

SeeMoreDigital
7th April 2025, 09:15
The extracted eac3 from the samples are reported ok with UsEac3To v1.3.4 and eac3to v3.52 (improved to manage eac3):

Thanks Teb,
Bugger... I wasn't aware of version 1.3.4. It looks like when you released it back in Febuary of last year I was in hospital :eek:

Anyway, I've just downloaded it now but whenever I try to unpack it, Windows 11 freeks out and removes it... Bloody Microsoft!!!

hellgauss
8th April 2025, 17:09
I checked ffmpeg source code and I also have to manage bit counting in count_frame_bits() and count_frame_bits_fixed().

It seems that num_blocks is always 6 for the high bitrate in a standard HQ 7.1. Hence I added 25 bits in header, and removed 24. That extra bit did not cause problems, probably for some byte/word alignement and I avoided bad luck.

Also I have to manage convsync bit.

md71 seems to be ok.

***********

I have been succesful in a lgpl v2.1 build of ffmpeg. Once I solve the above problems I will create a git with Windows binary.

tebasuna51
9th April 2025, 12:21
Good news, if we can distribute the special ffmpeg dependant frames encoder.

I can configure my Denon like 7.1 and I can confirm also than your samples play ok like 7.1.

I'm doing some test to obtain eac3 5.1.2 from atmos decoded files with Cavernize but when finish I will open a new thread and let this one only for the standard 7.1.

hellgauss
10th April 2025, 06:53
Here the first public 7.1 eac3 free encoder (in test phase):

https://github.com/HG3112/md71

Download the latest release. Requires also a standard build of ffmpeg to be installed or in same dir.

It has two presets. Ac3Core @1024kbps and EAc3Core @1536kbps. Just drag and drop 7.1 input file into the .bat icon.

tebasuna51
10th April 2025, 08:51
Thanks hellgauss, for me all work fine about the standard EAC3 7.1 encoder.

junh1024
12th April 2025, 03:01
DDP could capable of more than 71 or 512. The Dolby white paper (https://professional.dolby.com/globalassets/dolby-digital-plus/dolby-digital-plus-audio-coding-tech-paper.pdf) says you can do up to 15.1 . Positions of up to 12.2.6 are available from the spec but you can probably not use them all simultaneously. But this has not been well tested.

This is not Dolby Atmos because it does not use JOC. It is 3D surround in traditional CBA (but the consumer would not hear the difference in many cases). But it would be nice to add features such as adding and removing JOC & padding from existing DDPA streams. And 2nd/3rd dependant substreams for more channels.

Here is the table from ETSI TS 102 366 V1.4.1 (2017-09) p128 showing what speakers you can add.

chanmap bit Location
0 (MSB) Left
1 Centre
2 Right
3 Left Surround
4 Right Surround
5 Lc/Rc pair
6 Lrs/Rrs pair
7 Cs
8 Ts
9 Lsd/Rsd pair
10 Lw/Rw pair
11 Vhl/Vhr pair
12 Vhc
13 Lts/Rts pair
14 LFE2
15 LFE

Teba can move this comment if necessary in the future.

j7n
12th April 2025, 10:45
The JOC parameters are about 70 kbit/s, but not always the same size in every frame. The also don't seem to very compactly encoded, so the channel steering is coarse indeed. I don't see what is gained from removing them, except if you want a clean 5.1 mix on atmos-capable hardware. Then maybe, instead of removing JOC, it is possible to invalidate the data in place.

Is there a lot of duplication with these substreams that harms compression ratio? With 7.1 you get two complete channels that are redundant (summed side surround channels).

Discrete should be much better than Atmos, except who has 12 or more speakers in their room.

hellgauss
12th April 2025, 11:15
I did not performed tests, but the tools should be capable to create up to 10.2 audio. It is 100% NOT compatible with atmos, so don't use it on atmos audio files.

For basic settings (core type, bitrate core and bitrate dependent) just copy-paste one of the included .bat and edit the three "set" commands.

For advanced usage you have to play with md71 chanmap override, since ffmpeg_eac371 has fixed chanmap 1a00.

@tebasuna
If you only need your files to be played in your 5.1.2 setup, perhaps the best way to do that is to code as 5.1 core + 2 extra channels, so you save bitrate. Or 3.1 + 4, without channels replacement and without downmix.

PS for testers:
I would be very interested in knowing if, with this tool, an .mkv video with 7.1 audio with ac3 core plays well in DD hardware not DD+ capable, e.g. in a TV through USB. Has anyone performed this test?

tebasuna51
12th April 2025, 12:26
With the hellgauss method we create a standard 5.1 in independents frames (AC3 or EAC3 to be BD compliants or not) and a second stream 4-0 with dependents frames (always EAC3).
In the 5.1, the Ls/Rs pair have the downmix of original Ls/Rs and Lrs/Rrs.
In the 4.0 we have the originals Ls/Rs and Lrs/Rrs and with the "chanmap bit Location" 1a00 say: replace from 5.1 the Ls/Rs and add the Lrs/Rrs

If we have Atmos sources from decoders like Dolby Reference Player or Cavernize we can use the hellgauss method to create a specific EAC3 for our audio system:
5.1.2 Replacing L/R with L/R and add Vhl/Vhr (need a previous downmix L/R with Vhl/Vhr) chanmap: A010
5.1.2 Replacing Ls/Rs with Ls/Rs and Lts/Rts (work the same downmix than 7.1) chanmap: 1804
5.1.4 Adding the 4 new channels Vhl/Vhr and Lts/Rts (the core ignore those channels) chanmap: 0014
7.1.2 Adding Lrs/Rrs and Vhl/Vhr or Lts/Rts (the core ignore those channels) chanmap: 0210 or 0204

Maybe we can replace/add more channels if dependent frames add more channels but I think it is enough for standard players.
In my test I can generate now both 5.1.2 and 5.1.4 but not 7.1.2 (I still don't know for what)
The Atmos decoder can generate until 16 channels, of course I can't test that.

tebasuna51
12th April 2025, 23:51
Tree .bat to convert sources (Atmos decoded by Dolby Reference Player, aka DRP) 5.1.2, 5.1.4 and 7.1.2.

a) The 5.1.2: recognized by DRP with chanmap Ls/Rs-Lts/Rts but the audio Lts/Rts played in Ls/Rs speakers.
Decoded fine with ffmpeg recovering the same source and with maskchannel L R C LFE Ls Rs Tsl Tsr (MediaInfo channel names (https://mediaarea.net/AudioChannelLayout))

b) The 5.1.4: DRP show "Custom channel map: Ls, Rs, Lts/Rts" instead Vhl/Vhr-Lts/Rts chanmap: 0014. Only play in 5.1 speakers.
Decoded fine with ffmpeg recovering the same source and with maskchannel L R C LFE Ls Rs Tfl Tfr Tsl Tsr

c) The 7.1.2: DRP show "Not bitstream information available" but play 5.1 speakers.
ffmpeg can't recover the same source with a channel duplicated and other empty, the maskchannel is correct L R C LFE Ls Rs Lb Rb Tfl Tfr

junh1024
13th April 2025, 04:46
I tested a variety of extended 2D and 3D layouts (71w, 512 etc) with simplified settings but similar results as Teba - None of them would play in anything other than 5.1 using modern infrastructure (except for 71b) , but they mostly show up fine in FFMPEG-based apps.

If 512 doesn't work, theres no way 514 & 712 would work. 8.0 probably doesn't work.

DL input and samples: https://easyupload.io/b1xmb1

Simplified code below.

18933

hellgauss
13th April 2025, 10:40
7.1b is the "standard" 7.1?

It can be tried a different channel mask in input for the 4channel source. This should change the acmod field (which however should be replaced by the channelmap)

Try this change for the 4ch encoding, rather than pan=quad

"pan=4.0|c0=c6|c1=c4|c2=c7|c3=c5"

you have to guess the correct channel input order for you setup, but as a first test if they are played it is ok.

According to Table 5.8 there are two different acmod for 4 speakers. Pan=quad set acmod=110. Pan=4.0 set acmod=101.

junh1024
20th April 2025, 11:45
General Comments

With the hellgauss method we create a standard 5.1 in independents frames (AC3 or EAC3 to be BD compliants or not) and a second stream 4-0 with dependents frames (always EAC3)... we can use the hellgauss method to create a specific EAC3 for our audio system: 5.1.2 etc


Also, For keeping BD compatibility. The core is "usually" legacy AC3 51 core because ec3/ddp is not mandatory in the BD spec. however, ec3 /web core might work in practice.

I also tested some encodes made by official Dolby software, and it seems that they only playback in 5.1, so it seems that the problem is on Dolby's side. Probably No modern AVR / infrastructure supports 3D CBA surround.

7.1b is the "standard" 7.1?

It can be tried a different channel mask in input for the 4channel source. This should change the acmod field (which however should be replaced by the channelmap)

I don't think it matters in the context of creating a dependent stream, and it seems to play fine.

what is the correct 7.1-->5.1 downmix coefficients for surround in a "basic" downmix?


For downmixing 7.1, I have used a simplified approach, simply adding together side and back speakers at full volume. This is simple and valid approach. If you have side and back speakers at different volumes, this does not make sense, unless you’re doing a DPL2x-style downmix. Adjusting the volume of the surround speakers overall is mainly a trade-off between preserving the original power and avoiding clipping. I would recommend no quieter than 0.7x side & back into surround.

Features and enhancements

The JOC parameters are about 70 kbit/s, but not always the same size in every frame.... I don't see what is gained from removing them, except if you want a clean 5.1 mix on atmos-capable hardware. .

The ability to add/remove JOC would be good. Applications would include removing JOC from DA that's known to be upmixed, or adding JOC to say, 5.1 Spanish from DDPA English.

Here a first version of the script, probably buggy :)

https://github.com/HG3112/md71

Thank you for your tools. Also, If you use the "--disable-debug" build switch instead of enable debug, that might make your builds smaller.