📄 ac3_enc.cpp
字号:
// todo: mdct 256/512 switch
mdct.mdct512(mant[ch][b], mdct_buf);
// compute exponents
// normalize mdct coeffitients
// we take into account the normalization
for (s = 0; s < AC3_BLOCK_SAMPLES; s++)
{
exp_norm2 = 15 - bits_left(abs(mant[ch][b][s]));
if (exp_norm2 == 15)
exp[ch][b][s] = 24;
else
{
if (exp_norm1 + exp_norm2 > 24)
{
exp[ch][b][s] = 24;
mant[ch][b][s] >>= exp_norm1 + exp_norm2 - 24;
}
else
exp[ch][b][s] = exp_norm1 + exp_norm2;
}
}
// finished with MDCT and exponents
///////////////////////////////////////////////////////////////
} // for (b = 0; b < AC3_NBLOCKS; b++)
compute_expstr(expstr[ch], exp[ch], endmant);
restrict_exp(expcod[ch], ngrps[ch], exp[ch], expstr[ch], endmant);
// normalize mdct coefs
int b1;
for (b = 0; b < AC3_NBLOCKS; b++)
{
if (expstr[ch][b] != EXP_REUSE) b1 = b;
for (s = 0; s < endmant; s++)
// note: it is possible that exp[ch][b1][s] < exp_norm[b]
// exponent may be decreased because of differential
// restricttions
if (exp[ch][b1][s] - exp_norm[b] >= 0)
mant[ch][b][s] <<= exp[ch][b1][s] - exp_norm[b];
else
mant[ch][b][s] >>= exp_norm[b] - exp[ch][b1][s];
}
} // for (ch = 0; ch < nch; ch++)
// now we have computed exponents at exp[ch][b][s]
// and mantissas at mant[ch][b][s]
// mantissas are now in normalized form
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Compute bits left for mantissas
// acmod = 0 1 2 3 4 5 6 7
static const int bsi_plus[8] = { 0, 0, 2, 2, 2, 4, 2, 4 };
int bits_left;
bits_left = 0;
bits_left += 40; // syncinfo
bits_left += 25 + bsi_plus[acmod]; // bsi
bits_left += 54; // dynrnge, cplstre, cplinu, baie,
// sdcycod, fdcycod, sgaincod,
// dbpbcod, floorcod, snroffste,
// csnroffst, deltbaie, skiple
bits_left += 31 * nfchans; // blocksw, dithflag, chexpstr
// fsnroffst, fgaincod
if (acmod == 2)
{
bits_left += 6; // rematstr
bits_left += 4; // rematflg[]
}
for (ch = 0; ch < nfchans; ch++)
for (b = 0; b < AC3_NBLOCKS; b++)
if (expstr[ch][b] != EXP_REUSE)
{
bits_left += 12; // chbwcod, exps[0], gainrng
bits_left += 7 * (ngrps[ch][b]); // exps
}
if (lfe)
{
bits_left += 13; // lfeexpstr, lfesnroffst, lfegaincod
for (b = 0; b < AC3_NBLOCKS; b++)
if (expstr[nfchans] != EXP_REUSE)
{
bits_left += 4; // lfeexps[0]
bits_left += 7 * ngrps[nfchans][b];// lfeexps
}
}
bits_left += 16; // CRC
bits_left = frame_size * 8 - bits_left;
// Finished with bits left
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Bit allocation
int sdecay = sdecay_tbl[sdcycod];
int fdecay = fdecay_tbl[fdcycod];
int sgain = sgain_tbl[sgaincod];
int dbknee = dbknee_tbl[dbpbcod];
int floor = floor_tbl[floorcod];
int fgain = fgain_tbl[fgaincod];
int fastleak = 0;
int slowlwak = 0;
const int snroffset_max = (((63 - 15) << 4) + 15) << 2;
const int snroffset_min = (((0 - 15) << 4) + 0) << 2;
int snroffset = (((csnroffst - 15) << 4) + fsnroffst) << 2;
int ba_bits;
int ba_block;
int high, low; // bisection bounds
BAP_BitCount block_bits;
ba_bits = 0;
ba_block = 0;
for (ch = 0; ch < nch; ch++)
for (b = 0; b < AC3_NBLOCKS; b++)
if (expstr[ch][b] != EXP_REUSE)
{
bit_alloc(
bap[ch][b], exp[ch][b],
DELTA_BIT_NONE, 0,
0, nmant[ch],
fscod, halfratecod,
sdecay, fdecay,
sgain, fgain,
dbknee, floor,
0, 0,
snroffset);
block_bits.reset();
block_bits.add_bap(bap[ch][b], 0, nmant[ch]);
ba_bits += block_bits.bits;
ba_block = b;
}
else
{
memcpy(bap[ch][b], bap[ch][ba_block], sizeof(bap[0][0][0]) * nmant[ch]);
ba_bits += block_bits.bits;
}
// bisection init
if (ba_bits > bits_left)
{
high = snroffset;
low = snroffset_min;
}
else
{
high = snroffset_max;
low = snroffset;
}
// bisection steps
while (high - low > 4)
{
snroffset = ((high + low) >> 1) & ~3;
ba_bits = 0;
for (ch = 0; ch < nch; ch++)
for (b = 0; b < AC3_NBLOCKS; b++)
if (expstr[ch][b] != EXP_REUSE)
{
bit_alloc(
bap[ch][b], exp[ch][b],
DELTA_BIT_NONE, 0,
0, nmant[ch],
fscod, halfratecod,
sdecay, fdecay,
sgain, fgain,
dbknee, floor,
0, 0,
snroffset);
block_bits.reset();
block_bits.add_bap(bap[ch][b], 0, nmant[ch]);
ba_bits += block_bits.bits;
ba_block = b;
}
else
{
memcpy(bap[ch][b], bap[ch][ba_block], sizeof(bap[0][0][0]) * nmant[ch]);
ba_bits += block_bits.bits;
}
if (ba_bits > bits_left)
high = snroffset;
else
low = snroffset;
}
// do bit allocation
snroffset = low & ~3; // clear 2 last bits
ba_bits = 0;
for (ch = 0; ch < nch; ch++)
for (b = 0; b < AC3_NBLOCKS; b++)
if (expstr[ch][b] != EXP_REUSE)
{
bit_alloc(
bap[ch][b], exp[ch][b],
DELTA_BIT_NONE, 0,
0, nmant[ch],
fscod, halfratecod,
sdecay, fdecay,
sgain, fgain,
dbknee, floor,
0, 0,
snroffset);
block_bits.reset();
block_bits.add_bap(bap[ch][b], 0, nmant[ch]);
ba_bits += block_bits.bits;
ba_block = b;
}
else
{
memcpy(bap[ch][b], bap[ch][ba_block], sizeof(bap[0][0][0]) * nmant[ch]);
ba_bits += block_bits.bits;
}
if (ba_bits > bits_left)
// some error happen!!!
return 0;
// snroffset = (((csnroffst - 15) << 4) + fsnroffst) << 2;
csnroffst = (snroffset >> 6) + 15;
fsnroffst = (snroffset >> 2) - ((csnroffst - 15) << 4);
// debug:
assert(((((csnroffst - 15) << 4) + fsnroffst) << 2) == snroffset);
// Finished with bit allocation
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Output everything
pb.set_ptr(frame_buf, frame_size);
///////////////////////////////////////////////////////////////////
// BSI
pb.put_bits(16, 0x0b77);// 'syncword'
pb.put_bits(16, 0); // 'crc1'
pb.put_bits(2, fscod); // 'fscod'
pb.put_bits(6, frmsizecod);
pb.put_bits(5, bsid); // 'bsid'
pb.put_bits(3, 0); // 'bsmod' = complete main audio service
pb.put_bits(3, acmod);
if (acmod & 1 && acmod != 1)
pb.put_bits(2, 0); // 'cmixlev' = -3dB
if (acmod & 4)
pb.put_bits(2, 0); // 'surmixlev' = -3dB
if (acmod == 2)
if (spk.relation)
pb.put_bits(2, 2); // 'dsurmod' = Dolby surround encoded
else
pb.put_bits(2, 0); // 'dsurmod' = surround not indicated
pb.put_bool(spk.lfe()); // 'lfeon'
pb.put_bits(5, 31); // 'dialnorm' = -31dB
pb.put_bool(false); // 'compre'
pb.put_bool(false); // 'langcode'
pb.put_bool(false); // 'audprodie'
pb.put_bool(false); // 'copyrightb'
pb.put_bool(true); // 'origbs'
pb.put_bool(false); // 'timecod1e'
pb.put_bool(false); // 'timecod2e'
pb.put_bool(false); // 'addbsie'
///////////////////////////////////////////////////////////////////
// Audio blocks
for (b = 0; b < AC3_NBLOCKS; b++)
{
for (ch = 0; ch < nfchans; ch++)
pb.put_bool(false); // 'blksw[ch]' - 512-tap mdct
for (ch = 0; ch < nfchans; ch++)
pb.put_bool(true); // 'dithflag[ch]' - use dithering
pb.put_bool(false); // 'dynrnge'
if (b == 0)
{
pb.put_bool(true); // 'cplstre'
pb.put_bool(false); // 'cplinu'
}
else
pb.put_bool(false); // 'cplstre'
if (acmod == AC3_MODE_STEREO)
if (b == 0)
{
pb.put_bool(true); // 'rematstr'
pb.put_bool(false); // 'rematflg[0]'
pb.put_bool(false); // 'rematflg[1]'
pb.put_bool(false); // 'rematflg[2]'
pb.put_bool(false); // 'rematflg[3]'
}
else
pb.put_bool(false); // 'rematstr'
for (ch = 0; ch < nfchans; ch++)
pb.put_bits(2, expstr[ch][b]); // 'chexpstr'
if (lfe)
pb.put_bits(1, expstr[nfchans][b]); // 'lfeexpstr'
for (ch = 0; ch < nfchans; ch++)
if (expstr[ch][b] != EXP_REUSE)
pb.put_bits(6, chbwcod[ch]); // 'chbwcod'
// exponents
for (ch = 0; ch < nfchans; ch++)
if (expstr[ch][b] != EXP_REUSE)
{
pb.put_bits(4, expcod[ch][b][0]); // 'exps[ch][0]'
for (s = 1; s < ngrps[ch][b]+1; s++)// note: include the last group!
pb.put_bits(7, expcod[ch][b][s]); // 'exps[ch][grp]'
pb.put_bits(2, 0); // 'gainrng[ch]'
}
if (lfe && expstr[nfchans][b] != EXP_REUSE)
{
pb.put_bits(4, expcod[nfchans][b][0]); // 'lfeexp[0]'
for (s = 1; s < ngrps[nfchans][b]+1; s++) // note: include the last group!
pb.put_bits(7, expcod[nfchans][b][s]); // 'lfeexp[grp]'
}
// bit allocation
if (b == 0)
{
pb.put_bool(true); // 'baie'
pb.put_bits(2, sdcycod); // 'sdcycod'
pb.put_bits(2, fdcycod); // 'fdcycod'
pb.put_bits(2, sgaincod); // 'sgaincod'
pb.put_bits(2, dbpbcod); // 'dbpbcod'
pb.put_bits(3, floorcod); // 'floorcod'
pb.put_bool(true); // 'snroffste'
pb.put_bits(6, csnroffst); // 'csnroffst'
for (ch = 0; ch < nch; ch++)
{
pb.put_bits(4, fsnroffst); // 'fsnroffst[ch]'/'lfesnroffst'
pb.put_bits(3, fgaincod); // 'fgaincod[ch]'/'lfegaincod'
}
}
else
{
pb.put_bool(false); // 'baie'
pb.put_bool(false); // 'snroffste'
}
pb.put_bool(false); // 'deltbaie'
pb.put_bool(false); // 'skiple'
// mantissas
#ifdef _DEBUG
int bits0 = 0;
int bits1 = 0;
int bits2 = 0;
int bits4 = 0;
#define COUNT_BITS(id, n) { bits##id += n; }
#else
#define COUNT_BITS(id, n)
#endif
int qs1 = 0; int qch1 = 0;
int qs2 = 0; int qch2 = 0;
int qs4 = 0; int qch4 = 0;
int v;
for (ch = 0; ch < nch; ch++)
for (s = 0; s < nmant[ch]; s++)
#define GROUP_NEXT(q, value, levels, mul) \
while (qch##q < nch) \
{ \
while (qs##q < nmant[qch##q] && bap[qch##q][b][qs##q] != q) qs##q++; \
if (qs##q < nmant[qch##q]) break; \
qs##q = 0; \
qch##q++; \
} \
if (qs##q < nmant[qch##q] && qch##q < nch) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -