📄 parser.cpp
字号:
#include <string.h>
#include "parser.h"
#include "dither.h"
const int _acmod_nfchans[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
#define ACMOD_NFCHANS(acmod) _acmod_nfchans[(acmod)&7]
#define MANTISSA_BITS 15
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define EXP_REUSE 0
#define EXP_D15 1
#define EXP_D25 2
#define EXP_D45 3
#define DELTA_BIT_REUSE 0
#define DELTA_BIT_NEW 1
#define DELTA_BIT_NONE 2
#define DELTA_BIT_RESERVED 3
///////////////////////////////////////////////////////////////////////////////
// TABLES
///////////////////////////////////////////////////////////////////////////////
const uint8_t halfrate_tbl[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
const int rematrix_band[4] = {25, 37, 61, 253};
const sample_t clev_tbl[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
const sample_t slev_tbl[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};
///////////////////////////////////////////////////////////////////////////////
// scale factor
//
// definition:
// scale_factor[i] = 1/2^(i+15)
//
// usage:
// coef = mantissa * scale_factor[exponent]
// mantissa - integer value interpreted as fixed point value in range [-1;1]
// exponent - negative binary exponent
//
const sample_t scale_factor[25] =
{
0.000030517578125,
0.0000152587890625,
0.00000762939453125,
0.000003814697265625,
0.0000019073486328125,
0.00000095367431640625,
0.000000476837158203125,
0.0000002384185791015625,
0.00000011920928955078125,
0.000000059604644775390625,
0.0000000298023223876953125,
0.00000001490116119384765625,
0.000000007450580596923828125,
0.0000000037252902984619140625,
0.00000000186264514923095703125,
0.000000000931322574615478515625,
0.0000000004656612873077392578125,
0.00000000023283064365386962890625,
0.000000000116415321826934814453125,
0.0000000000582076609134674072265625,
0.00000000002910383045673370361328125,
0.000000000014551915228366851806640625,
0.0000000000072759576141834259033203125,
0.00000000000363797880709171295166015625,
0.000000000001818989403545856475830078125
};
///////////////////////////////////////////////////////////////////////////////
// symmetric quantization tables
//
const sample_t q3_tbl[3] =
{
sample_t(- 2 << MANTISSA_BITS) / 3,
0,
sample_t(+ 2 << MANTISSA_BITS) / 3
};
const sample_t q5_tbl[5] =
{
sample_t(- 4 << MANTISSA_BITS) / 5,
sample_t(- 2 << MANTISSA_BITS) / 5,
0,
sample_t(+ 2 << MANTISSA_BITS) / 5,
sample_t(+ 4 << MANTISSA_BITS) / 5
};
const sample_t q7_tbl[7] =
{
sample_t(- 6 << MANTISSA_BITS) / 7,
sample_t(- 4 << MANTISSA_BITS) / 7,
sample_t(- 2 << MANTISSA_BITS) / 7,
0,
sample_t(+ 2 << MANTISSA_BITS) / 7,
sample_t(+ 4 << MANTISSA_BITS) / 7,
sample_t(+ 6 << MANTISSA_BITS) / 7
};
const sample_t q11_tbl[11] =
{
sample_t(-10 << MANTISSA_BITS) / 11,
sample_t(- 8 << MANTISSA_BITS) / 11,
sample_t(- 6 << MANTISSA_BITS) / 11,
sample_t(- 4 << MANTISSA_BITS) / 11,
sample_t(- 2 << MANTISSA_BITS) / 11,
0,
sample_t(+ 2 << MANTISSA_BITS) / 11,
sample_t(+ 4 << MANTISSA_BITS) / 11,
sample_t(+ 6 << MANTISSA_BITS) / 11,
sample_t(+ 8 << MANTISSA_BITS) / 11,
sample_t(+10 << MANTISSA_BITS) / 11,
};
const sample_t q15_tbl[15] =
{
sample_t(-14 << MANTISSA_BITS) / 15,
sample_t(-12 << MANTISSA_BITS) / 15,
sample_t(-10 << MANTISSA_BITS) / 15,
sample_t(- 8 << MANTISSA_BITS) / 15,
sample_t(- 6 << MANTISSA_BITS) / 15,
sample_t(- 4 << MANTISSA_BITS) / 15,
sample_t(- 2 << MANTISSA_BITS) / 15,
0,
sample_t(+ 2 << MANTISSA_BITS) / 15,
sample_t(+ 4 << MANTISSA_BITS) / 15,
sample_t(+ 6 << MANTISSA_BITS) / 15,
sample_t(+ 8 << MANTISSA_BITS) / 15,
sample_t(+10 << MANTISSA_BITS) / 15,
sample_t(+12 << MANTISSA_BITS) / 15,
sample_t(+14 << MANTISSA_BITS) / 15
};
///////////////////////////////////////////////////////////////////////////////
// exponent decoding tables
//
const int8_t exp_1[128] = {
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
25,25,25
};
const int8_t exp_2[128] = {
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
25,25,25
};
const int8_t exp_3[128] = {
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
25,25,25
};
///////////////////////////////////////////////////////////////////////////////
//
// Parser class
//
///////////////////////////////////////////////////////////////////////////////
void
Parser::reset()
{
dynrng = 1.0;
dynrng2= 1.0;
clev = 1.0;
slev = 1.0;
memset(&timecode, 0, sizeof(timecode));
}
void
Parser::get_bsi(BSI &bsi)
{
const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
128, 160, 192, 224, 256, 320, 384, 448,
512, 576, 640 };
switch (fscod)
{
case 0: bsi.frame_size = 4 * rate[frmsizecod >> 1]; break;
case 1: bsi.frame_size = 2 * (320 * rate[frmsizecod >> 1] / 147 + (frmsizecod & 1)); break;
case 2: bsi.frame_size = 6 * rate[frmsizecod >> 1]; break;
}
bsi.spk = Speakers(lfeon? acmod | MODE_LFE: acmod, dsurmod == 2? DOLBY_SURROUND: NO_DOLBY);
bsi.bsid = bsid;
bsi.bitrate = bitrate;
bsi.sample_rate = sample_rate;
bsi.clev = clev;
bsi.slev = slev;
bsi.compre = compre != 0;
bsi.compr = compr; /// !!!!
bsi.compr2e = compr2e != 0;
bsi.compr2 = compr2;
bsi.dialnorm = dialnorm;
bsi.dialnorm2 = dialnorm2;
bsi.langcode = langcode != 0;
bsi.langcod = langcod;
bsi.langcod2e = langcod2e != 0;
bsi.langcod2 = langcod2;
bsi.audprodie = audprodie != 0;
bsi.mixlevel = mixlevel;
bsi.roomtyp = roomtyp;
bsi.audprodi2e = audprodi2e != 0;
bsi.mixlevel2 = mixlevel2;
bsi.roomtyp2 = roomtyp2;
bsi.copyrightb = copyrightb != 0;
bsi.origbs = origbs != 0;
memcpy(&bsi.timecode, &timecode, sizeof(timecode));
bsi.dynrnge = dynrnge;
bsi.dynrng = dynrng;
bsi.dynrng2e = dynrng2e;
bsi.dynrng2 = dynrng2;
double bin2freq = sample_rate / 512.0;
bsi.chincpl = chincpl;
bsi.cplbegf = int(cplinfo.strtmant * bin2freq);
bsi.cplendf = int(cplinfo.endmant * bin2freq);
bsi.chendf[0] = chincpl & 1? bsi.cplendf: int(chinfo[0].endmant * bin2freq);
bsi.chendf[1] = chincpl & 2? bsi.cplendf: int(chinfo[1].endmant * bin2freq);
bsi.chendf[2] = chincpl & 4? bsi.cplendf: int(chinfo[2].endmant * bin2freq);
bsi.chendf[3] = chincpl & 8? bsi.cplendf: int(chinfo[3].endmant * bin2freq);
bsi.chendf[4] = chincpl & 16? bsi.cplendf: int(chinfo[4].endmant * bin2freq);
}
int
Parser::syncinfo (uint8_t * buf)
{
const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
128, 160, 192, 224, 256, 320, 384, 448,
512, 576, 640 };
int frmsizecod, frmsize;
int half;
if ((buf[0] != 0x0b) || (buf[1] != 0x77)) // 'syncword' - syncronisation word
return 0;
if (buf[5] >= 0x60) // 'bsid' - bit stream identfication
return 0;
half = halfrate_tbl[buf[5] >> 3];
frmsizecod = buf[4] & 0x3f;
if (frmsizecod > 0x25)
return 0;
frmsize = rate [frmsizecod >> 1];
bitrate = (frmsize * 1000) >> half;
switch (buf[4] & 0xc0)
{
case 0: sample_rate = 48000 >> half;
return 4 * frmsize;
case 0x40: sample_rate = 44100 >> half;
return 2 * (320 * frmsize / 147 + (frmsizecod & 1));
case 0x80: sample_rate = 32000 >> half;
return 6 * frmsize;
default:
return 0;
}
}
int
Parser::frame(uint8_t * buf)
{
/////////////////////////////////////////////////////////////
// Parse bit stream information (BSI)
/////////////////////////////////////////////////////////////
frmsizecod = buf[4] & 0x3f; // 'frmsizecod' - frame size code
fscod = buf[4] >> 6; // 'fscod' - sample rate code
bsid = buf[5] >> 3; // 'bsid' - bitstream id
halfrate = halfrate_tbl[bsid];
acmod = buf[6] >> 5;
bitstream.set_ptr (buf + 6); // reset bitsteram pointer
acmod = bitstream.get (3); // 'acmod' - audio coding mode
if ((acmod & 1) && (acmod != 1))
clev = clev_tbl[bitstream.get(2)]; // 'clev' - center mix level
if (acmod & 4)
slev = slev_tbl[bitstream.get(2)]; // 'slev' - surround mix level
if (acmod == MODE_STEREO)
dsurmod = bitstream.get (2); // 'dsurmod' - Dolby Surround mode
else
dsurmod = 0;
lfeon = bitstream.get (1); // 'lfeon' - flag shows if it is LFE channel in stream
dialnorm = bitstream.get (5); // 'dialnorm' - dialog normalization
compre = bitstream.get (1); // 'compre' - compression gain word
if (compre)
compr = bitstream.get (8); // 'compr' - compression gain word
langcode = bitstream.get (1); // 'langcode' - language code exists
if (langcode)
langcod = bitstream.get (8); // 'langcod' - language code
audprodie = bitstream.get (1); // 'audprodie' - audio production information exists
if (audprodie)
{
mixlevel = bitstream.get(5) + 80; // 'mixlevel' - mixing level in SPL
roomtyp = bitstream.get(2); // 'roomtyp' - room type
}
if (acmod == MODE_DUAL)
{
dialnorm = bitstream.get (5); // 'dialnorm2' - dialog normalization
compre = bitstream.get (1); // 'compr2e' - compression gain word
if (compre)
compr = bitstream.get (8); // 'compr2' - compression gain word
langcode = bitstream.get (1); // 'langcod2e' - language code exists
if (langcod)
langcod = bitstream.get (8); // 'langcod2' - language code
audprodie = bitstream.get (1); // 'audprodi2e' - audio production information exists
if (audprodie)
{
mixlevel = bitstream.get(5) + 80;// 'mixlevel2' - mixing level in SPL
roomtyp = bitstream.get(2); // 'roomtyp2' - room type
}
}
copyrightb = bitstream.get(1); // 'copyrightb' - copyright bit
origbs = bitstream.get (1); // 'origbs' - original bitstream
if (bitstream.get (1)) // 'timecod1e' - timecode first half exists
{
timecode.hours = bitstream.get(5);
timecode.mins = bitstream.get(6);
timecode.secs = bitstream.get(3) << 4;
}
if (bitstream.get (1)) // 'timecod2e' - timecode second half exists
{
timecode.secs += bitstream.get(3);
timecode.frames = bitstream.get(5);
timecode.fracs = bitstream.get(6);
}
if (bitstream.get (1)) // 'addbsie' - additional bitstream information exists
{
int addbsil = bitstream.get (6); // 'addbsil' - additioanl bitstream information length
do
{
bitstream.get (8); // 'addbsi' - additional bitstream information
} while (addbsil--);
}
/////////////////////////////////////////////////////////////
// Init variables to for first block decoding
/////////////////////////////////////////////////////////////
cplinfo.deltbae = DELTA_BIT_NONE;
chinfo[0].deltbae = chinfo[1].deltbae =
chinfo[2].deltbae = chinfo[3].deltbae = chinfo[4].deltbae = DELTA_BIT_NONE;
// dynrng = 1.0;
// dynrng2 = 1.0;
return 0;
}
int
Parser::parse_block(sample_buffer_t &samples)
{
// block
int ch, bnd;
int do_bit_alloc;
int nfchans = ACMOD_NFCHANS(acmod);
/////////////////////////////////////////////////////////////
// Parse bitstream
/////////////////////////////////////////////////////////////
for (ch = 0; ch < nfchans; ch++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -