/*
 * @(#)MP3Structs.txt  1.0  2010-12-29
 *
 * Copyright (c) 2010 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */

/**
 * This file contains the description of the headers in an MP3 elementary stream.
 *
 * References:
 * http://www.mp3-tech.org/programmer/frame_header.html
 * http://www.altera.com/literature/dc/1.4-2005_Taiwan_2nd_SouthernTaiwanU-web.pdf
 * http://www.mp3-tech.org/programmer/docs/mp3_theory.pdf
 *
 * Books:
 * M. Ruckert. (2005) Understanding MP3. Vieweg+Teubner. Page 171.
 *
 * @author Werner Randelshofer
 * @version 1.0 2010-12-29 Created.
 */

magic Frame "Frame";
description Frame "Frame","Within an MPEG audio file, there is no main header, as an MPEG audio file is just built up from a succession of smaller parts called frames. Each frame is a datablock with its own header and audio information. In the case of Layer I or Layer II, frames are totally independent from each other, so you can cut any part of an MPEG audio file and play it correctly. The player will then play the music starting from the first full valid frame it will find. However, in the case of Layer III, frames are not always independent. Due to the possible use of the \"byte reservoir\", wich is a kind of internal buffer, frames are often dependent of each other. In the worst case, 9 input frames may be needed before beeing able to decode one single frame.";

magic MPEG25Reserved "25.-1";
magic MPEG25LayerIII "25.3";
magic MPEG25LayerII  "25.2";
magic MPEG25LayerI   "25.1";
magic MPEGReservedReserved "-1.-1";
magic MPEGReservedLayerIII "-1.3";
magic MPEGReservedLayerII  "-1.2";
magic MPEGReservedLayerI   "-1.1";
magic MPEG2Reserved "2.-1";
magic MPEG2LayerIII "2.3";
magic MPEG2LayerII  "2.2";
magic MPEG2LayerI   "2.1";
magic MPEG1Reserved "1.-1";
magic MPEG1LayerIII "1.3";
magic MPEG1LayerII  "1.2";
magic MPEG1LayerI   "1.1";
description MPEG25Reserved "MPEG 2.5, Layer reserved", "";
description MPEG25LayerIII "MPEG 2.5, Layer III", "MPEG 2.5, Layer III. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG25LayerII "MPEG 2.5, Layer II", "MPEG 2.5, Layer II. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG25LayerI "MPEG 2.5, Layer I", "MPEG 2.5, Layer I. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEGReservedReserved "MPEG reserved, Layer reserved", "";
description MPEGReservedLayerIII "MPEG reserved, Layer III", "";
description MPEGReservedLayerII "MPEG reserved, Layer II", "";
description MPEGReservedLayerI "MPEG reserved, Layer I", "";
description MPEG2Reserved "MPEG 2, Layer reserved", "";
description MPEG2LayerIII "MPEG 2, Layer III", "MPEG 2, Layer III. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG2LayerII "MPEG 2, Layer II", "MPEG 2, Layer II. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG2LayerI "MPEG 2, Layer I", "MPEG 2, Layer I. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG1Reserved "MPEG 1, Layer reserved", "";
description MPEG1LayerIII "MPEG 1, Layer III", "MPEG 1, Layer III. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG1LayerII "MPEG 1, Layer II", "MPEG 1, Layer II. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";
description MPEG1LayerI "MPEG 1, Layer I", "MPEG 1, Layer I. The header contains a synchronization word together with a description of the frame and an optional 16-bit CRC checksum.";

enum {
    mpeg2p5 = 0, // MPEG Version 2.5 (later extension of MPEG 2)
    reserved = 1,
    mpeg2 = 2, // MPEG Version 2 (ISO/IEC 13818-3)
    mpeg1 = 3, // MPEG Version 1 (ISO/IEC 11172-3)
} Version;

enum {
    reserved = 0,
    layerIII = 1,
    layerII = 2,
    layerI = 3,
} Layer;

enum {
    CRC = 0,
    notProtected = 1
} Protection;

