📄 ac3_enc.cpp
字号:
{ \
value += mul * sym_quant(mant[qch##q][b][qs##q], levels); \
qs##q++; \
}
switch (bap[ch][b][s])
{
case 0: break;
case 1:
// 5 bits 3 groups 3 q-levels
if ((qch1 > ch) || (qch1 == ch && qs1 > s)) break;
v = 9 * sym_quant(mant[ch][b][s], 3);
// seek for next value to group
// we start seeking from current position
qch1 = ch;
qs1 = s + 1;
while (qch1 < nch)
{
while (qs1 < nmant[qch1] && bap[qch1][b][qs1] != 1) qs1++;
if (qs1 < nmant[qch1]) break; // found
qs1 = 0;
qch1++;
}
// group value if found
if (qs1 < nmant[qch1] && qch1 < nch)
{
v += 3 * sym_quant(mant[qch1][b][qs1], 3);
qs1++;
}
// seek for next value to group
GROUP_NEXT(1, v, 3, 1)
pb.put_bits(5, v);
COUNT_BITS(1, 5);
break;
case 2:
// 7 bits 3 groups 5 q-levels
if ((qch2 > ch) || (qch2 == ch && qs2 > s)) break;
// note: ch >= qch2 && s >= qs2;
v = 25 * sym_quant(mant[ch][b][s], 5);
qch2 = ch;
qs2 = s + 1;
GROUP_NEXT(2, v, 5, 5);
GROUP_NEXT(2, v, 5, 1);
pb.put_bits(7, v);
COUNT_BITS(2, 7);
break;
case 3:
pb.put_bits(3, sym_quant(mant[ch][b][s], 7));
COUNT_BITS(0, 3);
break;
case 4:
// 7 bits 2 groups 11 q-levels
if ((qch4 > ch) || (qch4 == ch && qs4 > s)) break;
v = 11 * sym_quant(mant[ch][b][s], 11);
qch4 = ch;
qs4 = s + 1;
GROUP_NEXT(4, v, 11, 1);
pb.put_bits(7, v);
COUNT_BITS(4, 7);
break;
case 5:
pb.put_bits(4, sym_quant(mant[ch][b][s], 15));
COUNT_BITS(0, 4);
break;
case 14:
pb.put_bits(14, asym_quant(mant[ch][b][s], 14));
COUNT_BITS(0, 14);
break;
case 15:
pb.put_bits(16, asym_quant(mant[ch][b][s], 16));
COUNT_BITS(0, 16);
break;
default:
pb.put_bits(bap[ch][b][s] - 1, asym_quant(mant[ch][b][s], bap[ch][b][s] - 1));
COUNT_BITS(0, bap[ch][b][s] - 1);
break;
} // switch (bap[s])
// for (s = 0; s < nmant[ch]; s++)
// for (ch = 0; ch < nch; ch++)
} // for (b = 0; b < AC3_NBLOCKS; b++)
pb.flush();
memset(pb.get_ptr(), 0, frame_size - (pb.get_ptr() - pb.get_buf()));
// calc CRC
int frame_size1 = ((frame_size >> 1) + (frame_size >> 3)) & ~1; // should be even
int crc = calc_crc(0, frame_buf + 4, frame_size1 - 4);
int crc_inv = pow_poly((CRC16_POLY >> 1), (frame_size1 * 8) - 16, CRC16_POLY);
crc = mul_poly(crc_inv, crc, CRC16_POLY);
frame_buf[2] = crc >> 8;
frame_buf[3] = crc & 0xff;
crc = calc_crc(0, frame_buf + frame_size1, frame_size - frame_size1 - 2);
frame_buf[frame_size - 2] = crc >> 8;
frame_buf[frame_size - 1] = crc & 0xff;
frames++;
return frame_size;
}
inline void
AC3Enc::compute_expstr(int expstr[AC3_NBLOCKS], int8_t exp[AC3_NBLOCKS][AC3_BLOCK_SAMPLES], int endmant) const
{
int b, b1, s;
int exp_diff;
// compute variation of exponents over time and reuse
// old exponents if variation is too small
expstr[0] = EXP_D15;
for (b = 1; b < AC3_NBLOCKS; b++)
{
exp_diff = 0;
for (s = 0; s < endmant; s++)
exp_diff += abs(exp[b][s] - exp[b-1][s]);
if (exp_diff > EXP_DIFF_THRESHOLD)
expstr[b] = EXP_D15;
else
expstr[b] = EXP_REUSE;
}
// LFE always uses EXP_D15
if (endmant == 7) return;
// deicde exponent strategy based on now many blocks
// the new exponent set is used for
// todo: compute exponent strategy based on frequency variation
b = 0;
while (b < AC3_NBLOCKS)
{
b1 = b + 1;
while (b1 < AC3_NBLOCKS && expstr[b1] == EXP_REUSE)
b1++;
switch(b1 - b)
{
case 1:
expstr[b] = EXP_D45;
break;
case 2:
case 3:
expstr[b] = EXP_D25;
break;
default:
expstr[b] = EXP_D15;
break;
}
b = b1;
}
}
inline void
AC3Enc::restrict_exp(int8_t expcod[AC3_NBLOCKS][AC3_BLOCK_SAMPLES], int ngrps[AC3_NBLOCKS], int8_t exp[AC3_NBLOCKS][AC3_BLOCK_SAMPLES], int expstr[AC3_NBLOCKS], int endmant) const
{
int s, b, b1;
b = 0;
while (b < AC3_NBLOCKS)
{
// Find minimum of reused exponents
for (b1 = b + 1; b1 < AC3_NBLOCKS && expstr[b1] == EXP_REUSE; b1++)
for (s = 0; s < endmant; s++)
if (exp[b][s] > exp[b1][s])
exp[b][s] = exp[b1][s];
// compute encoded exponents
// and update exponents as decoder will see them
ngrps[b] = encode_exp(expcod[b], exp[b], expstr[b], endmant);
// copy reused exponents
// optimize: we may not do this
for (b1 = b + 1; b1 < AC3_NBLOCKS && expstr[b1] == EXP_REUSE; b1++)
{
ngrps[b1] = 0;
memcpy(exp[b1], exp[b], sizeof(exp[b]));
}
b = b1;
}
}
inline int
AC3Enc::encode_exp(int8_t expcod[AC3_BLOCK_SAMPLES], int8_t exp[AC3_BLOCK_SAMPLES], int expstr, int endmant) const
{
// Encodes exponents to differential form and applies AC3 restrictions.
// Encodes exponents into grouped form
// Decodes encoded exponens back to normal form for bit allocation unit.
// Returns number of exponent groups (without DC exponent)
int s, s1;
int ngrps;
int surplus;
int8_t e;
// find minimum in each group
expcod[0] = min(exp[0], 15); // limit DC exponent
switch (expstr)
{
case EXP_D15:
for (s = 1; s < endmant; s++)
expcod[s] = exp[s];
ngrps = s;
break;
case EXP_D25:
for (s = 1, s1 = 1; s < endmant; s += 2, s1++)
expcod[s1] = min(exp[s], exp[s+1]);
ngrps = s1;
break;
case EXP_D45:
for (s = 1, s1 = 1; s < endmant; s += 4, s1++)
expcod[s1] = min(min(exp[s+0], exp[s+1]),
min(exp[s+2], exp[s+3]));
ngrps = s1;
break;
default: assert(false); // we should never be here;
}
// encode differential exponents
// and convert it to exponent codes
for (s = ngrps-1; s > 0; s--)
expcod[s] -= expcod[s-1] - 2;
expcod[ngrps] = 2;
expcod[ngrps+1] = 2;
// appliy differential restrictions [-2; +2] (or, [0; 4] in codes)
// note: we cannot increase absolute exponent values!
// propagate positive surplus forward
// (do not modify DC component, we cannot increase it)
surplus = 0;
for (s = 1; s < ngrps; s++)
{
e = expcod[s] += surplus;
if (e > 4)
{
expcod[s] = 4;
surplus = e - 4;
}
else
surplus = 0;
}
// propagate negative surplus backward
// (we may need to decrease DC component)
surplus = 0;
for (s = ngrps-1; s >= 0; s--)
{
e = expcod[s] += surplus;
if (e < 0)
{
expcod[s] = 0;
surplus = e;
}
else
surplus = 0;
}
// decode encoded exponents back to fine-grained scale
e = exp[0] = expcod[0];
switch (expstr)
{
case EXP_D15:
for (s = 1; s < endmant; s++)
{
assert(exp[s] >= e + expcod[s] - 2);
exp[s] =
e += expcod[s] - 2;
}
break;
case EXP_D25:
for (s = 1, s1 = 1; s < endmant; s += 2, s1++)
{
assert(exp[s+0] >= e + expcod[s1] - 2);
assert(exp[s+1] >= e + expcod[s1] - 2);
exp[s+1] = exp[s] =
e += expcod[s1] - 2;
}
break;
case EXP_D45:
for (s = 1, s1 = 1; s < endmant; s += 4, s1++)
{
assert(exp[s+0] >= e + expcod[s1] - 2);
assert(exp[s+1] >= e + expcod[s1] - 2);
assert(exp[s+2] >= e + expcod[s1] - 2);
assert(exp[s+3] >= e + expcod[s1] - 2);
exp[s+3] = exp[s+2] = exp[s+1] = exp[s] =
e += expcod[s1] - 2;
}
break;
default: assert(false); // we should never be here;
}
// exponent grouping
for (s = 1, s1 = 1; s < ngrps; s += 3, s1++)
expcod[s1] = expcod[s] * 25 + expcod[s+1] * 5 + expcod[s+2];
// withoout DC exponent
return s1 - 1;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Math utils
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _M_IX86
inline int bits_left(int32_t v)
{
__asm {
mov ecx, v
shl ecx, 1
or ecx, 1
bsr eax, ecx
mov v, eax
}
return v;
}
#else
inline int bits_left(int32_t v)
{
int n = 0;
if (v & 0xffff0000) { v >>= 16; n += 16; }
if (v & 0xff00) { v >>= 8; n += 8; }
if (v & 0xf0) { v >>= 4; n += 4; }
if (v & 0xc) { v >>= 2; n += 2; }
if (v & 0x2) { n += 2; }
else
if (v & 0x1) { n++; }
return n;
}
#endif
inline unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly)
{
unsigned int c;
c = 0;
while (a)
{
if (a & 1)
c ^= b;
a = a >> 1;
b = b << 1;
if (b & (1 << 16))
b ^= poly;
}
return c;
}
inline unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly)
{
unsigned int r;
r = 1;
while (n)
{
if (n & 1)
r = mul_poly(r, a, poly);
a = mul_poly(a, a, poly);
n >>= 1;
}
return r;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -