diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index f1e44be78bdfea1016e77b24dd00e2433ca3d2cb..1a0219b2523b6ad44888add522e8a7d116343269 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -376,12 +376,14 @@ void sns_shape_spectrum_fx( { L64_tmp[k] = W_mult_32_32( spectrum[k], scf_int[i] ); // Q = q_spectrum + q_scf_int + 1 move64(); +#ifndef OPT_MCT_ENC_V3_NBE shift = W_norm( L64_tmp[k] ); if ( LT_16( shift, min_shift ) ) { min_shift = shift; move16(); } +#endif } } tmp_k = k; @@ -391,18 +393,29 @@ void sns_shape_spectrum_fx( *length = k; move16(); } +#ifdef OPT_MCT_ENC_V3_NBE + min_shift = W_norm_arr( L64_tmp, k ); +#endif q_tmp = sub( add( add( *q_spectrum, q_scf_int ), min_shift ), 32 ); if ( GT_16( q_tmp, 30 ) ) { q_tmp = 30; move16(); } +#ifdef OPT_MCT_ENC_V3_NBE + shift = sub( q_tmp, add( *q_spectrum, q_scf_int ) ); + FOR( k = 0; k < tmp_k; k++ ) + { + spectrum[k] = W_shl_sat_l( L64_tmp[k], shift ); // q_tmp+1 + move32(); +#else FOR( k = 0; k < tmp_k; k++ ) { L64_tmp[k] = W_shr( L64_tmp[k], sub( add( *q_spectrum, q_scf_int ), q_tmp ) ); // Q = q_tmp+1 move64(); spectrum[k] = W_sat_l( L64_tmp[k] ); // Q = q_tmp+1 move64(); +#endif } *q_spectrum = q_tmp; move16(); @@ -418,6 +431,7 @@ void sns_shape_spectrum_fx( { L64_tmp[k] = W_mult_32_32( spectrum[k], scf_int[i] ); // Q = q_spectrum + q_scf_int + 1 move64(); +#ifndef OPT_MCT_ENC_V3_NBE shift = W_norm( L64_tmp[k] ); test(); if ( LT_16( shift, min_shift ) && NE_64( L64_tmp[k], 0 ) ) @@ -425,6 +439,7 @@ void sns_shape_spectrum_fx( min_shift = shift; move16(); } +#endif } } tmp_k = k; @@ -434,18 +449,29 @@ void sns_shape_spectrum_fx( *length = k; move16(); } +#ifdef OPT_MCT_ENC_V3_NBE + min_shift = W_norm_arr( L64_tmp, k ); +#endif q_tmp = sub( add( add( *q_spectrum, q_scf_int ), min_shift ), 32 ); if ( GT_16( q_tmp, 30 ) ) { q_tmp = 30; move16(); } +#ifdef OPT_MCT_ENC_V3_NBE + shift = sub( q_tmp, add( *q_spectrum, q_scf_int ) ); + FOR( k = 0; k < tmp_k; k++ ) + { + spectrum[k] = W_shl_sat_l( L64_tmp[k], shift ); // q_tmp+1 + move32(); +#else FOR( k = 0; k < tmp_k; k++ ) { L64_tmp[k] = W_shr( L64_tmp[k], sub( add( *q_spectrum, q_scf_int ), q_tmp ) ); // q_tmp+1 move64(); spectrum[k] = W_sat_l( L64_tmp[k] ); // Q = q_tmp+1 move64(); +#endif } *q_spectrum = q_tmp; move16(); diff --git a/lib_com/options.h b/lib_com/options.h index 0f464530e07c877e3d207bfb6a183a8827c79fcf..362cad558310d27b69b017d5c4fb6c4238cca122 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -79,6 +79,7 @@ /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ +#define OPT_MCT_ENC_V3_NBE #define OPT_MCT_ENC_V2_BE #define OPT_MCH_DEC_V1_NBE #define OPT_MASA_DEC_V1_NBE diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index c8fab11a91ed6679f9e42728d3131b390a6b1285..b520d9eeb57e5d478103af673e2b08a571a37695 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -3203,6 +3203,11 @@ void QuantizeTCXSpectrum_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { +#ifdef OPT_MCT_ENC_V3_NBE + Word16 scale = sub( L_norm_arr( spectrum_fx, L_spec ), 2 ); + scale_sig32( spectrum_fx, L_spec, scale ); + *spectrum_e = sub( *spectrum_e, scale ); +#endif sqGain_fx = SQ_gain_estimate_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); } ELSE diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 9ca9eb82a3e656cac093bf48026bca1b3615631c..6ce40b00e3de8307ef7e00fd28acc788b6ca0243 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -1053,6 +1053,10 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain Word32 tmp = 0, tmpp = 0; move32(); move32(); +#ifdef OPT_MCT_ENC_V3_NBE + Word64 ener64_fx; + Word16 tmp_exp; +#endif /* tmp = 0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) + + 0.94f; lowest gain + expected value of the quantization noise energy per quadruple (log10(4/12)) in Q16*/ /* tmpp = 0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) * log2(10) in Q16 */ @@ -1166,9 +1170,21 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain lg_4 = shr( lg, 2 ); +#ifdef OPT_MCT_ENC_V3_NBE + tmp_exp = shl( x_e, 1 ); +#endif /* SNR of quadruples for unit step quantizer and lowest possible gain */ FOR( i = 0; i < lg_4; i++ ) { +#ifdef OPT_MCT_ENC_V3_NBE + ener64_fx = W_mac_32_32( 1, x[0], x[0] ); // exp:2*x_e + ener64_fx = W_mac_32_32( ener64_fx, x[1], x[1] ); // exp:2*x_e + ener64_fx = W_mac_32_32( ener64_fx, x[2], x[2] ); // exp:2*x_e + ener64_fx = W_mac_32_32( ener64_fx, x[3], x[3] ); // exp:2*x_e + s = W_norm( ener64_fx ); + ener = W_extract_h( W_shl( ener64_fx, s ) ); + s = sub( tmp_exp, s ); +#else /* normalization */ s = 15; move16(); @@ -1215,7 +1231,7 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain ener = L_mac( ener, tmp16, tmp16 ); s = shl( sub( x_e, s ), 1 ); - +#endif /* log */ tmp32 = L_add_sat( BASOP_Util_Log2( ener ), L_shl_sat( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */ en[i] = L_add_sat( L_shr( tmp32, 9 ), tmp ); /* 15Q16 */ @@ -1241,8 +1257,13 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain { tmp32 = L_sub( en[i], offset ); +#ifdef OPT_MCT_ENC_V3_NBE + /* avoid SV with 1 bin of amp < 0.5f */ + if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */ +#else /* avoid SV with 1 bin of amp < 0.5f */ IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */ +#endif { ener = L_add( ener, tmp32 ); }