enum {
    free = 0,
    "32kbps" = 1,
    "64kbps" = 2,
    "96kbps" = 3,
    "128kbps" = 4,
    "160kbps" = 5,
    "192kbps" = 6,
    "224kbps" = 7,
    "256kbps" = 8,
    "288kbps" = 9,
    "320kbps" = 10,
    "352kbps" = 11,
    "384kbps" = 12,
    "416kbps" = 13,
    "448kbps" = 14,
    bad = 15,
} BitrateMPEG1LayerI;
enum {
    free = 0,
    "32kbps" = 1,
    "48kbps" = 2,
    "56kbps" = 3,
    "64kbps" = 4,
    "80kbps" = 5,
    "96kbps" = 6,
    "112kbps" = 7,
    "128kbps" = 8,
    "160kbps" = 9,
    "192kbps" = 10,
    "224kbps" = 11,
    "256kbps" = 12,
    "320kbps" = 13,
    "384kbps" = 14,
    bad = 15,
} BitrateMPEG1LayerII;
enum {
    free = 0,
    "32kbps" = 1,
    "40kbps" = 2,
    "48kbps" = 3,
    "56kbps" = 4,
    "64kbps" = 5,
    "80kbps" = 6,
    "96kbps" = 7,
    "112kbps" = 8,
    "128kbps" = 9,
    "160kbps" = 10,
    "192kbps" = 11,
    "224kbps" = 12,
    "256kbps" = 13,
    "320kbps" = 14,
    bad = 15,
} BitrateMPEG1LayerIII;
enum {
    free = 0,
    "32kbps" = 1,
    "48kbps" = 2,
    "56kbps" = 3,
    "64kbps" = 4,
    "80kbps" = 5,
    "96kbps" = 6,
    "112kbps" = 7,
    "128kbps" = 8,
    "144kbps" = 9,
    "160kbps" = 10,
    "176kbps" = 11,
    "192kbps" = 12,
    "224kbps" = 13,
    "256kbps" = 14,
    bad = 15,
} BitrateMPEG2LayerI;
enum {
    free = 0,
    "8kbps" = 1,
    "16kbps" = 2,
    "24kbps" = 3,
    "32kbps" = 4,
    "40kbps" = 5,
    "48kbps" = 6,
    "56kbps" = 7,
    "64kbps" = 8,
    "80kbps" = 9,
    "96kbps" = 10,
    "112kbps" = 11,
    "128kbps" = 12,
    "144kbps" = 13,
    "160kbps" = 14,
    bad = 15,
} BitrateMPEG2LayerIIandIII;

enum {
    "44100Hz" = 0,
    "48000Hz" = 1,
    "32000Hz" = 2,
    reserved = 3,
} SamplingRateMPEG1;

enum {
    "22050Hz" = 0,
    "24000Hz" = 1,
    "16000Hz" = 2,
    reserved = 3,
} SamplingRateMPEG2;

enum {
    "11025Hz" = 0,
    "12000Hz" = 1,
    "8000Hz" = 2,
    reserved = 3,
} SamplingRateMPEG2p5;

enum {
    unpadded = 0,
    padded = 1,
} Padding;

enum {
    stereo = 0,
    jointStereo = 1,   // stereo
    dualChannel = 2,   // 2 mono channels
    singleChannel = 3, // mono
} ChannelMode;

enum {
    bands4To31 = 0,
    bands8To31 = 1,
    bands12To31 = 2,
    bands16To31 = 3,
} ModeExtensionLayerIandII;
enum {
    off = 0,
    intensityStereo = 1,
    "Mid/SideStereo" = 2,
    "intensityStereoAndMid/SideStereo" = 3,
} ModeExtensionLayerIII;

enum {
    notCopyrighted = 0,
    isCopyrighted = 1,
} Copyright;

enum {
    copyOfOriginalMedia = 0,
    originalMedia = 1,
} Original;

enum {
    none = 0,
    _50_15_ms = 1,
    reserved = 2,
    CCIT_J17 = 3,
} Emphasis;


