MPEGFrame.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * MPEGFrame.cpp
  3. * -------------
  4. * Purpose: Basic MPEG frame parsing functionality
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "MPEGFrame.h"
  11. #include "../common/FileReader.h"
  12. OPENMPT_NAMESPACE_BEGIN
  13. // Samples per frame - for each MPEG version and all three layers
  14. static constexpr uint16 samplesPerFrame[2][3] =
  15. {
  16. { 384, 1152, 1152 }, // MPEG 1
  17. { 384, 1152, 576 } // MPEG 2 / 2.5
  18. };
  19. // Bit rates for each MPEG version and all three layers
  20. static constexpr uint16 bitRates[2][3][15] =
  21. {
  22. // MPEG 1
  23. {
  24. { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, // Layer 1
  25. { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, // Layer 2
  26. { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } // Layer 3
  27. },
  28. // MPEG 2 / 2.5
  29. {
  30. { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, // Layer 1
  31. { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, // Layer 2
  32. { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } // Layer 3
  33. }
  34. };
  35. // Sampling rates for each MPEG version and all three layers
  36. static constexpr uint16 samplingRates[4][3] =
  37. {
  38. { 11025, 12000, 8000 }, // MPEG 2.5
  39. { 0, 0, 0 }, // Invalid
  40. { 22050, 24000, 16000 }, // MPEG 2
  41. { 44100, 48000, 32000 } // MPEG 1
  42. };
  43. // Samples per Frame / 8
  44. static constexpr uint8 mpegCoefficients[2][3] =
  45. {
  46. { 12, 144, 144 }, // MPEG 1
  47. { 12, 144, 72 } // MPEG 2 / 2.5
  48. };
  49. // Side info size = Offset in frame where Xing/Info magic starts
  50. static constexpr uint8 sideInfoSize[2][2] =
  51. {
  52. { 17, 32 }, // MPEG 1
  53. { 9, 17 } // MPEG 2 / 2.5
  54. };
  55. bool MPEGFrame::IsMPEGHeader(const uint8 (&header)[3])
  56. {
  57. return header[0] == 0xFF && (header[1] & 0xE0) == 0xE0 // Sync
  58. && (header[1] & 0x18) != 0x08 // Invalid MPEG version
  59. && (header[1] & 0x06) != 0x00 // Invalid MPEG layer
  60. && (header[2] & 0x0C) != 0x0C // Invalid frequency
  61. && (header[2] & 0xF0) != 0xF0; // Invalid bitrate
  62. }
  63. MPEGFrame::MPEGFrame(FileReader &file)
  64. : frameSize(0)
  65. , numSamples(0)
  66. , isValid(false)
  67. , isLAME(false)
  68. {
  69. uint8 header[4];
  70. file.ReadArray(header);
  71. if(!IsMPEGHeader(reinterpret_cast<const uint8(&)[3]>(header)))
  72. return;
  73. uint8 version = (header[1] & 0x18) >> 3;
  74. uint8 mpeg1 = (version == 3) ? 0 : 1;
  75. uint8 layer = 3 - ((header[1] & 0x06) >> 1);
  76. uint8 bitRate = (header[2] & 0xF0) >> 4;
  77. uint8 sampleRate = (header[2] & 0x0C) >> 2;
  78. uint8 padding = (header[2] & 0x02) >> 1;
  79. bool stereo = ((header[3] & 0xC0) >> 6) != 3;
  80. isValid = true;
  81. frameSize = (((mpegCoefficients[mpeg1][layer] * (bitRates[mpeg1][layer][bitRate] * 1000) / samplingRates[version][sampleRate]) + padding)) * (layer == 0 ? 4 : 1);
  82. numSamples = samplesPerFrame[mpeg1][layer];
  83. if(stereo) numSamples *= 2u;
  84. uint32 lameOffset = sideInfoSize[mpeg1][stereo ? 1 : 0];
  85. if(frameSize < lameOffset + 8)
  86. return;
  87. uint8 frame[36];
  88. file.ReadStructPartial(frame, lameOffset + 4);
  89. // Don't check first two bytes, might be CRC
  90. for(uint32 i = 2; i < lameOffset; i++)
  91. {
  92. if(frame[i] != 0)
  93. return;
  94. }
  95. // This is all we really need to know for our purposes in the MO3 decoder.
  96. isLAME = !memcmp(frame + lameOffset, "Info", 4) || !memcmp(frame + lameOffset, "Xing", 4);
  97. }
  98. OPENMPT_NAMESPACE_END