⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ac3_enc.cpp

📁 ac3的解码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
          {                                                              \
            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 + -