typedef struct {
   uint1[11]              sync;    // Frame sync (all bits must be set)
   uint2 enum Version     version; // Note: MPEG Version 2.5 was added later to
                                   // the MPEG 2 standard. It is an extension
                                   // used for very low bitrate files, allowing
                                   // the use of lower sampling frequencies. If
                                   // your decoder does not support this
                                   // extension, it is recommended for you to
                                   // use 12 bits for synchronization instead of
                                   // 11 bits.
   uint2 enum Layer       layer;
   uint1 enum Protection  errorProtection;

   uint4 enum BitrateMPEG1LayerI bitrate;
                                    // "free" means free format. The free bit-
                                    // rate must remain constant, an must be
                                    // lower than the maximum allowed bitrate.
                                    // Decoders are not required to support
                                    // decoding of free bitrate streams.
                                    // "bad" means that the value is unallowed.
                                    // MPEG files may feature variable bitrate
                                    // (VBR). Each frame may then be created
                                    // with a different bitrate. It may be used
                                    // in all layers. Layer III decoders must
                                    // support this method. Layer I & II deco-
                                    // ders may support it.
                                    // For Layer II there are some combinations
                                    // of bitrate and mode which are not allo-
                                    // wed.

   uint2 enum SamplingRateMPEG1 samplingRate;

   uint1 enum Padding     padding;  // Padding is used to exactly fit the bit-
                                    // rate. As an example: 128kbps 44.1kHz
                                    // layer II uses a lot of 418 bytes and some
                                    // of 417 bytes long frames to get the exact
                                    // 128k bitrate. For Layer I slot is 32 bits
                                    // long, for Layer II and Layer III slot is
                                    // 8 bits long.

   uint1                  private;  // This one is only informative.

   uint2 enum ChannelMode channelMode;
                                    // Note: Dual channel files are made of two
                                    // independent mono channel. Each one uses
                                    // exactly half the bitrate of the file.
                                    // Most decoders output them as stereo, but
                                    // it might not always be the case.
                                    // One example of use would be some speech
                                    // in two different languages carried in the
                                    // same bitstream, and then an appropriate
                                    // decoder would decode only the choosen
                                    // language.

   uint2 enum ModeExtensionLayerIandII modeExtension;
                                    // Only used in Joint stereo.
                                    // Mode extension is used to join informa-
                                    // tions that are of no use for stereo
                                    // effect, thus reducing needed bits. These
                                    // bits are dynamically determined by an
                                    // encoder in Joint stereo mode, and Joint
                                    // Stereo can be changed from one frame to
                                    // another, or even switched on or off.
                                    // Complete frequency range of MPEG file is
                                    // divided in subbands There are 32 sub-
                                    // bands. For Layer I & II these two bits
                                    // determine frequency range (bands) where
                                    // intensity stereo is applied. For Layer
                                    // III these two bits determine which type
                                    // of joint stereo is used (intensity stereo
                                    // or m/s stereo). Frequency range is deter-
                                    // mined within decompression algorithm.

   uint1 enum Copyright   copyright;// The copyright has the same meaning as the
                                    // copyright bit on CDs and DAT tapes, i.e.
                                    // telling that it is illegal to copy the
                                    // contents if the bit is set.

   uint1 enum Original    original; // The original bit indicates, if it is set,
                                    // that the frame is located on its original
                                    // media.

   uint2 enum Emphasis    emphasis; // The emphasis indication is here to tell
                                    // the decoder that the file must be de-
                                    // emphasized, ie the decoder must 're-
                                    // equalize' the sound after a Dolby-like
                                    // noise supression. It is rarely used.
   uint16 crc;
} MPEG1LayerI;

typedef struct {
   uint1[11]              sync; // Frame sync (all bits must be set)
   uint2 enum Version     version;
   uint2 enum Layer       layer;
   uint1 enum Protection  errorProtection;

   uint4 enum BitrateMPEG1LayerIII bitrate;
   uint2 enum SamplingRateMPEG1 samplingRate;
   uint1 enum Padding     padding;
   uint1                  private;

   uint2 enum ChannelMode channelMode;
   uint2 enum ModeExtensionLayerIII modeExtension;
   uint1 enum Copyright   copyright;
   uint1 enum Original    original;
   uint2 enum Emphasis    emphasis;
   uint16 crc;
} MPEG1LayerIII;

typedef struct {
   uint1[11]              sync; // Frame sync (all bits must be set)
   uint2 enum Version     version;
   uint2 enum Layer       layer;
   uint1 enum Protection  errorProtection;

   uint4 enum BitrateMPEG2LayerIIandIII bitrate;
   uint2 enum SamplingRateMPEG2 samplingRate;
   uint1 enum Padding     padding;
   uint1                  private;

   uint2 enum ChannelMode channelMode;
   uint2 enum ModeExtensionLayerIII modeExtension;
   uint1 enum Copyright   copyright;
   uint1 enum Original    original;
   uint2 enum Emphasis    emphasis;
   uint16 crc;
} MPEG2LayerIII;

magic SideInfoSingleIII "SideInfo (Single Channel)";
description SideInfoSingleIII "Side Info","Side information records the information needed for decoding the audio data. It is 17 bytes for single channel audio. The mainDataOffset gives the number of bytes borrowed from previous frames.";

enum {
    bands0to5 = 0,
    bands6to10 = 1,
    bands11to15 = 2,
    bands16to20 = 3,
} ScaleFactorGroups;
enum {
    "slen1=0, slen2=0" = 0,
    "slen1=0, slen2=1" = 1,
    "slen1=0, slen2=2" = 2,
    "slen1=0, slen2=3" = 3,
    "slen1=1, slen2=0" = 4,
    "slen1=1, slen2=1" = 5,
    "slen1=1, slen2=2" = 6,
    "slen1=1, slen2=3" = 7,
    "slen1=2, slen2=1" = 8,
    "slen1=2, slen2=2" = 9,
    "slen1=2, slen2=3" = 10,
    "slen1=3, slen2=1" = 11,
    "slen1=3, slen2=2" = 12,
    "slen1=3, slen2=3" = 13,
    "slen1=4, slen2=2" = 14,
    "slen1=4, slen2=3" = 15,
} ScalefacCompress;
enum {
    forbidden = 0,
    start = 1,
    threeShortWindows = 2,
    end = 3,
} BlockType;

