Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
170
Src/replicant/nsmp3/MPEGHeader.cpp
Normal file
170
Src/replicant/nsmp3/MPEGHeader.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
#include "MPEGHeader.h"
|
||||
#include <math.h>
|
||||
|
||||
// [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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue