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

📄 parser.cpp

📁 ac3的解码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    blksw[ch] = bitstream.get (1);               // 'blksw[ch]' - block switch

  for (ch = 0; ch < nfchans; ch++)
    dithflag[ch] = bitstream.get (1);            // 'dithflag[ch]' - dither flag

  if (bitstream.get(1))                          // 'dynrnge' - dynamic range gain word exists
  {
    uint32_t dynrng_word = bitstream.get(8);     // 'dynrng' - dynamic range gain word
    dynrng = (((dynrng_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng_word >> 5)) & 7];
  }                                               

  if (acmod == MODE_DUAL && bitstream.get(1))    // 'dynrng2e' - dynamic range gain word 2 exists
  {
    uint32_t dynrng2_word = bitstream.get(8);    // 'dynrng2' - dynamic range gain word 2
    dynrng2 = ((((dynrng2_word & 0x1f) | 0x20) << 13) * scale_factor[(3 - (dynrng2_word >> 5)) & 7]);
  }

  /////////////////////////////////////////////////////////////
  // Coupling information
  /////////////////////////////////////////////////////////////
  
  // in:  acmod nfchans
  // out: chincpl ncplbnd phsflginu cplinfo.strtmant cplinfo.endmant

  if (bitstream.get (1))                         // 'cplstre' - coupling strategy exists
  {
    chincpl = 0;
    if (bitstream.get (1))                       // 'cplinu' - coupling in use
    {
      int ncplsubnd;

      for (ch = 0; ch < nfchans; ch++)           // 'chincpl' - channel in coupling flag for each channel
        chincpl |= bitstream.get (1) << ch; 

      switch (acmod)
      {
        case MODE_DUAL: 
        case MODE_MONO:
          // this modes are not allowed for coupling
          return 1;

        case MODE_STEREO:          
          phsflginu = bitstream.get (1);         // 'phsflginu' - phase flag in use
      }

      int cplbegf = bitstream.get (4);           // 'cplbegf' - coupling begin frequency code
      int cplendf = bitstream.get (4);           // 'cplendf' - coupling begin frequency code
      if (cplendf + 3 - cplbegf < 0)             // check if the end band is before begin
        return 1;

      // calc 'ncplbnd' - number of sub-bands in coupling
      ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
      cplinfo.strtmant = cplbegf * 12 + 37;
      cplinfo.endmant  = cplendf * 12 + 73;

      cplbnd[0] = cplinfo.strtmant + 12;
      ncplbnd = 0;
      for (bnd = 0; bnd < ncplsubnd - 1; bnd++)
        if (bitstream.get (1)) 
          cplbnd[ncplbnd] += 12;
        else
        {
          ncplbnd++;
          cplbnd[ncplbnd] = cplbnd[ncplbnd-1] + 12;
        }
      ncplbnd++;   // coupling band index to number to coupling bands

    }
  }

  /////////////////////////////////////////////////////////////
  // Coupling coordinates
  /////////////////////////////////////////////////////////////
  
  // in:  acmod nfchans chincpl ncplbnd phsflginu
  // out: cplco[][]

  if (chincpl) 
  {             
    int cplcoe = 0;                              // 'cplcoe' - coupling coorinates exists

    for (ch = 0; ch < nfchans; ch++)
      if ((chincpl >> ch) & 1)        
        if (bitstream.get (1))                   // 'cplcoe' - coupling coorinates exists
        {
          int mstrcplco;                         // 'mstrcplco' - master coupling coordinate
          int cplcoexp;                          // 'cplcoexp' - coupling coordinate exponent
          int cplcomant;                         // 'cplcomant' - coupling coordinate mantissa

          cplcoe = 1;          
          mstrcplco = bitstream.get (2) * 3;     // 'mstrcplco' - master coupling coordinate

          for (bnd = 0; bnd < ncplbnd; bnd++) 
          {            
            cplcoexp = bitstream.get (4);        // 'cplcoexp' - coupling coordinate exponent            
            cplcomant = bitstream.get (4);       // 'cplcomant' - coupling coordinate mantissa

            if (cplcoexp == 15)
              cplcomant <<= 14;
            else
              cplcomant = (cplcomant | 0x10) << 13;

            cplco[ch][bnd] = cplcomant * scale_factor[cplcoexp + mstrcplco];
          }
        }

    // if 2/x mode & coupling & phase flag in use then
    // read read phase flags for each band
    if (acmod == MODE_STEREO && phsflginu && cplcoe)
      for (bnd = 0; bnd < ncplbnd; bnd++)
        if (bitstream.get (1))
          cplco[1][bnd] = -cplco[ch][bnd];       // 'phsflg' - phase flag
  }

  /////////////////////////////////////////////////////////////
  // Rematrixing
  /////////////////////////////////////////////////////////////

  // in:  acmod chincpl cplinfo.strtmant
  // out: rematflg

  if (acmod == MODE_STEREO && bitstream.get(1)) 
  {
    int end;

    rematflg = 0;

    end = (chincpl) ? cplinfo.strtmant : 253;  
    bnd = 0;
    do      
      rematflg |= bitstream.get (1) << bnd;       // 'rematflg' - rematrix flag
    while (rematrix_band[bnd++] < end);
  }

  /////////////////////////////////////////////////////////////
  // Exponent decoding
  /////////////////////////////////////////////////////////////

  // out: do_bit_alloc chinfo.endmant cplcoef[].exp coef[][].exp lfecoef[].exp

  do_bit_alloc = 0;

  {
    int cplexpstr = EXP_REUSE; // =?
    int lfeexpstr = EXP_REUSE; // =?
    int chexpstr[5];

    // exponent strategy

    if (chincpl) 
      cplexpstr = bitstream.get (2);             // 'cplexpstr' - coupling exponent strategy

    for (ch = 0; ch < nfchans; ch++)
      chexpstr[ch] = bitstream.get (2);          // 'chexpstr' - channel exponent strategy for each fbw channel

    if (lfeon) 
      lfeexpstr = bitstream.get (1);             // 'lfeexpstr' - LFE exponent strategy

    // chinfo[].strtmant, chinfo[].endmant

    for (ch = 0; ch < nfchans; ch++)
      if (chexpstr[ch] != EXP_REUSE) 
      {
        chinfo[ch].strtmant = 0;
        if ((chincpl >> ch) & 1)
          // if channel is coupled then use coupling start mantissa number
          chinfo[ch].endmant = cplinfo.strtmant;
        else 
        {
          int chbwcod;
          chbwcod = bitstream.get (6);           // 'chbwcod' = channel bandwidth code
          if (chbwcod > 60)
            return 1;
          chinfo[ch].endmant = chbwcod * 3 + 73;
        }
      }
    lfeinfo.strtmant = 0;
    lfeinfo.endmant = 7;


    // coupling channel exponents

    if (cplexpstr != EXP_REUSE) 
    {
      do_bit_alloc = 64;

      // 'ncplgrps' - number of coupling groups
      int grp_size = 3 << (cplexpstr - 1);
      int ncplgrps = (cplinfo.endmant - cplinfo.strtmant) / grp_size;
      exp_t cplabsexp = bitstream.get (4) << 1;  // 'cplabsexp' - coupling absolute exponents
      if (parse_exponents (cplexpstr, ncplgrps, cplabsexp, cplinfo.exp + cplinfo.strtmant))
        return 1;
    }

    // parse exponents for fbw channels

    for (ch = 0; ch < nfchans; ch++)
      if (chexpstr[ch] != EXP_REUSE) 
      {
        do_bit_alloc |= 1 << ch;

        int grp_size = 3 << (chexpstr[ch] - 1);
        int nchgrps = (chinfo[ch].endmant + grp_size - 4) / grp_size;
        chinfo[ch].exp[0] = bitstream.get (4);   // 'exps[0]' - absolute exponent
        if (parse_exponents (chexpstr[ch], nchgrps, chinfo[ch].exp[0], chinfo[ch].exp + 1))
          return 1;
      
        gainrng[ch] = bitstream.get (2);         // 'gainrng'  - channel gain range code
      }

    // parse lfe exponents

    if (lfeexpstr != EXP_REUSE) 
    {
      do_bit_alloc |= 32;
    
      // prase 2 diffenrential exponent groups for lfe
      lfeinfo.exp[0] = bitstream.get (4);        // 'lfeexps[0]' - absolute exponent
      if (parse_exponents (lfeexpstr, 2, lfeinfo.exp[0], lfeinfo.exp + 1))
        return 1;
    }
  }

  /////////////////////////////////////////////////////////////
  // Bit allocation information
  /////////////////////////////////////////////////////////////
  
  if (bitstream.get (1))                         // 'baie' - bit allication information exists
  {
    do_bit_alloc = -1;
    
    bai = bitstream.get (11);                    // bit allocation information
//    sdecay = slowdec[bitstream.get(2)];          // 'sdcycod' - slow decay code
//    fdecay = fastdec[bitstream.get(2)];          // 'fdcycod' - fast decay code
//    sgain  = slowgain[bitstream.get(2)];         // 'sgaincod' - slow gain code
//    dbknee = dbpbtab[bitstream.get(2)];          // 'dbpbcod' - Db per bit code
//    floor  = floortab[bitstream.get(3)];         // 'floorcod' - masking floor code
  }

  const int fastgain[8] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
  if (bitstream.get (1))                         // 'snroffste' - SNR offset exists
  {
    do_bit_alloc = -1;
    
    csnroffst = bitstream.get (6);               // 'csnroffst' - coarse SNR offset
    if (chincpl)
    {
      cplinfo.fsnroffst = bitstream.get(4);      // 'cplfsnroffst' - coupling fine SNR offset
      cplinfo.fgain = fastgain[bitstream.get(3)];// 'cplfgaincod' - coupling fast gain code
    }

    for (ch = 0; ch < nfchans; ch++)
    {      
      chinfo[ch].fsnroffst = bitstream.get(4);        // 'fsnroffst' - channel fine SNR offset
      chinfo[ch].fgain = fastgain[bitstream.get(3)];  // 'fgaincod' - channel fast gain code
    }

    if (lfeon)
    {      
      lfeinfo.fsnroffst = bitstream.get(4);           // 'lfesnroffst' - LFE channel SNR offset
      lfeinfo.fgain = fastgain[bitstream.get(3)];     // 'lfegaincod' - LFE channel gain code
    }
  }

  
  if ((chincpl) && (bitstream.get (1)))               // 'cplleake' - coupling leak initialization exists
  {
    do_bit_alloc |= 64;
    cplinfo.fastleak = (9 - bitstream.get(3)) << 8;   // 'cplfleak' - coupling fast leak initialization
    cplinfo.slowleak = (9 - bitstream.get(3)) << 8;   // 'cplsleak' - coupling slow leak initialization
  } 
  
  if (bitstream.get (1))                         // 'deltbaie' - delta bit allication information exists
  {
    do_bit_alloc = -1;

    if (chincpl)
      cplinfo.deltbae = bitstream.get (2);       // 'cpldeltbae' - couling delta bit allocation information exists

    for (ch = 0; ch < nfchans; ch++)
      chinfo[ch].deltbae = bitstream.get (2);    // 'deltbae' - delta bit allocation exists

    // parse delta bit information for coupling channels
    if (chincpl && (cplinfo.deltbae == DELTA_BIT_NEW) && parse_deltba (cplinfo.deltba))
      return 1;

    // parse delta bit information for fbw channels
    for (ch = 0; ch < nfchans; ch++)
      if ((chinfo[ch].deltbae == DELTA_BIT_NEW) && parse_deltba (chinfo[ch].deltba))
        return 1;
  }

  /////////////////////////////////////////////////////////////
  // Skip information
  /////////////////////////////////////////////////////////////
  
  // 'skiple' - skip length exists
  if (bitstream.get (1)) 
  {
    // 'skipl' - slkip length
    ch = bitstream.get (9);
    // skip
    while (ch--)
      bitstream.get (8);
  }

  /////////////////////////////////////////////////////////////
  // Perform bit allocation
  /////////////////////////////////////////////////////////////

  if (do_bit_alloc) 
  {
    if (is_zero_snr_offsets ())
    {
      memset (cplinfo.bap, 0, sizeof (cplinfo.bap));

      for (ch = 0; ch < nfchans; ch++)
        memset (chinfo[ch].bap, 0, sizeof (chinfo[ch].bap));

      memset (lfeinfo.bap, 0, sizeof (lfeinfo.bap));
    } 
    else 
    {
      if (chincpl && (do_bit_alloc & 64))
        bit_allocate (cplinfo);

      for (ch = 0; ch < nfchans; ch++)
        if (do_bit_alloc & (1 << ch))
        {
          chinfo[ch].strtmant = 0;
          chinfo[ch].fastleak = 0;
          chinfo[ch].slowleak = 0;
          bit_allocate (chinfo[ch]);
        }

      if (lfeon && (do_bit_alloc & 32)) 
      {
        lfeinfo.strtmant = 0;
        lfeinfo.fastleak = 0;
        lfeinfo.slowleak = 0;
        lfeinfo.deltbae = DELTA_BIT_NONE;
        bit_allocate (lfeinfo);
      }
    }
  }

  /////////////////////////////////////////////////////////////
  // Parse mantissas
  /////////////////////////////////////////////////////////////

  {
    int n, endmant;
    int got_cplchan = 0;

    sample_t q3[2];
    sample_t q5[2];
    sample_t q11;
    int      nq3  = -1;
    int      nq5  = -1;
    int      nq11 = -1;

    #define get_coef(coef, exp, bap, dithflag)                   \
    {                                                            \
      switch (bap)                                               \
      {                                                          \
        case -1:                                                 \
          if (nq3 >= 0)                                          \
            coef = q3[nq3--] * scale_factor[exp];                \
          else                                                   \
          {                                                      \
            int code = bitstream.get(5);                         \
            nq3 = 1;                                             \
            q3[0] = q3_tbl[(code%9)%3];                          \
            q3[1] = q3_tbl[(code%9)/3];                          \
            coef = q3_tbl[code/9] * scale_factor[exp];           \
          }                                                      \
          break;                                                 \
                                                                 \
        case -2:                                                 \
          if (nq5 >= 0)                                          \
            coef = q5[nq5--] * scale_factor[exp];                \
          else                                                   \
          {                                                      \
            int code = bitstream.get(7);                         \
            nq5 = 1;                                             \
            q5[0] = q5_tbl[(code%25)%5];                         \
            q5[1] = q5_tbl[(code%25)/5];                         \
            coef = q5_tbl[code/25] * scale_factor[exp];          \
          }                                                      \
          break;                                                 \
                                                                 \
                                                                 \
        case 3:                                                  \
          coef = q7_tbl[bitstream.get(3)] * scale_factor[exp];   \
          break;                                                 \
                                                                 \
        case -3:                                                 \
          if (nq11 >= 0)                                         \
          {                                                      \
            nq11--;                                              \
            coef = q11 * scale_factor[exp];                      \
          }                                                      \
          else                                                   \
          {                                                      \
            int code = bitstream.get(7);                         \
            nq11 = 0;                                            \
            q11 = q11_tbl[code%11];                              \
            coef = q11_tbl[code/11] * scale_factor[exp];         \
          }                                                      \
          break;                                                 \
                                                                 \
        case 4:                                                  \
          coef = q15_tbl[bitstream.get(4)] * scale_factor[exp];  \
          break;                                                 \
                                                                 \
        case 0:                                                  \
          if (dithflag)                                          \
            coef = dither_gen() * LEVEL_3DB * scale_factor[exp]; \
          else                                                   \
            coef = 0;                                            \
          break;                                                 \
                                                                 \
        default:                                                 \
          coef = (bitstream.get_signed(bap) << (16 - bap)) * scale_factor[exp];  \
          break;                                                 \
      }                                                          \
    }

    for (ch = 0; ch < nfchans; ch++)
    {
      sample_t *coef = samples[ch] + chinfo[ch].strtmant;
      for (n = chinfo[ch].strtmant; n < chinfo[ch].endmant; n++)    
        get_coef(samples[ch][n], chinfo[ch].exp[n], chinfo[ch].bap[n], dithflag[ch]);

      if ((chincpl >> ch) & 1)
      {
        if (!got_cplchan)
        {
          got_cplchan = 1;

          int cplch;
          sample_t coef;

          n = cplinfo.strtmant;
          for (bnd = 0; bnd < ncplbnd; bnd++)
            for (; n < cplbnd[bnd]; n++)
              if (cplinfo.bap[n])
              {
                get_coef(coef, cplinfo.exp[n], cplinfo.bap[n], 0);
                for (cplch = 0; cplch < nfchans; cplch++)
                  if ((chincpl >> cplch ) &  1)
                    samples[cplch][n] = coef * cplco[cplch][bnd];
              }
              else
              {
                for (cplch = 0; cplch < nfchans; cplch++)
                  if ((chincpl >> cplch ) &  1)
                    if (dithflag[cplch])
                      samples[cplch][n] = dither_gen() * cplco[cplch][bnd] * LEVEL_3DB * scale_factor[cplinfo.exp[n]];
                    else
                      samples[cplch][n] = 0.0;
              }
        }
        endmant = cplinfo.endmant;
      }
      else
        endmant = chinfo[ch].endmant;

      do

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -