summaryrefslogtreecommitdiff
path: root/src/libdts/parse.c
diff options
context:
space:
mode:
authorMichael Roitzsch <mroi@users.sourceforge.net>2004-04-09 14:57:25 +0000
committerMichael Roitzsch <mroi@users.sourceforge.net>2004-04-09 14:57:25 +0000
commitff3ff7253e5680592329b363b9f84cccd8231eff (patch)
tree47a2a24e09b447410a27cc5df75f9845d0b3c031 /src/libdts/parse.c
parentc3505ea78011062e183c550aab20fb6aeafda4b6 (diff)
downloadxine-lib-ff3ff7253e5680592329b363b9f84cccd8231eff.tar.gz
xine-lib-ff3ff7253e5680592329b363b9f84cccd8231eff.tar.bz2
including libdts as experimental DTS decoder
(xine wrapper code by James Stembridge) does not work on all DVDs, but better a sometimes failing decoder than no decoder at all; digital passthrough seems unaffected CVS patchset: 6361 CVS date: 2004/04/09 14:57:25
Diffstat (limited to 'src/libdts/parse.c')
-rw-r--r--src/libdts/parse.c1290
1 files changed, 1290 insertions, 0 deletions
diff --git a/src/libdts/parse.c b/src/libdts/parse.c
new file mode 100644
index 000000000..6aa11e606
--- /dev/null
+++ b/src/libdts/parse.c
@@ -0,0 +1,1290 @@
+/*
+ * 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"
+
+/* #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;
+
+ 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 (*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 (*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)
+ {
+ /* Audio header CRC check */
+ bitstream_get (state, 16);
+ }
+
+ state->current_subframe = 0;
+ state->current_subsubframe = 0;
+
+ return 0;
+}
+
+static int dts_subframe_header (dts_state_t * state)
+{
+ /* Primary audio coding side information */
+ int j, k;
+
+ /* Subsubframe count */
+ state->subsubframes = bitstream_get (state, 2) + 1;
+#ifdef DEBUG
+ fprintf (stderr, "subsubframes: %i\n", state->subsubframes);
+#endif
+
+ /* Partial subsubframe sample count */
+ state->partial_samples = bitstream_get (state, 3);
+#ifdef DEBUG
+ fprintf (stderr, "partial samples: %i\n", state->partial_samples);
+#endif
+
+ /* Get prediction mode for each subband */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ for (k = 0; k < state->subband_activity[j]; k++)
+ state->prediction_mode[j][k] = bitstream_get (state, 1);
+#ifdef DEBUG
+ fprintf (stderr, "prediction mode:");
+ for (k = 0; k < state->subband_activity[j]; k++)
+ fprintf (stderr, " %i", state->prediction_mode[j][k]);
+ fprintf (stderr, "\n");
+#endif
+ }
+
+ /* Get prediction codebook */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ for (k = 0; k < state->subband_activity[j]; k++)
+ {
+ if (state->prediction_mode[j][k] > 0)
+ {
+ /* (Prediction coefficient VQ address) */
+ state->prediction_vq[j][k] = bitstream_get (state, 12);
+#ifdef DEBUG
+ fprintf (stderr, "prediction coefs: %f, %f, %f, %f\n",
+ (double)adpcm_vb[state->prediction_vq[j][k]][0]/8192,
+ (double)adpcm_vb[state->prediction_vq[j][k]][1]/8192,
+ (double)adpcm_vb[state->prediction_vq[j][k]][2]/8192,
+ (double)adpcm_vb[state->prediction_vq[j][k]][3]/8192);
+#endif
+ }
+ }
+ }
+
+ /* Bit allocation index */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ for (k = 0; k < state->vq_start_subband[j]; k++)
+ {
+ if (state->bitalloc_huffman[j] == 6)
+ state->bitalloc[j][k] = bitstream_get (state, 5);
+ else if (state->bitalloc_huffman[j] == 5)
+ state->bitalloc[j][k] = bitstream_get (state, 4);
+ else
+ {
+ state->bitalloc[j][k] = InverseQ (state,
+ bitalloc_12[state->bitalloc_huffman[j]]);
+ }
+
+ if (state->bitalloc[j][k] > 26)
+ {
+ fprintf (stderr, "bitalloc index [%i][%i] too big (%i)\n",
+ j, k, state->bitalloc[j][k]);
+ return -1;
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "bitalloc index: ");
+ for (k = 0; k < state->vq_start_subband[j]; k++)
+ fprintf (stderr, "%2.2i ", state->bitalloc[j][k]);
+ fprintf (stderr, "\n");
+#endif
+ }
+
+ /* Transition mode */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ for (k = 0; k < state->subband_activity[j]; k++)
+ {
+ state->transition_mode[j][k] = 0;
+ if (state->subsubframes > 1 &&
+ k < state->vq_start_subband[j] &&
+ state->bitalloc[j][k] > 0)
+ {
+ state->transition_mode[j][k] = InverseQ (state,
+ tmode[state->transient_huffman[j]]);
+ }
+ }
+#ifdef DEBUG
+ fprintf (stderr, "Transition mode:");
+ for (k = 0; k < state->subband_activity[j]; k++)
+ fprintf (stderr, " %i", state->transition_mode[j][k]);
+ fprintf (stderr, "\n");
+#endif
+ }
+
+ /* Scale factors */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ int *scale_table;
+ int scale_sum;
+
+ for (k = 0; k < state->subband_activity[j]; k++)
+ {
+ state->scale_factor[j][k][0] = 0;
+ state->scale_factor[j][k][1] = 0;
+ }
+
+ if (state->scalefactor_huffman[j] == 6)
+ scale_table = scale_factor_quant7;
+ else
+ scale_table = scale_factor_quant6;
+
+ /* When huffman coded, only the difference is encoded */
+ scale_sum = 0;
+
+ for (k = 0; k < state->subband_activity[j]; k++)
+ {
+ if (k >= state->vq_start_subband[j] || state->bitalloc[j][k] > 0)
+ {
+ if (state->scalefactor_huffman[j] < 5)
+ {
+ /* huffman encoded */
+ scale_sum += InverseQ (state,
+ scales_129[state->scalefactor_huffman[j]]);
+ }
+ else if (state->scalefactor_huffman[j] == 5)
+ {
+ scale_sum = bitstream_get (state, 6);
+ }
+ else if (state->scalefactor_huffman[j] == 6)
+ {
+ scale_sum = bitstream_get (state, 7);
+ }
+
+ state->scale_factor[j][k][0] = scale_table[scale_sum];
+ }
+
+ if (k < state->vq_start_subband[j] && state->transition_mode[j][k])
+ {
+ /* Get second scale factor */
+ if (state->scalefactor_huffman[j] < 5)
+ {
+ /* huffman encoded */
+ scale_sum += InverseQ (state,
+ scales_129[state->scalefactor_huffman[j]]);
+ }
+ else if (state->scalefactor_huffman[j] == 5)
+ {
+ scale_sum = bitstream_get (state, 6);
+ }
+ else if (state->scalefactor_huffman[j] == 6)
+ {
+ scale_sum = bitstream_get (state, 7);
+ }
+
+ state->scale_factor[j][k][1] = scale_table[scale_sum];
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "Scale factor:");
+ for (k = 0; k < state->subband_activity[j]; k++)
+ {
+ if (k >= state->vq_start_subband[j] || state->bitalloc[j][k] > 0)
+ fprintf (stderr, " %i", state->scale_factor[j][k][0]);
+ if (k < state->vq_start_subband[j] && state->transition_mode[j][k])
+ fprintf (stderr, " %i(t)", state->scale_factor[j][k][1]);
+ }
+ fprintf (stderr, "\n");
+#endif
+ }
+
+ /* Joint subband scale factor codebook select */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ /* Transmitted only if joint subband coding enabled */
+ if (state->joint_intensity[j] > 0)
+ state->joint_huff[j] = bitstream_get (state, 3);
+ }
+
+ /* Scale factors for joint subband coding */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ int source_channel;
+
+ /* Transmitted only if joint subband coding enabled */
+ if (state->joint_intensity[j] > 0)
+ {
+ int scale = 0;
+ source_channel = state->joint_intensity[j] - 1;
+
+ /* When huffman coded, only the difference is encoded
+ * (is this valid as well for joint scales ???) */
+
+ for (k = state->subband_activity[j];
+ k < state->subband_activity[source_channel]; k++)
+ {
+ if (state->joint_huff[j] < 5)
+ {
+ /* huffman encoded */
+ scale = InverseQ (state,
+ scales_129[state->joint_huff[j]]);
+ }
+ else if (state->joint_huff[j] == 5)
+ {
+ scale = bitstream_get (state, 6);
+ }
+ else if (state->joint_huff[j] == 6)
+ {
+ scale = bitstream_get (state, 7);
+ }
+
+ scale += 64; /* bias */
+ state->joint_scale_factor[j][k] = scale;/*joint_scale_table[scale];*/
+ }
+
+ if (!state->debug_flag & 0x02)
+ {
+ fprintf (stderr, "Joint stereo coding not supported\n");
+ state->debug_flag |= 0x02;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "Joint scale factor index:\n");
+ for (k = state->subband_activity[j];
+ k < state->subband_activity[source_channel]; k++)
+ fprintf (stderr, " %i", state->joint_scale_factor[j][k]);
+ fprintf (stderr, "\n");
+#endif
+ }
+ }
+
+ /* Stereo downmix coefficients */
+ if (state->prim_channels > 2 && state->downmix)
+ {
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ state->downmix_coef[j][0] = bitstream_get (state, 7);
+ state->downmix_coef[j][1] = bitstream_get (state, 7);
+ }
+ }
+
+ /* Dynamic range coefficient */
+ if (state->dynrange) state->dynrange_coef = bitstream_get (state, 8);
+
+ /* Side information CRC check word */
+ if (state->crc_present)
+ {
+ bitstream_get (state, 16);
+ }
+
+ /*
+ * Primary audio data arrays
+ */
+
+ /* VQ encoded high frequency subbands */
+ for (j = 0; j < state->prim_channels; j++)
+ {
+ for (k = state->vq_start_subband[j];
+ k < state->subband_activity[j]; k++)
+ {
+ /* 1 vector -> 32 samples */
+ state->high_freq_vq[j][k] = bitstream_get (state, 10);
+
+#ifdef DEBUG
+ fprintf( stderr, "VQ index: %i\n", state->high_freq_vq[j][k] );
+#endif
+ }
+ }
+
+ /* Low frequency effect data */
+ if (state->lfe)
+ {
+ /* LFE samples */
+ int lfe_samples = 2 * state->lfe * state->subsubframes;
+ double lfe_scale;
+
+ for (j = lfe_samples; j < lfe_samples * 2; j++)
+ {
+ /* Signed 8 bits int */
+ state->lfe_data[j] =
+ (signed int)(signed char)bitstream_get (state, 8);
+ }
+
+ /* Scale factor index */
+ state->lfe_scale_factor =
+ scale_factor_quant7[bitstream_get (state, 8)];
+
+ /* Quantization step size * scale factor */
+ lfe_scale = 0.035 * state->lfe_scale_factor;
+
+ for (j = lfe_samples; j < lfe_samples * 2; j++)
+ state->lfe_data[j] *= lfe_scale;
+
+#ifdef DEBUG
+ fprintf (stderr, "LFE samples:\n");
+ for (j = lfe_samples; j < lfe_samples * 2; j++)
+ fprintf (stderr, " %f", state->lfe_data[j]);
+ fprintf (stderr, "\n");
+#endif
+
+ }
+
+ return 0;
+}
+
+static int dts_subsubframe (dts_state_t * state)
+{
+ int k, l;
+ int subsubframe = state->current_subsubframe;
+
+ double *quant_step_table;
+
+ /* FIXME */
+ double subband_samples[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS][8];
+
+ /*
+ * Audio data
+ */
+
+ /* Select quantization step size table */
+ if (state->bit_rate == 0x1f)
+ quant_step_table = lossless_quant_d;
+ else
+ quant_step_table = lossy_quant_d;
+
+ for (k = 0; k < state->prim_channels; k++)
+ {
+ for (l = 0; l < state->vq_start_subband[k] ; l++)
+ {
+ int m;
+
+ /* Select the mid-tread linear quantizer */
+ int abits = state->bitalloc[k][l];
+
+ double quant_step_size = quant_step_table[abits];
+ double rscale;
+
+ /*
+ * Determine quantization index code book and its type
+ */
+
+ /* Select quantization index code book */
+ int sel = state->quant_index_huffman[k][abits];
+
+ /* Determine its type */
+ int q_type = 1; /* (Assume Huffman type by default) */
+ if (abits >= 11 || !bitalloc_select[abits][sel])
+ {
+ /* Not Huffman type */
+ if (abits <= 7) q_type = 3; /* Block code */
+ else q_type = 2; /* No further encoding */
+ }
+
+ if (abits == 0) q_type = 0; /* No bits allocated */
+
+ /*
+ * Extract bits from the bit stream
+ */
+ switch (q_type)
+ {
+ case 0: /* No bits allocated */
+ for (m=0; m<8; m++)
+ subband_samples[k][l][m] = 0;
+ break;
+
+ case 1: /* Huffman code */
+ for (m=0; m<8; m++)
+ subband_samples[k][l][m] =
+ InverseQ (state, bitalloc_select[abits][sel]);
+ break;
+
+ case 2: /* No further encoding */
+ for (m=0; m<8; m++)
+ {
+ /* Extract (signed) quantization index */
+ int q_index = bitstream_get (state, abits - 3);
+ if( q_index & (1 << (abits - 4)) )
+ {
+ q_index = (1 << (abits - 3)) - q_index;
+ q_index = -q_index;
+ }
+ subband_samples[k][l][m] = q_index;
+ }
+ break;
+
+ case 3: /* Block code */
+ {
+ int block_code1, block_code2, size, levels;
+ int block[8];
+
+ switch (abits)
+ {
+ case 1:
+ size = 7;
+ levels = 3;
+ break;
+ case 2:
+ size = 10;
+ levels = 5;
+ break;
+ case 3:
+ size = 12;
+ levels = 7;
+ break;
+ case 4:
+ size = 13;
+ levels = 9;
+ break;
+ case 5:
+ size = 15;
+ levels = 13;
+ break;
+ case 6:
+ size = 17;
+ levels = 17;
+ break;
+ case 7:
+ default:
+ size = 19;
+ levels = 25;
+ break;
+ }
+
+ block_code1 = bitstream_get (state, size);
+ /* Should test return value */
+ decode_blockcode (block_code1, levels, block);
+ block_code2 = bitstream_get (state, size);
+ decode_blockcode (block_code2, levels, &block[4]);
+ for (m=0; m<8; m++)
+ subband_samples[k][l][m] = block[m];
+
+ }
+ break;
+
+ default: /* Undefined */
+ fprintf (stderr, "Unknown quantization index codebook");
+ return -1;
+ }
+
+ /*
+ * Account for quantization step and scale factor
+ */
+
+ /* Deal with transients */
+ if (state->transition_mode[k][l] &&
+ subsubframe >= state->transition_mode[k][l])
+ rscale = quant_step_size * state->scale_factor[k][l][1];
+ else
+ rscale = quant_step_size * state->scale_factor[k][l][0];
+
+ /* Adjustment */
+ rscale *= state->scalefactor_adj[k][sel];
+ for (m=0; m<8; m++) subband_samples[k][l][m] *= rscale;
+
+ /*
+ * Inverse ADPCM if in prediction mode
+ */
+ if (state->prediction_mode[k][l])
+ {
+ int n;
+ for (m=0; m<8; m++)
+ {
+ for (n=1; n<=4; n++)
+ if (m-n >= 0)
+ subband_samples[k][l][m] +=
+ (adpcm_vb[state->prediction_vq[k][l]][n-1] *
+ subband_samples[k][l][m-n]/8192);
+ else if (state->predictor_history)
+ subband_samples[k][l][m] +=
+ (adpcm_vb[state->prediction_vq[k][l]][n-1] *
+ state->subband_samples_hist[k][l][m-n+4]/8192);
+ }
+ }
+ }
+
+ /*
+ * Decode VQ encoded high frequencies
+ */
+ for (l = state->vq_start_subband[k];
+ l < state->subband_activity[k]; l++)
+ {
+ /* 1 vector -> 32 samples but we only need the 8 samples
+ * for this subsubframe. */
+ int m;
+
+ if (!state->debug_flag & 0x01)
+ {
+ fprintf (stderr, "Stream with high frequencies VQ coding\n");
+ state->debug_flag |= 0x01;
+ }
+
+ for (m=0; m<8; m++)
+ {
+ subband_samples[k][l][m] =
+ high_freq_vq[state->high_freq_vq[k][l]][subsubframe*8+m]
+ * (double)state->scale_factor[k][l][0] / 16.0;
+ }
+ }
+ }
+
+ /* Check for DSYNC after subsubframe */
+ if (state->aspf || subsubframe == state->subsubframes - 1)
+ {
+ if (0xFFFF == bitstream_get (state, 16)) /* 0xFFFF */
+ {
+#ifdef DEBUG
+ fprintf( stderr, "Got subframe DSYNC\n" );
+#endif
+ }
+ else
+ {
+ fprintf( stderr, "Didn't get subframe DSYNC\n" );
+ }
+ }
+
+ /* Backup predictor history for adpcm */
+ for (k = 0; k < state->prim_channels; k++)
+ {
+ for (l = 0; l < state->vq_start_subband[k] ; l++)
+ {
+ int m;
+ for (m = 0; m < 4; m++)
+ state->subband_samples_hist[k][l][m] =
+ subband_samples[k][l][4+m];
+ }
+ }
+
+ /* 32 subbands QMF */
+ for (k = 0; k < state->prim_channels; k++)
+ {
+ /*static double pcm_to_float[8] =
+ {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
+
+ qmf_32_subbands (state, k,
+ subband_samples[k],
+ &state->samples[256*k],
+ /*WTF ???*/ 32768.0*3/2/*pcm_to_float[state->source_pcm_res]*/,
+ 0/*state->bias*/);
+ }
+
+ /* Down/Up mixing */
+ if (state->prim_channels < dts_channels[state->output & DTS_CHANNEL_MASK])
+ {
+ dts_upmix (state->samples, state->amode, state->output);
+ } else
+ if (state->prim_channels > dts_channels[state->output & DTS_CHANNEL_MASK])
+ {
+ dts_downmix (state->samples, state->amode, state->output, state->bias,
+ state->clev, state->slev);
+ }
+
+ /* Generate LFE samples for this subsubframe FIXME!!! */
+ if (state->output & DTS_LFE)
+ {
+ int lfe_samples = 2 * state->lfe * state->subsubframes;
+ int i_channels = dts_channels[state->output & DTS_CHANNEL_MASK];
+
+ lfe_interpolation_fir (state->lfe, 2 * state->lfe,
+ state->lfe_data + lfe_samples +
+ 2 * state->lfe * subsubframe,
+ &state->samples[256*i_channels],
+ 8388608.0, state->bias);
+ /* Outputs 20bits pcm samples */
+ }
+
+ return 0;
+}
+
+static int dts_subframe_footer (dts_state_t * state)
+{
+ int aux_data_count = 0, i;
+ int lfe_samples;
+
+ /*
+ * Unpack optional information
+ */
+
+ /* Time code stamp */
+ if (state->timestamp) bitstream_get (state, 32);
+
+ /* Auxiliary data byte count */
+ if (state->aux_data) aux_data_count = bitstream_get (state, 6);
+
+ /* Auxiliary data bytes */
+ for(i = 0; i < aux_data_count; i++)
+ bitstream_get (state, 8);
+
+ /* Optional CRC check bytes */
+ if (state->crc_present && (state->downmix || state->dynrange))
+ bitstream_get (state, 16);
+
+ /* Backup LFE samples history */
+ lfe_samples = 2 * state->lfe * state->subsubframes;
+ for (i = 0; i < lfe_samples; i++)
+ {
+ state->lfe_data[i] = state->lfe_data[i+lfe_samples];
+ }
+
+#ifdef DEBUG
+ fprintf( stderr, "\n" );
+#endif
+
+ return 0;
+}
+
+int dts_block (dts_state_t * state)
+{
+ /* Sanity check */
+ if (state->current_subframe >= state->subframes)
+ {
+ fprintf (stderr, "check failed: %i>%i",
+ state->current_subframe, state->subframes);
+ return -1;
+ }
+
+ if (!state->current_subsubframe)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "DSYNC dts_subframe_header\n");
+#endif
+ /* Read subframe header */
+ if (dts_subframe_header (state)) return -1;
+ }
+
+ /* Read subsubframe */
+#ifdef DEBUG
+ fprintf (stderr, "DSYNC dts_subsubframe\n");
+#endif
+ if (dts_subsubframe (state)) return -1;
+
+ /* Update state */
+ state->current_subsubframe++;
+ if (state->current_subsubframe >= state->subsubframes)
+ {
+ state->current_subsubframe = 0;
+ state->current_subframe++;
+ }
+ if (state->current_subframe >= state->subframes)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "DSYNC dts_subframe_footer\n");
+#endif
+ /* Read subframe footer */
+ if (dts_subframe_footer (state)) return -1;
+ }
+
+ return 0;
+}
+
+/* Very compact version of the block code decoder that does not use table
+ * look-up but is slightly slower */
+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;
+ }
+}
+
+static void pre_calc_cosmod( dts_state_t * state )
+{
+ int i, j, k;
+
+ for (j=0,k=0;k<16;k++)
+ for (i=0;i<16;i++)
+ state->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++)
+ state->cos_mod[j++] = cos((i)*(2*k+1)*M_PI/32);
+
+ for (k=0;k<16;k++)
+ state->cos_mod[j++] = 0.25/(2*cos((2*k+1)*M_PI/128));
+
+ for (k=0;k<16;k++)
+ state->cos_mod[j++] = -0.25/(2.0*sin((2*k+1)*M_PI/128));
+}
+
+static void qmf_32_subbands (dts_state_t * state, int chans,
+ double samples_in[32][8], sample_t *samples_out,
+ double scale, sample_t bias)
+{
+ double *prCoeff;
+ int i, j, k;
+ double raXin[32];
+
+ double *subband_fir_hist = state->subband_fir_hist[chans];
+ double *subband_fir_hist2 = state->subband_fir_noidea[chans];
+
+ int nChIndex = 0, NumSubband = 32, nStart = 0, nEnd = 8, nSubIndex;
+
+ /* Select filter */
+ if (!state->multirate_inter) /* Non-perfect reconstruction */
+ prCoeff = fir_32bands_nonperfect;
+ else /* Perfect reconstruction */
+ prCoeff = fir_32bands_perfect;
+
+ /* Reconstructed channel sample index */
+ for (nSubIndex=nStart; nSubIndex<nEnd; nSubIndex++)
+ {
+ double A[16], B[16], SUM[16], DIFF[16];
+
+ /* Load in one sample from each subband */
+ for (i=0; i<state->subband_activity[chans]; i++)
+ raXin[i] = samples_in[i][nSubIndex];
+
+ /* Clear inactive subbands */
+ for (i=state->subband_activity[chans]; i<NumSubband; i++)
+ raXin[i] = 0.0;
+
+ /* Multiply by cosine modulation coefficients and
+ * create temporary arrays SUM and DIFF */
+ for (j=0,k=0;k<16;k++)
+ {
+ A[k] = 0.0;
+ for (i=0;i<16;i++)
+ A[k]+=(raXin[2*i]+raXin[2*i+1])*state->cos_mod[j++];
+ }
+
+ for (k=0;k<16;k++)
+ {
+ B[k] = 0.0;
+ for (i=0;i<16;i++)
+ {
+ if(i>0) B[k]+=(raXin[2*i]+raXin[2*i-1])*state->cos_mod[j++];
+ else B[k]+=(raXin[2*i])*state->cos_mod[j++];
+ }
+ SUM[k]=A[k]+B[k];
+ DIFF[k]=A[k]-B[k];
+ }
+
+ /* Store history */
+ for (k=0;k<16;k++)
+ subband_fir_hist[k]=state->cos_mod[j++]*SUM[k];
+ for (k=0;k<16;k++)
+ subband_fir_hist[32-k-1]=state->cos_mod[j++]*DIFF[k];
+ /* Multiply by filter coefficients */
+ for (k=31,i=0;i<32;i++,k--)
+ for (j=0;j<512;j+=64)
+ subband_fir_hist2[i] += prCoeff[i+j]*
+ (subband_fir_hist[i+j] - subband_fir_hist[j+k]);
+ for (k=31,i=0;i<32;i++,k--)
+ for (j=0;j<512;j+=64)
+ subband_fir_hist2[32+i] += prCoeff[32+i+j]*
+ (-subband_fir_hist[i+j] - subband_fir_hist[j+k]);
+
+ /* Create 32 PCM output samples */
+ for (i=0;i<32;i++)
+ samples_out[nChIndex++] = subband_fir_hist2[i] / scale + bias;
+
+ /* Update working arrays */
+ for (i=511;i>=32;i--)
+ subband_fir_hist[i] = subband_fir_hist[i-32];
+ for (i=0;i<NumSubband;i++)
+ subband_fir_hist2[i] = subband_fir_hist2[i+32];
+ for (i=0;i<NumSubband;i++)
+ subband_fir_hist2[i+32] = 0.0;
+ }
+}
+
+static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample,
+ double *samples_in, sample_t *samples_out,
+ double scale, sample_t bias)
+{
+ /* samples_in: An array holding decimated samples.
+ * Samples in current subframe starts from samples_in[0],
+ * while samples_in[-1], samples_in[-2], ..., stores samples
+ * from last subframe as history.
+ *
+ * samples_out: An array holding interpolated samples
+ */
+
+ int nDeciFactor, k, J;
+ double *prCoeff;
+
+ int NumFIRCoef = 512; /* Number of FIR coefficients */
+ int nInterpIndex = 0; /* Index to the interpolated samples */
+ int nDeciIndex;
+
+ /* Select decimation filter */
+ if (nDecimationSelect==1)
+ {
+ /* 128 decimation */
+ nDeciFactor = 128;
+ /* Pointer to the FIR coefficients array */
+ prCoeff = lfe_fir_128;
+ } else {
+ /* 64 decimation */
+ nDeciFactor = 64;
+ prCoeff = lfe_fir_64;
+ }
+
+ /* Interpolation */
+ for (nDeciIndex=0; nDeciIndex<nNumDeciSample; nDeciIndex++)
+ {
+ /* One decimated sample generates nDeciFactor interpolated ones */
+ for (k=0; k<nDeciFactor; k++)
+ {
+ /* Clear accumulation */
+ double rTmp = 0.0;
+
+ /* Accumulate */
+ for (J=0; J<NumFIRCoef/nDeciFactor; J++)
+ rTmp += samples_in[nDeciIndex-J]*prCoeff[k+J*nDeciFactor];
+
+ /* Save interpolated samples */
+ samples_out[nInterpIndex++] = rTmp / scale + bias;
+ }
+ }
+}
+
+void dts_dynrng (dts_state_t * state,
+ level_t (* call) (level_t, void *), void * data)
+{
+ state->dynrange = 0;
+ if (call) {
+ state->dynrange = 1;
+ state->dynrngcall = call;
+ state->dynrngdata = data;
+ }
+}
+
+void dts_free (dts_state_t * state)
+{
+ free (state->samples);
+ free (state);
+}