Opened 13 years ago

Last modified 9 months ago

#1258 open enhancement

Codec support request : MPEG Multichannel Audio

Reported by: Aaron Scheiner Owned by:
Priority: wish Component: avcodec
Version: git-master Keywords: mp2
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Hi

Support for MPEG Multichannel audio seems to be missing. This is different to ac3. More information can be found here : http://en.wikipedia.org/wiki/MPEG_Multichannel

It's a method of encoding surround audio into stereo mpeg2 files. If the files are played back using software that doesn't support the extra channels, the data is dropped and only the first two channels are decoded.

This codec forms part of the HDV specification (specifically the 4 channel audio option on some HDV camcorders). The Canon XLH1, in particular, made use of this system.

I have found a very old project called mctoolamed : http://mctoolame.sourceforge.net which can decode this codec.

mctoolamed has several issues; it doesn't make provision for sample rates other than 44.1kHz and it also only supports 2,6 and 8 channel files (HDV cameras shoot 4 channels).

Attachments (5)

test.aiff-mpeg1-192.mp2 (234.5 KB ) - added by Aaron Scheiner 13 years ago.
Sample of a 6 channel mix encoded in a stereo mp2 file.
mctoolamed-01a.tgz (42.5 KB ) - added by Aaron Scheiner 13 years ago.
The original mctoolamed source.
lamedecoder.zip (157.2 KB ) - added by Aaron Scheiner 13 years ago.
Modified version of mctoolamed to set bitrate to 48kHz and add support for 4 channel files.
4CHsample.mp2 (500.0 KB ) - added by Aaron Scheiner 13 years ago.
4 channel sample from an HDV stream
lamedecoder-fix.zip (59.9 KB ) - added by Andrew-R 10 months ago.
fixed lamedecoder.zip to build on modern gcc/clang (missed "gets" function replaced with fgets())

Download all attachments as: .zip

Change History (19)

by Aaron Scheiner, 13 years ago

Attachment: test.aiff-mpeg1-192.mp2 added

Sample of a 6 channel mix encoded in a stereo mp2 file.

by Aaron Scheiner, 13 years ago

Attachment: mctoolamed-01a.tgz added

The original mctoolamed source.

comment:1 by Aaron Scheiner, 13 years ago

I've included mctoolamed-01a.tgz, which is also available on Sourceforge. I've also included my modified version of the code "lamedecoder"... my C++ skills are really bad, so I've highlighted the changes I've made below. I also tried modifying the code to change the output file names depending on the input file name... but yeah, C skills are lacking.

To compile mctoolamed on Debian you need to change the architecture in the Makefile. I changed it to "core2" to get it to run on my Core-based machine (Intel Xeon).

I had to modify part of the code to get it to handle 4 channel files :
in audio_write.c : I modified the soundfile array

Original :

char soundfile[MTYPES][MAXCHANNELS][256] = {
  {"left.wav", "right.wav", "centre.wav", "left_surround.wav", "right_surround.wav"},
  {"left.wav", "right.wav", "centre.wav", "lfe_this_may_not_play.wav", "left_surround.wav", "right_surround.wav"}
};

Revised :

char soundfile[MTYPES][MAXCHANNELS][256] = {
  {"left.wav", "right.wav", "centre.wav", "left_surround.wav", "right_surround.wav"},
  {"left.wav", "right.wav", "centre.wav", "lfe_this_may_not_play.wav", "left_surround.wav", "right_surround.wav"},
  {"left.wav", "right.wav", "rearleft.wav", "rearright.wav"}
};

The "waveheader" array has the sample rate flag set for 44.1kHz. If left unchanged the resulting files will play back slower than they should.

Modification to handle 4 channels :

Original :

void init_audio_outputs(int numchan) {
  int i,j;
  int type=-1;

  numchannels = numchan; // Set the global var for later on.
  if (numchan == 5)
    type = 0;
  if (numchan == 6)
    type = 1;
  if (soundfile>=0) {
    fprintf(stderr,"initialising %i output files\n",numchannels);
    for (i=0;i<numchannels;i++) {
      if ( (audioout[i] = fopen(soundfile[type][i], "w")) == NULL ) {
	fprintf(stderr,"Error opening %s for output\n",soundfile[type][i]);
	exit(99);
      }
      /* Write a really dodgy wave header */
      /* Fix this to write the proper sampling frequency */
      for (j=0;j<WAVEHEADERSIZE;j++)
	fputc(wave_header[j], audioout[i]);
    }
  }
}

