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

📄 dts_parser.cpp

📁 ac3的解码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <math.h>
#include <stdio.h>
#include "dts_parser.h"
#include "dts_header.h"

#include "dts_tables.h"
#include "dts_tables_huffman.h"
#include "dts_tables_quantization.h"
#include "dts_tables_adpcm.h"
#include "dts_tables_fir.h"
#include "dts_tables_vq.h"

#define DTS_MODE_MONO           0
#define DTS_MODE_CHANNEL        1
#define DTS_MODE_STEREO         2
#define DTS_MODE_STEREO_SUMDIFF 3
#define DTS_MODE_STEREO_TOTAL   4
#define DTS_MODE_3F             5
#define DTS_MODE_2F1R           6
#define DTS_MODE_3F1R           7
#define DTS_MODE_2F2R           8
#define DTS_MODE_3F2R           9

static const int dts_order[NCHANNELS] = { CH_C, CH_L, CH_R, CH_SL, CH_SR, CH_LFE };

static const int amode2mask_tbl[] = 
{
  MODE_MONO, 
  MODE_STEREO,
  MODE_STEREO,
  MODE_STEREO,
  MODE_STEREO,
  MODE_3_0,
  MODE_2_1,
  MODE_3_1,
  MODE_2_2,
  MODE_3_2
};

static const int amode2rel_tbl[] = 
{
  NO_RELATION,
  NO_RELATION,
  NO_RELATION,
  RELATION_SUMDIFF,
  RELATION_DOLBY,
  NO_RELATION,
  NO_RELATION,
  NO_RELATION,
  NO_RELATION,
  NO_RELATION,
};

inline int 
decode_blockcode(int code, int levels, int *values)
{ 
  int i;
  int offset = (levels - 1) >> 1;
  
  for (i = 0; i < 4; i++)
  {
    values[i] = (code % levels) - offset;
    code /= levels;
  }
  
  if (code == 0)
    return 1;
  else
  {
    fprintf (stderr, "ERROR: block code look-up failed\n");
    return 0;
  }
}







///////////////////////////////////////////////////////////////////////////////
// DTSParser
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Init

DTSParser::DTSParser()
{
  init_cosmod();
  samples.allocate(DTS_NCHANNELS, DTS_MAX_SAMPLES);
  reset();
}

void 
DTSParser::init_cosmod()
{
  int i, j, k;
  
  for (j=0,k=0;k<16;k++)
    for (i=0;i<16;i++)
      cos_mod[j++] = cos((2*i+1)*(2*k+1)*M_PI/64);
    
  for (k=0;k<16;k++)
    for (i=0;i<16;i++)
      cos_mod[j++] = cos((i)*(2*k+1)*M_PI/32);
      
  for (k=0;k<16;k++)
    cos_mod[j++] = 0.25/(2*cos((2*k+1)*M_PI/128));
  
  for (k=0;k<16;k++)
    cos_mod[j++] = -0.25/(2.0*sin((2*k+1)*M_PI/128));
}

///////////////////////////////////////////////////////////////////////////////
// FrameParser overrides

const HeaderParser *
DTSParser::header_parser() const
{
  return &dts_header;
}


void 
DTSParser::reset()
{
  spk = spk_unknown;
  frame_size = 0;
  nsamples = 0;

  frame_type      = 0;
  samples_deficit = 0;
  crc_present     = 0;
  sample_blocks   = 0;
  amode           = 0;
  sample_rate     = 0;
  bit_rate        = 0;

  memset(subband_samples_hist, 0, sizeof(subband_samples_hist));
  memset(subband_fir_hist, 0, sizeof(subband_fir_hist));
  memset(subband_fir_noidea, 0, sizeof(subband_fir_noidea));
  memset(lfe_data, 0, sizeof(lfe_data));
}

bool
DTSParser::parse_frame(uint8_t *frame, size_t size)
{
  HeaderInfo hinfo;

  if (!dts_header.parse_header(frame, &hinfo))
    return false;

  if (hinfo.frame_size > size)
    return false;

  spk = hinfo.spk;
  spk.format = FORMAT_LINEAR;
  frame_size = hinfo.frame_size;
  nsamples = hinfo.nsamples;
  bs_type = hinfo.bs_type;

  bs.set_ptr(frame, bs_type);
  if (!parse_frame_header())
    return false;

  // 8 samples per subsubframe and per subband
  for (int i = 0; i < sample_blocks / 8; i++) 
  {
    // Sanity check
    if (current_subframe >= subframes)
      return false;
  
    // Read subframe header
    if (!current_subsubframe)
      if (!parse_subframe_header())
        return false;
  
    // Read subsubframe
    if (!parse_subsubframe()) 
      return false;
  
    // Update state
    current_subsubframe++;
    if (current_subsubframe >= subsubframes)
    {
      current_subsubframe = 0;
      current_subframe++;
    }

    // Read subframe footer
    if (current_subframe >= subframes)
      if (!parse_subframe_footer()) 
        return false;
  }

  return true;
}

