Loading lib_dec/ivas_spar_decoder.c +105 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ #include <assert.h> #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "prot_fx1.h" #include "prot_fx2.h" #include "ivas_prot_fx.h" #endif // IVAS_FLOAT_FIXED #ifdef DUMPS_ENABLED Loading Loading @@ -539,6 +541,16 @@ static float get_random_number( return x; } #ifdef IVAS_FLOAT_FIXED static Word32 matrix_det_fx( const Word32 a00, const Word32 a01, const Word32 a10, const Word32 a11 ) { return L_sub( Mpy_32_32( a00, a11 ), Mpy_32_32( a01, a10 ) ); } #endif static float matrix_det( const float a00, Loading @@ -549,6 +561,85 @@ static float matrix_det( return a00 * a11 - a01 * a10; } #ifdef IVAS_FLOAT_FIXED static void matrix_inverse_fx( Word32 in[3][3], Word32 out[3][3], const Word16 size, Word16 *out_q ) { Word32 det, fac, tmp_32; Word32 eps_fx = 1; move32(); Word16 q_fac, shift = 0, tmp_e = 0; move16(); move16(); IF( EQ_16( size, 1 ) ) { tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q27, L_max( in[0][0], eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); out[0][0] = L_shl( tmp_32, shift ); move32(); *out_q = add( shift, sub( Q15, tmp_e ) ); return; } ELSE IF( EQ_16( size, 2 ) ) { det = matrix_det_fx( in[0][1], in[0][1], in[1][0], in[1][1] ); tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q23, L_max( det, eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); fac = L_shl( tmp_32, shift ); q_fac = add( shift, sub( Q15, tmp_e ) ); out[0][0] = Mpy_32_32( in[1][1], fac ); move32(); out[1][0] = Mpy_32_32( in[1][0], L_negate( fac ) ); move32(); out[0][1] = Mpy_32_32( in[0][1], L_negate( fac ) ); move32(); out[1][1] = Mpy_32_32( in[0][0], fac ); move32(); *out_q = add( Q27, sub( q_fac, 31 ) ); return; } det = L_add( L_sub( Mpy_32_32( in[0][0], matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ) ), Mpy_32_32( in[1][0], matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ) ) ), Mpy_32_32( in[2][0], matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ) ) ); tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q19, L_max( det, eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); fac = L_shl( tmp_32, shift ); q_fac = add( shift, sub( Q15, tmp_e ) ); out[0][0] = Mpy_32_32( matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ), fac ); move32(); out[1][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][2], in[2][0], in[2][2] ), L_negate( fac ) ); move32(); out[2][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][1], in[2][0], in[2][1] ), fac ); move32(); out[0][1] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ), L_negate( fac ) ); move32(); out[1][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[2][0], in[2][2] ), fac ); move32(); out[2][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[2][0], in[2][1] ), L_negate( fac ) ); move32(); out[0][2] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ), fac ); move32(); out[1][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[1][0], in[1][2] ), L_negate( fac ) ); move32(); out[2][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[1][0], in[1][1] ), fac ); move32(); *out_q = add( Q23, sub( q_fac, 31 ) ); return; } #endif static void matrix_inverse( float in[3][3], Loading Loading @@ -772,7 +863,21 @@ void ivas_spar_get_cldfb_gains( } } #ifdef IVAS_FLOAT_FIXED Word32 Tt_t_fx[3][3], Tt_T_inv_fx[3][3]; Word16 input_q = Q27, output_q = 0; FOR( Word16 i = 0; i < num_cf_slots; ++i ) { floatToFixed_arrL( Tt_T[i], Tt_t_fx[i], input_q, num_cf_slots ); } matrix_inverse_fx( Tt_t_fx, Tt_T_inv_fx, num_cf_slots, &output_q ); FOR( Word16 i = 0; i < num_cf_slots; ++i ) { fixedToFloat_arrL( Tt_T_inv_fx[i], Tt_T_inv[i], output_q, num_cf_slots ); } #else matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots ); #endif /* compute the optimal coefficients */ for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) Loading Loading
lib_dec/ivas_spar_decoder.c +105 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ #include <assert.h> #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "prot_fx1.h" #include "prot_fx2.h" #include "ivas_prot_fx.h" #endif // IVAS_FLOAT_FIXED #ifdef DUMPS_ENABLED Loading Loading @@ -539,6 +541,16 @@ static float get_random_number( return x; } #ifdef IVAS_FLOAT_FIXED static Word32 matrix_det_fx( const Word32 a00, const Word32 a01, const Word32 a10, const Word32 a11 ) { return L_sub( Mpy_32_32( a00, a11 ), Mpy_32_32( a01, a10 ) ); } #endif static float matrix_det( const float a00, Loading @@ -549,6 +561,85 @@ static float matrix_det( return a00 * a11 - a01 * a10; } #ifdef IVAS_FLOAT_FIXED static void matrix_inverse_fx( Word32 in[3][3], Word32 out[3][3], const Word16 size, Word16 *out_q ) { Word32 det, fac, tmp_32; Word32 eps_fx = 1; move32(); Word16 q_fac, shift = 0, tmp_e = 0; move16(); move16(); IF( EQ_16( size, 1 ) ) { tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q27, L_max( in[0][0], eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); out[0][0] = L_shl( tmp_32, shift ); move32(); *out_q = add( shift, sub( Q15, tmp_e ) ); return; } ELSE IF( EQ_16( size, 2 ) ) { det = matrix_det_fx( in[0][1], in[0][1], in[1][0], in[1][1] ); tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q23, L_max( det, eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); fac = L_shl( tmp_32, shift ); q_fac = add( shift, sub( Q15, tmp_e ) ); out[0][0] = Mpy_32_32( in[1][1], fac ); move32(); out[1][0] = Mpy_32_32( in[1][0], L_negate( fac ) ); move32(); out[0][1] = Mpy_32_32( in[0][1], L_negate( fac ) ); move32(); out[1][1] = Mpy_32_32( in[0][0], fac ); move32(); *out_q = add( Q27, sub( q_fac, 31 ) ); return; } det = L_add( L_sub( Mpy_32_32( in[0][0], matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ) ), Mpy_32_32( in[1][0], matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ) ) ), Mpy_32_32( in[2][0], matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ) ) ); tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q19, L_max( det, eps_fx ), &tmp_e ); shift = norm_l( tmp_32 ); fac = L_shl( tmp_32, shift ); q_fac = add( shift, sub( Q15, tmp_e ) ); out[0][0] = Mpy_32_32( matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ), fac ); move32(); out[1][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][2], in[2][0], in[2][2] ), L_negate( fac ) ); move32(); out[2][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][1], in[2][0], in[2][1] ), fac ); move32(); out[0][1] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ), L_negate( fac ) ); move32(); out[1][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[2][0], in[2][2] ), fac ); move32(); out[2][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[2][0], in[2][1] ), L_negate( fac ) ); move32(); out[0][2] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ), fac ); move32(); out[1][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[1][0], in[1][2] ), L_negate( fac ) ); move32(); out[2][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[1][0], in[1][1] ), fac ); move32(); *out_q = add( Q23, sub( q_fac, 31 ) ); return; } #endif static void matrix_inverse( float in[3][3], Loading Loading @@ -772,7 +863,21 @@ void ivas_spar_get_cldfb_gains( } } #ifdef IVAS_FLOAT_FIXED Word32 Tt_t_fx[3][3], Tt_T_inv_fx[3][3]; Word16 input_q = Q27, output_q = 0; FOR( Word16 i = 0; i < num_cf_slots; ++i ) { floatToFixed_arrL( Tt_T[i], Tt_t_fx[i], input_q, num_cf_slots ); } matrix_inverse_fx( Tt_t_fx, Tt_T_inv_fx, num_cf_slots, &output_q ); FOR( Word16 i = 0; i < num_cf_slots; ++i ) { fixedToFloat_arrL( Tt_T_inv_fx[i], Tt_T_inv[i], output_q, num_cf_slots ); } #else matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots ); #endif /* compute the optimal coefficients */ for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) Loading