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

📄 parser.cpp

📁 ac3的解码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <string.h>
#include "parser.h"
#include "dither.h"



const int _acmod_nfchans[8] =  { 2, 1, 2, 3, 3, 4, 4, 5 };
#define ACMOD_NFCHANS(acmod) _acmod_nfchans[(acmod)&7]

#define MANTISSA_BITS 15
#define min(a, b)  (((a) < (b)) ? (a) : (b))


#define EXP_REUSE 0
#define EXP_D15   1
#define EXP_D25   2
#define EXP_D45   3

#define DELTA_BIT_REUSE    0
#define DELTA_BIT_NEW      1
#define DELTA_BIT_NONE     2
#define DELTA_BIT_RESERVED 3



///////////////////////////////////////////////////////////////////////////////
// TABLES
///////////////////////////////////////////////////////////////////////////////

const uint8_t halfrate_tbl[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
const int rematrix_band[4] = {25, 37, 61, 253};
const sample_t clev_tbl[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
const sample_t slev_tbl[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};


///////////////////////////////////////////////////////////////////////////////
// scale factor
//
// definition:
//   scale_factor[i] = 1/2^(i+15)
//
// usage: 
//   coef = mantissa * scale_factor[exponent]
//   mantissa - integer value interpreted as fixed point value in range [-1;1]
//   exponent - negative binary exponent
//

const sample_t scale_factor[25] = 
{
  0.000030517578125,
  0.0000152587890625,
  0.00000762939453125,
  0.000003814697265625,
  0.0000019073486328125,
  0.00000095367431640625,
  0.000000476837158203125,
  0.0000002384185791015625,
  0.00000011920928955078125,
  0.000000059604644775390625,
  0.0000000298023223876953125,
  0.00000001490116119384765625,
  0.000000007450580596923828125,
  0.0000000037252902984619140625,
  0.00000000186264514923095703125,
  0.000000000931322574615478515625,
  0.0000000004656612873077392578125,
  0.00000000023283064365386962890625,
  0.000000000116415321826934814453125,
  0.0000000000582076609134674072265625,
  0.00000000002910383045673370361328125,
  0.000000000014551915228366851806640625,
  0.0000000000072759576141834259033203125,
  0.00000000000363797880709171295166015625,
  0.000000000001818989403545856475830078125
};



///////////////////////////////////////////////////////////////////////////////
// symmetric quantization tables
//

const sample_t q3_tbl[3] = 
{
  sample_t(- 2 << MANTISSA_BITS) / 3,
  0,
  sample_t(+ 2 << MANTISSA_BITS) / 3
};

const sample_t q5_tbl[5] = 
{
  sample_t(- 4 << MANTISSA_BITS) / 5,
  sample_t(- 2 << MANTISSA_BITS) / 5,
  0,
  sample_t(+ 2 << MANTISSA_BITS) / 5,
  sample_t(+ 4 << MANTISSA_BITS) / 5
};

const sample_t q7_tbl[7] = 
{
  sample_t(- 6 << MANTISSA_BITS) / 7,
  sample_t(- 4 << MANTISSA_BITS) / 7,
  sample_t(- 2 << MANTISSA_BITS) / 7,
  0,
  sample_t(+ 2 << MANTISSA_BITS) / 7,
  sample_t(+ 4 << MANTISSA_BITS) / 7,
  sample_t(+ 6 << MANTISSA_BITS) / 7
};

const sample_t q11_tbl[11] = 
{
  sample_t(-10 << MANTISSA_BITS) / 11,
  sample_t(- 8 << MANTISSA_BITS) / 11,
  sample_t(- 6 << MANTISSA_BITS) / 11,
  sample_t(- 4 << MANTISSA_BITS) / 11,
  sample_t(- 2 << MANTISSA_BITS) / 11,
  0,        
  sample_t(+ 2 << MANTISSA_BITS) / 11,
  sample_t(+ 4 << MANTISSA_BITS) / 11,
  sample_t(+ 6 << MANTISSA_BITS) / 11,
  sample_t(+ 8 << MANTISSA_BITS) / 11,
  sample_t(+10 << MANTISSA_BITS) / 11,
};

const sample_t q15_tbl[15] = 
{
  sample_t(-14 << MANTISSA_BITS) / 15,
  sample_t(-12 << MANTISSA_BITS) / 15,
  sample_t(-10 << MANTISSA_BITS) / 15,
  sample_t(- 8 << MANTISSA_BITS) / 15,
  sample_t(- 6 << MANTISSA_BITS) / 15,
  sample_t(- 4 << MANTISSA_BITS) / 15,
  sample_t(- 2 << MANTISSA_BITS) / 15,
  0,
  sample_t(+ 2 << MANTISSA_BITS) / 15,
  sample_t(+ 4 << MANTISSA_BITS) / 15,
  sample_t(+ 6 << MANTISSA_BITS) / 15,
  sample_t(+ 8 << MANTISSA_BITS) / 15,
  sample_t(+10 << MANTISSA_BITS) / 15,
  sample_t(+12 << MANTISSA_BITS) / 15,
  sample_t(+14 << MANTISSA_BITS) / 15
};


///////////////////////////////////////////////////////////////////////////////
// exponent decoding tables
// 

const int8_t exp_1[128] = {
    -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    25,25,25
};

const int8_t exp_2[128] = {
    -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
    -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
    -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
    -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
    -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
    25,25,25
};

const int8_t exp_3[128] = {
    -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
    -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
    -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
    -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
    -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
    25,25,25
};





































///////////////////////////////////////////////////////////////////////////////
//
// Parser class
//
///////////////////////////////////////////////////////////////////////////////

void 
Parser::reset()
{
  dynrng = 1.0;
  dynrng2= 1.0;
  clev = 1.0;
  slev = 1.0;
  memset(&timecode, 0, sizeof(timecode));
}


void 
Parser::get_bsi(BSI &bsi)
{
  const int rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
                       128, 160, 192, 224, 256, 320, 384, 448,
                       512, 576, 640 };

  switch (fscod) 
  {
    case 0:   bsi.frame_size = 4 * rate[frmsizecod >> 1]; break;
    case 1:   bsi.frame_size = 2 * (320 * rate[frmsizecod >> 1] / 147 + (frmsizecod & 1)); break;
    case 2:   bsi.frame_size = 6 * rate[frmsizecod >> 1]; break;
  }


  bsi.spk         = Speakers(lfeon? acmod | MODE_LFE: acmod, dsurmod == 2? DOLBY_SURROUND: NO_DOLBY);
  bsi.bsid        = bsid;
  bsi.bitrate     = bitrate;
  bsi.sample_rate = sample_rate;

  bsi.clev        = clev;
  bsi.slev        = slev;

  bsi.compre      = compre != 0;         
  bsi.compr       = compr;         /// !!!!
  bsi.compr2e     = compr2e != 0;
  bsi.compr2      = compr2;

  bsi.dialnorm    = dialnorm;
  bsi.dialnorm2   = dialnorm2;

  bsi.langcode    = langcode != 0;
  bsi.langcod     = langcod;
  bsi.langcod2e   = langcod2e != 0;
  bsi.langcod2    = langcod2;

  bsi.audprodie   = audprodie != 0;
  bsi.mixlevel    = mixlevel;
  bsi.roomtyp     = roomtyp;
                         
  bsi.audprodi2e  = audprodi2e != 0;
  bsi.mixlevel2   = mixlevel2;
  bsi.roomtyp2    = roomtyp2;
                         
  bsi.copyrightb  = copyrightb != 0;
  bsi.origbs      = origbs != 0;

  memcpy(&bsi.timecode, &timecode, sizeof(timecode));

  bsi.dynrnge     = dynrnge;  
  bsi.dynrng      = dynrng;   
  bsi.dynrng2e    = dynrng2e; 
  bsi.dynrng2     = dynrng2;  

  double bin2freq = sample_rate / 512.0;
  bsi.chincpl     = chincpl;
  bsi.cplbegf     = int(cplinfo.strtmant  * bin2freq);
  bsi.cplendf     = int(cplinfo.endmant   * bin2freq);
  bsi.chendf[0]   = chincpl & 1?  bsi.cplendf: int(chinfo[0].endmant * bin2freq);
  bsi.chendf[1]   = chincpl & 2?  bsi.cplendf: int(chinfo[1].endmant * bin2freq);
  bsi.chendf[2]   = chincpl & 4?  bsi.cplendf: int(chinfo[2].endmant * bin2freq);
  bsi.chendf[3]   = chincpl & 8?  bsi.cplendf: int(chinfo[3].endmant * bin2freq);
  bsi.chendf[4]   = chincpl & 16? bsi.cplendf: int(chinfo[4].endmant * bin2freq);
}



int       
Parser::syncinfo (uint8_t * buf)
{
  const int rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
                       128, 160, 192, 224, 256, 320, 384, 448,
                       512, 576, 640 };
  int frmsizecod, frmsize;
  int half;

  
  if ((buf[0] != 0x0b) || (buf[1] != 0x77))      // 'syncword' - syncronisation word
    return 0;
  
  if (buf[5] >= 0x60)                            // 'bsid' - bit stream identfication
    return 0;
  
  half = halfrate_tbl[buf[5] >> 3];

  frmsizecod = buf[4] & 0x3f;
  if (frmsizecod > 0x25)
    return 0;

  frmsize = rate [frmsizecod >> 1];
  bitrate = (frmsize * 1000) >> half;

  switch (buf[4] & 0xc0) 
  {
    case 0:    sample_rate = 48000 >> half;  
      return 4 * frmsize;
    case 0x40: sample_rate = 44100 >> half;  
      return 2 * (320 * frmsize / 147 + (frmsizecod & 1));
    case 0x80: sample_rate = 32000 >> half;  
      return 6 * frmsize;
    default:
      return 0;
  }
}










