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

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)

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:

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

Notice how it changed from:

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


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


-strict experimental -c:a dts

Results in a mediainfo of:

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

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?

  • BTW, you don't need to convert the FLAC file (lossless compression) to play it on your system, undoing the compression in the process and using up more disk space. A player application will do the conversion during playback. Make sure your audio (ALSA/Pulseaudio/whatever) is correctly setup for 6.1. – dirkt Dec 25 '17 at 8:43
  • @dirkt, in my experience, telling the player to do the conversion is easier said than done. Most players simply decode the audio format and pipe the uncompressed audio do the sound driver. It's a battle on its own just to tell the player not to touch the audio stream and let the audio drivers on the platform handle it. As for disk space DD(-EX) and DTS(-ES) are lossy formats taking less space than FLAC does. I might get away with having ALSA (doing the conversion to DD)[alsa-project.org/main/index.php/A52_plugin], but that's another question. – LeoRochael Dec 25 '17 at 15:02
  • The advantage of FLAC is really that it's *lossless while taking up less space then raw PCM (what one answer suggests). Converting it to DD/DTS instead of PCM is a completely different topic: You'll loose quality, and there are licensing issues for the encoders as well. I wouldn't recommend using on-the-fly conversion to DD/DTS, that just makes no sense. But converting to PCM on the fly and streaming it is totally fine. And if you only have crappy audio players, just use ffmpeg to stream to an ALSA device etc. (which again requires an ALSA/Pulseaudio 6.1 device). – dirkt Dec 25 '17 at 15:48
  • @dirkt, I understand well the advantages of FLAC. The point of this question is exactly that I don't have an ALSA/Pulseaudio 6.1 device (hence, I have nowhere to pipe the 7 channels of lossless PCM data resulting from decoding the FLAC data). Instead, I have an optical S/PDIF link to a DTS-ES/DD-EX amp, so I need to pipe either DTS-ES or DD-EX data into this S/PDIF link if I want to actually hear the 6 channels. I know this conversion is lossy, but I have no alternative. I need to either do the lossy conversion in real time while playing, or when preparing the files to be played later. – LeoRochael Dec 26 '17 at 1:34
  • 1
    @dirkt, beg to differ. Due to the way S/PDIF link is designed, "it cannot support lossless formats (other than 2ch LPCM)" (en.wikipedia.org/wiki/S/PDIF). If I want surround in this specific equipment, I have no alternative but to pipe DTS or DD thru the S/PDIF link. This is not an HDMI link pretending to be S/PDIF. It's an actual optical S/PDIF over TOSLINK interface. So my question remains: how to transcode to DD/DTS preserving 6.1 channels, as I already tested and 5.1 surround works when DD or DTS (and nothing else) is piped thru the S/PDIF link. – LeoRochael Dec 27 '17 at 17:20

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.

| improve this answer | |
  • 1
    Thanks @dirkt, this look to be the closest to a solution to my question that seems to be possible with current Linux and Open Source solutions. As a point of interest, the amp has a digital readout that announces the format it's receiving through the S/PDIF output; and on "DTS Discrete 6.1" test files that I found on the Internet, it does announce that it's receiving a stream that contains (or at least is labeled as containing) "3+3.1" channels (whether that's actually transmitting 7 discrete channels I can't tell). – LeoRochael Dec 29 '17 at 20:33
  • Ah, if you have test files that contain the flag, then it should be possible to figure out how the flag is encoded. The standard is here, but I didn't see the flag in there. Though there's enough info in there to make it easy to spot. If you happen to find it, please document it somewhere. To test the encoding, I'd try to extract 5.1 channels with ffmpeg using raw input with a format flag, and see what comes out ... – dirkt Dec 29 '17 at 22:26
  • I actually tested only one file: ES 6.1 - 5.1 16bit.dts. I can pipe it to my amp with mplayer -ao alsa:device=hw=0.3 -ac hwdts "ES 6.1 - 5.1 16bit.dts". The amp correctly identifies it as [3+3.1]. mediainfo reports it as 7 channels / 6 channels | Front: L C R, Side: L R, Back: C, LFE / Front: L C R, Side: L R, LFE. samples.ffmpeg.org has other DTS example files in the same folder, and the ones that start with ES are the ones that my amp can decode. – LeoRochael Jan 2 '18 at 22:44
  • unfortunately I don't have the attention bandwidth right not to hunt for the flag or for the right encoding incantation, but I'm leaving the info here in case others can pick it up. – LeoRochael Jan 2 '18 at 22:45
  • 1
    I just bumped into the documentation for the ffmpeg flag that actually marks a AC3 stream as Dolby-EX (7.1 downmixed to 5.1) -dsurex_mode 2 – LeoRochael Feb 25 '18 at 5:27

Since your amp supports PCM, use that.

ffmpeg -i Input.FLAC.6.1.mkv -c:s copy -c:v copy -c:a pcm_s16le  Output.PCM.6.1.mkv
| improve this answer | |
  • 2
    Thanks @mulvya, but I should have made clear that PCM coded S/PDIF transmission is bandwidth limited to 2 channels. I'll clarify the question. – LeoRochael Dec 25 '17 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.