From c50dc5e888627bd1644f46585a44dc118c865127 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Thu, 9 Aug 2001 11:41:39 +0200 Subject: Improvements from Matjaz Thaler --- ac3dec/coeff.c | 446 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 262 insertions(+), 184 deletions(-) (limited to 'ac3dec/coeff.c') diff --git a/ac3dec/coeff.c b/ac3dec/coeff.c index b9f03ff6..7d5579ca 100644 --- a/ac3dec/coeff.c +++ b/ac3dec/coeff.c @@ -28,51 +28,183 @@ #include "ac3_internal.h" -#include "decode.h" #include "bitstream.h" #include "dither.h" #include "coeff.h" + // //Lookup tables of 0.15 two's complement quantization values // -static const uint_16 q_1[3] = +#define Q0 ((-2 << 15) / 3.0) +#define Q1 (0) +#define Q2 ((2 << 15) / 3.0) + +static const float q_1_0[ 32 ] = { - ( -2 << 15)/3, 0,( 2 << 15)/3 -}; + Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, + Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, + 0,0,0,0,0 +}; -static const uint_16 q_2[5] = +static const float q_1_1[ 32 ] = { - ( -4 << 15)/5,( -2 << 15)/5, 0, - ( 2 << 15)/5,( 4 << 15)/5 -}; + Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, + Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, + Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, + 0,0,0,0,0 +}; -static const uint_16 q_3[7] = +static const float q_1_2[ 32 ] = +{ + Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, + Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, + Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, + 0,0,0,0,0 +}; + +#undef Q0 +#undef Q1 +#undef Q2 + +#define Q0 ((-4 << 15) / 5.0) +#define Q1 ((-2 << 15) / 5.0) +#define Q2 (0) +#define Q3 ((2 << 15) / 5.0) +#define Q4 ((4 << 15) / 5.0) + +static const float q_2_0[ 128 ] = +{ + Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, + Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, + Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, + Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, + Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, + Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, + Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, + Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, + Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, + 0,0,0 +}; + +static const float q_2_1[ 128 ] = +{ + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, + Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0, + Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2, + Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, + Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0, + Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2, + Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3, + Q4,Q4,Q4,Q4,Q4,0,0,0 + }; + +static const float q_2_2[ 128 ] = + { + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,0,0,0 +}; + +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +#undef Q4 + +static const float q_3[7] = { - ( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0, - ( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7 + (-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0.0, + ( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0 }; -static const uint_16 q_4[11] = +#define Q0 ((-10 << 15) / 11.0) +#define Q1 ((-8 << 15) / 11.0) +#define Q2 ((-6 << 15) / 11.0) +#define Q3 ((-4 << 15) / 11.0) +#define Q4 ((-2 << 15) / 11.0) +#define Q5 (0) +#define Q6 ((2 << 15) / 11.0) +#define Q7 ((4 << 15) / 11.0) +#define Q8 ((6 << 15) / 11.0) +#define Q9 ((8 << 15) / 11.0) +#define QA ((10 << 15) / 11.0) + +static const float q_4_0[ 128 ] = { - (-10 << 15)/11,(-8 << 15)/11,(-6 << 15)/11, ( -4 << 15)/11,(-2 << 15)/11, 0, - ( 2 << 15)/11,( 4 << 15)/11,( 6 << 15)/11, ( 8 << 15)/11,(10 << 15)/11 + Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, + Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, + Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, + Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, + Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, + Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, + Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, + Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, + Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, + Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, + QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, + 0, 0, 0, 0, 0, 0, 0 + }; + +static const float q_4_1[ 128 ] = +{ + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + 0, 0, 0, 0, 0, 0, 0 }; -static const uint_16 q_5[15] = +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +#undef Q4 +#undef Q5 +#undef Q6 +#undef Q7 +#undef Q8 +#undef Q9 +#undef QA + +static const float q_5[15] = { - (-14 << 15)/15,(-12 << 15)/15,(-10 << 15)/15, - ( -8 << 15)/15,( -6 << 15)/15,( -4 << 15)/15, - ( -2 << 15)/15, 0 ,( 2 << 15)/15, - ( 4 << 15)/15,( 6 << 15)/15,( 8 << 15)/15, - ( 10 << 15)/15,( 12 << 15)/15,( 14 << 15)/15 -}; + (-14 << 15)/15.0,(-12 << 15)/15.0,(-10 << 15)/15.0, + ( -8 << 15)/15.0,( -6 << 15)/15.0,( -4 << 15)/15.0, + ( -2 << 15)/15.0, 0.0 ,( 2 << 15)/15.0, + ( 4 << 15)/15.0,( 6 << 15)/15.0,( 8 << 15)/15.0, + ( 10 << 15)/15.0,( 12 << 15)/15.0,( 14 << 15)/15.0 +}; // // Scale factors for convert_to_float // -static const uint_32 u32_scale_factors[25] = +static const uint32_t u32_scale_factors[25] = { 0x38000000, //2 ^ -(0 + 15) 0x37800000, //2 ^ -(1 + 15) @@ -104,230 +236,179 @@ static const uint_32 u32_scale_factors[25] = static float *scale_factor = (float*)u32_scale_factors; //These store the persistent state of the packed mantissas -static uint_16 m_1[3]; -static uint_16 m_2[3]; -static uint_16 m_4[2]; -static uint_16 m_1_pointer; -static uint_16 m_2_pointer; -static uint_16 m_4_pointer; +static float q_1[2]; +static float q_2[2]; +static float q_4[1]; +static int32_t q_1_pointer; +static int32_t q_2_pointer; +static int32_t q_4_pointer; +static float __inline__ +coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp); //Conversion from bap to number of bits in the mantissas //zeros account for cases 0,1,2,4 which are special cased -static uint_16 qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; - -static void coeff_reset(void); -static sint_16 coeff_get_mantissa(uint_16 bap, uint_16 dithflag); -static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint_32 ch); - -// -// Convert a 0.15 fixed point number into IEEE single -// precision floating point and scale by 2^-exp -// -static inline float -convert_to_float(uint_16 exp, sint_16 mantissa) +static uint16_t qnttztab[16] = { - float x; - - //the scale by 2^-15 is built into the scale factor table - x = mantissa * scale_factor[exp]; + 0, 0, 0, 3, + 0, 4, 5, 6, + 7, 8, 9, 10, + 11, 12, 14, 16 +}; - return x; -} +static void coeff_reset(void); +static float coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp); +static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch); -void -coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples) +void coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples) { - uint_16 i,j; - uint_32 done_cpl = 0; - sint_16 mantissa; + uint16_t i,j; + uint32_t done_cpl = 0; coeff_reset(); - for(i=0; i< bsi->nfchans; i++) - { + for(i=0; i< bsi->nfchans; i++) { for(j=0; j < audblk->endmant[i]; j++) - { - mantissa = coeff_get_mantissa(audblk->fbw_bap[i][j],audblk->dithflag[i]); - samples[i][j] = convert_to_float(audblk->fbw_exp[i][j],mantissa); - } + samples[i][j] = coeff_get_float(audblk->fbw_bap[i][j], audblk->dithflag[i], audblk->fbw_exp[i][j]); - if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) - { + if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) { // ncplmant is equal to 12 * ncplsubnd - // Don't dither coupling channel until channel separation so that - // interchannel noise is uncorrelated + // Don't dither coupling channel until channel + // separation so that interchannel noise is uncorrelated for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) - audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0); + audblk->cpl_flt[j] = coeff_get_float(audblk->cpl_bap[j],0, audblk->cpl_exp[j]); done_cpl = 1; } } //uncouple the channel if necessary - if(audblk->cplinu) - { - for(i=0; i< bsi->nfchans; i++) - { + if(audblk->cplinu) { + for(i=0; i< bsi->nfchans; i++) { if(audblk->chincpl[i]) coeff_uncouple_ch(samples[i],bsi,audblk,i); } } - if(bsi->lfeon) - { + if(bsi->lfeon) { // There are always 7 mantissas for lfe, no dither for lfe for(j=0; j < 7 ; j++) - { - mantissa = coeff_get_mantissa(audblk->lfe_bap[j],0); - samples[5][j] = convert_to_float(audblk->lfe_exp[j],mantissa); - } + samples[5][j] = coeff_get_float(audblk->lfe_bap[j], 0, audblk->lfe_exp[j]); } } -// -//Fetch a mantissa from the bitstream -// -//The mantissa returned is a signed 0.15 fixed point number -// -static sint_16 -coeff_get_mantissa(uint_16 bap, uint_16 dithflag) + +/** + * Fetch a float from the bitstream + **/ + +static float inline coeff_get_float (uint16_t bap, uint16_t dithflag, uint16_t exp) { - uint_16 mantissa; - uint_16 group_code; + uint16_t dummy = 0; //If the bap is 0-5 then we have special cases to take care of - switch(bap) - { + switch(bap) { case 0: if(dithflag) - mantissa = dither_gen(); - else - mantissa = 0; - break; + return (dither_gen() * scale_factor[exp]); + + return 0.0; case 1: - if(m_1_pointer > 2) - { - group_code = bitstream_get(5); - - if(group_code > 26) - goto error; - - m_1[0] = group_code / 9; - m_1[1] = (group_code % 9) / 3; - m_1[2] = (group_code % 9) % 3; - m_1_pointer = 0; - } - mantissa = m_1[m_1_pointer++]; - mantissa = q_1[mantissa]; - break; + if (q_1_pointer >= 0) + return(q_1[q_1_pointer--] * scale_factor[exp]); + + if ((dummy = bitstream_get (5)) > 26) + goto error; + + q_1[1] = q_1_1[dummy]; + q_1[0] = q_1_2[dummy]; + q_1_pointer = 1; + + return (q_1_0[dummy] * scale_factor[exp]); + case 2: + if(q_2_pointer >= 0) + return (q_2[q_2_pointer--] * scale_factor[exp]); - if(m_2_pointer > 2) - { - group_code = bitstream_get(7); + if ((dummy = bitstream_get (7)) > 124) + goto error; - if(group_code > 124) - goto error; + q_2[1] = q_2_1[dummy]; + q_2[0] = q_2_2[dummy]; + q_2_pointer = 1; - m_2[0] = group_code / 25; - m_2[1] = (group_code % 25) / 5 ; - m_2[2] = (group_code % 25) % 5 ; - m_2_pointer = 0; - } - mantissa = m_2[m_2_pointer++]; - mantissa = q_2[mantissa]; - break; + return (q_2_0[dummy] * scale_factor[exp]); case 3: - mantissa = bitstream_get(3); - - if(mantissa > 6) + if ((dummy = bitstream_get (3)) > 6) goto error; - mantissa = q_3[mantissa]; - break; + return (q_3[dummy] * scale_factor[exp]); case 4: - if(m_4_pointer > 1) - { - group_code = bitstream_get(7); + if(q_4_pointer >= 0) + return (q_4[q_4_pointer--] * scale_factor[exp]); - if(group_code > 120) - goto error; + if ((dummy = bitstream_get (7)) > 120) + goto error; - m_4[0] = group_code / 11; - m_4[1] = group_code % 11; - m_4_pointer = 0; - } - mantissa = m_4[m_4_pointer++]; - mantissa = q_4[mantissa]; - break; + q_4[0] = q_4_1[dummy]; + q_4_pointer = 0; - case 5: - mantissa = bitstream_get(4); + return (q_4_0[dummy] * scale_factor[exp]); - if(mantissa > 14) + case 5: + if ((dummy = bitstream_get (4)) > 14) goto error; - mantissa = q_5[mantissa]; - break; + return (q_5[dummy] * scale_factor[exp]); default: - mantissa = bitstream_get(qnttztab[bap]); - mantissa <<= 16 - qnttztab[bap]; + dummy = bitstream_get(qnttztab[bap]); + dummy <<= 16 - qnttztab[bap]; + return ((int16_t)dummy * scale_factor[exp]); } - return mantissa; - - - error: - if(!error_flag) - fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); - error_flag = 1; - - return 0; +#ifdef DEBUG + fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); +#endif + HANDLE_ERROR(); } -// -// Reset the mantissa state -// -static void -coeff_reset(void) + +/** + * Reset the mantissa state + **/ + +static void coeff_reset(void) { - m_1[2] = m_1[1] = m_1[0] = 0; - m_2[2] = m_2[1] = m_2[0] = 0; - m_4[1] = m_4[0] = 0; - m_1_pointer = m_2_pointer = m_4_pointer = 3; + q_1_pointer = q_2_pointer = q_4_pointer = -1; } -// -// Uncouple the coupling channel into a fbw channel -// -static void -coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint_32 ch) + +/** + * Uncouple the coupling channel into a fbw channel + **/ + +static void coeff_uncouple_ch (float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch) { - uint_32 bnd = 0; - uint_32 sub_bnd = 0; - uint_32 i,j; + uint32_t bnd = 0; + uint32_t sub_bnd = 0; + uint32_t i,j; float cpl_coord = 1.0; - uint_32 cpl_exp_tmp; - uint_32 cpl_mant_tmp; - sint_16 mantissa; - + uint32_t cpl_exp_tmp; + uint32_t cpl_mant_tmp; - for(i=audblk->cplstrtmant;icplendmant;) - { - if(!audblk->cplbndstrc[sub_bnd++]) - { + for (i=audblk->cplstrtmant;icplendmant;) { + if (!audblk->cplbndstrc[sub_bnd++]) { cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; - if(audblk->cplcoexp[ch][bnd] == 15) + if (audblk->cplcoexp[ch][bnd] == 15) cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11; else cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10; - cpl_coord = convert_to_float(cpl_exp_tmp,cpl_mant_tmp) * 8.0f; + cpl_coord = (cpl_mant_tmp * scale_factor[cpl_exp_tmp]) * 8.0f; //Invert the phase for the right channel if necessary if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) @@ -336,16 +417,13 @@ coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint_32 ch) bnd++; } - for(j=0;j < 12; j++) - { - //Get new dither values for each channel if necessary, so - //the channels are uncorrelated - if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0) - mantissa = dither_gen(); + for(j=0;j < 12; j++) { + // Get new dither values for each channel if necessary, + // so the channels are uncorrelated + if(audblk->dithflag[ch] && !audblk->cpl_bap[i]) + samples[i] = cpl_coord * (dither_gen() * scale_factor[audblk->cpl_exp[i]]); else - mantissa = audblk->cplmant[i]; - - samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa); + samples[i] = cpl_coord * audblk->cpl_flt[i]; i++; } -- cgit v1.2.3