📄 parser.cpp
字号:
blksw[ch] = bitstream.get (1); // 'blksw[ch]' - block switch
for (ch = 0; ch < nfchans; ch++)
dithflag[ch] = bitstream.get (1); // 'dithflag[ch]' - dither flag
if (bitstream.get(1)) // 'dynrnge' - dynamic range gain word exists
{
uint32_t dynrng_word = bitstream.get(8); // 'dynrng' - dynamic range gain word
dynrng = (((dynrng_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng_word >> 5)) & 7];
}
if (acmod == MODE_DUAL && bitstream.get(1)) // 'dynrng2e' - dynamic range gain word 2 exists
{
uint32_t dynrng2_word = bitstream.get(8); // 'dynrng2' - dynamic range gain word 2
dynrng2 = ((((dynrng2_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng2_word >> 5)) & 7]);
}
/////////////////////////////////////////////////////////////
// Coupling information
/////////////////////////////////////////////////////////////
// in: acmod nfchans
// out: chincpl ncplbnd phsflginu cplinfo.strtmant cplinfo.endmant
if (bitstream.get (1)) // 'cplstre' - coupling strategy exists
{
chincpl = 0;
if (bitstream.get (1)) // 'cplinu' - coupling in use
{
int ncplsubnd;
for (ch = 0; ch < nfchans; ch++) // 'chincpl' - channel in coupling flag for each channel
chincpl |= bitstream.get (1) << ch;
switch (acmod)
{
case MODE_DUAL:
case MODE_MONO:
// this modes are not allowed for coupling
return 1;
case MODE_STEREO:
phsflginu = bitstream.get (1); // 'phsflginu' - phase flag in use
}
int cplbegf = bitstream.get (4); // 'cplbegf' - coupling begin frequency code
int cplendf = bitstream.get (4); // 'cplendf' - coupling begin frequency code
if (cplendf + 3 - cplbegf < 0) // check if the end band is before begin
return 1;
// calc 'ncplbnd' - number of sub-bands in coupling
ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
cplinfo.strtmant = cplbegf * 12 + 37;
cplinfo.endmant = cplendf * 12 + 73;
cplbnd[0] = cplinfo.strtmant + 12;
ncplbnd = 0;
for (bnd = 0; bnd < ncplsubnd - 1; bnd++)
if (bitstream.get (1))
cplbnd[ncplbnd] += 12;
else
{
ncplbnd++;
cplbnd[ncplbnd] = cplbnd[ncplbnd-1] + 12;
}
ncplbnd++; // coupling band index to number to coupling bands
}
}
/////////////////////////////////////////////////////////////
// Coupling coordinates
/////////////////////////////////////////////////////////////
// in: acmod nfchans chincpl ncplbnd phsflginu
// out: cplco[][]
if (chincpl)
{
int cplcoe = 0; // 'cplcoe' - coupling coorinates exists
for (ch = 0; ch < nfchans; ch++)
if ((chincpl >> ch) & 1)
if (bitstream.get (1)) // 'cplcoe' - coupling coorinates exists
{
int mstrcplco; // 'mstrcplco' - master coupling coordinate
int cplcoexp; // 'cplcoexp' - coupling coordinate exponent
int cplcomant; // 'cplcomant' - coupling coordinate mantissa
cplcoe = 1;
mstrcplco = bitstream.get (2) * 3; // 'mstrcplco' - master coupling coordinate
for (bnd = 0; bnd < ncplbnd; bnd++)
{
cplcoexp = bitstream.get (4); // 'cplcoexp' - coupling coordinate exponent
cplcomant = bitstream.get (4); // 'cplcomant' - coupling coordinate mantissa
if (cplcoexp == 15)
cplcomant <<= 14;
else
cplcomant = (cplcomant | 0x10) << 13;
cplco[ch][bnd] = cplcomant * scale_factor[cplcoexp + mstrcplco];
}
}
// if 2/x mode & coupling & phase flag in use then
// read read phase flags for each band
if (acmod == MODE_STEREO && phsflginu && cplcoe)
for (bnd = 0; bnd < ncplbnd; bnd++)
if (bitstream.get (1))
cplco[1][bnd] = -cplco[ch][bnd]; // 'phsflg' - phase flag
}
/////////////////////////////////////////////////////////////
// Rematrixing
/////////////////////////////////////////////////////////////
// in: acmod chincpl cplinfo.strtmant
// out: rematflg
if (acmod == MODE_STEREO && bitstream.get(1))
{
int end;
rematflg = 0;
end = (chincpl) ? cplinfo.strtmant : 253;
bnd = 0;
do
rematflg |= bitstream.get (1) << bnd; // 'rematflg' - rematrix flag
while (rematrix_band[bnd++] < end);
}
/////////////////////////////////////////////////////////////
// Exponent decoding
/////////////////////////////////////////////////////////////
// out: do_bit_alloc chinfo.endmant cplcoef[].exp coef[][].exp lfecoef[].exp
do_bit_alloc = 0;
{
int cplexpstr = EXP_REUSE; // =?
int lfeexpstr = EXP_REUSE; // =?
int chexpstr[5];
// exponent strategy
if (chincpl)
cplexpstr = bitstream.get (2); // 'cplexpstr' - coupling exponent strategy
for (ch = 0; ch < nfchans; ch++)
chexpstr[ch] = bitstream.get (2); // 'chexpstr' - channel exponent strategy for each fbw channel
if (lfeon)
lfeexpstr = bitstream.get (1); // 'lfeexpstr' - LFE exponent strategy
// chinfo[].strtmant, chinfo[].endmant
for (ch = 0; ch < nfchans; ch++)
if (chexpstr[ch] != EXP_REUSE)
{
chinfo[ch].strtmant = 0;
if ((chincpl >> ch) & 1)
// if channel is coupled then use coupling start mantissa number
chinfo[ch].endmant = cplinfo.strtmant;
else
{
int chbwcod;
chbwcod = bitstream.get (6); // 'chbwcod' = channel bandwidth code
if (chbwcod > 60)
return 1;
chinfo[ch].endmant = chbwcod * 3 + 73;
}
}
lfeinfo.strtmant = 0;
lfeinfo.endmant = 7;
// coupling channel exponents
if (cplexpstr != EXP_REUSE)
{
do_bit_alloc = 64;
// 'ncplgrps' - number of coupling groups
int grp_size = 3 << (cplexpstr - 1);
int ncplgrps = (cplinfo.endmant - cplinfo.strtmant) / grp_size;
exp_t cplabsexp = bitstream.get (4) << 1; // 'cplabsexp' - coupling absolute exponents
if (parse_exponents (cplexpstr, ncplgrps, cplabsexp, cplinfo.exp + cplinfo.strtmant))
return 1;
}
// parse exponents for fbw channels
for (ch = 0; ch < nfchans; ch++)
if (chexpstr[ch] != EXP_REUSE)
{
do_bit_alloc |= 1 << ch;
int grp_size = 3 << (chexpstr[ch] - 1);
int nchgrps = (chinfo[ch].endmant + grp_size - 4) / grp_size;
chinfo[ch].exp[0] = bitstream.get (4); // 'exps[0]' - absolute exponent
if (parse_exponents (chexpstr[ch], nchgrps, chinfo[ch].exp[0], chinfo[ch].exp + 1))
return 1;
gainrng[ch] = bitstream.get (2); // 'gainrng' - channel gain range code
}
// parse lfe exponents
if (lfeexpstr != EXP_REUSE)
{
do_bit_alloc |= 32;
// prase 2 diffenrential exponent groups for lfe
lfeinfo.exp[0] = bitstream.get (4); // 'lfeexps[0]' - absolute exponent
if (parse_exponents (lfeexpstr, 2, lfeinfo.exp[0], lfeinfo.exp + 1))
return 1;
}
}
/////////////////////////////////////////////////////////////
// Bit allocation information
/////////////////////////////////////////////////////////////
if (bitstream.get (1)) // 'baie' - bit allication information exists
{
do_bit_alloc = -1;
bai = bitstream.get (11); // bit allocation information
// sdecay = slowdec[bitstream.get(2)]; // 'sdcycod' - slow decay code
// fdecay = fastdec[bitstream.get(2)]; // 'fdcycod' - fast decay code
// sgain = slowgain[bitstream.get(2)]; // 'sgaincod' - slow gain code
// dbknee = dbpbtab[bitstream.get(2)]; // 'dbpbcod' - Db per bit code
// floor = floortab[bitstream.get(3)]; // 'floorcod' - masking floor code
}
const int fastgain[8] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
if (bitstream.get (1)) // 'snroffste' - SNR offset exists
{
do_bit_alloc = -1;
csnroffst = bitstream.get (6); // 'csnroffst' - coarse SNR offset
if (chincpl)
{
cplinfo.fsnroffst = bitstream.get(4); // 'cplfsnroffst' - coupling fine SNR offset
cplinfo.fgain = fastgain[bitstream.get(3)];// 'cplfgaincod' - coupling fast gain code
}
for (ch = 0; ch < nfchans; ch++)
{
chinfo[ch].fsnroffst = bitstream.get(4); // 'fsnroffst' - channel fine SNR offset
chinfo[ch].fgain = fastgain[bitstream.get(3)]; // 'fgaincod' - channel fast gain code
}
if (lfeon)
{
lfeinfo.fsnroffst = bitstream.get(4); // 'lfesnroffst' - LFE channel SNR offset
lfeinfo.fgain = fastgain[bitstream.get(3)]; // 'lfegaincod' - LFE channel gain code
}
}
if ((chincpl) && (bitstream.get (1))) // 'cplleake' - coupling leak initialization exists
{
do_bit_alloc |= 64;
cplinfo.fastleak = (9 - bitstream.get(3)) << 8; // 'cplfleak' - coupling fast leak initialization
cplinfo.slowleak = (9 - bitstream.get(3)) << 8; // 'cplsleak' - coupling slow leak initialization
}
if (bitstream.get (1)) // 'deltbaie' - delta bit allication information exists
{
do_bit_alloc = -1;
if (chincpl)
cplinfo.deltbae = bitstream.get (2); // 'cpldeltbae' - couling delta bit allocation information exists
for (ch = 0; ch < nfchans; ch++)
chinfo[ch].deltbae = bitstream.get (2); // 'deltbae' - delta bit allocation exists
// parse delta bit information for coupling channels
if (chincpl && (cplinfo.deltbae == DELTA_BIT_NEW) && parse_deltba (cplinfo.deltba))
return 1;
// parse delta bit information for fbw channels
for (ch = 0; ch < nfchans; ch++)
if ((chinfo[ch].deltbae == DELTA_BIT_NEW) && parse_deltba (chinfo[ch].deltba))
return 1;
}
/////////////////////////////////////////////////////////////
// Skip information
/////////////////////////////////////////////////////////////
// 'skiple' - skip length exists
if (bitstream.get (1))
{
// 'skipl' - slkip length
ch = bitstream.get (9);
// skip
while (ch--)
bitstream.get (8);
}
/////////////////////////////////////////////////////////////
// Perform bit allocation
/////////////////////////////////////////////////////////////
if (do_bit_alloc)
{
if (is_zero_snr_offsets ())
{
memset (cplinfo.bap, 0, sizeof (cplinfo.bap));
for (ch = 0; ch < nfchans; ch++)
memset (chinfo[ch].bap, 0, sizeof (chinfo[ch].bap));
memset (lfeinfo.bap, 0, sizeof (lfeinfo.bap));
}
else
{
if (chincpl && (do_bit_alloc & 64))
bit_allocate (cplinfo);
for (ch = 0; ch < nfchans; ch++)
if (do_bit_alloc & (1 << ch))
{
chinfo[ch].strtmant = 0;
chinfo[ch].fastleak = 0;
chinfo[ch].slowleak = 0;
bit_allocate (chinfo[ch]);
}
if (lfeon && (do_bit_alloc & 32))
{
lfeinfo.strtmant = 0;
lfeinfo.fastleak = 0;
lfeinfo.slowleak = 0;
lfeinfo.deltbae = DELTA_BIT_NONE;
bit_allocate (lfeinfo);
}
}
}
/////////////////////////////////////////////////////////////
// Parse mantissas
/////////////////////////////////////////////////////////////
{
int n, endmant;
int got_cplchan = 0;
sample_t q3[2];
sample_t q5[2];
sample_t q11;
int nq3 = -1;
int nq5 = -1;
int nq11 = -1;
#define get_coef(coef, exp, bap, dithflag) \
{ \
switch (bap) \
{ \
case -1: \
if (nq3 >= 0) \
coef = q3[nq3--] * scale_factor[exp]; \
else \
{ \
int code = bitstream.get(5); \
nq3 = 1; \
q3[0] = q3_tbl[(code%9)%3]; \
q3[1] = q3_tbl[(code%9)/3]; \
coef = q3_tbl[code/9] * scale_factor[exp]; \
} \
break; \
\
case -2: \
if (nq5 >= 0) \
coef = q5[nq5--] * scale_factor[exp]; \
else \
{ \
int code = bitstream.get(7); \
nq5 = 1; \
q5[0] = q5_tbl[(code%25)%5]; \
q5[1] = q5_tbl[(code%25)/5]; \
coef = q5_tbl[code/25] * scale_factor[exp]; \
} \
break; \
\
\
case 3: \
coef = q7_tbl[bitstream.get(3)] * scale_factor[exp]; \
break; \
\
case -3: \
if (nq11 >= 0) \
{ \
nq11--; \
coef = q11 * scale_factor[exp]; \
} \
else \
{ \
int code = bitstream.get(7); \
nq11 = 0; \
q11 = q11_tbl[code%11]; \
coef = q11_tbl[code/11] * scale_factor[exp]; \
} \
break; \
\
case 4: \
coef = q15_tbl[bitstream.get(4)] * scale_factor[exp]; \
break; \
\
case 0: \
if (dithflag) \
coef = dither_gen() * LEVEL_3DB * scale_factor[exp]; \
else \
coef = 0; \
break; \
\
default: \
coef = (bitstream.get_signed(bap) << (16 - bap)) * scale_factor[exp]; \
break; \
} \
}
for (ch = 0; ch < nfchans; ch++)
{
sample_t *coef = samples[ch] + chinfo[ch].strtmant;
for (n = chinfo[ch].strtmant; n < chinfo[ch].endmant; n++)
get_coef(samples[ch][n], chinfo[ch].exp[n], chinfo[ch].bap[n], dithflag[ch]);
if ((chincpl >> ch) & 1)
{
if (!got_cplchan)
{
got_cplchan = 1;
int cplch;
sample_t coef;
n = cplinfo.strtmant;
for (bnd = 0; bnd < ncplbnd; bnd++)
for (; n < cplbnd[bnd]; n++)
if (cplinfo.bap[n])
{
get_coef(coef, cplinfo.exp[n], cplinfo.bap[n], 0);
for (cplch = 0; cplch < nfchans; cplch++)
if ((chincpl >> cplch ) & 1)
samples[cplch][n] = coef * cplco[cplch][bnd];
}
else
{
for (cplch = 0; cplch < nfchans; cplch++)
if ((chincpl >> cplch ) & 1)
if (dithflag[cplch])
samples[cplch][n] = dither_gen() * cplco[cplch][bnd] * LEVEL_3DB * scale_factor[cplinfo.exp[n]];
else
samples[cplch][n] = 0.0;
}
}
endmant = cplinfo.endmant;
}
else
endmant = chinfo[ch].endmant;
do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -