📄 mpa_parser.cpp
字号:
#include <stdio.h>
#include <string.h>
#include "../../crc.h"
#include "mpa_parser.h"
#include "mpa_header.h"
#include "mpa_tables.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MPAParser::MPAParser()
{
samples.allocate(2, MPA_NSAMPLES);
synth[0] = new SynthBufferFPU();
synth[1] = new SynthBufferFPU();
// always useful
reset();
}
MPAParser::~MPAParser()
{
safe_delete(synth[0]);
safe_delete(synth[1]);
}
///////////////////////////////////////////////////////////////////////////////
// FrameParser overrides
const HeaderParser *
MPAParser::header_parser() const
{
return &mpa_header;
}
void
MPAParser::reset()
{
spk = spk_unknown;
samples.zero();
if (synth[0]) synth[0]->reset();
if (synth[1]) synth[1]->reset();
}
bool
MPAParser::parse_frame(uint8_t *frame, size_t size)
{
if (!parse_header(frame, size))
return false;
bs.set_ptr(frame, bsi.bs_type);
bs.get(32); // skip header
if (hdr.error_protection)
bs.get(16); // skip crc
switch (bsi.layer)
{
case MPA_LAYER_I:
I_decode_frame();
break;
case MPA_LAYER_II:
II_decode_frame();
break;
}
return true;
}
size_t
MPAParser::stream_info(char *buf, size_t size) const
{
char info[1024];
size_t len = sprintf(info,
"MPEG Audio\n"
"speakers: %s\n"
"ver: %s\n"
"frame size: %i bytes\n"
"stream: %s\n"
"bitrate: %ikbps\n"
"sample rate: %iHz\n"
"bandwidth: %ikHz/%ikHz\n\0",
spk.mode_text(),
bsi.ver? "MPEG2 LSF": "MPEG1",
bsi.frame_size,
(bsi.bs_type == BITSTREAM_8? "8 bit": "16bit low endian"),
bsi.bitrate / 1000,
bsi.freq,
bsi.jsbound * bsi.freq / SBLIMIT / 1000 / 2,
bsi.sblimit * bsi.freq / SBLIMIT / 1000 / 2);
if (len + 1 > size) len = size - 1;
memcpy(buf, info, len + 1);
buf[len] = 0;
return len;
}
size_t
MPAParser::frame_info(char *buf, size_t size) const
{
if (buf && size) buf[0] = 0;
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// BaseParser overrides
/*
bool
MPAParser::crc_check()
{
// Note: MPA uses standard CRC16 polinomial and 0xffff start value
// MPA LayerII has variable number of protected bits.
// To calculate it we must parse much of bs.
// So we will check CRC on frame decode.
// Maybe later.........
return true;
}
*/
//////////////////////////////////////////////////////////////////////
// MPA parsing
//////////////////////////////////////////////////////////////////////
bool
MPAParser::parse_header(const uint8_t *frame, size_t size)
{
// 8 bit or 16 bit big endian stream sync
if ((frame[0] == 0xff) && // sync
((frame[1] & 0xf0) == 0xf0) && // sync
((frame[1] & 0x06) != 0x00) && // layer
((frame[2] & 0xf0) != 0xf0) && // bitrate
((frame[2] & 0x0c) != 0x0c)) // sample rate
{
uint32_t h = *(uint32_t *)frame;
hdr = swab_u32(h);
bsi.bs_type = BITSTREAM_8;
}
else
// 16 bit low endian stream sync
if ((frame[1] == 0xff) && // sync
((frame[0] & 0xf0) == 0xf0) && // sync
((frame[0] & 0x06) != 0x00) && // layer
((frame[3] & 0xf0) != 0xf0) && // bitrate
((frame[3] & 0x0c) != 0x0c)) // sample rate
{
uint32_t h = *(uint32_t *)frame;
hdr = (h >> 16) | (h << 16);
bsi.bs_type = BITSTREAM_16LE;
}
else
return false;
hdr.error_protection = ~hdr.error_protection;
// common information
bsi.ver = 1 - hdr.version;
bsi.mode = hdr.mode;
bsi.layer = 3 - hdr.layer;
bsi.bitrate = bitrate_tbl[bsi.ver][bsi.layer][hdr.bitrate_index] * 1000;
bsi.freq = freq_tbl[bsi.ver][hdr.sampling_frequency];
bsi.nch = bsi.mode == MPA_MODE_SINGLE? 1: 2;
bsi.nsamples = bsi.layer == MPA_LAYER_I? SCALE_BLOCK * SBLIMIT: SCALE_BLOCK * SBLIMIT * 3;
// frame size calculation
if (bsi.bitrate)
{
bsi.frame_size = bsi.bitrate * slots_tbl[bsi.layer] / bsi.freq + hdr.padding;
if (bsi.layer == MPA_LAYER_I)
bsi.frame_size *= 4;
if (bsi.frame_size > size)
return false;
}
else
bsi.frame_size = 0;
// layerII: table select
II_table = 0;
if (bsi.layer == MPA_LAYER_II)
{
// todo: check for allowed bitrate ??? (look at sec 2.4.2.3 of ISO 11172-3)
if (bsi.ver)
// MPEG2 LSF
II_table = 4;
else
{
// MPEG1
if (bsi.mode == MPA_MODE_SINGLE)
II_table = II_table_tbl[hdr.sampling_frequency][hdr.bitrate_index];
else
II_table = II_table_tbl[hdr.sampling_frequency][II_half_bitrate_tbl[hdr.bitrate_index]];
}
}
// subband information
bsi.sblimit = bsi.layer == MPA_LAYER_II?
II_sblimit_tbl[II_table]:
SBLIMIT;
bsi.jsbound = bsi.mode == MPA_MODE_JOINT?
jsbound_tbl[bsi.layer][hdr.mode_ext]:
bsi.sblimit;
spk = Speakers(FORMAT_LINEAR, (bsi.mode == MPA_MODE_SINGLE)? MODE_MONO: MODE_STEREO, bsi.freq);
return true;
}
///////////////////////////////////////////////////////////////////////////////
// Layer II
///////////////////////////////////////////////////////////////////////////////
bool
MPAParser::II_decode_frame()
{
int sb, ch;
int nch = bsi.nch;
int sblimit = bsi.sblimit;
int jsbound = bsi.jsbound;
int table = II_table;
int16_t bit_alloc[MPA_NCH][SBLIMIT];
sample_t scale[MPA_NCH][3][SBLIMIT];
/////////////////////////////////////////////////////////
// Load bitalloc
const int16_t *ba_bits = II_ba_bits_tbl[table];
if (nch == 1)
{
for (sb = 0; sb < sblimit; sb++)
{
int bits = ba_bits[sb];
bit_alloc[0][sb] = II_ba_tbl[table][sb][bs.get(bits)];
}
for (sb = sblimit; sb < SBLIMIT; sb++)
bit_alloc[0][sb] = 0;
}
else
{
for (sb = 0; sb < jsbound; sb++)
{
int bits = ba_bits[sb];
if (bits)
{
bit_alloc[0][sb] = II_ba_tbl[table][sb][bs.get(bits)];
bit_alloc[1][sb] = II_ba_tbl[table][sb][bs.get(bits)];
}
else
{
bit_alloc[0][sb] = II_ba_tbl[table][sb][0];
bit_alloc[1][sb] = II_ba_tbl[table][sb][0];
}
}
for (sb = jsbound; sb < sblimit; sb++)
{
int bits = ba_bits[sb];
if (bits)
bit_alloc[0][sb] = bit_alloc[1][sb] = II_ba_tbl[table][sb][bs.get(bits)];
else
bit_alloc[0][sb] = bit_alloc[1][sb] = II_ba_tbl[table][sb][0];
}
for (sb = sblimit; sb < SBLIMIT; sb++)
bit_alloc[0][sb] = bit_alloc[1][sb] = 0;
}
/////////////////////////////////////////////////////////
// Load scalefactors bitalloc
uint16_t scfsi[2][SBLIMIT];
for (sb = 0; sb < sblimit; sb++)
for (ch = 0; ch < nch; ch++) // 2 bit scfsi
if (bit_alloc[ch][sb])
scfsi[ch][sb] = (uint16_t) bs.get(2);
// do we need this?
for (sb = sblimit; sb < SBLIMIT; sb++)
for (ch = 0; ch < nch; ch++)
scfsi[ch][sb] = 0;
/////////////////////////////////////////////////////////
// CRC check
// Do crc check up to current point. Note that we
// include CRC word into processing AFTER protected
// data. Due to CRC properties we must get zero result
// in case of no errors.
/*
if (hdr.error_protection && do_crc)
{
uint32_t crc_bits = bs.get_pos() - 32 - 16;
uint32_t crc = crc16.crc_init(0xffff);
crc = crc16.calc_bits(crc, frame + 2, 0, 16, bs_type); // header
crc = crc16.calc_bits(crc, frame + 6, 0, crc_bits, bs_type); // frame data
crc = crc16.calc_bits(crc, frame + 4, 0, 16, bs_type); // crc
if (crc)
return false;
}
*/
/////////////////////////////////////////////////////////
// Load scalefactors
sample_t c;
for (sb = 0; sb < sblimit; sb++)
for (ch = 0; ch < nch; ch ++)
{
int ba = bit_alloc[ch][sb];
if (ba)
{
if (ba > 0)
c = c_tbl[ba];
else
switch (ba)
{
case -5: c = c_tbl[0]; break;
case -7: c = c_tbl[1]; break;
case -10: c = c_tbl[2]; break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -