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

📄 ac3_enc.cpp

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