Guest User

mp3 frame header

a guest
Jul 1st, 2025
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.25 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include <string>
  4.  
  5. //MPEG audio frame header
  6. //variables are declared in their serialized order
  7. struct FrameHeader
  8. {
  9.   static const unsigned int SERIALIZED_SIZE = 4;
  10.  
  11.   //bitmasks for frame header fields grouped by byte
  12.   static const unsigned char FRAMESYNC_FIRST_BYTEMASK  = 0b11111111;
  13.  
  14.   static const unsigned char FRAMESYNC_SECOND_BYTEMASK = 0b1110000;
  15.   static const unsigned char AUDIO_VERSION_MASK        = 0b00011000;
  16.   static const unsigned char LAYER_DESCRIPTION_MASK    = 0b00000110;
  17.   static const unsigned char PROTECTION_BIT_MASK       = 0b00000001;
  18.  
  19.   static const unsigned char BITRATE_INDEX_MASK        = 0b11110000;
  20.   static const unsigned char SAMPLERATE_INDEX_MASK     = 0b00001100;
  21.   static const unsigned char PADDING_BIT_MASK          = 0b00000010;
  22.   static const unsigned char PRIVATE_BIT_MASK          = 0b00000001;
  23.  
  24.   static const unsigned char CHANNEL_MODE_MASK         = 0b11000000;
  25.   static const unsigned char MODE_EXTENTION_MASK       = 0b00110000;
  26.   static const unsigned char COPYRIGHT_BIT_MASK        = 0b00001000;
  27.   static const unsigned char ORIGINAL_BIT_MASK         = 0b00000100;
  28.   static const unsigned char EMPHASIS_MASK             = 0b00000011;
  29.  
  30.   char FrameSyncByte;
  31.   bool FrameSyncBits: 3;
  32.  
  33.   //indicates MPEG standard version
  34.   enum class AudioVersionID : unsigned
  35.   {
  36.     MPEG_2_5 = 0b00,
  37.     INVALID  = 0b01,
  38.     MPEG_2   = 0b10,
  39.     MPEG_1   = 0b11,
  40.   } AudioVersion : 2;
  41.  
  42.   //indicates which audio layer of the MPEG standard
  43.   enum class LayerID : unsigned
  44.   {
  45.     INVALID = 0b00,
  46.     LAYER_3 = 0b01,
  47.     LAYER_2 = 0b10,
  48.     LAYER_1 = 0b11,
  49.   } Layer : 2;
  50.  
  51.   //indicates whether theres a 16 bit crc checksum following the header
  52.   bool Protection : 1;
  53.  
  54.   //sample & bitrate indexes meaning differ depending on MPEG version
  55.   //use GetBitrate() and GetSamplerate()
  56.   bool BitrateIndex : 4;
  57.   bool SampleRateIndex : 2;
  58.  
  59.   //indicates whether the audio data is padded with 1 extra byte (slot)
  60.   bool Padding : 1;
  61.  
  62.   //this is only informative
  63.   bool Private : 1;
  64.  
  65.   //indicates channel mode
  66.   enum class ChannelModeID : unsigned
  67.   {
  68.     STEREO = 0b00,
  69.     JOINT  = 0b01, //joint stereo
  70.     DUAL   = 0b10, //dual channel (2 mono channels)
  71.     SINGLE = 0b11, //single channel (mono)
  72.   } ChannelMode : 2;
  73.  
  74.   //Only used in joint channel mode. Meaning differ depending on audio layer
  75.   //Use GetExtentionMode()
  76.   bool ExtentionMode : 2;
  77.  
  78.   //indicates whether the audio is copyrighted
  79.   bool Copyright : 1;
  80.  
  81.   //indicates whether the frame is located on the original media or a copy
  82.   bool Original : 1;
  83.  
  84.   //indicates to the decoder that the file must be de-emphasized, ie the
  85.   //decoder must 're-equalize' the sound after a Dolby-like noise supression.
  86.   //It is rarely used.
  87.   enum class EmphasisID : unsigned
  88.   {
  89.     NONE     = 0b00,
  90.     MS_50_15 = 0b01,
  91.     INVALID  = 0b10,
  92.     CCIT_J17 = 0b10,
  93.   } Emphasis : 2;
  94.  
  95.   enum SpecialBitrate
  96.   {
  97.     INVALID = -8000,
  98.     ANY = 0,
  99.   };
  100.  
  101.   signed int GetBitrate() const
  102.   {
  103.     //version, layer, bit index
  104.     static signed char rateTable[4][4][16] =
  105.     {
  106.       //version[00] = MPEG_2_5
  107.       {
  108.         //layer[00] = INVALID
  109.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  110.         //layer[01] = LAYER_3
  111.         { 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 18, 20, -1},
  112.         //layer[10] = LAYER_2
  113.         { 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 18, 20, -1},
  114.         //layer[11] = LAYER_1
  115.         { 0,  4,  6,  7,  8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, -1},
  116.       },
  117.  
  118.       //version[01] = INVALID
  119.       {
  120.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  121.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  122.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  123.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  124.       },
  125.  
  126.       //version[10] = MPEG_2
  127.       {
  128.         //layer[00] = INVALID
  129.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  130.         //layer[01] = LAYER_3
  131.         { 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 18, 20, -1},
  132.         //layer[10] = LAYER_2
  133.         { 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 18, 20, -1},
  134.         //layer[11] = LAYER_1
  135.         { 0,  4,  6,  7,  8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, -1},
  136.       },
  137.  
  138.       //version[11] = MPEG_1
  139.       {
  140.         //layer[00] = INVALID
  141.         {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  142.         //layer[01] = LAYER_3
  143.         { 0,  4,  5,  6,  7,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, -1},
  144.         //layer[10] = LAYER_2
  145.         { 0,  4,  6,  7,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, -1},
  146.         //layer[11] = LAYER_1
  147.         { 0,  4,  8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, -1},
  148.       },
  149.     };
  150.  
  151.     return rateTable[AudioVersion][Layer][BitrateIndex] * 8000;
  152.   }
  153.  
  154.   enum SpecialSampleRate
  155.   {
  156.     RESERVED = 0,
  157.   };
  158.  
  159.   unsigned short GetSampleRate() const
  160.   {
  161.     //version, sample rate index
  162.     static unsigned short rateTable[4][4] =
  163.     {
  164.       //version[00] = MPEG_2_5
  165.       {11025, 12000,  8000,  0},
  166.       //version[01] = INVALID
  167.       {  0,     0,       0,  0},
  168.       //version[10] = MPEG_2
  169.       {22050, 24000, 16000,  0},
  170.       //version[11] = MPEG_1
  171.       {44100, 48000, 32000,  0},
  172.     };
  173.  
  174.     return rateTable[AudioVersion][SampleRateIndex];
  175.   }
  176.  
  177.   std::string GetSampleRateStr() const
  178.   {
  179.     auto rate = GetSampleRate();
  180.     return rate == SpecialSampleRate::RESERVED ? "INVALID" : std::to_string(rate);
  181.   }
  182.  
  183.   std::string GetBitrateStr() const
  184.   {
  185.     auto rate = GetBitrate();
  186.  
  187.     return rate == SpecialBitrate::ANY      ? "ANY" :
  188.            rate == SpecialBitrate::INVALID  ? "INVALID" :
  189.            std::to_string(rate);
  190.   }
  191.  
  192.   std::string GetVersionStr() const
  193.   {
  194.     return AudioVersion == AudioVersionID::MPEG_1   ? "1" :
  195.            AudioVersion == AudioVersionID::MPEG_2   ? "2" :
  196.            AudioVersion == AudioVersionID::MPEG_2_5 ? "2.5" : "INVALID";
  197.   }
  198.  
  199.   std::string GetLayerStr() const
  200.   {
  201.     return Layer == LayerID::LAYER_1 ? "1" :
  202.            Layer == LayerID::LAYER_2 ? "2" :
  203.            Layer == LayerID::LAYER_3 ? "3" : "INVALID";
  204.   }
  205.  
  206. };
Advertisement
Add Comment
Please, Sign In to add comment