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

📄 ac3_parser.cpp

📁 ac3的解码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    int skipl = bs.get(9);
    while (skipl--)
      bs.get(8);
  }

  /////////////////////////////////////////////////////////
  // Do bit allocation
  /////////////////////////////////////////////////////////

  if (bitalloc)
  {
    bool got_cplchan = false;
    BAP_BitCount counter;

    for (ch = 0; ch < nfchans; ch++)
    {
      if (bitalloc & (1 << ch))
      {
        bit_alloc(
          bap[ch], exps[ch],
          deltbae[ch], deltba[ch],
          0, endmant[ch], 
          fscod, halfrate, 
          sdecay, fdecay, 
          sgain, fgain[ch], 
          dbknee, floor, 
          0, 0, 
          snroffset[ch]);

        counter.add_bap(bap[ch], 0, endmant[ch]);
      }

      if (cplinu && !got_cplchan && (bitalloc & (1 << 6)))
      {
        got_cplchan = true;
        bit_alloc(
          cplbap, cplexps, 
          cpldeltbae, cpldeltba,
          cplstrtmant, cplendmant, 
          fscod, halfrate, 
          sdecay, fdecay, 
          sgain, cplfgain, 
          dbknee, floor, 
          cplfleak, cplsleak, 
          cplsnroffset);

        counter.add_bap(cplbap, cplstrtmant, cplendmant);
      }
    }

    if (lfeon && bitalloc & (1 << 5))
    {
      bit_alloc(
        lfebap, lfeexps,
        DELTA_BIT_NONE, 0,
        0, 7, 
        fscod, halfrate, 
        sdecay, fdecay, 
        sgain, lfefgain, 
        dbknee, floor, 
        0, 0, 
        lfesnroffset);

      counter.add_bap(lfebap, 0, 7);
    }

    if (bs.get_pos() + counter.bits > frame_size * 8)
      return false;
  }

  return true;
}

bool
AC3Parser::parse_exponents(int8_t *exps, int8_t absexp, int expstr, int nexpgrps)
{
  int expgrp;

  switch (expstr)
  {
  case EXP_D15:
    while (nexpgrps--)
    {
      expgrp = bs.get(7);

      absexp += exp1_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;

      absexp += exp2_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;

      absexp += exp3_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
    }
    break;

  case EXP_D25:
    while (nexpgrps--)
    {
      expgrp = bs.get(7);

      absexp += exp1_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;

      absexp += exp2_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;

      absexp += exp3_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;
    }
    break;

  case EXP_D45:
    while (nexpgrps--)
    {
      expgrp = bs.get(7);
      if (expgrp >= 125) 
        return false;

      absexp += exp1_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;

      absexp += exp2_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;

      absexp += exp3_tbl[expgrp];
      if (absexp > 24) return false;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;
      *(exps++) = absexp;
    }
    break;
  }

  return true;
}

bool
AC3Parser::parse_deltba(int8_t *deltba)
{
  int deltnseg, deltlen, delta, band;

  memset(deltba, 0, 50);

  deltnseg = bs.get(3) + 1;                   // 'cpldeltnseg'/'deltnseg'' - coupling/channel delta bit allocation number of segments
  band = 0;
  while (deltnseg--)
  {
    band += bs.get(5);                        // 'cpldeltoffst'/'deltoffst' - coupling/channel delta bit allocation offset
    deltlen = bs.get(4);                      // 'cpldeltlen'/'deltlen' - coupling/channel delta bit allocation length
    delta = bs.get(3);                        // 'cpldeltba'/'deltba' - coupling/channel delta bit allocation

    if (delta >= 4)
      delta = (delta - 3) << 7;
    else
      delta = (delta - 4) << 7;

    if (band + deltlen >= 50)
      return false;

    while (deltlen--)
      deltba[band++] = delta;
  }

  return true;
}

