diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 685ed26c108bcc319b8cc983db300cf75c93ee2d..1e35c78c4c590651080c7e4bb8877217efafdb25 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -2416,15 +2416,17 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { - Word16 i, k, win, segmentOffset; - Word32 sqErrorNrg, n; - Word64 sqErrorNrg64; - Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; + Word16 i, k, win, segmentOffset, j; + Word32 sqErrorNrg = 0, n; + move32(); + Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1, exp_sqErrorNrg = 0; + move16(); Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; Word16 c1, c2; Word16 att; /* noise level attenuation factor for transient windows */ Word32 xMax; + Word16 exp_spQ[N_MAX]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -2432,13 +2434,12 @@ void tcx_noise_factor_ivas_fx( assert( nTransWidth <= 16 ); + set16_fx( exp_spQ, x_orig_e, N_MAX ); c1 = sub( shl( nTransWidth, 1 ), 4 ); c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] ); nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ - sqErrorNrg64 = 0; - move64(); n = 0; move32(); @@ -2452,10 +2453,8 @@ void tcx_noise_factor_ivas_fx( /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */ tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */ - tmp1 = norm_l( tmp32 ); - inv_gain2 = round_fx( L_shl( tmp32, tmp1 ) ); - inv_gain2_e = add( sub( 15, tmp1 ), gain_tcx_e ); - inv_gain2 = Inv16( inv_gain2, &inv_gain2_e ); + inv_gain2 = BASOP_Util_Divide3232_Scale( MAX_32, tmp32, &inv_gain2_e ); + inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) ); inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */ inv_gain2_e = add( inv_gain2_e, 2 ); @@ -2588,13 +2587,19 @@ void tcx_noise_factor_ivas_fx( } FOR( k = segmentOffset; k < i - win; k++ ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); sqQ[k] = 0; move32(); + exp_spQ[k] = 0; + move16(); } FOR( ; win > 0; win-- ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k++] = 0; move32(); } @@ -2608,8 +2613,10 @@ void tcx_noise_factor_ivas_fx( win = add( win, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ - sqQ[i] = L_shl( Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ), inv_gain2_e ); + sqQ[i] = Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ); move32(); + exp_spQ[i] = add( x_orig_e, inv_gain2_e ); + move16(); } } IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ @@ -2649,38 +2656,45 @@ void tcx_noise_factor_ivas_fx( } FOR( k = segmentOffset; k < i - win; k++ ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k] = 0; move32(); } FOR( ; win > 0; win-- ) { - sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); sqQ[k++] = 0; move32(); } } - + Word32 tmp4; /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { - tmp2 = W_norm( sqErrorNrg64 ); - sqErrorNrg = W_extract_l( W_shr( sqErrorNrg64, sub( 32, tmp2 ) ) ); // 31 - (x_orig_e - 1) - 32 + tmp2 - tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); - s = add( add( add( x_orig_e, sub( 31, tmp2 ) ), -15 ), s ); + tmp4 = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); + s = add( add( exp_sqErrorNrg, -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; - tmp1 = shl_o( tmp1, s, &Overflow ); + tmp4 = L_shl_o( tmp4, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; } ELSE { - tmp1 = 0; + tmp4 = 0; move16(); } - + FOR( j = 0; j < N_MAX; j++ ) + { + sqQ[j] = L_shl( sqQ[j], sub( x_orig_e, exp_spQ[j] ) ); + move32(); + } /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */ - tmp2 = round_fx( L_shr( L_mult( tmp1, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); - + tmp2 = round_fx( L_shr( Mpy_32_16_1( tmp4, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) ) { tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1;