int 
Parser::frame(uint8_t * buf)
{
  /////////////////////////////////////////////////////////////
  // Parse bit stream information (BSI)
  /////////////////////////////////////////////////////////////

  frmsizecod = buf[4] & 0x3f;          // 'frmsizecod' - frame size code
  fscod    = buf[4] >> 6;              // 'fscod' - sample rate code
  bsid     = buf[5] >> 3;              // 'bsid' - bitstream id
  halfrate = halfrate_tbl[bsid];       
  acmod    = buf[6] >> 5;              
  
  bitstream.set_ptr (buf + 6);         // reset bitsteram pointer

  acmod = bitstream.get (3);           // 'acmod' - audio coding mode

  if ((acmod & 1) && (acmod != 1))
    clev = clev_tbl[bitstream.get(2)]; // 'clev' - center mix level

  if (acmod & 4)
    slev = slev_tbl[bitstream.get(2)]; // 'slev' - surround mix level

  if (acmod == MODE_STEREO)
    dsurmod = bitstream.get (2);       // 'dsurmod' - Dolby Surround mode
  else
    dsurmod = 0;

  lfeon     = bitstream.get (1);       // 'lfeon' - flag shows if it is LFE channel in stream
  dialnorm  = bitstream.get (5);       // 'dialnorm' - dialog normalization

  compre    = bitstream.get (1);       // 'compre' - compression gain word
  if (compre)
    compr   = bitstream.get (8);       // 'compr' - compression gain word

  langcode  = bitstream.get (1);       // 'langcode' - language code exists
  if (langcode)
    langcod = bitstream.get (8);       // 'langcod' - language code

  audprodie = bitstream.get (1);       // 'audprodie' - audio production information exists
  if (audprodie)
  {
    mixlevel = bitstream.get(5) + 80;  // 'mixlevel' - mixing level in SPL
    roomtyp  = bitstream.get(2);       // 'roomtyp' - room type
  }

  if (acmod == MODE_DUAL)
  {
    dialnorm  = bitstream.get (5);     // 'dialnorm2' - dialog normalization

    compre    = bitstream.get (1);     // 'compr2e' - compression gain word
    if (compre)
      compr   = bitstream.get (8);     // 'compr2' - compression gain word

    langcode  = bitstream.get (1);     // 'langcod2e' - language code exists
    if (langcod)
      langcod = bitstream.get (8);     // 'langcod2' - language code

    audprodie = bitstream.get (1);     // 'audprodi2e' - audio production information exists
    if (audprodie)
    {
      mixlevel = bitstream.get(5) + 80;// 'mixlevel2' - mixing level in SPL
      roomtyp  = bitstream.get(2);     // 'roomtyp2' - room type
    }
  }

  copyrightb = bitstream.get(1);       // 'copyrightb' - copyright bit
  origbs = bitstream.get (1);          // 'origbs' - original bitstream

  if (bitstream.get (1))               // 'timecod1e' - timecode first half exists
  {
    timecode.hours = bitstream.get(5);
    timecode.mins  = bitstream.get(6);
    timecode.secs  = bitstream.get(3) << 4;
  }
  if (bitstream.get (1))               // 'timecod2e' - timecode second half exists
  {
    timecode.secs  += bitstream.get(3);
    timecode.frames = bitstream.get(5);
    timecode.fracs  = bitstream.get(6);
  }
  
  if (bitstream.get (1))               // 'addbsie' - additional bitstream information exists
  {
    int addbsil = bitstream.get (6);   // 'addbsil' - additioanl bitstream information length
    do 
    {
      bitstream.get (8);               // 'addbsi' - additional bitstream information
    } while (addbsil--);
  }

  /////////////////////////////////////////////////////////////
  // Init variables to for first block decoding
  /////////////////////////////////////////////////////////////

  cplinfo.deltbae = DELTA_BIT_NONE;
  chinfo[0].deltbae = chinfo[1].deltbae = 
  chinfo[2].deltbae = chinfo[3].deltbae = chinfo[4].deltbae = DELTA_BIT_NONE;

//  dynrng = 1.0;
//  dynrng2 = 1.0;

  return 0;
}










int 
Parser::parse_block(sample_buffer_t &samples)
{
  // block 
  int ch, bnd;
  int do_bit_alloc;
  int nfchans = ACMOD_NFCHANS(acmod);

  /////////////////////////////////////////////////////////////
  // Parse bitstream
  /////////////////////////////////////////////////////////////

  for (ch = 0; ch < nfchans; ch++)

⌨️ 快捷键说明

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