typedef struct {
    uint3[3] subblockGain;
                       // This 3 bit variable indicates the gain offset from
                       // globalGain for each short block.
} SubblockGain; // 9 bits

typedef struct {
   uint2 enum BlockType blockType;
                       // This field is only used when windowsSwitchingFlag is
                       // set and indicates the type of window used for the
                       // particular granule (all values but 3 are long windows). The value 00 is forbidden since
                       // block_type is only used when other than normal windows
                       // are used.
   uint1 mixedBlockFlag;
                       // The mixedBlockFlag indicates that different types of
                       // windows are used in the lower and higher frequencies.
                       // If mixedBlockFlag is set the two lowest subbands are
                       // transformed using a normal window and the remaining 30
                       // subbands are transformed using the window specified by
                       // the block_type variable.
   uint5[2] tableSelection;
   SubblockGain[blockType == "threeShortWindows"] s;
} WindowSwitching; // 22 bits

typedef struct {
   uint5[3] tableSelection;
   uint4 region0Pairs;
   uint3 region1Pairs;
} NormalWindow; // 22 bits

typedef struct {
   uint12 mainDataBits; // States the number of bits allocated in the main data
                       // part of the frame for scalefactors (part2) and Huffman
                       // encoded data (part3). This field can be used to
                       // calculate the location of the next granule and the
                       // ancillary information (if used).
   uint9 bigValues;     // The 576 frequency lines of each granule are not coded
                       // with the same Huffmancode table. These frequencies
                       // range from zero to the Nyquist frequency and are
                       // divided into five regions. The purpose of this
                       // partitioning is to allow different Huffman tables to
                       // different parts of the spectrum in order to enhance
                       // the performance of the Huffman encoder.
   uint8 globalGain;   // Specifies the quantization step size, this is needed
                       // in the requantization block of the decoder.
   uint4 enum ScalefacCompress scaleFactorBits;
                       // Determines the number of bits used for the
                       // transmission of scalefactors. A granule can be divided
                       // into 12 or 21 scalefactor bands. If long windows are
                       // used (block_type = {0,1,3})the granule will be
                       // partitioned into 21 scalefactor bands. Using short
                       // windows (block_type = 2) will partition the granule
                       // into 12 scalefactor bands. The scale factors are then
                       // further divided into two groups, 0-10, 11-20 for long
                       // windows and 0-6, 7-11 for short windows.
   uint1 windowSwitchingFlag;
                       // Indicates that another window than the normal is used.
                       // blockType, mixedBlockFlag and subblockGain are
                       // only used if windowsSwitchingFlag is set.

   WindowSwitching[windowSwitchingFlag == 1] w;
   NormalWindow[windowSwitchingFlag == 0] w;

   uint1 preemphasisFlag;
   uint1 scalefactorScale;
   uint1 tableSelect;  // Two possible Huffman code tables are available for the
                       // count1 region. This field specifies which table to apply.
// 3 bits
} SideInfoGranule; // 59 bits

typedef struct {
    uint9 mainDataOffset; // Using the layer III format there is a technique
                        // called the byte reservoir which enables the left over
                        // free space in the main data area of a frame to be
                        // used by consecutive frames. To be able to find where
                        // the main data of a certain frame begins the decoder
                        // has to read the mainDataOffset value. The value is as
                        // a negative offset from the first byte of the
                        // synchronization word. Since it is 9 bits long it can
                        // point (2^9 – 1) * 8 = 4088 bits. This means that data
                        // for one frame can be found several previous frames.
                        // Note that static parts of a frame like the header,
                        // which is always 32 bytes, are not included in the
                        // offset. If mainDataBegin = 0 the main data starts
                        // directly after the side information.
    uint1[5] private;      // Five bits for private use, these will not be used in the
                        // future by ISO.
    uint4 enum ScaleFactorGroups sharedScaleFactors;
                        // The ScaleFactor Selection Information determines
                        // wether the same scalefactors are transferred for both
                        // granules or not. 
    SideInfoGranule[2] granule;
} SideInfoSingleIII;

magic SideInfoDualIII "SideInfo";
description SideInfoDualIII "Side Info","Side information records the information needed for the decoding of the audio data. The mainDataOffset gives the number of bytes borrowed from previous frames.";


typedef struct {
    uint9 mainDataOffset;
    uint1[3] private; // Three bits for private use.
    uint4 enum ScaleFactorGroups sharedScaleFactorsLeft;
    uint4 enum ScaleFactorGroups sharedScaleFactorsRight;
    SideInfoGranule[4] granule;
} SideInfoDualIII;


magic MainData "MainData";
description MainData "Main Data","The main data part of the frame consists of scalefactors, Huffman coded bits and ancillary data.";

