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

📄 ac3_parser.cpp

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