void 
AC3Parser::parse_coeff(samples_t samples)
{
  int ch, bnd, s;
  Quantizer q;

  int nfchans = nfchans_tbl[acmod];
  bool got_cplchan = false;

  /////////////////////////////////////////////////////////////
  // Get coeffs

  for (ch = 0; ch < nfchans; ch++)
  {
    // parse channel mantissas
    q.get_coeff(bs, samples[ch], bap[ch], exps[ch], endmant[ch], dithflag[ch]);

    if (chincpl[ch] && !got_cplchan)
    {
      // parse coupling channel mantissas
      got_cplchan = true;
      q.get_coeff(bs, samples[ch] + cplstrtmant, cplbap + cplstrtmant, cplexps + cplstrtmant, cplendmant - cplstrtmant, false);

      // copy coupling coeffs to all coupled channels
      for (int ch2 = ch + 1; ch2 < nfchans; ch2++)
        if (chincpl[ch2])
          memcpy(samples[ch2] + cplstrtmant, samples[ch] + cplstrtmant, (cplendmant - cplstrtmant) * sizeof(sample_t));
    }
  }

  if (lfeon)
  {
    q.get_coeff(bs, samples[nfchans], lfebap, lfeexps, 7, false);
    memset(samples[nfchans] + 7, 0, 249 * sizeof(sample_t));
  }

  // Dither
  for (ch = 0; ch < nfchans; ch++)
    if (chincpl[ch] && dithflag[ch])
      for (s = cplstrtmant; s < cplendmant; s++)
        if (!cplbap[s])
          samples[ch][s] = dither_gen() * scale_factor[cplexps[s]];

  // Apply coupling coordinates
  for (ch = 0; ch < nfchans; ch++)
    if (chincpl[ch])
    {
      s = cplstrtmant;
      for (bnd = 0; bnd < ncplbnd; bnd++)
        while (s < cplbnd[bnd])
          samples[ch][s++] *= cplco[ch][bnd];
    }

  // Clear tails
  for (ch = 0; ch < nfchans; ch++)
    if (chincpl[ch])
      memset(samples[ch] + cplendmant, 0, (256 - cplendmant) * sizeof(sample_t));
    else
      memset(samples[ch] + endmant[ch], 0, (256 - endmant[ch]) * sizeof(sample_t));

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

  if (acmod == AC3_MODE_STEREO) 
  {
    int bin = 13;
    int bnd = 0;
    int band_end = 0;
    int last_bin = MIN(endmant[0], endmant[1]);
    int remat = rematflg;
    do
    {
      if (!(remat & 1))
      {
        remat >>= 1;
        bin = rematrix_tbl[bnd++];
        continue;
      }
      remat >>= 1;
      band_end = rematrix_tbl[bnd++];

      if (band_end > last_bin)
        band_end = last_bin;

      do 
      {
        sample_t tmp0 = samples[0][bin];
        sample_t tmp1 = samples[1][bin];
        samples[0][bin] = tmp0 + tmp1;
        samples[1][bin] = tmp0 - tmp1;
      } while (++bin < band_end);
    } while (bin < last_bin);
  }
}

void 
Quantizer::get_coeff(ReadBS &bs, sample_t *s, int8_t *bap, int8_t *exp, int n, bool dither)
{
  int ibap;
  while (n--)
  {
    ibap = *bap++;
    switch (ibap)
    {
      case 0:
        if (dither)
          *s++ = dither_gen() * scale_factor[*exp++];
        else
        {
          *s++ = 0;
          exp++;
        }
        break;

      case 1: 
        // 3-levels 3 values in 5 bits
        if (q3_cnt--)
          *s++ = q3[q3_cnt] * scale_factor[*exp++];
        else
        {
          int code = bs.get(5);
          q3[0] = q3_3_tbl[code];
          q3[1] = q3_2_tbl[code];
          q3_cnt = 2;
          *s++ = q3_1_tbl[code] * scale_factor[*exp++];
        }
        break;

      case 2:  
        // 5-levels 3 values in 7 bits
        if (q5_cnt--)
          *s++ = q5[q5_cnt] * scale_factor[*exp++];
        else
        {
          int code = bs.get(7);
          q5[0] = q5_3_tbl[code];
          q5[1] = q5_2_tbl[code];
          q5_cnt = 2;
          *s++ = q5_1_tbl[code] * scale_factor[*exp++];
        }
        break;

      case 3:
        *s++ = q7_tbl[bs.get(3)] * scale_factor[*exp++];
        break;

      case 4:
        // 11-levels 2 values in 7 bits
        if (q11_cnt--)
          *s++ = q11 * scale_factor[*exp++];
        else
        {
          int code = bs.get(7);
          q11 = q11_2_tbl[code];
          q11_cnt = 1;
          *s++ = q11_1_tbl[code] * scale_factor[*exp++];
        }
        break;

      case 5:
        *s++ = q15_tbl[bs.get(4)] * scale_factor[*exp++];
        break;

      case 14:       
        *s++ = (bs.get_signed(14) << 2) * scale_factor[*exp++];
        break;

      case 15: 
        *s++ = bs.get_signed(16) * scale_factor[*exp++];
        break;

      default: 
        *s++ = (bs.get_signed(ibap - 1) << (16 - (ibap - 1))) * scale_factor[*exp++];
        break;
    }
  }
}

⌨️ 快捷键说明

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