size_t
DTSParser::stream_info(char *buf, size_t size) const
{
  char info[1024];

  char *stream = "???";
  switch (bs_type)
  {
    case BITSTREAM_16BE: stream = "16bit BE"; break;
    case BITSTREAM_16LE: stream = "16bit LE"; break;
    case BITSTREAM_14BE: stream = "14bit BE"; break;
    case BITSTREAM_14LE: stream = "14bit LE"; break;
  }

  size_t len = sprintf(info,
    "DTS\n"
    "speakers:  %s\n"
    "sample rate: %iHz\n"
    "bitrate: %ikbps\n"
    "stream: %s\n"
    "frame size: %i bytes\n"
    "nsamples: %i\n"
    "amode: %i\n"
    "%s"
    "\0",
    spk.mode_text(),
    spk.sample_rate,
    dts_bit_rates[bit_rate] / 1000,
    stream, 
    frame_size,
    nsamples,
    amode,
    crc_present? "CRC protected\n": "No CRC"
    );

  if (len + 1 > size) len = size - 1;
  memcpy(buf, info, len + 1);
  buf[len] = 0;
  return len;
}

size_t
DTSParser::frame_info(char *buf, size_t size) const 
{
  if (buf && size) buf[0] = 0;
  return 0;
}

///////////////////////////////////////////////////////////////////////////////
//                         FRAME HEADER
///////////////////////////////////////////////////////////////////////////////



bool 
DTSParser::parse_frame_header()
{
  int i, j;
  static const float adj_table[] = { 1.0, 1.1250, 1.2500, 1.4375 };

  /////////////////////////////////////////////////////////
  // Skip sync

  bs.get(32);

  /////////////////////////////////////////////////////////
  // Frame header

  frame_type        = bs.get(1);
  samples_deficit   = bs.get(5)  + 1;
  crc_present       = bs.get(1);
  sample_blocks     = bs.get(7)  + 1;
  frame_size        = bs.get(14) + 1;
  amode             = bs.get(6);
  sample_rate       = bs.get(4);
  bit_rate          = bs.get(5);

  downmix           = bs.get(1);
  dynrange          = bs.get(1);
  timestamp         = bs.get(1);
  aux_data          = bs.get(1);
  hdcd              = bs.get(1);
  ext_descr         = bs.get(3);
  ext_coding        = bs.get(1);
  aspf              = bs.get(1);
  lfe               = bs.get(2);
  predictor_history = bs.get(1);

  if (crc_present) 
  {
    // todo: check CRC
    header_crc = bs.get(16);
  }

  multirate_inter   = bs.get(1);
  version           = bs.get(4);
  copy_history      = bs.get(2);
  source_pcm_res    = bs.get(3);
  front_sum         = bs.get(1);
  surround_sum      = bs.get(1);
  dialog_norm       = bs.get(4);

  /////////////////////////////////////////////////////////
  // Primary audio coding header

  subframes         = bs.get(4) + 1;
  prim_channels     = bs.get(3) + 1;

  for (i = 0; i < prim_channels; i++)
  {
    subband_activity[i] = bs.get(5) + 2;
    if (subband_activity[i] > DTS_SUBBANDS)
      subband_activity[i] = DTS_SUBBANDS;
  }

  for (i = 0; i < prim_channels; i++)
  {
    vq_start_subband[i] = bs.get(5) + 1;
    if (vq_start_subband[i] > DTS_SUBBANDS)
      vq_start_subband[i] = DTS_SUBBANDS;
  }

  for (i = 0; i < prim_channels; i++)
    joint_intensity[i] = bs.get(3);

  for (i = 0; i < prim_channels; i++)
    transient_huffman[i] = bs.get(2);

  for (i = 0; i < prim_channels; i++)
    scalefactor_huffman[i] = bs.get(3);

  for (i = 0; i < prim_channels; i++)
  {
    bitalloc_huffman[i] = bs.get(3);
    // if (bitalloc_huffman[i] == 7) bailout
  }

  // Get codebooks quantization indexes
  for (i = 0; i < prim_channels; i++)
  {
    quant_index_huffman[i][0] = 0; // Not transmitted
    quant_index_huffman[i][1] = bs.get(1);
  }

  for (j = 2; j < 6; j++)
    for (i = 0; i < prim_channels; i++)
      quant_index_huffman[i][j] = bs.get(2);

  for (j = 6; j < 11; j++)
    for (i = 0; i < prim_channels; i++)
      quant_index_huffman[i][j] = bs.get(3);

  for (j = 11; j < 27; j++)
    for (i = 0; i < prim_channels; i++)
      quant_index_huffman[i][j] = 0; // Not transmitted

  // Get scale factor adjustment
  for (j = 0; j < 11; j++)
    for (i = 0; i < prim_channels; i++)
      scalefactor_adj[i][j] = 1;

  for (i = 0; i < prim_channels; i++)
    if (quant_index_huffman[i][1] == 0)
      scalefactor_adj[i][1] = adj_table[bs.get(2)];

  for (j = 2; j < 6; j++)
    for (i = 0; i < prim_channels; i++)
      if (quant_index_huffman[i][j] < 3)
        scalefactor_adj[i][j] = adj_table[bs.get(2)];

  for (j = 6; j < 11; j++)
    for (i = 0; i < prim_channels; i++)
      if (quant_index_huffman[i][j] < 7)
        scalefactor_adj[i][j] = adj_table[bs.get(2)];

  if (crc_present)
  {
    // todo: audio header CRC check
    bs.get(16);
  }

  /////////////////////////////////////////////////////////
  // Some initializations

⌨️ 快捷键说明

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