Loading lib_com/options.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ #define OPT_MCH_DEC_V1_NBE #define OPT_MASA_DEC_V1_NBE #define OPT_MASA_DEC_V2_NBE #define OPT_MCT_ENC_48KB_NBE #define OPT_MCH_DEC_V1_BE #define OPT_MCT_ENC_V2_NBE Loading lib_com/tools.c +2 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,7 @@ void v_sub_fixed( return; } #ifdef VEC_ARITH_OPT_v1 void v_sub_fixed_no_hdrm( const Word32 x1[], /* i : Input vector 1 */ const Word32 x2[], /* i : Input vector 2 */ Loading @@ -794,6 +795,7 @@ void v_sub_fixed_no_hdrm( return; } #endif /* VEC_ARITH_OPT_v1 */ /*-------------------------------------------------------------------* * v_multc_fixed() Loading lib_rend/ivas_objectRenderer_hrFilt_fx.c +144 −4 Original line number Diff line number Diff line Loading @@ -193,7 +193,6 @@ static void GenerateFilter_fx( ) { Word16 qp, p, k, i; Word32 index; Word16 AzIdx[HRTF_MODEL_BSPLINE_NUM_COEFFS][HRTF_MODEL_BSPLINE_NUM_COEFFS], EvIdx[HRTF_MODEL_BSPLINE_NUM_COEFFS]; /* non-zero basis functions */ Word16 num_az_idx[HRTF_MODEL_BSPLINE_NUM_COEFFS]; Word16 num_ev_idx; Loading Loading @@ -255,6 +254,16 @@ static void GenerateFilter_fx( move16(); FOR( p = 0; p < num_ev_idx; p++ ) { #ifdef OPT_MASA_DEC_V1_NBE Word32 expt = L_shl_sat( modelEval->elevBfVec_fx[p], 1 ); FOR( i = 0; i < num_az_idx[p]; i++ ) { modelEval->BM_fx[qp + i] = Mpy_32_32( expt, modelEval->azimBfVec_fx[p][i] ); /*Q30 - ( Q30 * 2 - 31 )*/ // Q30 move32(); BM_idx[qp + i] = add( model->azim_start_idx[EvIdx[p]], AzIdx[p][i] ); move16(); } #else /* OPT_MASA_DEC_V1_NBE */ FOR( i = 0; i < num_az_idx[p]; i++ ) { modelEval->BM_fx[add( qp, i )] = L_shl( Mpy_32_32( modelEval->elevBfVec_fx[p], modelEval->azimBfVec_fx[p][i] ), 1 ); /*Q30 - ( Q30 * 2 - 31 )*/ // Q30 Loading @@ -262,12 +271,21 @@ static void GenerateFilter_fx( BM_idx[add( qp, i )] = add( model->azim_start_idx[EvIdx[p]], AzIdx[p][i] ); move16(); } #endif /* OPT_MASA_DEC_V1_NBE */ qp = add( qp, num_az_idx[p] ); } #ifdef OPT_MASA_DEC_V1_NBE Word16 expL = add( model->AlphaL_e, 1 ); Word16 expR = add( model->AlphaR_e, 1 ); BMEnergiesL_e = add( model->EL_e, 2 ); BMEnergiesR_e = add( model->ER_e, 2 ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Compute HR filters, approximate optimized model evaluation */ FOR( iSec = 0; iSec < HRTF_MODEL_N_SECTIONS; iSec++ ) { #ifndef OPT_MASA_DEC_V1_NBE ETotL = 0; move32(); ETotR = 0; Loading @@ -288,45 +306,102 @@ static void GenerateFilter_fx( BMEnergiesL_e = add( model->EL_e, 2 ); BMEnergiesR_e = add( model->ER_e, 2 ); #else /* OPT_MASA_DEC_V1_NBE */ Word64 temp1 = 0; move64(); Word64 temp2 = 0; move64(); #endif /* OPT_MASA_DEC_V1_NBE */ /* Energy is precalculated part updated with square of BM value. Store index for sorting */ FOR( i = 0; i < qp; i++ ) { #ifdef OPT_MASA_DEC_V1_NBE modelEval->BMEnergiesL[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->EL_fx[( iSec * model->AlphaN ) + BM_idx[i]] ); // exp: model->EL_e + 2 modelEval->BMEnergiesR[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->ER_fx[( iSec * model->AlphaN ) + BM_idx[i]] ); // exp: model->ER_e + 2 #else /* OPT_MASA_DEC_V1_NBE */ modelEval->BMEnergiesL[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->EL_fx[add( i_mult( iSec, model->AlphaN ), BM_idx[i] )] ); // exp: model->EL_e + 2 modelEval->BMEnergiesR[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->ER_fx[add( i_mult( iSec, model->AlphaN ), BM_idx[i] )] ); // exp: model->ER_e + 2 #endif /* OPT_MASA_DEC_V1_NBE */ move32(); move32(); modelEval->BMEnergiesL[i].i = i; move16(); modelEval->BMEnergiesR[i].i = i; move16(); #ifndef OPT_MASA_DEC_V1_NBE ETotL = BASOP_Util_Add_Mant32Exp( ETotL, ETotL_e, modelEval->BMEnergiesL[i].val_fx, BMEnergiesL_e, &ETotL_e ); ETotR = BASOP_Util_Add_Mant32Exp( ETotR, ETotR_e, modelEval->BMEnergiesR[i].val_fx, BMEnergiesR_e, &ETotR_e ); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = W_add( temp1, modelEval->BMEnergiesL[i].val_fx ); // BMEnergiesL_e temp2 = W_add( temp2, modelEval->BMEnergiesR[i].val_fx ); // BMEnergiesR_e #endif /* OPT_MASA_DEC_V1_NBE */ } #ifdef OPT_MASA_DEC_V1_NBE ETotL_e = W_norm( temp1 ); ETotL_e = sub( ETotL_e, 32 ); ETotL = W_shl_sat_l( temp1, ETotL_e ); ETotL_e = sub( BMEnergiesL_e, ETotL_e ); ETotR_e = W_norm( temp2 ); ETotR_e = sub( ETotR_e, 32 ); ETotR = W_shl_sat_l( temp2, ETotR_e ); ETotR_e = sub( BMEnergiesR_e, ETotR_e ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Number of basis components actually used. */ p = s_min( HRTF_MODEL_N_CPTS_VAR[iSec], qp ); SkipSmallest_ValueIndex_fx( modelEval->UseIndsL, modelEval->BMEnergiesL, qp, sub( qp, p ) ); SkipSmallest_ValueIndex_fx( modelEval->UseIndsR, modelEval->BMEnergiesR, qp, sub( qp, p ) ); #ifndef OPT_MASA_DEC_V1_NBE /* Account for lost energy */ FOR( i = 0; i < p; i++ ) { ESynL = BASOP_Util_Add_Mant32Exp( ESynL, ESynL_e, modelEval->BMEnergiesL[modelEval->UseIndsL[i]].val_fx, BMEnergiesL_e, &ESynL_e ); ESynR = BASOP_Util_Add_Mant32Exp( ESynR, ESynR_e, modelEval->BMEnergiesR[modelEval->UseIndsR[i]].val_fx, BMEnergiesR_e, &ESynR_e ); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = 0; move64(); temp2 = 0; move64(); /* Account for lost energy */ FOR( i = 0; i < p; i++ ) { temp1 = W_add( temp1, modelEval->BMEnergiesL[modelEval->UseIndsL[i]].val_fx ); // BMEnergiesL_e temp2 = W_add( temp2, modelEval->BMEnergiesR[modelEval->UseIndsR[i]].val_fx ); // BMEnergiesR_e } ESynL_e = W_norm( temp1 ); ESynL_e = sub( ESynL_e, 32 ); ESynL = W_shl_sat_l( temp1, ESynL_e ); ESynL_e = sub( BMEnergiesL_e, ESynL_e ); ESynR_e = W_norm( temp2 ); ESynR_e = sub( ESynR_e, 32 ); ESynR = W_shl_sat_l( temp2, ESynR_e ); ESynR_e = sub( BMEnergiesR_e, ESynR_e ); #endif /* OPT_MASA_DEC_V1_NBE */ tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ETotL, ESynL, &ScaleL_e ) ); ScaleL_e = add( ScaleL_e, sub( ETotL_e, ESynL_e ) ); ScaleL = Sqrt32( tmp32, &ScaleL_e ); #ifdef OPT_MASA_DEC_V1_NBE ScaleL_e = sub( ScaleL_e, 1 ); #endif /* OPT_MASA_DEC_V1_NBE */ tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ETotR, ESynR, &ScaleR_e ) ); ScaleR_e = add( ScaleR_e, sub( ETotR_e, ESynR_e ) ); ScaleR = Sqrt32( tmp32, &ScaleR_e ); #ifdef OPT_MASA_DEC_V1_NBE ScaleR_e = sub( ScaleR_e, 1 ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Build using only the most energetic components. */ FOR( k = model->iSecFirst[iSec]; k <= model->iSecLast[iSec]; k++ ) { #ifndef OPT_MASA_DEC_V1_NBE modelEval->hrfModL_fx[k] = 0; move32(); modelEval->hrfModR_fx[k] = 0; Loading @@ -337,6 +412,7 @@ static void GenerateFilter_fx( tmp_hrfModR_e = 0; move16(); Word32 index; FOR( i = 0; i < p; i++ ) { index = L_add( BM_idx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i], imult3216( model->AlphaN, k ) ); Loading @@ -348,6 +424,42 @@ static void GenerateFilter_fx( modelEval->hrfModR_fx[k] = BASOP_Util_Add_Mant32Exp( modelEval->hrfModR_fx[k], tmp_hrfModR_e, tmp32, add( model->AlphaR_e, 1 ), &tmp_hrfModR_e ); move32(); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = 0; move64(); temp2 = 0; move64(); FOR( i = 0; i < p; i++ ) { temp1 = W_add( temp1, Mpy_32_32( modelEval->BM_fx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i], model->AlphaL_fx[BM_idx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i] + ( model->AlphaN * k )] ) ); // add(model->AlphaL_e, 1) temp2 = W_add( temp2, Mpy_32_32( modelEval->BM_fx[modelEval->BMEnergiesR[modelEval->UseIndsR[i]].i], model->AlphaR_fx[BM_idx[modelEval->BMEnergiesR[modelEval->UseIndsR[i]].i] + ( model->AlphaN * k )] ) ); // add(model->AlphaR_e, 1) } tmp_hrfModL_e = W_norm( temp1 ); tmp_hrfModL_e = sub( tmp_hrfModL_e, 32 ); modelEval->hrfModL_fx[k] = W_shl_sat_l( temp1, tmp_hrfModL_e ); move32(); tmp_hrfModL_e = sub( expL, tmp_hrfModL_e ); if ( temp1 == 0 ) { tmp_hrfModL_e = 0; move16(); } tmp_hrfModR_e = W_norm( temp2 ); tmp_hrfModR_e = sub( tmp_hrfModR_e, 32 ); modelEval->hrfModR_fx[k] = W_shl_sat_l( temp2, tmp_hrfModR_e ); move32(); tmp_hrfModR_e = sub( expR, tmp_hrfModR_e ); if ( temp2 == 0 ) { tmp_hrfModR_e = 0; move16(); } #endif /* OPT_MASA_DEC_V1_NBE */ /* Account for lost energy */ modelEval->hrfModL_fx[k] = Mpy_32_32( modelEval->hrfModL_fx[k], ScaleL ); move32(); Loading @@ -355,8 +467,13 @@ static void GenerateFilter_fx( move32(); /* NOTE: Assuming that finally, hrfMod values will be <= 1. Hence making it Q30 */ #ifdef OPT_MASA_DEC_V1_NBE modelEval->hrfModL_fx[k] = L_shl( modelEval->hrfModL_fx[k], add( tmp_hrfModL_e, ScaleL_e ) ); // assuming Q30 modelEval->hrfModR_fx[k] = L_shl( modelEval->hrfModR_fx[k], add( tmp_hrfModR_e, ScaleR_e ) ); // assuming Q30 #else /* OPT_MASA_DEC_V1_NBE */ modelEval->hrfModL_fx[k] = L_shl( modelEval->hrfModL_fx[k], sub( add( tmp_hrfModL_e, ScaleL_e ), 1 ) ); // assuming Q30 modelEval->hrfModR_fx[k] = L_shl( modelEval->hrfModR_fx[k], sub( add( tmp_hrfModR_e, ScaleR_e ), 1 ) ); // assuming Q30 #endif /* OPT_MASA_DEC_V1_NBE */ // move32(); move32(); } Loading Loading @@ -487,11 +604,18 @@ static void GenerateITD_fx( } ELSE { #ifdef OPT_MASA_DEC_V2_NBE Word16 temp_e = add( imult1616( EvIdx[p], model->azimDim3 ), elev_offset ); #endif /* OPT_MASA_DEC_V2_NBE */ FOR( i = 0; i < num_az_idx; i++ ) { modelEval->BM_ITD_fx[qp + i] = L_shl( Mpy_32_32( modelEval->elevBfVecITD_fx[p], modelEval->azimBfVecITD_fx[i] ), 1 ); // Q30 move32(); #ifdef OPT_MASA_DEC_V2_NBE BM_idx[qp + i] = add( temp_e, AzIdx[i] ); #else /* OPT_MASA_DEC_V2_NBE */ BM_idx[qp + i] = add( add( imult1616( EvIdx[p], model->azimDim3 ), elev_offset ), AzIdx[i] ); #endif /* OPT_MASA_DEC_V2_NBE */ move16(); } qp = add( qp, num_az_idx ); Loading @@ -506,19 +630,35 @@ static void GenerateITD_fx( } /* Matrix multiplcation (row x column) */ #ifndef OPT_MASA_DEC_V2_NBE modelEval->itdMod_fx = 0; move16(); itdMod_e = 0; move16(); #else /* OPT_MASA_DEC_V2_NBE */ Word64 temp = 0; move64(); Word16 res_e = add( model->W_e, 1 ); #endif /* OPT_MASA_DEC_V2_NBE */ FOR( i = 0; i < qp; i++ ) { Word16 tmp_e; index = BM_idx[i]; move32(); #ifndef OPT_MASA_DEC_V2_NBE Word16 tmp_e; modelEval->itdMod_fx = BASOP_Util_Add_Mant32Exp( modelEval->itdMod_fx, itdMod_e, Mpy_32_32( modelEval->BM_ITD_fx[i], model->W_fx[index] ), add( model->W_e, 1 ), &tmp_e ); itdMod_e = tmp_e; move16(); #else /* OPT_MASA_DEC_V2_NBE */ temp = W_add( temp, Mpy_32_32( modelEval->BM_ITD_fx[i], model->W_fx[index] ) ); #endif /* OPT_MASA_DEC_V2_NBE */ } #ifdef OPT_MASA_DEC_V2_NBE itdMod_e = W_norm( temp ); itdMod_e = sub( itdMod_e, 32 ); modelEval->itdMod_fx = W_shl_sat_l( temp, itdMod_e ); itdMod_e = sub( res_e, itdMod_e ); #endif /* OPT_MASA_DEC_V2_NBE */ Word32 tmp32 = Mpy_32_16_1( modelEval->itdMod_fx, model->resamp_factor_fx ); // Q = 31 - ( itdMod_e + 1 ) Word16 tmp_q = sub( 30, itdMod_e ); Loading lib_rend/ivas_objectRenderer_sfx_fx.c +69 −5 Original line number Diff line number Diff line Loading @@ -191,6 +191,9 @@ static void sincResample_fx( Word16 t_step_e; Word32 t_frac_fx; Word16 t_frac_e; #ifdef OPT_MASA_DEC_V2_NBE Word64 t_frac_fx_acc; #endif /* OPT_MASA_DEC_V2_NBE */ Word64 tmp64_fx; // Qx + 32 const Word32 *p_mid_fx; const Word32 *p_forward_fx; Loading @@ -212,6 +215,10 @@ static void sincResample_fx( /* Compute fractional time step */ t_step_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( length_in, length_out, &t_step_e ) ); // exp(t_step_e) #ifdef OPT_MASA_DEC_V2_NBE t_frac_fx_acc = 0; move64(); #endif /* OPT_MASA_DEC_V2_NBE */ t_frac_fx = 0; move32(); t_frac_e = 0; Loading @@ -224,13 +231,21 @@ static void sincResample_fx( t = extract_l( L_shr( t_frac_plus_eps, sub( 31, t_frac_plus_eps_e ) ) ); // Q0 /* Calculate the sinc-index for the center value of the sinc */ Word32 center_val; Word16 center_val_e; #ifndef OPT_MASA_DEC_V2_NBE Word32 center_val; center_val = BASOP_Util_Add_Mant32Exp( t_frac_plus_eps, t_frac_plus_eps_e, L_negate( L_deposit_h( t ) ), 15, ¢er_val_e ); // exp(center_val_e) center_val_e = add( center_val_e, 6 ); // center_val * SFX_SPAT_BIN_NUM_SUBSAMPLES (i.e. 64) center_val = BASOP_Util_Add_Mant32Exp( center_val, center_val_e, ONE_IN_Q29, 1, ¢er_val_e ); // exp(center_val_e) snc0 = extract_l( L_shr( center_val, sub( 31, center_val_e ) ) ); // Q0 #else /* OPT_MASA_DEC_V2_NBE */ Word64 center_val; center_val = W_sub( t_frac_plus_eps, W_shl( t, sub( 31, t_frac_plus_eps_e ) ) ); // exp(center_val_e) center_val_e = add( t_frac_plus_eps_e, 6 ); Word16 com_e = s_max( 0, center_val_e ); center_val = W_add( W_shr( center_val, sub( com_e, center_val_e ) ), W_shl( 1, sub( 30, com_e ) ) ); // exp(center_val_e) snc0 = extract_l( W_shl_sat_l( center_val, sub( com_e, 31 ) ) ); #endif /* OPT_MASA_DEC_V2_NBE */ /* Run convolution forward and backward from mid point */ p_mid_fx = input_fx + t; // Qx p_forward_fx = p_mid_fx + 1; // Qx Loading @@ -255,7 +270,16 @@ static void sincResample_fx( move32(); /* Advance fractional time */ #ifndef OPT_MASA_DEC_V2_NBE t_frac_fx = BASOP_Util_Add_Mant32Exp( t_frac_fx, t_frac_e, t_step_fx, t_step_e, &t_frac_e ); // exp( t_frac_fx ) #else /* OPT_MASA_DEC_V2_NBE */ t_frac_fx_acc = W_add( t_frac_fx_acc, t_step_fx ); // t_step_e Word16 hdrm = W_norm( t_frac_fx_acc ); hdrm = sub( hdrm, 32 ); t_frac_fx = W_shl_sat_l( t_frac_fx_acc, hdrm ); t_frac_e = sub( t_step_e, hdrm ); move16(); #endif /* OPT_MASA_DEC_V2_NBE */ } return; Loading Loading @@ -292,7 +316,9 @@ void TDREND_firfilt_fx( Word32 step_fx /* Q31 */, gain_tmp_fx /* Q31 */, gain_delta_fx /* Q30 */; Word16 tmp_e; Word64 tmp64_fx; #ifdef OPT_MASA_DEC_V1_NBE Word16 shift = sub( filter_e, 32 ); #endif /* OPT_MASA_DEC_V1_NBE */ gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q30 step_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( gain_delta_fx, subframe_length, &tmp_e ) ); // exp(tmp_e) tmp_e = sub( tmp_e, Q30 ); Loading @@ -306,12 +332,18 @@ void TDREND_firfilt_fx( Copy32( signal_fx + add( sub( subframe_length, filterlength ), 1 ), mem_fx, sub( filterlength, 1 ) ); /* Update memory for next frame */ // Qx /* Convolution */ #ifdef OPT_MASA_DEC_V1_NBE FOR( i = 0; i < intp_count; i++ ) #else /* OPT_MASA_DEC_V1_NBE */ FOR( i = 0; i < subframe_length; i++ ) #endif /* OPT_MASA_DEC_V1_NBE */ { tmp64_fx = 0; move64(); #ifndef OPT_MASA_DEC_V1_NBE tmp_e = 0; move16(); #endif /* OPT_MASA_DEC_V1_NBE */ p_tmp_fx = p_signal_fx + i; // Qx p_filter_fx = filter_fx; // exp(filter_e) Loading @@ -324,18 +356,50 @@ void TDREND_firfilt_fx( } // This is done to keep the output Q same as input Q for signal #ifdef OPT_MASA_DEC_V1_NBE tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx #else /* OPT_MASA_DEC_V1_NBE */ tmp64_fx = W_shl( tmp64_fx, filter_e ); // Qx + 32 tmp_fx = W_extract_h( tmp64_fx ); // Qx #endif /* OPT_MASA_DEC_V1_NBE */ /* Apply linear gain interpolation in case of abrupt gain changes */ gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx move32(); #ifndef OPT_MASA_DEC_V1_NBE IF( LT_16( i, intp_count ) ) { v_add_fx( filter_fx, filter_delta_fx, filter_fx, filterlength ); // exp(filter_e) } } #else /* OPT_MASA_DEC_V1_NBE */ v_add_fx( filter_fx, filter_delta_fx, filter_fx, filterlength ); // exp(filter_e) } FOR( ; i < subframe_length; i++ ) { tmp64_fx = 0; move64(); p_tmp_fx = p_signal_fx + i; // Qx p_filter_fx = filter_fx; // exp(filter_e) FOR( j = 0; j < filterlength; j++ ) { tmp64_fx = W_mac_32_32( tmp64_fx, *p_filter_fx, *p_tmp_fx ); // Qx + (Q31 - filter_e) + 1 p_filter_fx++; // exp(filter_e) p_tmp_fx--; // Qx } // This is done to keep the output Q same as input Q for signal tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx /* Apply linear gain interpolation in case of abrupt gain changes */ gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx move32(); } #endif /* OPT_MASA_DEC_V1_NBE */ return; } Loading
lib_com/options.h +2 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ #define OPT_MCH_DEC_V1_NBE #define OPT_MASA_DEC_V1_NBE #define OPT_MASA_DEC_V2_NBE #define OPT_MCT_ENC_48KB_NBE #define OPT_MCH_DEC_V1_BE #define OPT_MCT_ENC_V2_NBE Loading
lib_com/tools.c +2 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,7 @@ void v_sub_fixed( return; } #ifdef VEC_ARITH_OPT_v1 void v_sub_fixed_no_hdrm( const Word32 x1[], /* i : Input vector 1 */ const Word32 x2[], /* i : Input vector 2 */ Loading @@ -794,6 +795,7 @@ void v_sub_fixed_no_hdrm( return; } #endif /* VEC_ARITH_OPT_v1 */ /*-------------------------------------------------------------------* * v_multc_fixed() Loading
lib_rend/ivas_objectRenderer_hrFilt_fx.c +144 −4 Original line number Diff line number Diff line Loading @@ -193,7 +193,6 @@ static void GenerateFilter_fx( ) { Word16 qp, p, k, i; Word32 index; Word16 AzIdx[HRTF_MODEL_BSPLINE_NUM_COEFFS][HRTF_MODEL_BSPLINE_NUM_COEFFS], EvIdx[HRTF_MODEL_BSPLINE_NUM_COEFFS]; /* non-zero basis functions */ Word16 num_az_idx[HRTF_MODEL_BSPLINE_NUM_COEFFS]; Word16 num_ev_idx; Loading Loading @@ -255,6 +254,16 @@ static void GenerateFilter_fx( move16(); FOR( p = 0; p < num_ev_idx; p++ ) { #ifdef OPT_MASA_DEC_V1_NBE Word32 expt = L_shl_sat( modelEval->elevBfVec_fx[p], 1 ); FOR( i = 0; i < num_az_idx[p]; i++ ) { modelEval->BM_fx[qp + i] = Mpy_32_32( expt, modelEval->azimBfVec_fx[p][i] ); /*Q30 - ( Q30 * 2 - 31 )*/ // Q30 move32(); BM_idx[qp + i] = add( model->azim_start_idx[EvIdx[p]], AzIdx[p][i] ); move16(); } #else /* OPT_MASA_DEC_V1_NBE */ FOR( i = 0; i < num_az_idx[p]; i++ ) { modelEval->BM_fx[add( qp, i )] = L_shl( Mpy_32_32( modelEval->elevBfVec_fx[p], modelEval->azimBfVec_fx[p][i] ), 1 ); /*Q30 - ( Q30 * 2 - 31 )*/ // Q30 Loading @@ -262,12 +271,21 @@ static void GenerateFilter_fx( BM_idx[add( qp, i )] = add( model->azim_start_idx[EvIdx[p]], AzIdx[p][i] ); move16(); } #endif /* OPT_MASA_DEC_V1_NBE */ qp = add( qp, num_az_idx[p] ); } #ifdef OPT_MASA_DEC_V1_NBE Word16 expL = add( model->AlphaL_e, 1 ); Word16 expR = add( model->AlphaR_e, 1 ); BMEnergiesL_e = add( model->EL_e, 2 ); BMEnergiesR_e = add( model->ER_e, 2 ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Compute HR filters, approximate optimized model evaluation */ FOR( iSec = 0; iSec < HRTF_MODEL_N_SECTIONS; iSec++ ) { #ifndef OPT_MASA_DEC_V1_NBE ETotL = 0; move32(); ETotR = 0; Loading @@ -288,45 +306,102 @@ static void GenerateFilter_fx( BMEnergiesL_e = add( model->EL_e, 2 ); BMEnergiesR_e = add( model->ER_e, 2 ); #else /* OPT_MASA_DEC_V1_NBE */ Word64 temp1 = 0; move64(); Word64 temp2 = 0; move64(); #endif /* OPT_MASA_DEC_V1_NBE */ /* Energy is precalculated part updated with square of BM value. Store index for sorting */ FOR( i = 0; i < qp; i++ ) { #ifdef OPT_MASA_DEC_V1_NBE modelEval->BMEnergiesL[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->EL_fx[( iSec * model->AlphaN ) + BM_idx[i]] ); // exp: model->EL_e + 2 modelEval->BMEnergiesR[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->ER_fx[( iSec * model->AlphaN ) + BM_idx[i]] ); // exp: model->ER_e + 2 #else /* OPT_MASA_DEC_V1_NBE */ modelEval->BMEnergiesL[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->EL_fx[add( i_mult( iSec, model->AlphaN ), BM_idx[i] )] ); // exp: model->EL_e + 2 modelEval->BMEnergiesR[i].val_fx = Mpy_32_32( Mpy_32_32( modelEval->BM_fx[i], modelEval->BM_fx[i] ) /*Q29*/, model->ER_fx[add( i_mult( iSec, model->AlphaN ), BM_idx[i] )] ); // exp: model->ER_e + 2 #endif /* OPT_MASA_DEC_V1_NBE */ move32(); move32(); modelEval->BMEnergiesL[i].i = i; move16(); modelEval->BMEnergiesR[i].i = i; move16(); #ifndef OPT_MASA_DEC_V1_NBE ETotL = BASOP_Util_Add_Mant32Exp( ETotL, ETotL_e, modelEval->BMEnergiesL[i].val_fx, BMEnergiesL_e, &ETotL_e ); ETotR = BASOP_Util_Add_Mant32Exp( ETotR, ETotR_e, modelEval->BMEnergiesR[i].val_fx, BMEnergiesR_e, &ETotR_e ); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = W_add( temp1, modelEval->BMEnergiesL[i].val_fx ); // BMEnergiesL_e temp2 = W_add( temp2, modelEval->BMEnergiesR[i].val_fx ); // BMEnergiesR_e #endif /* OPT_MASA_DEC_V1_NBE */ } #ifdef OPT_MASA_DEC_V1_NBE ETotL_e = W_norm( temp1 ); ETotL_e = sub( ETotL_e, 32 ); ETotL = W_shl_sat_l( temp1, ETotL_e ); ETotL_e = sub( BMEnergiesL_e, ETotL_e ); ETotR_e = W_norm( temp2 ); ETotR_e = sub( ETotR_e, 32 ); ETotR = W_shl_sat_l( temp2, ETotR_e ); ETotR_e = sub( BMEnergiesR_e, ETotR_e ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Number of basis components actually used. */ p = s_min( HRTF_MODEL_N_CPTS_VAR[iSec], qp ); SkipSmallest_ValueIndex_fx( modelEval->UseIndsL, modelEval->BMEnergiesL, qp, sub( qp, p ) ); SkipSmallest_ValueIndex_fx( modelEval->UseIndsR, modelEval->BMEnergiesR, qp, sub( qp, p ) ); #ifndef OPT_MASA_DEC_V1_NBE /* Account for lost energy */ FOR( i = 0; i < p; i++ ) { ESynL = BASOP_Util_Add_Mant32Exp( ESynL, ESynL_e, modelEval->BMEnergiesL[modelEval->UseIndsL[i]].val_fx, BMEnergiesL_e, &ESynL_e ); ESynR = BASOP_Util_Add_Mant32Exp( ESynR, ESynR_e, modelEval->BMEnergiesR[modelEval->UseIndsR[i]].val_fx, BMEnergiesR_e, &ESynR_e ); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = 0; move64(); temp2 = 0; move64(); /* Account for lost energy */ FOR( i = 0; i < p; i++ ) { temp1 = W_add( temp1, modelEval->BMEnergiesL[modelEval->UseIndsL[i]].val_fx ); // BMEnergiesL_e temp2 = W_add( temp2, modelEval->BMEnergiesR[modelEval->UseIndsR[i]].val_fx ); // BMEnergiesR_e } ESynL_e = W_norm( temp1 ); ESynL_e = sub( ESynL_e, 32 ); ESynL = W_shl_sat_l( temp1, ESynL_e ); ESynL_e = sub( BMEnergiesL_e, ESynL_e ); ESynR_e = W_norm( temp2 ); ESynR_e = sub( ESynR_e, 32 ); ESynR = W_shl_sat_l( temp2, ESynR_e ); ESynR_e = sub( BMEnergiesR_e, ESynR_e ); #endif /* OPT_MASA_DEC_V1_NBE */ tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ETotL, ESynL, &ScaleL_e ) ); ScaleL_e = add( ScaleL_e, sub( ETotL_e, ESynL_e ) ); ScaleL = Sqrt32( tmp32, &ScaleL_e ); #ifdef OPT_MASA_DEC_V1_NBE ScaleL_e = sub( ScaleL_e, 1 ); #endif /* OPT_MASA_DEC_V1_NBE */ tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ETotR, ESynR, &ScaleR_e ) ); ScaleR_e = add( ScaleR_e, sub( ETotR_e, ESynR_e ) ); ScaleR = Sqrt32( tmp32, &ScaleR_e ); #ifdef OPT_MASA_DEC_V1_NBE ScaleR_e = sub( ScaleR_e, 1 ); #endif /* OPT_MASA_DEC_V1_NBE */ /* Build using only the most energetic components. */ FOR( k = model->iSecFirst[iSec]; k <= model->iSecLast[iSec]; k++ ) { #ifndef OPT_MASA_DEC_V1_NBE modelEval->hrfModL_fx[k] = 0; move32(); modelEval->hrfModR_fx[k] = 0; Loading @@ -337,6 +412,7 @@ static void GenerateFilter_fx( tmp_hrfModR_e = 0; move16(); Word32 index; FOR( i = 0; i < p; i++ ) { index = L_add( BM_idx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i], imult3216( model->AlphaN, k ) ); Loading @@ -348,6 +424,42 @@ static void GenerateFilter_fx( modelEval->hrfModR_fx[k] = BASOP_Util_Add_Mant32Exp( modelEval->hrfModR_fx[k], tmp_hrfModR_e, tmp32, add( model->AlphaR_e, 1 ), &tmp_hrfModR_e ); move32(); } #else /* OPT_MASA_DEC_V1_NBE */ temp1 = 0; move64(); temp2 = 0; move64(); FOR( i = 0; i < p; i++ ) { temp1 = W_add( temp1, Mpy_32_32( modelEval->BM_fx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i], model->AlphaL_fx[BM_idx[modelEval->BMEnergiesL[modelEval->UseIndsL[i]].i] + ( model->AlphaN * k )] ) ); // add(model->AlphaL_e, 1) temp2 = W_add( temp2, Mpy_32_32( modelEval->BM_fx[modelEval->BMEnergiesR[modelEval->UseIndsR[i]].i], model->AlphaR_fx[BM_idx[modelEval->BMEnergiesR[modelEval->UseIndsR[i]].i] + ( model->AlphaN * k )] ) ); // add(model->AlphaR_e, 1) } tmp_hrfModL_e = W_norm( temp1 ); tmp_hrfModL_e = sub( tmp_hrfModL_e, 32 ); modelEval->hrfModL_fx[k] = W_shl_sat_l( temp1, tmp_hrfModL_e ); move32(); tmp_hrfModL_e = sub( expL, tmp_hrfModL_e ); if ( temp1 == 0 ) { tmp_hrfModL_e = 0; move16(); } tmp_hrfModR_e = W_norm( temp2 ); tmp_hrfModR_e = sub( tmp_hrfModR_e, 32 ); modelEval->hrfModR_fx[k] = W_shl_sat_l( temp2, tmp_hrfModR_e ); move32(); tmp_hrfModR_e = sub( expR, tmp_hrfModR_e ); if ( temp2 == 0 ) { tmp_hrfModR_e = 0; move16(); } #endif /* OPT_MASA_DEC_V1_NBE */ /* Account for lost energy */ modelEval->hrfModL_fx[k] = Mpy_32_32( modelEval->hrfModL_fx[k], ScaleL ); move32(); Loading @@ -355,8 +467,13 @@ static void GenerateFilter_fx( move32(); /* NOTE: Assuming that finally, hrfMod values will be <= 1. Hence making it Q30 */ #ifdef OPT_MASA_DEC_V1_NBE modelEval->hrfModL_fx[k] = L_shl( modelEval->hrfModL_fx[k], add( tmp_hrfModL_e, ScaleL_e ) ); // assuming Q30 modelEval->hrfModR_fx[k] = L_shl( modelEval->hrfModR_fx[k], add( tmp_hrfModR_e, ScaleR_e ) ); // assuming Q30 #else /* OPT_MASA_DEC_V1_NBE */ modelEval->hrfModL_fx[k] = L_shl( modelEval->hrfModL_fx[k], sub( add( tmp_hrfModL_e, ScaleL_e ), 1 ) ); // assuming Q30 modelEval->hrfModR_fx[k] = L_shl( modelEval->hrfModR_fx[k], sub( add( tmp_hrfModR_e, ScaleR_e ), 1 ) ); // assuming Q30 #endif /* OPT_MASA_DEC_V1_NBE */ // move32(); move32(); } Loading Loading @@ -487,11 +604,18 @@ static void GenerateITD_fx( } ELSE { #ifdef OPT_MASA_DEC_V2_NBE Word16 temp_e = add( imult1616( EvIdx[p], model->azimDim3 ), elev_offset ); #endif /* OPT_MASA_DEC_V2_NBE */ FOR( i = 0; i < num_az_idx; i++ ) { modelEval->BM_ITD_fx[qp + i] = L_shl( Mpy_32_32( modelEval->elevBfVecITD_fx[p], modelEval->azimBfVecITD_fx[i] ), 1 ); // Q30 move32(); #ifdef OPT_MASA_DEC_V2_NBE BM_idx[qp + i] = add( temp_e, AzIdx[i] ); #else /* OPT_MASA_DEC_V2_NBE */ BM_idx[qp + i] = add( add( imult1616( EvIdx[p], model->azimDim3 ), elev_offset ), AzIdx[i] ); #endif /* OPT_MASA_DEC_V2_NBE */ move16(); } qp = add( qp, num_az_idx ); Loading @@ -506,19 +630,35 @@ static void GenerateITD_fx( } /* Matrix multiplcation (row x column) */ #ifndef OPT_MASA_DEC_V2_NBE modelEval->itdMod_fx = 0; move16(); itdMod_e = 0; move16(); #else /* OPT_MASA_DEC_V2_NBE */ Word64 temp = 0; move64(); Word16 res_e = add( model->W_e, 1 ); #endif /* OPT_MASA_DEC_V2_NBE */ FOR( i = 0; i < qp; i++ ) { Word16 tmp_e; index = BM_idx[i]; move32(); #ifndef OPT_MASA_DEC_V2_NBE Word16 tmp_e; modelEval->itdMod_fx = BASOP_Util_Add_Mant32Exp( modelEval->itdMod_fx, itdMod_e, Mpy_32_32( modelEval->BM_ITD_fx[i], model->W_fx[index] ), add( model->W_e, 1 ), &tmp_e ); itdMod_e = tmp_e; move16(); #else /* OPT_MASA_DEC_V2_NBE */ temp = W_add( temp, Mpy_32_32( modelEval->BM_ITD_fx[i], model->W_fx[index] ) ); #endif /* OPT_MASA_DEC_V2_NBE */ } #ifdef OPT_MASA_DEC_V2_NBE itdMod_e = W_norm( temp ); itdMod_e = sub( itdMod_e, 32 ); modelEval->itdMod_fx = W_shl_sat_l( temp, itdMod_e ); itdMod_e = sub( res_e, itdMod_e ); #endif /* OPT_MASA_DEC_V2_NBE */ Word32 tmp32 = Mpy_32_16_1( modelEval->itdMod_fx, model->resamp_factor_fx ); // Q = 31 - ( itdMod_e + 1 ) Word16 tmp_q = sub( 30, itdMod_e ); Loading
lib_rend/ivas_objectRenderer_sfx_fx.c +69 −5 Original line number Diff line number Diff line Loading @@ -191,6 +191,9 @@ static void sincResample_fx( Word16 t_step_e; Word32 t_frac_fx; Word16 t_frac_e; #ifdef OPT_MASA_DEC_V2_NBE Word64 t_frac_fx_acc; #endif /* OPT_MASA_DEC_V2_NBE */ Word64 tmp64_fx; // Qx + 32 const Word32 *p_mid_fx; const Word32 *p_forward_fx; Loading @@ -212,6 +215,10 @@ static void sincResample_fx( /* Compute fractional time step */ t_step_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( length_in, length_out, &t_step_e ) ); // exp(t_step_e) #ifdef OPT_MASA_DEC_V2_NBE t_frac_fx_acc = 0; move64(); #endif /* OPT_MASA_DEC_V2_NBE */ t_frac_fx = 0; move32(); t_frac_e = 0; Loading @@ -224,13 +231,21 @@ static void sincResample_fx( t = extract_l( L_shr( t_frac_plus_eps, sub( 31, t_frac_plus_eps_e ) ) ); // Q0 /* Calculate the sinc-index for the center value of the sinc */ Word32 center_val; Word16 center_val_e; #ifndef OPT_MASA_DEC_V2_NBE Word32 center_val; center_val = BASOP_Util_Add_Mant32Exp( t_frac_plus_eps, t_frac_plus_eps_e, L_negate( L_deposit_h( t ) ), 15, ¢er_val_e ); // exp(center_val_e) center_val_e = add( center_val_e, 6 ); // center_val * SFX_SPAT_BIN_NUM_SUBSAMPLES (i.e. 64) center_val = BASOP_Util_Add_Mant32Exp( center_val, center_val_e, ONE_IN_Q29, 1, ¢er_val_e ); // exp(center_val_e) snc0 = extract_l( L_shr( center_val, sub( 31, center_val_e ) ) ); // Q0 #else /* OPT_MASA_DEC_V2_NBE */ Word64 center_val; center_val = W_sub( t_frac_plus_eps, W_shl( t, sub( 31, t_frac_plus_eps_e ) ) ); // exp(center_val_e) center_val_e = add( t_frac_plus_eps_e, 6 ); Word16 com_e = s_max( 0, center_val_e ); center_val = W_add( W_shr( center_val, sub( com_e, center_val_e ) ), W_shl( 1, sub( 30, com_e ) ) ); // exp(center_val_e) snc0 = extract_l( W_shl_sat_l( center_val, sub( com_e, 31 ) ) ); #endif /* OPT_MASA_DEC_V2_NBE */ /* Run convolution forward and backward from mid point */ p_mid_fx = input_fx + t; // Qx p_forward_fx = p_mid_fx + 1; // Qx Loading @@ -255,7 +270,16 @@ static void sincResample_fx( move32(); /* Advance fractional time */ #ifndef OPT_MASA_DEC_V2_NBE t_frac_fx = BASOP_Util_Add_Mant32Exp( t_frac_fx, t_frac_e, t_step_fx, t_step_e, &t_frac_e ); // exp( t_frac_fx ) #else /* OPT_MASA_DEC_V2_NBE */ t_frac_fx_acc = W_add( t_frac_fx_acc, t_step_fx ); // t_step_e Word16 hdrm = W_norm( t_frac_fx_acc ); hdrm = sub( hdrm, 32 ); t_frac_fx = W_shl_sat_l( t_frac_fx_acc, hdrm ); t_frac_e = sub( t_step_e, hdrm ); move16(); #endif /* OPT_MASA_DEC_V2_NBE */ } return; Loading Loading @@ -292,7 +316,9 @@ void TDREND_firfilt_fx( Word32 step_fx /* Q31 */, gain_tmp_fx /* Q31 */, gain_delta_fx /* Q30 */; Word16 tmp_e; Word64 tmp64_fx; #ifdef OPT_MASA_DEC_V1_NBE Word16 shift = sub( filter_e, 32 ); #endif /* OPT_MASA_DEC_V1_NBE */ gain_delta_fx = L_sub( Gain_fx, prevGain_fx ); // Q30 step_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( gain_delta_fx, subframe_length, &tmp_e ) ); // exp(tmp_e) tmp_e = sub( tmp_e, Q30 ); Loading @@ -306,12 +332,18 @@ void TDREND_firfilt_fx( Copy32( signal_fx + add( sub( subframe_length, filterlength ), 1 ), mem_fx, sub( filterlength, 1 ) ); /* Update memory for next frame */ // Qx /* Convolution */ #ifdef OPT_MASA_DEC_V1_NBE FOR( i = 0; i < intp_count; i++ ) #else /* OPT_MASA_DEC_V1_NBE */ FOR( i = 0; i < subframe_length; i++ ) #endif /* OPT_MASA_DEC_V1_NBE */ { tmp64_fx = 0; move64(); #ifndef OPT_MASA_DEC_V1_NBE tmp_e = 0; move16(); #endif /* OPT_MASA_DEC_V1_NBE */ p_tmp_fx = p_signal_fx + i; // Qx p_filter_fx = filter_fx; // exp(filter_e) Loading @@ -324,18 +356,50 @@ void TDREND_firfilt_fx( } // This is done to keep the output Q same as input Q for signal #ifdef OPT_MASA_DEC_V1_NBE tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx #else /* OPT_MASA_DEC_V1_NBE */ tmp64_fx = W_shl( tmp64_fx, filter_e ); // Qx + 32 tmp_fx = W_extract_h( tmp64_fx ); // Qx #endif /* OPT_MASA_DEC_V1_NBE */ /* Apply linear gain interpolation in case of abrupt gain changes */ gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx move32(); #ifndef OPT_MASA_DEC_V1_NBE IF( LT_16( i, intp_count ) ) { v_add_fx( filter_fx, filter_delta_fx, filter_fx, filterlength ); // exp(filter_e) } } #else /* OPT_MASA_DEC_V1_NBE */ v_add_fx( filter_fx, filter_delta_fx, filter_fx, filterlength ); // exp(filter_e) } FOR( ; i < subframe_length; i++ ) { tmp64_fx = 0; move64(); p_tmp_fx = p_signal_fx + i; // Qx p_filter_fx = filter_fx; // exp(filter_e) FOR( j = 0; j < filterlength; j++ ) { tmp64_fx = W_mac_32_32( tmp64_fx, *p_filter_fx, *p_tmp_fx ); // Qx + (Q31 - filter_e) + 1 p_filter_fx++; // exp(filter_e) p_tmp_fx--; // Qx } // This is done to keep the output Q same as input Q for signal tmp_fx = W_shl_sat_l( tmp64_fx, shift ); // Qx /* Apply linear gain interpolation in case of abrupt gain changes */ gain_tmp_fx = L_add_sat( gain_tmp_fx, step_fx ); /* Saturating values which just exceeds 1, Q31*/ signal_fx[i] = Mpy_32_32( tmp_fx, gain_tmp_fx ); // Qx move32(); } #endif /* OPT_MASA_DEC_V1_NBE */ return; }