diff options
Diffstat (limited to 'src/libac3/coeff.c')
-rw-r--r-- | src/libac3/coeff.c | 524 |
1 files changed, 212 insertions, 312 deletions
diff --git a/src/libac3/coeff.c b/src/libac3/coeff.c index 6c95f74a5..2913c18d4 100644 --- a/src/libac3/coeff.c +++ b/src/libac3/coeff.c @@ -21,9 +21,6 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -31,6 +28,7 @@ #include "ac3_internal.h" +#include "decode.h" #include "bitstream.h" #include "dither.h" #include "coeff.h" @@ -38,169 +36,37 @@ // //Lookup tables of 0.15 two's complement quantization values // -#define Q0 ((-2 << 15) / 3.0) -#define Q1 (0) -#define Q2 ((2 << 15) / 3.0) - -static const float q_1_0[ 32 ] = +static const uint16_t q_1[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 -}; + ( -2 << 15)/3, 0,( 2 << 15)/3 +}; -static const float q_1_1[ 32 ] = +static const uint16_t q_2[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 -}; + ( -4 << 15)/5,( -2 << 15)/5, 0, + ( 2 << 15)/5,( 4 << 15)/5 +}; -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] = +static const uint16_t q_3[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 + ( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0, + ( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7 }; -#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 ] = +static const uint16_t q_4[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 + (-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 }; -#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] = +static const uint16_t q_5[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 -}; + (-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 +}; // // Scale factors for convert_to_float @@ -238,200 +104,234 @@ static const uint32_t u32_scale_factors[25] = static float *scale_factor = (float*)u32_scale_factors; //These store the persistent state of the packed mantissas -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); +static uint16_t m_1[3]; +static uint16_t m_2[3]; +static uint16_t m_4[2]; +static uint16_t m_1_pointer; +static uint16_t m_2_pointer; +static uint16_t m_4_pointer; //Conversion from bap to number of bits in the mantissas //zeros account for cases 0,1,2,4 which are special cased -static uint16_t qnttztab[16] = -{ - 0, 0, 0, 3, - 0, 4, 5, 6, - 7, 8, 9, 10, - 11, 12, 14, 16 -}; +static uint16_t qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16}; -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); +static void coeff_reset(void); +static int16_t coeff_get_mantissa(uint16_t bap, uint16_t dithflag); +static void coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch); -void coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples) +// +// Convert a 0.15 fixed point number into IEEE single +// precision floating point and scale by 2^-exp +// +static inline float +convert_to_float(uint16_t exp, int16_t mantissa) { - uint16_t i,j; - uint32_t done_cpl = 0; - - coeff_reset(); - - for(i=0; i< bsi->nfchans; i++) { - for(j=0; j < audblk->endmant[i]; j++) - 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)) { - // ncplmant is equal to 12 * ncplsubnd - // Don't dither coupling channel until channel - // separation so that interchannel noise is uncorrelated - for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) - 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->chincpl[i]) - coeff_uncouple_ch(samples[i],bsi,audblk,i); - } + float x; - } + //the scale by 2^-15 is built into the scale factor table + x = mantissa * scale_factor[exp]; - if(bsi->lfeon) { - // There are always 7 mantissas for lfe, no dither for lfe - for(j=0; j < 7 ; j++) - samples[5][j] = coeff_get_float(audblk->lfe_bap[j], 0, audblk->lfe_exp[j]); - } + return x; } - -/** - * Fetch a float from the bitstream - **/ - -static float inline coeff_get_float (uint16_t bap, uint16_t dithflag, uint16_t exp) +void +coeff_unpack(ac3_state_t *state, audblk_t *audblk, stream_samples_t samples) { - uint16_t dummy = 0; + uint16_t i,j; + uint32_t done_cpl = 0; + int16_t mantissa; - //If the bap is 0-5 then we have special cases to take care of - switch(bap) { - case 0: - if(dithflag) - return (dither_gen() * scale_factor[exp]); - return 0.0; + coeff_reset(); - case 1: - if (q_1_pointer >= 0) - return(q_1[q_1_pointer--] * scale_factor[exp]); + for(i=0; i< state->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); + } - if ((dummy = bitstream_get (5)) > 26) - goto error; + 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 + for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++) + audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0); + done_cpl = 1; + } + } - q_1[1] = q_1_1[dummy]; - q_1[0] = q_1_2[dummy]; - q_1_pointer = 1; + //uncouple the channel if necessary + if(audblk->cplinu) { + for(i=0; i< state->nfchans; i++) { + if(audblk->chincpl[i]) + coeff_uncouple_ch(samples[i],state,audblk,i); + } + } - return (q_1_0[dummy] * scale_factor[exp]); + if(state->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); + } + } +} - case 2: - if(q_2_pointer >= 0) - return (q_2[q_2_pointer--] * scale_factor[exp]); +// +//Fetch a mantissa from the bitstream +// +//The mantissa returned is a signed 0.15 fixed point number +// +static int16_t +coeff_get_mantissa(uint16_t bap, uint16_t dithflag) +{ + uint16_t mantissa; + uint16_t group_code; + + //If the bap is 0-5 then we have special cases to take care of + switch(bap) { + case 0: + if(dithflag) + mantissa = dither_gen(); + else + mantissa = 0; + break; + + 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; + case 2: + + if(m_2_pointer > 2) { + group_code = bitstream_get(7); + + if(group_code > 124) + goto error; + + 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; - if ((dummy = bitstream_get (7)) > 124) - goto error; + case 3: + mantissa = bitstream_get(3); - q_2[1] = q_2_1[dummy]; - q_2[0] = q_2_2[dummy]; - q_2_pointer = 1; + if(mantissa > 6) + goto error; - return (q_2_0[dummy] * scale_factor[exp]); + mantissa = q_3[mantissa]; + break; - case 3: - if ((dummy = bitstream_get (3)) > 6) - goto error; + case 4: + if(m_4_pointer > 1) { + group_code = bitstream_get(7); - return (q_3[dummy] * scale_factor[exp]); + if(group_code > 120) + goto error; - case 4: - if(q_4_pointer >= 0) - return (q_4[q_4_pointer--] * scale_factor[exp]); + 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; - if ((dummy = bitstream_get (7)) > 120) - goto error; + case 5: + mantissa = bitstream_get(4); - q_4[0] = q_4_1[dummy]; - q_4_pointer = 0; + if(mantissa > 14) + goto error; - return (q_4_0[dummy] * scale_factor[exp]); + mantissa = q_5[mantissa]; + break; - case 5: - if ((dummy = bitstream_get (4)) > 14) - goto error; + default: + mantissa = bitstream_get(qnttztab[bap]); + mantissa <<= 16 - qnttztab[bap]; + } - return (q_5[dummy] * scale_factor[exp]); + return mantissa; - default: - dummy = bitstream_get(qnttztab[bap]); - dummy <<= 16 - qnttztab[bap]; - return ((int16_t)dummy * scale_factor[exp]); - } -error: -#ifdef FAST_ERROR - HANDLE_ERROR (); -#else - if(!error_flag) - fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); - error_flag = 1; - - return 0.0; -#endif -} +error: + if(!error_flag) + fprintf(stderr,"** Invalid mantissa - skipping frame **\n"); + error_flag = 1; -/** - * Reset the mantissa state - **/ + return 0; +} -static void coeff_reset(void) +// +// Reset the mantissa state +// +static void +coeff_reset(void) { - q_1_pointer = q_2_pointer = q_4_pointer = -1; + 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; } +// +// Uncouple the coupling channel into a fbw channel +// +static void +coeff_uncouple_ch(float samples[],ac3_state_t *state,audblk_t *audblk,uint32_t ch) +{ + uint32_t bnd = 0; + uint32_t sub_bnd = 0; + uint32_t i,j; + float cpl_coord = 1.0; + uint32_t cpl_exp_tmp; + uint32_t cpl_mant_tmp; + int16_t mantissa; + + for(i=audblk->cplstrtmant;i<audblk->cplendmant;) { + if(!audblk->cplbndstrc[sub_bnd++]) { + cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; + 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; + + //Invert the phase for the right channel if necessary + if(state->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd]) + cpl_coord *= -1; + + 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(); + else + mantissa = audblk->cplmant[i]; -/** - * Uncouple the coupling channel into a fbw channel - **/ + samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa); -static void coeff_uncouple_ch (float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch) -{ - uint32_t bnd = 0; - uint32_t sub_bnd = 0; - uint32_t i,j; - float cpl_coord = 1.0; - uint32_t cpl_exp_tmp; - uint32_t cpl_mant_tmp; - - for (i=audblk->cplstrtmant;i<audblk->cplendmant;) { - if (!audblk->cplbndstrc[sub_bnd++]) { - cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch]; - 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 = (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]) - cpl_coord *= -1; - - 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]) - samples[i] = cpl_coord * (dither_gen() * scale_factor[audblk->cpl_exp[i]]); - else - samples[i] = cpl_coord * audblk->cpl_flt[i]; - - i++; - } + i++; } + } } |