diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 80996fb819f88f50a2c47220c153cd57ede3e915..46284eb325f30e6bfb818232a26118031c55a055 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1198,6 +1198,13 @@ void ivas_get_ism_sid_quan_bitbudget( int16_t *nBits_sce_id /* o : number of Q bits for sce_id_dtx */ ); +#ifdef CR_FIX_ISM_DTX_INFINITE_CNG_ON_TRAILING_SILENCE +void ivas_ism_dtx_limit_noise_energy_for_near_silence( + SCE_DEC_HANDLE hSCE[], /* i/o: SCE encoder structures */ + const int16_t sce_id_dtx, /* i : SCE DTX ID */ + const int16_t nchan_transport /* i : number of transport channels */ +); +#endif /*----------------------------------------------------------------------------------* * DFT Stereo prototypes diff --git a/lib_com/options.h b/lib_com/options.h index 9a841e2ac77a382e49c040c108ce5ac87686bb4d..fc1d8a98b29bc8044aa46dc3bb4f3b6539706bfe 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -226,10 +226,10 @@ /* any switch which is non-be wrt operation points tested in selection */ /* all switches in this category should start with "CR_" */ #define CR_FIX_585_MASA_2TC_DTX_EXT /* Nokia: issue 585: fixes transition artifacts in MASA 2TC DTX by applying correct condition */ +#define CR_FIX_ISM_DTX_INFINITE_CNG_ON_TRAILING_SILENCE /* FhG: fix for cng in ISM DTX on sudden silence periods */ /* ##################### End NON-BE CR switches ########################### */ - /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index b8552427d82be9a92d7ddcaaf52c7e07167f640a..70136e9592514497307a36cb1898aa451c6b625c 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -196,6 +196,16 @@ ivas_error ivas_dec( { return error; } +#ifdef CR_FIX_ISM_DTX_INFINITE_CNG_ON_TRAILING_SILENCE + + /* decode dominant object first so the noise energy of the other objects can be limited */ + if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); +#endif } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { @@ -214,10 +224,21 @@ ivas_error ivas_dec( for ( n = 0; n < st_ivas->nchan_transport; n++ ) { +#ifdef CR_FIX_ISM_DTX_INFINITE_CNG_ON_TRAILING_SILENCE + /* for DTX frames, dominant object has already been decoded before */ + if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) ) + { + if ( ( error = ivas_sce_dec( st_ivas, n, &output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( ( error = ivas_sce_dec( st_ivas, n, &output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) { return error; } +#endif /* HP filtering */ hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 1c48050bee21382019bfebade5f3832a449e299a..fada7caaecd56a2c8658c8188d6133b2af0cf6b1 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include +#include #include "options.h" #include "ivas_prot.h" #include "prot.h" @@ -156,3 +157,51 @@ ivas_error ivas_ism_dtx_dec( return IVAS_ERR_OK; } + + +#ifdef CR_FIX_ISM_DTX_INFINITE_CNG_ON_TRAILING_SILENCE +/*-------------------------------------------------------------------* + * ivs_ism_dtx_limit_noise_energy_for_near_silence() + * + * for DTX frames where the energy of the sent noise estimate of the dominant object + * is near silence, limit the other objects CNG energies to the same level + *-------------------------------------------------------------------*/ + +void ivas_ism_dtx_limit_noise_energy_for_near_silence( + SCE_DEC_HANDLE hSCE[], /* i/o: SCE encoder structures */ + const int16_t sce_id_dtx, /* i : SCE DTX ID */ + const int16_t nchan_transport /* i : number of transport channels */ +) +{ + float fac, cng_noise_nrg_obj, cng_noise_nrg_dominant; + int16_t ch, cng_noise_level_len; + HANDLE_FD_CNG_COM hFdCngCom; + + hFdCngCom = hSCE[sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom; + cng_noise_level_len = hFdCngCom->stopFFTbin - hFdCngCom->startBand; + cng_noise_nrg_dominant = dotp( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + + if ( cng_noise_nrg_dominant < 1.f ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + if ( ch == sce_id_dtx ) + { + continue; + } + + hFdCngCom = hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom; + cng_noise_level_len = hFdCngCom->stopFFTbin - hFdCngCom->startBand; + cng_noise_nrg_obj = dotp( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + + if ( cng_noise_nrg_obj > cng_noise_nrg_dominant ) + { + fac = sqrtf( cng_noise_nrg_dominant / cng_noise_nrg_obj ); + v_multc( hFdCngCom->cngNoiseLevel, fac, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + } + } + } + + return; +} +#endif diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c index b9272ad2453a67d0d8928ecc269bbca03acbbd1b..c502bedf6cd299161e7fe9c45fb9729ec8263f07 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -312,7 +312,6 @@ void ivas_ism_get_sce_id_dtx( SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ const int16_t nchan_transport, /* i : number of transport channels */ const int16_t input_frame /* i : input frame length per channel */ - ) { float tmp_energy[MAX_NUM_OBJECTS];