From e067c53a81cf4aed0ede7c7b3da85c114deca858 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Tue, 5 Aug 2003 11:30:56 +0000 Subject: Some more updates. Started to enter huffman tables. General reorganisation as xine_decoder.c was getting too big. CVS patchset: 5245 CVS date: 2003/08/05 11:30:56 --- src/libdts/decoder.c | 849 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 849 insertions(+) create mode 100644 src/libdts/decoder.c (limited to 'src/libdts/decoder.c') diff --git a/src/libdts/decoder.c b/src/libdts/decoder.c new file mode 100644 index 000000000..724d61927 --- /dev/null +++ b/src/libdts/decoder.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a unix video player. + * + * xine 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. + * + * xine 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 + * + * $Id: decoder.c,v 1.1 2003/08/05 11:30:56 jcdutton Exp $ + * + * 04-08-2003 DTS software decode (C) James Courtier-Dutton + * + */ + +#ifndef __sun +/* required for swab() */ +#define _XOPEN_SOURCE 500 +#endif + +#include +#include +#include +#include +#include +#include +#include /* ntohs */ +#include + +#include "xine_internal.h" +#include "xineutils.h" +#include "audio_out.h" +#include "buffer.h" + +#include "dts_debug.h" +#include "decoder.h" +#include "decoder_internal.h" +#include "print_info.h" + +#ifdef ENABLE_DTS_PARSE + +typedef struct { + uint8_t *start; + uint32_t byte_position; + uint32_t bit_position; + uint8_t byte; +} getbits_state_t; + +static float AdjTable[] = { + 1.0000, + 1.1250, + 1.2500, + 1.4375 +}; + +#include "huffman_tables.h" + +static int32_t getbits_init(getbits_state_t *state, uint8_t *start) { + if ((state == NULL) || (start == NULL)) return -1; + state->start = start; + state->bit_position = 0; + state->byte_position = 0; + state->byte = start[0]; + return 0; +} +/* Non-optimized getbits. */ +/* This can easily be optimized for particular platforms. */ +static uint32_t getbits(getbits_state_t *state, uint32_t number_of_bits) { + uint32_t result=0; + uint8_t byte=0; + if (number_of_bits > 32) { + printf("Number of bits > 32 in getbits\n"); + assert(0); + } + + if ((state->bit_position) > 0) { /* Last getbits left us in the middle of a byte. */ + if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */ + byte = state->byte; + byte = byte >> (state->bit_position); + result = byte; + number_of_bits -= (8-state->bit_position); + state->bit_position = 0; + state->byte_position++; + state->byte = state->start[state->byte_position]; + } else { + byte=state->byte; + state->byte = state->byte << number_of_bits; + byte = byte >> (8 - number_of_bits); + result = byte; + state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */ + if (state->bit_position == 8) { + state->bit_position = 0; + state->byte_position++; + state->byte = state->start[state->byte_position]; + } + number_of_bits = 0; + } + } + if ((state->bit_position) == 0) + while (number_of_bits > 7) { + result = (result << 8) + state->byte; + state->byte_position++; + state->byte = state->start[state->byte_position]; + number_of_bits -= 8; + } + if (number_of_bits > 0) { /* number_of_bits < 8 */ + byte = state->byte; + state->byte = state->byte << number_of_bits; + state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */ + if (state->bit_position > 7) printf ("bit_pos2 too large: %d\n",state->bit_position); + byte = byte >> (8 - number_of_bits); + result = (result << number_of_bits) + byte; + number_of_bits = 0; + } + + return result; +} + +static int32_t huff_lookup(getbits_state_t *state, int32_t HuffTable[][2] ) { + int32_t n=1; + int32_t bit; + + { + bit = getbits(state, 1); + n = HuffTable[n][bit]; + } while (n > 0); + /* printf("returning %d\n", n + HuffTable[0][0]); */ + return n + HuffTable[0][0]; +} + + +static int32_t qscales(int32_t nQSelect, getbits_state_t *state, int32_t *nScale) { +/* FIXME: IMPLEMENT */ +return 0; +} + +/* Used by dts.wav files, only 14 bits of the 16 possible are used in the CD. */ +static void squash14to16(uint8_t *buf_from, uint8_t *buf_to, uint32_t number_of_bytes) { + int32_t from; + int32_t to=0; + uint16_t sample1; + uint16_t sample2; + uint16_t sample3; + uint16_t sample4; + uint16_t sample16bit; + /* This should convert the 14bit sync word into a 16bit one. */ + printf("libdts: squashing %d bytes.\n", number_of_bytes); + for(from=0;from> 2); + sample2 = buf_from[from+2] | buf_from[from+3] << 8; + sample2 = (sample2 & 0x1fff) | ((sample2 & 0x8000) >> 2); + sample16bit = (sample1 << 2) | (sample2 >> 12); + buf_to[to++] = sample16bit >> 8; /* Add some swabbing in as well */ + buf_to[to++] = sample16bit & 0xff; + sample3 = buf_from[from+4] | buf_from[from+5] << 8; + sample3 = (sample3 & 0x1fff) | ((sample3 & 0x8000) >> 2); + sample16bit = ((sample2 & 0xfff) << 4) | (sample3 >> 10); + buf_to[to++] = sample16bit >> 8; /* Add some swabbing in as well */ + buf_to[to++] = sample16bit & 0xff; + sample4 = buf_from[from+6] | buf_from[from+7] << 8; + sample4 = (sample4 & 0x1fff) | ((sample4 & 0x8000) >> 2); + sample16bit = ((sample3 & 0x3ff) << 6) | (sample4 >> 8); + buf_to[to++] = sample16bit >> 8; /* Add some swabbing in as well */ + buf_to[to++] = sample16bit & 0xff; + buf_to[to++] = sample4 & 0xff; + } + +} + +#if 0 +/* FIXME: Make this re-entrant */ +static void InverseADPCM(void) { +/* + * NumADPCMCoeff =4, the number of ADPCM coefficients. + * raADPCMcoeff[] are the ADPCM coefficients extracted + * from the bit stream. + * raSample[NumADPCMCoeff], ..., raSample[-1] are the + * history from last subframe or subsubframe. It must + * updated each time before reverse ADPCM is run for a + * block of samples for each subband. + */ +for (m=0; mcontent; + getbits_state_t state; + decoder_data_t decoder_data; + decoder_data.sync_type=0; + decoder_data.header_crc_check_bytes=0; + + int32_t n, ch, i; + printf("libdts: buf->size = %d\n", buf->size); + printf("libdts: parse1: "); + for(i=0;i<16;i++) { + printf("%02x ",data_in[i]); + } + printf("\n"); + + if ((data_in[0] == 0x7f) && + (data_in[1] == 0xfe) && + (data_in[2] == 0x80) && + (data_in[3] == 0x01)) { + decoder_data.sync_type=1; + } + if (data_in[0] == 0xff && + data_in[1] == 0x1f && + data_in[2] == 0x00 && + data_in[3] == 0xe8 && + data_in[4] == 0xf1 && /* DTS standard document was wrong here! */ + data_in[5] == 0x07 ) { /* DTS standard document was wrong here! */ + squash14to16(&data_in[0], &data_in[0], buf->size); + buf->size = buf->size - (buf->size / 8); /* size = size * 7 / 8; */ + decoder_data.sync_type=2; + } + if (decoder_data.sync_type == 0) { + printf("libdts: DTS Sync bad\n"); + return; + } + printf("libdts: DTS Sync OK. type=%d\n", decoder_data.sync_type); + printf("libdts: parse2: "); + for(i=0;i<16;i++) { + printf("%02x ",data_in[i]); + } + printf("\n"); + + getbits_init(&state, &data_in[4]); + + /* B.2 Unpack Frame Header Routine */ + /* Frame Type V FTYPE 1 bit */ + decoder_data.frame_type = getbits(&state, 1); /* 1: Normal Frame, 2:Termination Frame */ + /* Deficit Sample Count V SHORT 5 bits */ + decoder_data.deficit_sample_count = getbits(&state, 5); + /* CRC Present Flag V CPF 1 bit */ + decoder_data.crc_present_flag = getbits(&state, 1); + /* Number of PCM Sample Blocks V NBLKS 7 bits */ + decoder_data.number_of_pcm_blocks = getbits(&state, 7); + /* Primary Frame Byte Size V FSIZE 14 bits */ + decoder_data.primary_frame_byte_size = getbits(&state, 14); + /* Audio Channel Arrangement ACC AMODE 6 bits */ + decoder_data.audio_channel_arrangement = getbits(&state, 6); + /* Core Audio Sampling Frequency ACC SFREQ 4 bits */ + decoder_data.core_audio_sampling_frequency = getbits(&state, 4); + /* Transmission Bit Rate ACC RATE 5 bits */ + decoder_data.transmission_bit_rate = getbits(&state, 5); + /* Embedded Down Mix Enabled V MIX 1 bit */ + decoder_data.embedded_down_mix_enabled = getbits(&state, 1); + /* Embedded Dynamic Range Flag V DYNF 1 bit */ + decoder_data.embedded_dynamic_range_flag = getbits(&state, 1); + /* Embedded Time Stamp Flag V TIMEF 1 bit */ + decoder_data.embedded_time_stamp_flag = getbits(&state, 1); + /* Auxiliary Data Flag V AUXF 1 bit */ + decoder_data.auxiliary_data_flag = getbits(&state, 1); + /* HDCD NV HDCD 1 bits */ + decoder_data.hdcd = getbits(&state, 1); + /* Extension Audio Descriptor Flag ACC EXT_AUDIO_ID 3 bits */ + decoder_data.extension_audio_descriptor_flag = getbits(&state, 3); + /* Extended Coding Flag ACC EXT_AUDIO 1 bit */ + decoder_data.extended_coding_flag = getbits(&state, 1); + /* Audio Sync Word Insertion Flag ACC ASPF 1 bit */ + decoder_data.audio_sync_word_insertion_flag = getbits(&state, 1); + /* Low Frequency Effects Flag V LFF 2 bits */ + decoder_data.low_frequency_effects_flag = getbits(&state, 2); + /* Predictor History Flag Switch V HFLAG 1 bit */ + decoder_data.predictor_history_flag_switch = getbits(&state, 1); + /* Header CRC Check Bytes V HCRC 16 bits */ + if (decoder_data.crc_present_flag == 1) + decoder_data.header_crc_check_bytes = getbits(&state, 16); + /* Multirate Interpolator Switch NV FILTS 1 bit */ + decoder_data.multirate_interpolator_switch = getbits(&state, 1); + /* Encoder Software Revision ACC/NV VERNUM 4 bits */ + decoder_data.encoder_software_revision = getbits(&state, 4); + /* Copy History NV CHIST 2 bits */ + decoder_data.copy_history = getbits(&state, 2); + /* Source PCM Resolution ACC/NV PCMR 3 bits */ + decoder_data.source_pcm_resolution = getbits(&state, 3); + /* Front Sum/Difference Flag V SUMF 1 bit */ + decoder_data.front_sum_difference_flag = getbits(&state, 1); + /* Surrounds Sum/Difference Flag V SUMS 1 bit */ + decoder_data.surrounds_sum_difference_flag = getbits(&state, 1); + /* Dialog Normalisation Parameter/Unspecified V DIALNORM/UNSPEC 4 bits */ + switch (decoder_data.encoder_software_revision) { + case 6: + decoder_data.dialog_normalisation_unspecified = 0; + decoder_data.dialog_normalisation_parameter = getbits(&state, 4); + decoder_data.dialog_normalisation_gain = - (16+decoder_data.dialog_normalisation_parameter); + break; + case 7: + decoder_data.dialog_normalisation_unspecified = 0; + decoder_data.dialog_normalisation_parameter = getbits(&state, 4); + decoder_data.dialog_normalisation_gain = - (decoder_data.dialog_normalisation_parameter); + break; + default: + decoder_data.dialog_normalisation_unspecified = getbits(&state, 4); + decoder_data.dialog_normalisation_gain = decoder_data.dialog_normalisation_parameter = 0; + break; + } + + /* B.3 Audio Decoding */ + /* B.3.1 Primary Audio Coding Header */ + + /* Number of Subframes V SUBFS 4 bits */ + decoder_data.number_of_subframes = getbits(&state, 4) + 1 ; + /* Number of Primary Audio Channels V PCHS 3 bits */ + decoder_data.number_of_primary_audio_channels = getbits(&state, 3) + 1 ; + /* Subband Activity Count V SUBS 5 bits per channel */ + for (ch=0; ch0 ) { /* Transmitted only when ADPCM active */ + /* Extract the VQindex */ + decoder_data.nVQIndex = getbits(&state,12); + /* Look up the VQ table for prediction coefficients. */ + /* FIXME: How to implement LookUp? */ + decoder_data.PVQIndex[ch][n] = decoder_data.nVQIndex; + /* FIXME: We don't have the ADPCMCoeff table. */ + /* ADPCMCoeffVQ.LookUp(nVQIndex, PVQ[ch][n]);*/ /* 4 coefficients FIXME: Need to work out what this does. */ + } + } + } + + + /* Bit Allocation Index V ABITS variable bits */ + /* FIXME: No getbits here InverseQ does the getbits */ + for (ch=0; chInverseQ(&state, bit_allocation_index[ch][n]); */ + } + } + + /* Transition Mode V TMODE variable bits */ + + /* Always assume no transition unless told */ + for (ch=0; ch1 ) { + /* Transient possible only if more than one subsubframe. */ + for (ch=0; ch0 ) { + /* Present only if bits allocated */ + /* Use codebook nQSelect to decode transition_mode from the bit stream */ + /* FIXME: What is Inverse Quantization(InverseQ) ? */ + if (decoder_data.nQSelect == 0) { + decoder_data.transition_mode[ch][n] = huff_lookup(&state, HuffA4); + } else { + XINE_ASSERT(0, "transition mod parse failed, (nQSelect != 0) not implemented yet."); + } + + /* QTMODE.ppQ[nQSelect]->InverseQ(&state,transition_mode[ch][n]); */ + } else { + decoder_data.transition_mode[ch][n] = 0; + } + } + } + } + } + +/* WORKING ON THIS BIT */ + + +#if 0 + /* Scale Factors V SCALES variable bits */ + for (ch=0; ch0 ) { /* Not present if no bit allocated */ + /* + * First scale factor + */ + /* Use the (Huffman) code indicated by nQSelect to decode */ + /* the quantization index of scale_factors from the bit stream */ + /* FIXME: What is Inverse Quantization(InverseQ) ? */ + qscales(nQSelect, &state, &nScale); + /* QSCALES.ppQ[nQSelect]->InverseQ(InputFrame, nScale); */ + /* Take care of difference encoding */ + if ( nQSelect < 5 ) { /* Huffman encoded, nScale is the difference */ + nScaleSum += nScale; /* of the quantization indexes of scale_factors. */ + } else { /* Otherwise, nScale is the quantization */ + nScaleSum = nScale; /* level of scale_factors. */ + } + /* Look up scale_factors from the root square table */ + /* FIXME: How to implement LookUp? */ + pScaleTable->LookUp(nScaleSum, scale_factors[ch][n][0]) + /* + * Two scale factors transmitted if there is a transient + */ + if (transition_mode[ch][n]>0) { + /* Use the (Huffman) code indicated by nQSelect to decode */ + /* the quantization index of scale_factors from the bit stream */ + /* FIXME: What is Inverse Quantization(InverseQ) ? */ + QSCALES.ppQ[nQSelect]->InverseQ(InputFrame, nScale); + /* Take care of difference encoding */ + if ( nQSelect < 5 ) /* Huffman encoded, nScale is the difference */ + nScaleSum += nScale; /* of the quantization indexes of scale_factors. */ + else /* Otherwise, nScale is the quantization */ + nScaleSum = nScale; /* level of scale_factors. */ + /* Look up scale_factors from the root square table */ + /* FIXME: How to implement LookUp? */ + pScaleTable->LookUp(nScaleSum, scale_factors[ch][n][1]); + } + } + } + /* + * High frequency VQ subbands + */ + for (n=high_frequency_VQ_start_subband[ch]; nInverseQ(InputFrame, nScale); + /* Take care of difference encoding */ + if ( nQSelect < 5 ) /* Huffman encoded, nScale is the difference */ + nScaleSum += nScale; /* of the quantization indexes of scale_factors. */ + else /* Otherwise, nScale is the quantization */ + nScaleSum = nScale; /* level of scale_factors. */ + /* Look up scale_factors from the root square table */ + /* FIXME: How to implement LookUp? */ + pScaleTable->LookUp(nScaleSum, scale_factors[ch][n][0]) + } + } + +/* #if 0 */ +/* FIXME: ALL CODE BELOW HERE does not compile yet. */ + + + /* Joint Subband Scale Factor Codebook Select V JOIN SHUFF 3 bits per channel */ + for (ch=0; ch0 ) /* Transmitted only if joint subband coding enabled. */ + joint_subband_scale_factor_codebook_select[ch] = getbits(&state,3); + + /* Scale Factors for Joint Subband Coding V JOIN SCALES variable bits */ + int nSourceCh; + for (ch=0; ch0 ) { /* Only if joint subband coding enabled. */ + nSourceCh = joint_intensity_coding_index[ch]-1; /* Get source channel. joint_intensity_coding_index counts */ + /* channels as 1,2,3,4,5, so minus 1. */ + nQSelect = joint_subband_scale_factor_codebook_select[ch]; /* Select code book. */ + for (n=subband_activity_count[ch]; nInverseQ(InputFrame, nJScale); + /* Bias by 64 */ + nJScale = nJScale + 64; + /* Look up scale_factors_for_joint_subband_coding from the joint scale table */ + /* FIXME: How to implement LookUp? */ + JScaleTbl.LookUp(nJScale, scale_factors_for_joint_subband_coding[ch][n]); + } + } + } + + /* Stereo Down-Mix Coefficients NV DOWN 7 bits per coefficient */ + if ( (MIX!=0) && (number_of_primary_audio_channels>2) ) { + /* Extract down mix indexes */ + for (ch=0; ch0 ) { /* Present only if flagged by low_frequency_effects_flag */ + /* extract low_frequency_effect_data samples from the bit stream */ + for (n=0; n<2*low_frequency_effects_flag*subsubframe_count; n++) { + low_frequency_effect_data[n] = (signed int)(signed char)getbits(&state,8); + /* Use char to get sign extension because it */ + /* is 8-bit 2's compliment. */ + /* Extract scale factor index from the bit stream */ + } + LFEscaleIndex = getbits(&state,8); + /* Look up the 7-bit root square quantization table */ + /* FIXME: How to implement LookUp? */ + pLFE_RMS->LookUp(LFEscaleIndex,nScale); + /* Account for the quantizer step size which is 0.035 */ + rScale = nScale*0.035; + /* Get the actual low_frequency_effect_data samples */ + for (n=0; n<2*low_frequency_effects_flag*subsubframe_count; n++) { + LFECh.rLFE[k] = low_frequency_effect_data[n]*rScale; + } + /* Interpolation low_frequency_effect_data samples */ + LFECh.InterpolationFIR(low_frequency_effects_flag); /* low_frequency_effects_flag indicates which */ + /* interpolation filter to use */ + } + + /* Audio Data V AUDIO variable bits */ + /* + * Select quantization step size table + */ + if ( RATE == 0x1f ) { + pStepSizeTable = &StepSizeLossLess; /* Lossless quantization */ + } else { + pStepSizeTable = &StepSizeLossy; /* Lossy */ + } + /* + * Unpack the subband samples + */ + for (nSubSubFrame=0; nSubSubFrameppQ[nSEL]->InverseQ(InputFrame,AUDIO[m]); + break; + case 2: /* No further encoding */ + for (m=0; m<8; m++) { + /* Extract quantization index from the bit stream */ + /* FIXME: What is Inverse Quantization(InverseQ) ? */ + pCQGroup->ppQ[nSEL]->InverseQ(InputFrame, nCode) + /* Take care of 2's compliment */ + AUDIO[m] = pCQGroup->ppQ[nSEL]->SignExtension(nCode); + } + break; + case 3: /* Block code */ + /* Block code is just 1 value with 4 samples derived from it. + * with each sample a digit from the number (using a base derived from nABITS via a table) + * E.g. nABITS = 10, base = 5 (Base value taken from table.) + * 1st sample = (value % 5) - (int(5/2); (Values between -2 and +2 ) + * 2st sample = ((value / 5) % 5) - (int(5/2); + * 3rd sample = ((value / 25) % 5) - (int(5/2); + * 4th sample = ((value / 125) % 5) - (int(5/2); + * + */ + pCBQ = &pCBlockQ[nABITS-1]; /* Select block code book */ + m = 0; + for (nBlock=0; nBlock<2; nBlock++) { + /* Extract the block code index from the bit stream */ + /* FIXME: What is Inverse Quantization(InverseQ) ? */ + pCQGroup->ppQ[nSEL]->InverseQ(InputFrame, nCode) + /* Look up 4 samples from the block code book */ + /* FIXME: How to implement LookUp? */ + pCBQ->LookUp(nCode,&AUDIO[m]) + m += 4; + } + break; + default: /* Undefined */ + printf("ERROR: Unknown AUDIO quantization index code book."); + } + /* + * Account for quantization step size and scale factor + */ + /* Look up quantization step size */ + nABITS = bit_allocation_index[ch][n]; + /* FIXME: How to implement LookUp? */ + pStepSizeTable->LookUp(nABITS, rStepSize); + /* Identify transient location */ + nTmode = transition_mode[ch][n]; + if ( nTmode == 0 ) /* No transient */ + nTmode = subsubframe_count; + /* Determine proper scale factor */ + if (nSubSubFrame