Convert audio inside MKV to AC3 or DTS preserving 6.1 channels

audioffmpeg

I have some .mkv files that contain 6.1 audio in FLAC format. mediainfo reports the audio track in these files as:

Audio
ID                       : 2
Format                   : FLAC
Format/Info              : Free Lossless Audio Codec
Codec ID                 : A_FLAC
Duration                 : 2mn 29s
Bit rate mode            : Variable
Channel(s)               : 7 channels
Channel positions        : Front: L C R, Side: L R, Back: C, LFE 
Sampling rate            : 48.0 KHz
Bit depth                : 24 bits
Delay relative to video  : 14ms
Writing library          : libFLAC 1.3.0 (UTC 2013-05-26)
Language                 : English
Default                  : Yes
Forced                   : No

I also have a "Home Theater" 6.1 amp (Sony STR-DE895, if anyone cares) that accepts digital audio natively through an S/PDIF (optical and coax) connection in the following formats:

  • PCM (limited to 2 channels on S/PDIF)
  • DTS (5.1)
    • DTS-ES (6.1)
    • NEO6 (6.1)
  • Dolby Digital (5.1)
    • DIGITAL-EX (6.1)
    • PRO LOGIC II

I'd like to have these .mkv files driving all the 6.1 speakers from the amp, but if I convert the .mkv file with a command like this:

ffmpeg -i Input.FLAC.6.1.mkv -c:s copy -c:v copy -c:a ac3 Output.AC3.6.1.mkv

Then I get 5.1 audio, i.e. I lose the center back channel. Per mediainfo:

Audio
ID                           : 2
Format                       : AC-3
Format/Info                  : Audio Coding 3
Mode extension               : CM (complete main)
Format settings, Endianness  : Big
Codec ID                     : A_AC3
Duration                     : 2mn 29s
Bit rate mode                : Constant
Bit rate                     : 448 Kbps
Channel(s)                   : 6 channels
Channel positions            : Front: L C R, Side: L R, LFE
Sampling rate                : 48.0 KHz
Bit depth                    : 16 bits
Compression mode             : Lossy
Delay relative to video      : 9ms
Stream size                  : 8.00 MiB (9%)
Writing library              : Lavc57.107.100 ac3
Language                     : English
Default                      : Yes
Forced                       : No
DURATION                     : 00:02:29.768000000
NUMBER_OF_FRAMES             : 1755
NUMBER_OF_BYTES              : 56974307
_STATISTICS_WRITING_APP      : mkvmerge v8.2.0 ('World of Adventure') 64bit
_STATISTICS_WRITING_DATE_UTC : 2015-08-01 13:29:10
_STATISTICS_TAGS             : BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES

Notice how it changed from:

Channel(s)               : 7 channels
Channel positions        : Front: L C R, Side: L R, Back: C, LFE 

To:

Channel(s)                   : 6 channels
Channel positions            : Front: L C R, Side: L R, LFE

If I try to force the number of channels with -ac 7 I get:

[ac3 @ 0x43f2a40] Specified channel layout '6.1' is not supported

Trying to convert to DTS has the exact same result. I.e. replacing:

-c:a ac3

With:

-strict experimental -c:a dts

Results in a mediainfo of:

Audio
ID                            : 2
Format                        : DTS
Format/Info                   : Digital Theater Systems
Mode                          : 16
Format settings, Endianness   : Big
Codec ID                      : A_DTS
Duration                      : 2mn 29s
Bit rate mode                 : Constant 
Bit rate                      : 1 413 Kbps 
Channel(s)                    : 6 channels 
Channel positions             : Front: L C R, Side: L R, LFE
Sampling rate                 : 48.0 KHz 
Bit depth                     : 16 bits
Compression mode              : Lossy
Delay relative to video       : 14ms
Stream size                   : 25.2 MiB (23%)
Writing library               : Lavc57.107.100 dca
Language                      : English
Default                       : Yes
Forced                        : No
DURATION                      : 00:02:29.774000000
NUMBER_OF_FRAMES              : 1755
NUMBER_OF_BYTES               : 56974307 
_STATISTICS_WRITING_APP       : mkvmerge v8.2.0 ('World of Adventure') 64bit
_STATISTICS_WRITING_DATE_UTC  : 2015-08-01 13:29:10
_STATISTICS_TAGS              : BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES

And trying to force 6.1 with -ac 7 causes the same '6.1' is not supported error as above.

For what is worth, the ffmpeg used in the tests above was:

$ ffmpeg -version
ffmpeg version 3.4.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.4.0 (Debian 6.4.0-10) 20171112
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
libavutil      55. 78.100 / 55. 78.100
libavcodec     57.107.100 / 57.107.100
libavformat    57. 83.100 / 57. 83.100
libavdevice    57. 10.100 / 57. 10.100
libavfilter     6.107.100 /  6.107.100
libswscale      4.  8.100 /  4.  8.100
libswresample   2.  9.100 /  2.  9.100
libpostproc    54.  7.100 / 54.  7.100

So, how can I convert the audio in the .mkv file to a format supported by my system, while preserving the 6.1 channel format?

Best Answer

Partial answer (untested):

So the main problem seems to be that you are stuck with an optical/coax S/PDIF connection for some reason, which doesn't have enough bandwidth (actually, as you say, it even doesn't even have enough bandwidth for more than two uncompressed audio channels; the 5.1 variant is already compressed).

I can confirm that ffmpeg doesn't support encoding more than 6 channels by looking at the code both for DTS or AC3. If ffmpeg doesn't support it, my guess is that no ready-made tools for Linux exist which do support it.

Looking at how DTS-ES and Dolby Digital EX work, one can see that all of them don't give you an additional independent channel either, but instead mix (or "matrix") the back center channel onto the other channels in some way, and set a special flag for 6.1 mode in the digital data stream. The encoder then has to separate the channels again, which (because of loss of information) is not always possible, and can lead to sound artifacts, depending on the source material.

(The possible exception is "DTS-ES Discrete 6.1", which claims to have a real separate channel in addition to the matrix encoding, but it's not clear how this channel is encoded, and how it is supposed to fit the limited S/PDIF bandwidth if transported via S/PDIF, so it's quite likely that the separation only exists in the source material, and is lost on S/PDIF, anyway).

So there are two problems: How to enable the 6.1 flag in the data stream, and how to mix the extra channel onto the existing channels. Fortunately, your Sony STR-DE895 seems to have a SB DEC [MATRIX] mode (manual page 32), which ignores the flag and always applies the Dolby Digital EX decoder matrix regardless of the flag. So that solves the first problem without having to modify e.g. ffmpeg source code.

I couldn't find exact information about the coefficients of this matrix, but as it is "similar in practice to Dolby's earlier Pro-Logic format", which simply adds the center channel to both left and right after decreasing it by 3 dB (factor 0.5), in first approximation I'd try the same for the back channels using the ffmpeg pan filter, encode this as ac3, and see if the result is acceptable.

Assuming this works, a longer term solution would be to hack the ALSA A52 plugin to support this kind of mixing internally, so you'd have a true 6.1 channel ALSA device. You can then use this to play a 6.1 source in any format, without having to go through the contortions of re-encoding the source material.

Another, completely different approach (and I'd recommend to try this, and make a listening comparison to get an idea both about the difference in quality, and possible presence of sound artifacts) is to use your Multi Ch In 1 field on the Sony, together with a good analog 7.1 soundcard (if you have one, or can borrow one). This will provide true channel separation, but of course will now use the D/A converters of the soundcard, and not of the Sony.

Related Question