diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 335f61c1e5d300df92356059d3064030f3db7351..3b1a0cf21666618d0ad0f75ddf6170d36cbc2d81 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -2720,25 +2720,59 @@ Word32 dotWord32_16_Mant32Exp( const Word32 *bufX32, /* i: 32-bit buffer with un const Word16 *bufY16, /* i: 16-bit buffer quite right-aligned */ Word16 bufY16_exp, /* i: exponent of buffer bufY16 */ Word16 len, /* i: buffer len to process */ - Word16 *exp ) /* o: result exponent */ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + Word16 *exp, /* o: result exponent */ + const Word16 is_ivas ) /* i: flag indicating IVAS to maintain EVS BE */ +#else + Word16 *exp ) /* o: result exponent */ +#endif { Word32 L_sum; Word16 shift, shift1, i; - shift = getScaleFactor32( bufX32, len ); /* current available headroom */ + shift = getScaleFactor32( bufX32, len ); /* current available headroom */ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + IF( EQ_16( is_ivas, 1 ) ) + { + shift = sub( shift, sub( 15, norm_s( len ) ) ); /* reduced required headroom */ + } + ELSE + { + shift = sub( shift, sub( 14, norm_s( len ) ) ); /* reduced required headroom */ + } +#else shift = sub( shift, sub( 14, norm_s( len ) ) ); /* reduced required headroom */ - L_sum = 0; /* Clear accu */ +#endif + L_sum = 0; /* Clear accu */ move32(); FOR( i = 0; i < len; i++ ) { +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + IF( EQ_16( is_ivas, 1 ) ) + { + L_sum = L_add( L_sum, Mpy_32_16_1( L_shl( bufX32[i], shift ), bufY16[i] ) ); + } + ELSE + { + L_sum = L_mac0( L_sum, round_fx( L_shl( bufX32[i], shift ) ), bufY16[i] ); + } +#else L_sum = L_mac0( L_sum, round_fx( L_shl( bufX32[i], shift ) ), bufY16[i] ); +#endif } shift1 = norm_l( L_sum ); L_sum = L_shl( L_sum, shift1 ); /* return value */ shift = sub( add( bufX32_exp, bufY16_exp ), add( shift, shift1 ) ); +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + IF( EQ_16( is_ivas, 0 ) ) + { + shift = add( shift, 1 ); /* compensate for factor of 2 introduced by L_mac0 */ + } +#else shift = add( shift, 1 ); /* compensate for factor of 2 introduced by L_mac0 */ +#endif /* In case of NULL result, we want to have a 0 exponent too */ if ( L_sum == 0 ) shift = 0; diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index d5283043068cc058b96c41460f52b8c63d1189dc..19b0bb4aaf9535e1e737ce701b326825102876e8 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -864,7 +864,12 @@ Word32 dotWord32_16_Mant32Exp( const Word32 *bufX32, /* i: 32-bit buffer with un const Word16 *bufY16, /* i: 16-bit buffer quite right-aligned */ Word16 bufY16_exp, /* i: exponent of buffer bufY16 */ Word16 len, /* i: buffer len to process */ - Word16 *exp ); /* o: result exponent */ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + Word16 *exp, /* o: result exponent */ + const Word16 is_ivas ); /* i: flag indicating IVAS to maintain EVS BE */ +#else + Word16 *exp ); /* o: result exponent */ +#endif /*!********************************************************************** \brief Converts linear factor or energy to Decibel diff --git a/lib_com/options.h b/lib_com/options.h index a1b758cfc563aca2adef722e54399cc2355c02f1..17408984580afc64e416c57dcba0a0185e93809c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -106,6 +106,7 @@ #define FIX_BASOP_2599_TCA_OVERFLOW /* VA: issue 2599, Fix TCA overflow */ #define FIX_2588_MISSING_CONDITIONS /* VA: Proposed fix to 2588, addition of a condition in lsf_dec */ #define FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI /* Nokia: BASOP issue 2442: Increase accuracy of computations and add additional gain clamp for low energy decorrelated signal rendering. */ +#define FIX_BASOP_1765_MASA1TC_CNG_MISMATCH /* Nokia: BASOP issue 1765: Improve accuracy of FD CNG noise estimation */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 6458662e7e8522d0f2acdea2d7b0c5b6262879dc..f4d4c2c3b77b12e24a49df7fa239fa34ad89de29 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6448,7 +6448,12 @@ void noisy_speech_detection_fx( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ const Word16 vad, /* i : VAD flag */ const Word16 *syn, /* i : i time-domain frame */ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + const Word16 Q, + const Word16 is_ivas ); +#else const Word16 Q ); +#endif void generate_comfort_noise_dec_fx( Word32 **bufferReal, /* o : matrix to real part of i bands */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index f0d79382c224c042ba3e8b1886230ece1e363735..cdb551e700ba6ca8315252aa7e7a4f28f6daebdf 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1549,7 +1549,18 @@ ivas_error acelp_core_dec_fx( IF( st->idchan == 0 && ( st->flag_cna || ( EQ_16( st->cng_type, FD_CNG ) && LE_32( st->total_brate, ACELP_32k ) ) || ( st->cng_type == LP_CNG && LE_32( st->core_brate, SID_2k40 ) ) ) ) { /*Noisy speech detector*/ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + IF( NE_16( st->element_mode, EVS_MONO ) ) + { + noisy_speech_detection_fx( st->hFdCngDec, st->VAD, psyn_fx, st->Q_syn, 1 ); + } + ELSE + { + noisy_speech_detection_fx( st->hFdCngDec, st->VAD, psyn_fx, st->Q_syn, 0 ); + } +#else noisy_speech_detection_fx( st->hFdCngDec, st->VAD, psyn_fx, st->Q_syn ); +#endif st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( st->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ ); move16(); diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 1fdfe44a4d749b9fcab176963c3860d83364668f..fbe877f58c3d65c9cf93063dbe675d412873ac97 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -798,7 +798,11 @@ ivas_error amr_wb_dec_fx( move16(); /*Noisy speech detector*/ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD, syn_fx, st_fx->Q_syn, 0 ); +#else noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD, syn_fx, st_fx->Q_syn ); +#endif st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ ); IF( st_fx->hFdCngDec->hFdCngCom->flag_noisy_speech != 0 ) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index add3a07c325f324e755746fcd5a0cadee4832812..85fde0949d609da0904f7a25015427f4a4023ab8 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -940,7 +940,11 @@ ivas_error evs_dec_fx( * -------------------------------------------------------------- */ HANDLE_FD_CNG_DEC hFdCngDec = st_fx->hFdCngDec; +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD && EQ_16( st_fx->m_frame_type, ACTIVE_FRAME ), output_sp, 0, 0 ); +#else noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD && EQ_16( st_fx->m_frame_type, ACTIVE_FRAME ), output_sp, 0 ); +#endif hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ ); /*Q15*/ if ( hFdCngDec->hFdCngCom->flag_noisy_speech != 0 ) diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index dc24fc6f95d392b159d59871821adf309a494eed..6e44864a92f41cdd0aca3c89f9c980ace78f16a5 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1481,7 +1481,11 @@ void perform_noise_estimation_dec_ivas_fx( FOR( p = 0; p < npart; p++ ) { temp = L_shl( msPeriodog[p], q_shift ); +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + msNoiseEst[p] = Madd_32_16( Mpy_32_16_r( msNoiseEst[p], add( sub( MAX_16, alpha ), 1 ) ), temp, alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/ /* add one to alpha comp to get ONE_IN_Q15 - alpha */ +#else msNoiseEst[p] = Madd_32_16( Mpy_32_16_r( msNoiseEst[p], sub( MAX_16, alpha ) ), temp, alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/ +#endif move32(); } } @@ -1681,7 +1685,11 @@ void perform_noise_estimation_dec_ivas_fx( move16(); } } +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + *ptr_per = Madd_32_16( ( *ptr_per ), enr, add( sub( MAX_16, alpha ), 1 ) ); /*Q31 - enr_e*/ /* add one to alpha comp to get ONE_IN_Q15 - alpha */ +#else *ptr_per = Madd_32_16( ( *ptr_per ), enr, sub( MAX_16, alpha ) ); /*Q31 - enr_e*/ +#endif move32(); ptr_per++; } @@ -2093,7 +2101,12 @@ void noisy_speech_detection_fx( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ const Word16 vad, /*Q0*/ const Word16 *syn, /* i : input time-domain frame Q*/ +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + const Word16 Q, + const Word16 is_ivas ) +#else const Word16 Q ) +#endif { Word16 i; Word32 tmp; @@ -2109,7 +2122,11 @@ void noisy_speech_detection_fx( IF( vad == 0 ) { +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + totalNoise = dotWord32_16_Mant32Exp( hFdCngDec->msNoiseEst, hFdCngDec->msNoiseEst_exp, hFdCngDec->psize_shaping_norm, hFdCngDec->psize_shaping_norm_exp, hFdCngDec->nFFTpart_shaping, &totalNoise_exp, is_ivas ); /*Q31 - totalNoise_exp*/ +#else totalNoise = dotWord32_16_Mant32Exp( hFdCngDec->msNoiseEst, hFdCngDec->msNoiseEst_exp, hFdCngDec->psize_shaping_norm, hFdCngDec->psize_shaping_norm_exp, hFdCngDec->nFFTpart_shaping, &totalNoise_exp ); /*Q31 - totalNoise_exp*/ +#endif /* - logTotalNoise is scaled by LD_DATA_SCALE+2 diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index c64baefe63ce0e9cc2d37760a076376ce568428d..d04d30a06ea645ac8ced5a944bffd2f29a37a7f2 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -1023,7 +1023,11 @@ static void run_min_stats_fx( Copy_Scale_sig32_16( x[ch][0], x_fx_16, L_FRAME16k, 0 ); /* exp(x_e) */ test(); +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + noisy_speech_detection_fx( st->hFdCngDec, save_VAD[ch] && EQ_16( st->m_frame_type, ACTIVE_FRAME ), x_fx_16, sub( Q15, x_e[ch][0] ), 1 ); +#else noisy_speech_detection_fx( st->hFdCngDec, save_VAD[ch] && EQ_16( st->m_frame_type, ACTIVE_FRAME ), x_fx_16, sub( Q15, x_e[ch][0] ) ); +#endif st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( mult_r( 32440 /* 0.99 in Q15 */, st->hFdCngDec->hFdCngCom->likelihood_noisy_speech ), mult_r( st->hFdCngDec->hFdCngCom->flag_noisy_speech, 328 /* 0.01 in Q15 */ ) ); /* Q15 */ move16(); st->lp_noise = st->hFdCngDec->lp_noise; /* Q9.23 */ diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index 59932995308c88f81fc563d19779520b4a2cb3e8..cd03669c32038823979d0781515b0a72b1ecac51 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -837,7 +837,11 @@ void stereo_tcx_core_dec_fx( test(); IF( st->hFdCngDec != NULL && ( EQ_32( st->sr_core, INT_FS_12k8 ) || EQ_32( st->sr_core, INT_FS_16k ) ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) { +#ifdef FIX_BASOP_1765_MASA1TC_CNG_MISMATCH + noisy_speech_detection_fx( st->hFdCngDec, st->VAD && EQ_16( st->m_frame_type, ACTIVE_FRAME ), signal_out_fx, 0, 1 ); +#else noisy_speech_detection_fx( st->hFdCngDec, st->VAD && EQ_16( st->m_frame_type, ACTIVE_FRAME ), signal_out_fx, 0 ); +#endif st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( mult_r( 32440 /* 0.99f in Q15 */, st->hFdCngDec->hFdCngCom->likelihood_noisy_speech ), mult_r( st->hFdCngDec->hFdCngCom->flag_noisy_speech, 328 /* 0.01f in Q15 */ ) ); /* Q15 */ st->lp_noise = st->hFdCngDec->lp_noise; /* Q9.23 */ move16();