Revised :

void init_audio_outputs(int numchan) {
  int i,j;
  int type=-1;

  numchannels = numchan; // Set the global var for later on.
  if (numchan == 5)
    type = 0;
  if (numchan == 6)
    type = 1;
  if (numchan == 4)
    type = 2;
  if (soundfile>=0) {
    fprintf(stderr,"initialising %i output files\n",numchannels);
    for (i=0;i<numchannels;i++) {
      if ( (audioout[i] = fopen(soundfile[type][i], "w")) == NULL ) {
	fprintf(stderr,"Error opening %s for output\n",soundfile[type][i]);
	exit(99);
      }
      /* Write a really dodgy wave header */
      /* Fix this to write the proper sampling frequency */
      for (j=0;j<WAVEHEADERSIZE;j++)
	fputc(wave_header[j], audioout[i]);
    }
  }
}

by Aaron Scheiner, 13 years ago

Attachment: lamedecoder.zip added

Modified version of mctoolamed to set bitrate to 48kHz and add support for 4 channel files.

comment:2 by Carl Eugen Hoyos, 13 years ago

Component: FFmpegavcodec
Keywords: mp2 added; mpeg mctoolame multichannel removed
Priority: normalwish
Status: newopen
Version: unspecifiedgit-master

comment:3 by Carl Eugen Hoyos, 13 years ago

Do you have a 4-channel sample?

in reply to:  3 comment:4 by Aaron Scheiner, 13 years ago

Replying to cehoyos:

Do you have a 4-channel sample?

Yes I do, I'll attach it now. This is the process used to get the file :

ffmpeg -i hdvinput.hdv -vn -acodec copy out.mp2
(where hdvinput.hdv is a raw hdv file captured off HDV tape)

dd if=out.mp2 of=4CHsample.mp2 bs=1024 count=500

Hope that helps.

by Aaron Scheiner, 13 years ago

Attachment: 4CHsample.mp2 added

4 channel sample from an HDV stream

by Andrew-R, 10 months ago

Attachment: lamedecoder-fix.zip added

fixed lamedecoder.zip to build on modern gcc/clang (missed "gets" function replaced with fgets())

comment:5 by Andrew-R, 10 months ago

played around with provided sample, it decodes to 4 wav files, they all look real (loaded them all into cinelerra-gg, waveform is different, so they not just duplicates).

You need to call ./mctoolamed with input and output file names without extensions. resulted AIFF file is not decodeable by sox/libsndfile tools, but additional wav files are.

comment:7 by Andrew-R, 10 months ago

https://courses.e-ce.uth.gr/CE401/tree_menu/tutorials/MPEG2/13818-3.pdf

spec, I hope (relies on earlier ISO/IEC 11172-3)

comment:9 by Andrew-R, 10 months ago

There also attempt at reworking reference MPEG audio encoder, but multichannel encoder marked NOT WORKING (and I tried it, really does not work!)

https://github.com/joncampbell123/iso-dist10

comment:11 by Andrew-R, 10 months ago

I think I fixed multichannel encoder from iso-dist10 on i586:

https://github.com/joncampbell123/iso-dist10/pull/2

comment:12 by Andrew-R, 10 months ago

ah, interesting, 384Kbit/s figure is just form MPEG1 compatible bitstream.

=======
2.11 Extension Bit Stream
2.11.1 Introduction
The MPEG-2 audio standard contains a provision which allows the use of an extension bit stream.The extension bit stream provides a way to increase the bit rate above the maximum rate defined in MPEG-1 (384 Kbits/s). If the extension bit stream is used, two audio bit streams are parsed out by the system decoder: the MPEG-1 compatible stream and the extension bit stream. Frames from the two streams are paired together increasing the number of bits to code the sample in each combined frame.
=====

src:
http://dspace.mit.edu/bitstream/handle/1721.1/11468/33352495-MIT.pdf?sequence=2

but I guess this is not important for HDV use case?

comment:13 by Aaron Scheiner, 10 months ago

The audio bitrate for HDV is fixed at 384 kbit/sec as far as I know.

I only know of two HDV cameras that produced HDV with four audio channels: The Canon XL-H1 and the Sony HVR-S270.

comment:14 by Andrew-R, 9 months ago

yeah .... not very widely supported (I guess hw encoders/decoders were rare, and it was never integrated in open source software)

Found little utillity that can detect such streams:

https://mp3guessenc.sourceforge.io/

Note: See TracTickets for help on using tickets.