#include "MPEGHeader.h" #include // [mpeg_version][layer][index] static const int bitrates[4][4][15] = { { // MPEG-2.5 { 0,}, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000}, // Layer 3 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000}, // Layer 2 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000}, // Layer 1 }, { // invalid { 0, }, { 0, }, { 0, }, { 0, }, }, { // MPEG-2 { 0,}, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000}, // Layer 3 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000}, // Layer 2 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000}, // Layer 1 }, { // MPEG-1 { 0,}, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000}, // Layer 3 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000}, // Layer 2 { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000}, // Layer 1 }, }; // [mpeg_version][index] static const int sample_rates[4][4] = { {11025, 12000, 8000, 0}, // MPEG-2.5 {0, }, {22050, 24000, 16000, 0}, // MPEG-2 {44100, 48000, 32000, 0}, // MPEG-1 }; // [mpeg_version][layer] static const int samples_per_frame[4][4] = { // Layer 3, Layer 2, Layer 1 { 0, 576, 1152, 384}, // MPEG2.5 { 0, }, { 0, 576, 1152, 384}, // MPEG2 { 0, 1152, 1152, 384}, // MPEG1 }; // [layer] static const int bits_per_slot[4] = { 0, 8, 8, 32 }; void MPEGHeader::ReadBuffer(const uint8_t *buffer) { sync = ((uint16_t)buffer[0] << 3) | (buffer[1] >> 5); mpeg_version = (buffer[1] >> 3) & 3; layer = (buffer[1] >> 1) & 3; protection = (buffer[1]) & 1; bitrate_index = (buffer[2] >> 4) & 0xF; sample_rate_index = (buffer[2] >> 2) & 3; padding_bit = (buffer[2] >> 1) & 1; private_bit = buffer[2] & 1; channel_mode = (buffer[3] >> 6) & 3; mode_extension = (buffer[3] >> 4) & 3; copyright = (buffer[3] >> 3) & 1; original = (buffer[3] >> 2) & 1; emphasis = (buffer[3]) & 3; } bool MPEGHeader::IsSync() const { return sync == 0x07FF && layer != LayerError && mpeg_version != MPEG_Error && bitrate_index != 15 && bitrate_index != 0 && sample_rate_index != 3 && !(mpeg_version == MPEG2 && layer != Layer3) && !(mpeg_version == MPEG2_5 && layer != Layer3); } int MPEGHeader::GetBitrate() const { return bitrates[mpeg_version][layer][bitrate_index]; } int MPEGHeader::HeaderSize() const { if (protection == CRC) return 4 + 2; // 32bits frame header, 16bits CRC else return 4; // 32bits frame ehader } int MPEGHeader::GetSampleRate() const { return sample_rates[mpeg_version][sample_rate_index]; } bool MPEGHeader::IsCopyright() const { return copyright == 1; } bool MPEGHeader::IsCRC() const { return protection == CRC; } bool MPEGHeader::IsOriginal() const { return original == 1; } int MPEGHeader::GetSamplesPerFrame() const { return samples_per_frame[mpeg_version][layer]; } int MPEGHeader::FrameSize() const { int nBitsPerSlot; int nAvgSlotsPerFrame; nBitsPerSlot = bits_per_slot[layer]; nAvgSlotsPerFrame = (GetSamplesPerFrame() * (bitrates[mpeg_version][layer][bitrate_index] / nBitsPerSlot)) / sample_rates[mpeg_version][sample_rate_index]; return (nAvgSlotsPerFrame + padding_bit) * nBitsPerSlot / 8; } int MPEGHeader::GetLayer() const { switch(layer) { case Layer1: return 1; case Layer2: return 2; case Layer3: return 3; default: return 0; } } int MPEGHeader::GetNumChannels() const { switch(channel_mode) { case Stereo: return 2; case JointStereo: return 2; case DualChannel: return 2; case Mono: return 1; default: return 0; } }