📄 ac3_parser.cpp
字号:
deltbae[2] = DELTA_BIT_NONE;
deltbae[3] = DELTA_BIT_NONE;
deltbae[4] = DELTA_BIT_NONE;
return true;
}
bool
AC3Parser::decode_block()
{
samples_t d = delay;
samples_t s = samples;
s += (block * AC3_BLOCK_SAMPLES);
if (block >= AC3_NBLOCKS || !parse_block())
{
block = AC3_NBLOCKS; // prevent further decoding
return false;
}
parse_coeff(s);
if (do_imdct)
{
int nfchans = spk.lfe()? spk.nch() - 1: spk.nch();
for (int ch = 0; ch < nfchans; ch++)
if (blksw[ch])
imdct.imdct_256(s[ch], delay[ch]);
else
imdct.imdct_512(s[ch], delay[ch]);
if (spk.lfe())
imdct.imdct_512(s[nfchans], d[nfchans]);
}
block++;
return true;
}
bool
AC3Parser::parse_block()
{
int nfchans = nfchans_tbl[acmod];
int ch, bnd;
///////////////////////////////////////////////
// bit allocation bitarray; bits are:
// 0-4 = do bit allocation for fbw channels
// 5 = do bit allocation for lfe channel
// 6 = do bit allocation for coupling channel
int bitalloc = 0;
for (ch = 0; ch < nfchans; ch++)
blksw[ch] = bs.get_bool(); // 'blksw[ch]' - block switch flag
for (ch = 0; ch < nfchans; ch++)
dithflag[ch] = bs.get_bool(); // 'dithflag[ch]' - dither flag
// reset dithering info
// if we do not want to dither
if (!do_dither)
for (ch = 0; ch < nfchans; ch++)
dithflag[ch] = 0;
if (bs.get_bool()) // 'dynrnge' - dynamic range gain word exists
{
int32_t dynrng_word = bs.get_signed(8); // 'dynrng' - dynamic range gain word
dynrng = (((dynrng_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng_word >> 5)) & 7];
}
if (acmod == AC3_MODE_DUAL)
if (bs.get_bool()) // 'dynrng2e' - dynamic range gain word 2 exists
{
int32_t dynrng_word = bs.get_signed(8); // 'dynrng2' - dynamic range gain word 2
dynrng2 = (((dynrng_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng_word >> 5)) & 7];
}
/////////////////////////////////////////////////////////
// Coupling strategy information
/////////////////////////////////////////////////////////
if (bs.get_bool()) // 'cplstre' - coupling strategy exists
{
cplinu = bs.get_bool(); // 'cplinu' - coupling in use
if (cplinu)
{
if (acmod == AC3_MODE_MONO || acmod == AC3_MODE_DUAL)
return false; // this modes are not allowed for coupling
// constraint p...
for (ch = 0; ch < nfchans; ch++)
chincpl[ch] = bs.get_bool(); // 'chincpl[ch]' - channel in coupliing
if (acmod == AC3_MODE_STEREO)
phsflginu = bs.get_bool(); // 'phsflginu' - phase flags in use
int cplbegf = bs.get(4); // 'cplbegf' - coupling begin frequency code
int cplendf = bs.get(4); // 'cplendf' - coupling end frequency code
int ncplsubnd = cplendf - cplbegf + 3;
if (ncplsubnd < 0)
return false; // constraint p...
cplstrtmant = cplbegf * 12 + 37;
cplendmant = cplendf * 12 + 73;
ncplbnd = 0;
cplbnd[0] = cplstrtmant + 12;
for (bnd = 0; bnd < ncplsubnd - 1; bnd++)
if (bs.get_bool()) // 'cplbndstrc[bnd]' - coupling band structure
cplbnd[ncplbnd] += 12;
else
{
ncplbnd++;
cplbnd[ncplbnd] = cplbnd[ncplbnd - 1] + 12;
}
ncplbnd++; // coupling band index to number to coupling bands
}
else
{
chincpl[0] = false;
chincpl[1] = false;
chincpl[2] = false;
chincpl[3] = false;
chincpl[4] = false;
}
}
else // if (bs.get_bool()) // 'cplstre' - coupling strategy exists
if (!block) // cplstre <> 0 for block 0 (constraint p39 s5.4.3.7)
return false;
/////////////////////////////////////////////////////////
// Coupling coordinates
// todo: constraint p.41 s5.4.3.14
/////////////////////////////////////////////////////////
if (cplinu)
{
bool cplcoe = false;
int mstrcplco;
int cplcoexp;
int cplcomant;
for (ch = 0; ch < nfchans; ch++)
if (chincpl[ch])
if (bs.get_bool()) // 'cplcoe[ch]' coupling coordinates exists
{
cplcoe = true;
mstrcplco = bs.get(2) * 3; // 'mstrcplco' - master coupling coordinate
for (bnd = 0; bnd < ncplbnd; bnd++)
{
cplcoexp = bs.get(4); // 'cplcoexp' - coupling coordinate exponent
cplcomant = bs.get(4); // 'cplcomant' - coupling coordinate mantissa
if (cplcoexp == 15)
cplcomant <<= 14;
else
cplcomant = (cplcomant | 0x10) << 13;
cplco[ch][bnd] = cplcomant * scale_factor[cplcoexp + mstrcplco];
} // for (int bnd = 0; bnd < ncplbnd; bnd++)
} // if (bs.get_bool()) // 'cplcoe[ch]' coupling coordinates exists
if (acmod == AC3_MODE_STEREO && phsflginu && cplcoe)
for (bnd = 0; bnd < ncplbnd; bnd++)
if (bs.get_bool()) // 'phsflg' - phase flag
cplco[1][bnd] = -cplco[1][bnd];
}
/////////////////////////////////////////////////////////
// Rematrixing
/////////////////////////////////////////////////////////
if (acmod == AC3_MODE_STEREO)
if (bs.get_bool()) // 'rematstr' - rematrixing strategy
{
bnd = 0;
rematflg = 0;
int endbin = cplinu? cplstrtmant: 253;
do
rematflg |= bs.get(1) << bnd; // rematflg[bnd] - rematrix flag
while (rematrix_tbl[bnd++] < endbin);
}
/*
This check is disabled because some buggy encoder exists that
breaks this rule.
else if (block == 0) // rematstr <> 0 for block 0 (constraint p41 s5.4.3.19)
return false;
*/
/////////////////////////////////////////////////////////
// Exponents
/////////////////////////////////////////////////////////
int cplexpstr;
int chexpstr[5];
int lfeexpstr;
if (cplinu)
{
cplexpstr = bs.get(2); // 'cplexpstr' coupling exponent strategy
if (cplexpstr == EXP_REUSE && block == 0) // cplexpstr <> reuse in block 0 (constraint p42 s5.4.3.21)
return false;
}
for (ch = 0; ch < nfchans; ch++)
{
chexpstr[ch] = bs.get(2); // 'chexpstr[ch]' - channel exponent strategy
if (chexpstr[ch] == EXP_REUSE && block == 0) // chexpstr[ch] <> reuse in block 0 (constraint p42 s5.4.3.22)
return false;
}
if (lfeon)
{
lfeexpstr = bs.get(1); // 'lfeexpstr' - LFE exponent strategy
if (lfeexpstr == EXP_REUSE && block == 0) // lfeexpstr <> reuse in block 0 (constraint p42 s5.4.3.23)
return false;
}
for (ch = 0; ch < nfchans; ch++)
if (chexpstr[ch] != EXP_REUSE)
if (chincpl[ch])
endmant[ch] = cplstrtmant;
else
{
int chbwcod = bs.get(6); // 'chbwcod[ch]' - channel bandwidth code
if (chbwcod > 60)
return false; // chbwcod[ch] <= 60 (constraint p42 s5.4.3.24)
endmant[ch] = chbwcod * 3 + 73;
}
if (cplinu && cplexpstr != EXP_REUSE)
{
bitalloc |= 1 << 6; // do bit allocation for coupling channel
int ncplgrps = (cplendmant - cplstrtmant) / (3 << (cplexpstr - 1));
int8_t cplabsexp = bs.get(4) << 1;
if (!parse_exponents(cplexps + cplstrtmant, cplabsexp, cplexpstr, ncplgrps))
return false;
}
for (ch = 0; ch < nfchans; ch++)
if (chexpstr[ch] != EXP_REUSE)
{
bitalloc |= 1 << ch; // do bit allocation for channel ch
int nexpgrps;
switch (chexpstr[ch])
{
case EXP_D15: nexpgrps = (endmant[ch] - 1) / 3; break;
case EXP_D25: nexpgrps = (endmant[ch] - 1 + 3) / 6; break;
case EXP_D45: nexpgrps = (endmant[ch] - 1 + 9) / 12; break;
}
exps[ch][0] = bs.get(4);
if (!parse_exponents(exps[ch] + 1, exps[ch][0], chexpstr[ch], nexpgrps))
return false;
gainrng[ch] = bs.get(2); // 'gainrng[ch]' - gain range code
}
if (lfeon && lfeexpstr != EXP_REUSE)
{
bitalloc |= 1 << 5; // do bit allocation for lfe channel
lfeexps[0] = bs.get(4);
if (!parse_exponents(lfeexps + 1, lfeexps[0], lfeexpstr, 2))
return false;
}
/////////////////////////////////////////////////////////
// Bit allocation parametric information
/////////////////////////////////////////////////////////
if (bs.get_bool()) // 'baie' - bit allocation information exists
{
bitalloc |= -1; // do all bit allocation
sdecay = sdecay_tbl[bs.get(2)]; // 'sdcycod' - slow decay code
fdecay = fdecay_tbl[bs.get(2)]; // 'fdcycod' - fast decay code
sgain = sgain_tbl[bs.get(2)]; // 'sgaincod' - slow gain code
dbknee = dbknee_tbl[bs.get(2)]; // 'dbpbcod' - dB per bit code
floor = floor_tbl[bs.get(3)]; // 'floorcod' - masking floor code
}
else // if (bs.get_bool()) // 'baie' - bit allocation information exists
if (block == 0) // baie <> 0 in block 0 (constraint p43 s5.4.3.30)
return false;
if (bs.get_bool()) // 'snroffste' - SNR offset exists
{
bitalloc |= -1; // do all bit allocation
int csnroffst = bs.get(6); // 'csnroffst' - coarse SNR offset
if (cplinu)
{
int cplfsnroffst = bs.get(4); // 'cplfsnroffst' - coupling fine SNR offset
cplsnroffset = (((csnroffst - 15) << 4) + cplfsnroffst) << 2;
cplfgain = fgain_tbl[bs.get(3)]; // 'cplfgaincod' - coupling fast gain code
}
for (ch = 0; ch < nfchans; ch++)
{
int fsnroffst = bs.get(4); // 'fsnroffst' - channel fine SNR offset
snroffset[ch] = (((csnroffst - 15) << 4) + fsnroffst) << 2;
fgain[ch] = fgain_tbl[bs.get(3)]; // 'fgaincod' - channel fast gain code
}
if (lfeon)
{
int lfefsnroffst = bs.get(4); // 'lfesnroffst' - LFE channel SNR offset
lfesnroffset = (((csnroffst - 15) << 4) + lfefsnroffst) << 2;
lfefgain = fgain_tbl[bs.get(3)]; // 'lfegaincod' - LFE channel gain code
}
}
else // if (bs.get_bool()) // 'snroffste' - SNR offset exists
if (block == 0) // snroffte <> 0 in block 0 (constraint p44 s5.4.3.36)
return false;
if (cplinu)
if (bs.get_bool()) // 'cplleake' - coupling leak initalization exists
{
bitalloc |= 1 << 6; // do bit allocations for coupling channel
cplfleak = (bs.get(3) << 8) + 768; // 'cplfleak' - coupling fast leak initialization
cplsleak = (bs.get(3) << 8) + 768; // 'cplsleak' - coupling slow leak initialization
}
else // if (bs.get_bool()) // 'cplleake' - coupling leak initalization exists
if (block == 0) // cplleake <> 0 in block 0 (constraint p44 s5.4.3.44)
return false;
/////////////////////////////////////////////////////////
// Delta bit allocation information
/////////////////////////////////////////////////////////
if (bs.get_bool()) // 'deltbaie' - delta bit information exists
{
bitalloc |= -1; // do all bit allocation?
if (cplinu)
{
cpldeltbae = bs.get(2); // 'cpldeltbae' - coupling delta bit allocation exists
if (cpldeltbae == DELTA_BIT_REUSE && block == 0)
return false; // cpldeltbae <> 0 in block 0 (constraint p45 s5.4.3.48)
}
for (ch = 0; ch < nfchans; ch++)
{
deltbae[ch] = bs.get(2); // 'deltbae[ch]' - delta bit allocation exists
if (deltbae == DELTA_BIT_REUSE && block == 0)
return false; // deltbae[ch] <> 0 in block 0 (constraint p45 s5.4.3.49)
}
if (cplinu && cpldeltbae == DELTA_BIT_NEW)
if (!parse_deltba(cpldeltba))
return false;
for (ch = 0; ch < nfchans; ch++)
if (deltbae[ch] == DELTA_BIT_NEW)
if (!parse_deltba(deltba[ch]))
return false;
}
/////////////////////////////////////////////////////////
// Skip data
/////////////////////////////////////////////////////////
if (bs.get_bool())
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -