📄 parse.c
字号:
/*
* parse.c
* Copyright (C) 2004 Gildas Bazin <gbazin@videolan.org>
*
* This file is part of dtsdec, a free DTS Coherent Acoustics stream decoder.
* See http://www.videolan.org/dtsdec.html for updates.
*
* dtsdec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* dtsdec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795029
#endif
#include "dts.h"
#include "dts_internal.h"
#include "bitstream.h"
#include "tables.h"
#include "tables_huffman.h"
#include "tables_quantization.h"
#include "tables_adpcm.h"
#include "tables_fir.h"
#include "tables_vq.h"
#include "../../compiler.h"
/* #define DEBUG */
#if defined(HAVE_MEMALIGN) && !defined(__cplusplus)
/* some systems have memalign() but no declaration for it */
void * memalign (size_t align, size_t size);
#else
/* assume malloc alignment is sufficient */
#define memalign(align,size) malloc (size)
#endif
static int decode_blockcode (int code, int levels, int *values);
static void qmf_32_subbands (dts_state_t * state, int chans,
double samples_in[32][8], sample_t *samples_out,
double rScale, sample_t bias);
static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
double *samples_in, sample_t *samples_out,
double rScale, sample_t bias );
static void pre_calc_cosmod( dts_state_t * state );
dts_state_t * dts_init (uint32_t mm_accel)
{
dts_state_t * state;
int i;
(void)mm_accel;
state = (dts_state_t *) malloc (sizeof (dts_state_t));
if (state == NULL)
return NULL;
memset (state, 0, sizeof(dts_state_t));
state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t));
if (state->samples == NULL) {
free (state);
return NULL;
}
for (i = 0; i < 256 * 12; i++)
state->samples[i] = 0;
/* Pre-calculate cosine modulation coefficients */
pre_calc_cosmod( state );
state->downmixed = 1;
return state;
}
sample_t * dts_samples (dts_state_t * state)
{
return state->samples;
}
int dts_blocks_num (dts_state_t * state)
{
/* 8 samples per subsubframe and per subband */
return state->sample_blocks / 8;
}
static int syncinfo (dts_state_t * state, int * flags,
int * sample_rate, int * bit_rate, int * frame_length)
{
int frame_size;
/* Sync code */
bitstream_get (state, 32);
/* Frame type */
bitstream_get (state, 1);
/* Samples deficit */
bitstream_get (state, 5);
/* CRC present */
bitstream_get (state, 1);
*frame_length = (bitstream_get (state, 7) + 1) * 32;
frame_size = bitstream_get (state, 14) + 1;
if (!state->word_mode) frame_size = frame_size * 8 / 14 * 2;
/* Audio channel arrangement */
*flags = bitstream_get (state, 6);
if (*flags > 63)
return 0;
*sample_rate = bitstream_get (state, 4);
if ((size_t)*sample_rate >= sizeof (dts_sample_rates) / sizeof (int))
return 0;
*sample_rate = dts_sample_rates[ *sample_rate ];
if (!*sample_rate) return 0;
*bit_rate = bitstream_get (state, 5);
if ((size_t)*bit_rate >= sizeof (dts_bit_rates) / sizeof (int))
return 0;
*bit_rate = dts_bit_rates[ *bit_rate ];
if (!*bit_rate) return 0;
/* LFE */
bitstream_get (state, 10);
if (bitstream_get (state, 2)) *flags |= DTS_LFE;
return frame_size;
}
int dts_syncinfo (dts_state_t * state, uint8_t * buf, int * flags,
int * sample_rate, int * bit_rate, int * frame_length)
{
/*
* Look for sync code
*/
/* 14 bits and little endian bitstream */
if (buf[0] == 0xff && buf[1] == 0x1f &&
buf[2] == 0x00 && buf[3] == 0xe8 &&
(buf[4] & 0xf0) == 0xf0 && buf[5] == 0x07)
{
int frame_size;
dts_bitstream_init (state, buf, 0, 0);
frame_size = syncinfo (state, flags, sample_rate,
bit_rate, frame_length);
return frame_size;
}
/* 14 bits and big endian bitstream */
if (buf[0] == 0x1f && buf[1] == 0xff &&
buf[2] == 0xe8 && buf[3] == 0x00 &&
buf[4] == 0x07 && (buf[5] & 0xf0) == 0xf0)
{
int frame_size;
dts_bitstream_init (state, buf, 0, 1);
frame_size = syncinfo (state, flags, sample_rate,
bit_rate, frame_length);
return frame_size;
}
/* 16 bits and little endian bitstream */
if (buf[0] == 0xfe && buf[1] == 0x7f &&
buf[2] == 0x01 && buf[3] == 0x80)
{
int frame_size;
dts_bitstream_init (state, buf, 1, 0);
frame_size = syncinfo (state, flags, sample_rate,
bit_rate, frame_length);
return frame_size;
}
/* 16 bits and big endian bitstream */
if (buf[0] == 0x7f && buf[1] == 0xfe &&
buf[2] == 0x80 && buf[3] == 0x01)
{
int frame_size;
dts_bitstream_init (state, buf, 1, 1);
frame_size = syncinfo (state, flags, sample_rate,
bit_rate, frame_length);
return frame_size;
}
return 0;
}
int dts_frame (dts_state_t * state, uint8_t * buf, int * flags,
level_t * level, sample_t bias)
{
int i, j;
static float adj_table[] = { 1.0, 1.1250, 1.2500, 1.4375 };
dts_bitstream_init (state, buf, state->word_mode, state->bigendian_mode);
/* Sync code */
bitstream_get (state, 32);
/* Frame header */
state->frame_type = bitstream_get (state, 1);
state->samples_deficit = bitstream_get (state, 5) + 1;
state->crc_present = bitstream_get (state, 1);
state->sample_blocks = bitstream_get (state, 7) + 1;
state->frame_size = bitstream_get (state, 14) + 1;
state->amode = bitstream_get (state, 6);
state->sample_rate = bitstream_get (state, 4);
state->bit_rate = bitstream_get (state, 5);
state->downmix = bitstream_get (state, 1);
state->dynrange = bitstream_get (state, 1);
state->timestamp = bitstream_get (state, 1);
state->aux_data = bitstream_get (state, 1);
state->hdcd = bitstream_get (state, 1);
state->ext_descr = bitstream_get (state, 3);
state->ext_coding = bitstream_get (state, 1);
state->aspf = bitstream_get (state, 1);
state->lfe = bitstream_get (state, 2);
state->predictor_history = bitstream_get (state, 1);
/* TODO: check CRC */
if (state->crc_present) state->header_crc = bitstream_get (state, 16);
state->multirate_inter = bitstream_get (state, 1);
state->version = bitstream_get (state, 4);
state->copy_history = bitstream_get (state, 2);
state->source_pcm_res = bitstream_get (state, 3);
state->front_sum = bitstream_get (state, 1);
state->surround_sum = bitstream_get (state, 1);
state->dialog_norm = bitstream_get (state, 4);
/* FIME: channels mixing levels */
state->clev = state->slev = 1;
state->output = dts_downmix_init (state->amode, *flags, level,
state->clev, state->slev);
if (state->output < 0)
return 1;
if (state->lfe && (*flags & DTS_LFE))
state->output |= DTS_LFE;
*flags = state->output;
state->dynrng = state->level = MUL_C (*level, 2);
state->bias = bias;
state->dynrnge = 1;
state->dynrngcall = NULL;
#ifdef DEBUG
fprintf (stderr, "frame type: %i\n", state->frame_type);
fprintf (stderr, "samples deficit: %i\n", state->samples_deficit);
fprintf (stderr, "crc present: %i\n", state->crc_present);
fprintf (stderr, "sample blocks: %i (%i samples)\n",
state->sample_blocks, state->sample_blocks * 32);
fprintf (stderr, "frame size: %i bytes\n", state->frame_size);
fprintf (stderr, "amode: %i (%i channels)\n",
state->amode, dts_channels[state->amode]);
fprintf (stderr, "sample rate: %i (%i Hz)\n",
state->sample_rate, dts_sample_rates[state->sample_rate]);
fprintf (stderr, "bit rate: %i (%i bits/s)\n",
state->bit_rate, dts_bit_rates[state->bit_rate]);
fprintf (stderr, "downmix: %i\n", state->downmix);
fprintf (stderr, "dynrange: %i\n", state->dynrange);
fprintf (stderr, "timestamp: %i\n", state->timestamp);
fprintf (stderr, "aux_data: %i\n", state->aux_data);
fprintf (stderr, "hdcd: %i\n", state->hdcd);
fprintf (stderr, "ext descr: %i\n", state->ext_descr);
fprintf (stderr, "ext coding: %i\n", state->ext_coding);
fprintf (stderr, "aspf: %i\n", state->aspf);
fprintf (stderr, "lfe: %i\n", state->lfe);
fprintf (stderr, "predictor history: %i\n", state->predictor_history);
fprintf (stderr, "header crc: %i\n", state->header_crc);
fprintf (stderr, "multirate inter: %i\n", state->multirate_inter);
fprintf (stderr, "version number: %i\n", state->version);
fprintf (stderr, "copy history: %i\n", state->copy_history);
fprintf (stderr, "source pcm resolution: %i (%i bits/sample)\n",
state->source_pcm_res,
dts_bits_per_sample[state->source_pcm_res]);
fprintf (stderr, "front sum: %i\n", state->front_sum);
fprintf (stderr, "surround sum: %i\n", state->surround_sum);
fprintf (stderr, "dialog norm: %i\n", state->dialog_norm);
fprintf (stderr, "\n");
#endif
/* Primary audio coding header */
state->subframes = bitstream_get (state, 4) + 1;
state->prim_channels = bitstream_get (state, 3) + 1;
#ifdef DEBUG
fprintf (stderr, "subframes: %i\n", state->subframes);
fprintf (stderr, "prim channels: %i\n", state->prim_channels);
#endif
for (i = 0; i < state->prim_channels; i++)
{
state->subband_activity[i] = bitstream_get (state, 5) + 2;
#ifdef DEBUG
fprintf (stderr, "subband activity: %i\n", state->subband_activity[i]);
#endif
if (state->subband_activity[i] > DTS_SUBBANDS)
state->subband_activity[i] = DTS_SUBBANDS;
}
for (i = 0; i < state->prim_channels; i++)
{
state->vq_start_subband[i] = bitstream_get (state, 5) + 1;
#ifdef DEBUG
fprintf (stderr, "vq start subband: %i\n", state->vq_start_subband[i]);
#endif
if (state->vq_start_subband[i] > DTS_SUBBANDS)
state->vq_start_subband[i] = DTS_SUBBANDS;
}
for (i = 0; i < state->prim_channels; i++)
{
state->joint_intensity[i] = bitstream_get (state, 3);
#ifdef DEBUG
fprintf (stderr, "joint intensity: %i\n", state->joint_intensity[i]);
if (state->joint_intensity[i]) {fprintf (stderr, "JOINTINTENSITY\n");}
#endif
}
for (i = 0; i < state->prim_channels; i++)
{
state->transient_huffman[i] = bitstream_get (state, 2);
#ifdef DEBUG
fprintf (stderr, "transient mode codebook: %i\n",
state->transient_huffman[i]);
#endif
}
for (i = 0; i < state->prim_channels; i++)
{
state->scalefactor_huffman[i] = bitstream_get (state, 3);
#ifdef DEBUG
fprintf (stderr, "scale factor codebook: %i\n",
state->scalefactor_huffman[i]);
#endif
}
for (i = 0; i < state->prim_channels; i++)
{
state->bitalloc_huffman[i] = bitstream_get (state, 3);
/* if (state->bitalloc_huffman[i] == 7) bailout */
#ifdef DEBUG
fprintf (stderr, "bit allocation quantizer: %i\n",
state->bitalloc_huffman[i]);
#endif
}
/* Get codebooks quantization indexes */
for (i = 0; i < state->prim_channels; i++)
{
state->quant_index_huffman[i][0] = 0; /* Not transmitted */
state->quant_index_huffman[i][1] = bitstream_get (state, 1);
}
for (j = 2; j < 6; j++)
for (i = 0; i < state->prim_channels; i++)
state->quant_index_huffman[i][j] = bitstream_get (state, 2);
for (j = 6; j < 11; j++)
for (i = 0; i < state->prim_channels; i++)
state->quant_index_huffman[i][j] = bitstream_get (state, 3);
for (j = 11; j < 27; j++)
for (i = 0; i < state->prim_channels; i++)
state->quant_index_huffman[i][j] = 0; /* Not transmitted */
#ifdef DEBUG
for (i = 0; i < state->prim_channels; i++)
{
fprintf( stderr, "quant index huff:" );
for (j = 0; j < 11; j++)
fprintf (stderr, " %i", state->quant_index_huffman[i][j]);
fprintf (stderr, "\n");
}
#endif
/* Get scale factor adjustment */
for (j = 0; j < 11; j++)
{
for (i = 0; i < state->prim_channels; i++)
state->scalefactor_adj[i][j] = 1;
}
for (i = 0; i < state->prim_channels; i++)
{
if (state->quant_index_huffman[i][1] == 0)
{
/* Transmitted only if quant_index_huffman=0 (Huffman code used) */
state->scalefactor_adj[i][1] = adj_table[bitstream_get (state, 2)];
}
}
for (j = 2; j < 6; j++)
for (i = 0; i < state->prim_channels; i++)
if (state->quant_index_huffman[i][j] < 3)
{
/* Transmitted only if quant_index_huffman < 3 */
state->scalefactor_adj[i][j] =
adj_table[bitstream_get (state, 2)];
}
for (j = 6; j < 11; j++)
for (i = 0; i < state->prim_channels; i++)
if (state->quant_index_huffman[i][j] < 7)
{
/* Transmitted only if quant_index_huffman < 7 */
state->scalefactor_adj[i][j] =
adj_table[bitstream_get (state, 2)];
}
#ifdef DEBUG
for (i = 0; i < state->prim_channels; i++)
{
fprintf (stderr, "scalefac adj:");
for (j = 0; j < 11; j++)
fprintf (stderr, " %1.3f", state->scalefactor_adj[i][j]);
fprintf (stderr, "\n");
}
#endif
if (state->crc_present)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -