diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 2db2a465119df16834cf15fe649ff924198e9f95..72af37ef8aec31483e6bfa982721f3af967deb27 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -805,16 +805,25 @@ enum fea_names #define MAX_MDCT_ITD_BRATE IVAS_64k #define SNS_LOW_BR_MODE -1 -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ -#define MDCT_ST_PLC_FADEOUT_START_FRAME 3 +#define MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG 0.001f +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS +#define MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME 2 * FRAMES_PER_SEC +#define MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN 20 +#endif typedef enum { EQUAL_CORES, TCX10_IN_0_TCX20_IN_1, TCX20_IN_0_TCX10_IN_1, } TONALMDCTCONC_NOISE_GEN_MODE; + +typedef enum { + ON_FIRST_LOST_FRAME, + ON_FIRST_GOOD_FRAME, +} TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE; #endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 10516239c9538b09e775285680c1f3036ea9a333..eafa392c8c60527789c7be540a09ea9372e7b48a 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1950,15 +1950,12 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - const int16_t isMCT, -#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ); void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1973,7 +1970,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame */ @@ -2058,7 +2055,12 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : bad frame indicator */ + const int16_t is_mct /* i : flag to signal MCT or SMDCT */ +#else const int16_t bfi /* i : bad frame indicator */ +#endif ); void ms_processing( @@ -2091,7 +2093,12 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ + const int16_t bfi_apply_damping /* i : decoder element mode */ +#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ +#endif ); void IGFEncStereoEncoder( @@ -5442,7 +5449,7 @@ ivas_error ivas_orient_trk_GetTrackedOrientation( float *roll ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -5454,6 +5461,18 @@ void TonalMdctConceal_create_concealment_noise( const int16_t crossfade_gain, const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ); + +void TonalMdctConceal_whiten_noise_shape( + Decoder_State *st, + const int16_t L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE +); + +int16_t get_igf_startline( + Decoder_State *st, + int16_t L_frame, + int16_t L_frameTCX +); #endif float rand_triangular_signed( diff --git a/lib_com/ivas_sns_com.c b/lib_com/ivas_sns_com.c index 51f5fcee64c94f68dc271eb94d7c20d1abe85c51..b1555a038baa267d666d7f912414102fc34e3fd9 100644 --- a/lib_com/ivas_sns_com.c +++ b/lib_com/ivas_sns_com.c @@ -37,7 +37,7 @@ #include "ivas_prot.h" #include "rom_com.h" #include -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #include #endif #ifdef DEBUGGING @@ -45,7 +45,7 @@ #endif #include "wmops.h" -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /*------------------------------------------------------------------- * sns_compute_scf() diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index 7093a9109349c1bc02fc7a9a2e63a7af3ad3be3d..4ca10255a71a5d5da84d26eaa8e32b5474cde311 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -68,11 +68,10 @@ static void SpectrumWeighting_Init( * initialize a PsychoacousticParameters structure *-------------------------------------------------------------------*/ -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE static #endif - ivas_error - PsychoacousticParameters_Init( +ivas_error PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ const int8_t nBands, /* i : Number of spectrum subbands */ diff --git a/lib_com/options.h b/lib_com/options.h index 7f07d86a9c994ae58147db937e21d8c553500979..3c30e33d86a712ab0ef4f87270d26ea19d411eb8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -142,7 +142,8 @@ #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -/*#define FIX_IVAS_185_MDCT_ST_PLC_FADEOUT*/ /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ +#define MDCT_STEREO_PLC_FADE_2_BG_NOISE /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ +#define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ #define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 4c91c8cd52b0e321b8a24d216eb733209d5967e1..f793d75bb7da3b2f26f80e779bb18da3bd909cd2 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -5145,7 +5145,7 @@ void decod_amr_wb( ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -6776,7 +6776,7 @@ void enc_acelp_tcx_main( void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t MCT_flag #endif @@ -7893,7 +7893,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t isMCT #endif @@ -7949,7 +7949,7 @@ void decoder_acelp( void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -8140,7 +8140,7 @@ void con_tcx( const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const float *A_cng #endif @@ -8689,7 +8689,7 @@ void configureFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -8700,7 +8700,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ @@ -9202,7 +9202,7 @@ void open_decoder_LPD( const int32_t last_total_brate, /* i : last total bitrate */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t is_mct, /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call during initialization */ @@ -9245,7 +9245,7 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t last_element_mode /* i : last element mode */ #endif @@ -9529,7 +9529,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t numSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t infoIGFStartLine #endif @@ -9567,8 +9567,9 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, /*IN/OUT*/ const float tiltCompFactor, const float crossfadeGain, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const float concealment_noise[L_FRAME48k], + const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ); @@ -9604,7 +9605,7 @@ void RefineTonalComponents( float floorPowerSpectrum, const PsychoacousticParameters *psychParamsCurrent ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ivas_error PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 5c601c5825375bca56befc276bdec8d527b8d506..684c12b57e3843545a0fc5ba96369ae2a49f1a0d 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -160,7 +160,7 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( NULL, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( NULL, NULL, NULL, st, 0, 0 ); @@ -534,7 +534,7 @@ ivas_error acelp_core_dec( { st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1123,7 +1123,7 @@ ivas_error acelp_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { /*Noise estimate*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1192,7 +1192,7 @@ ivas_error acelp_core_dec( /*Noise estimate*/ if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index c220c8201e42744efb4c0de9041e4c8d9614e23f..907d90e9abf7b1a8c3443180800c27c2193387e0 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -621,7 +621,7 @@ ivas_error amr_wb_dec( /*VAD only for non inactive frame*/ st->VAD = ( st->VAD && ( st->coder_type != INACTIVE ) ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( syn, NULL, NULL, st, 0, 0 ); diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index d2d94799ef04fc4ec848738aa0492f1a02226369..bc8d95e24f411f537ecdcd6c034f88d255e93d40 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -57,7 +57,7 @@ void open_decoder_LPD( const int32_t last_total_brate, const int16_t bwidth, const int16_t is_mct, /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ @@ -552,9 +552,8 @@ void open_decoder_LPD( { st->hTcxDec->prev_widow_left_rect = 0; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - /* Todo: should be considered for other stereo modes as well */ - if ( is_init || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( is_init || is_mct || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = PLC_MIN_CNG_LEV; st->hTcxDec->NoiseLevelIndex_bfi = PLC_MIN_STAT_BUFF_SIZE - 1; diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index f952a8638fa668f270c78e33c042b62624a2b668..c2084f3f12332620b8c4fd55118b9d4ffc70222a 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -57,7 +57,7 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t last_element_mode /* i : last element mode */ #endif @@ -109,7 +109,7 @@ void mode_switch_decoder_LPD( if ( fscale != st->fscale || switchWB || bSwitchFromAmrwbIO || st->last_codec_mode == MODE1 || st->force_lpd_reset ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, last_element_mode, 0 ); #else open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, 0 ); diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index 422104ac4380f7df7ea72735711ed598f66cd161..a28630886e53ebbfbbe27405a53494f90ed6d3c4 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -478,7 +478,7 @@ void decoder_LPD( if ( bfi && st->last_core != ACELP_CORE ) { /* PLC: [TCX: TD PLC] */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -650,7 +650,7 @@ void decoder_LPD( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index b1bfd3e225d87eb29551e5ef57848bd16c7b0f7c..1ca75fff209bdd9102d3329d73861c68aa90f5e2 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -198,7 +198,7 @@ static void decode_frame_type( st->rate_switching_init = 1; /* Reconf Core */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0 ); diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 37c64f18a3b4106c47ad3329135875d13ad56ac3..925b561fd6ad28365bd111442e22557fb11e7669 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -55,7 +55,7 @@ void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t MCT_flag #endif @@ -94,7 +94,7 @@ void getTCXMode( } st->coder_type = INACTIVE; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) { st->VAD = get_next_indice( st0, 1 ); @@ -793,7 +793,7 @@ void dec_prm( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index ae5faa4d73a1dd7473a6350b7892f9353f76cc66..502433517e87c41442cc4afa9590b1f6d85bc953 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -98,13 +98,9 @@ void decoder_tcx( init_tcx_info( st, L_frame_glob, L_frameTCX_glob, frame_cnt, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, 0, /* <- isMCT */ frame_cnt ); -#else decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, frame_cnt ); -#endif -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_noisefilling( st, NULL, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, 0, frame_cnt ); #else decoder_tcx_noisefilling( st, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, frame_cnt ); @@ -133,7 +129,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t isMCT #endif @@ -188,7 +184,7 @@ void decoder_tcx_post( /* PLC: [TCX: Fade-out] * PLC: update or retrieve the background level */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi == 0 && st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) && st->clas_dec == UNVOICED_CLAS ) #else if ( bfi == 0 && st->tcxonly && st->clas_dec == UNVOICED_CLAS ) @@ -206,6 +202,20 @@ void decoder_tcx_post( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / ( level_syn + 0.01f ); +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS + + if ( st->element_mode == IVAS_CPE_MDCT && ! isMCT ) + { + if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) + { + gainCNG = 0.f; + } + else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) + { + gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif } else { @@ -696,9 +706,6 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ1, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - const int16_t isMCT, -#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ) { @@ -913,16 +920,7 @@ void decoder_tcx_invQ( hTcxDec->damping = 1; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - else if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - *gain_tcx = hTcxDec->old_gaintcx_bfi; - hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); - } - else if ( st->element_mode != IVAS_CPE_MDCT || !isMCT ) -#else else -#endif { *gain_tcx = hTcxDec->old_gaintcx_bfi; hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); @@ -1079,7 +1077,7 @@ void decoder_tcx_invQ( void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1094,7 +1092,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame*/ @@ -1120,6 +1118,9 @@ void decoder_tcx_noisefilling( *-----------------------------------------------------------------*/ /* Init lengths */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX ); +#else if ( st->igf == 0 ) { if ( st->narrowBand == 0 ) @@ -1137,6 +1138,7 @@ void decoder_tcx_noisefilling( { infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); } +#endif noiseFillingSize = L_spec; if ( st->igf ) @@ -1248,7 +1250,7 @@ void decoder_tcx_noisefilling( if ( !bfi && st->element_mode != IVAS_CPE_MDCT ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2, infoIGFStartLine ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2 ); @@ -1261,8 +1263,8 @@ void decoder_tcx_noisefilling( { /* set f to 1 to not fade out */ /* set f to 0 to immediately switch to white noise */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - if ( st->tcxonly && st->element_mode != IVAS_CPE_MDCT ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) ) #else if ( st->tcxonly ) #endif @@ -1304,14 +1306,14 @@ void decoder_tcx_noisefilling( noiseTiltFactor = 1.0f; tcxGetNoiseFillingTilt( A, L_frame, ( total_brate >= ACELP_13k20 && !st->rf_flag ), &noiseTiltFactor ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !isMCT ) { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } else { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } #else TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, infoIGFStartLine ); @@ -1393,7 +1395,7 @@ void decoder_tcx_noiseshaping_igf( * Noise shaping in frequency domain (1/Wz) * *-----------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->igf && ( !bfi || ( st->element_mode == IVAS_CPE_MDCT && st->prev_bfi ) ) ) #else if ( st->igf && !bfi ) @@ -1943,7 +1945,12 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ - const int16_t bfi /* i : bad frame indicator */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : bad frame indicator */ + const int16_t is_mct /* i : flag to signal MCT or SMDCT */ +#else + const int16_t bfi /* i : bad frame indicator */ +#endif ) { int16_t coreMsMask[N_MAX]; @@ -1996,7 +2003,11 @@ void decoder_tcx_IGF_stereo( igfGridIdx = ( sts[0]->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; } +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi, is_mct ); +#else IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi ); +#endif } return; diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c index 18a71c9939969ca0e140226fbb15ef552049de6a..d72e88da5f490c7b8181b8a6fd7085c658f9087b 100644 --- a/lib_dec/er_dec_tcx.c +++ b/lib_dec/er_dec_tcx.c @@ -34,6 +34,8 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ +#include "cnst.h" +#include "ivas_cnst.h" #include #include #include "options.h" @@ -57,7 +59,7 @@ void con_tcx( const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const float *A_cng #endif @@ -279,19 +281,7 @@ void con_tcx( st->bpf_gain_param = 0; /* PLC: calculate damping factor */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); -#endif + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); if ( st->nbLostCmpt == 1 ) { @@ -350,19 +340,7 @@ void con_tcx( set_f( pitch_buf, (float) L_SUBFR, st->nb_subfr ); /* PLC: calculate damping factor */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); -#endif + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); } /*-----------------------------------------------------------------* @@ -459,7 +437,7 @@ void con_tcx( /* PLC: [TCX: Fade-out] retrieve background level */ tmp = 1.0f; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( A_cng != NULL ) { gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_cng, L_frame / 4, st->preemph_fac, 1 ) / 4.f; @@ -474,6 +452,20 @@ void con_tcx( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / gainSynthDeemph; + +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS + if ( st->element_mode == IVAS_CPE_MDCT && A_cng != NULL ) + { + if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) + { + gainCNG = 0.f; + } + else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) + { + gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif } else { @@ -569,26 +561,13 @@ void con_tcx( mvr2r( buf, mem_syn, M ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( A_cng != NULL ) { - if ( ( st->nbLostCmpt == 1 && st->idchan == 0 ) || ( st->nbLostCmpt == 2 && st->idchan == 1 ) ) - { - float lsp_cng[M]; - - lpc_from_spectrum( st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->startBand, st->hFdCngDec->hFdCngCom->stopFFTbin, 0.f ); - - a2lsp_stab( st->hFdCngDec->hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - } - - if ( alpha != 1.0f ) + if ( st->plcBackgroundNoiseUpdated && alpha != 1.0f ) { - float lsp_local[M]; - float lsp_fade[M]; - float alpha_inv; + float lsp_local[M], lsp_fade[M], alpha_inv; - wmops_sub_start( "Fade LSPs" ); alpha_inv = 1.0f - alpha; a2lsp_stab( A_local, lsp_local, lsp_local ); @@ -599,7 +578,6 @@ void con_tcx( } lsp2a_stab( lsp_fade, A_local, M ); - wmops_sub_end(); } } #endif diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index b51ed8d6eacb0ed9572ee56853cd5a152d1cf11b..e03b2ff2bc63b860983c33cc1b10c1d5abd95827 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -676,7 +676,7 @@ ivas_error evs_dec( st->lp_noise = st->hFdCngDec->lp_noise; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); #else ApplyFdCng( output, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 974d046368d5d5f31edd11f30bfb2cb0b89946fa..85d82d953c821d3c15c84b3109d6ea458dc20207 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -368,7 +368,7 @@ void deleteFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -384,7 +384,7 @@ void ApplyFdCng( int16_t j, k; float factor; float lsp_cng[M]; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t L_frame, last_L_frame; int32_t sr_core; @@ -419,7 +419,7 @@ void ApplyFdCng( /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ /* set noise estimation inactive when we have bit errors, as no update with noise generated by corrupt frame (biterror) should be performed. */ if ( concealWholeFrame == 0 && -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ( timeDomainInput == NULL || ( *timeDomainInput( -FLT_MAX ) && *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && @@ -435,7 +435,7 @@ void ApplyFdCng( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -471,7 +471,7 @@ void ApplyFdCng( } } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); @@ -488,7 +488,7 @@ void ApplyFdCng( if ( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -496,65 +496,47 @@ void ApplyFdCng( } } +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) && sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) { -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 ); #else - if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) - { - float scf[SNS_NPTS]; - float scf_int[FDNS_NPTS]; - float whitenend_noise_shape[L_FRAME16k]; - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr; - - wmops_sub_start( "get scfs for bg" ); + if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) ) + { + /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ - inc = ( st->core > TCX_20 ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = cngNoiseLevel; + /* always set psychParameters for MDCT-Stereo ... */ + if ( st->element_mode == IVAS_CPE_MDCT && st->hTonalMDCTConc != NULL ) + { + st->hTonalMDCTConc->psychParams = ( st->core == TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10; + } - set_zero( whitenend_noise_shape, start_idx ); - for ( j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - if ( st->core == TCX_20_CORE ) + /* ... but do actual computations only if sufficient energy in noise shape */ + if ( sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) + { + if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; + TonalMdctConceal_whiten_noise_shape( st, L_frame, ON_FIRST_LOST_FRAME ); } - else + else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE ) { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); + a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); + mvr2r( lsp_cng, st->lspold_cng, M ); + lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); } - - sns_compute_scf( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scf_int, scf, ENC ); - sns_interpolate_scalefactors( st->hTonalMDCTConc->scaleFactorsBackground, scf, DEC ); - sns_shape_spectrum( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame ); - - mvr2r( whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx ); - wmops_sub_end(); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); + st->plcBackgroundNoiseUpdated = 1; } #endif +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); mvr2r( lsp_cng, st->lspold_cng, M ); lsp2lsf( lsp_cng, st->lsf_cng, M, st->sr_core ); -#endif st->plcBackgroundNoiseUpdated = 1; +#endif } break; @@ -567,7 +549,7 @@ void ApplyFdCng( if ( st != NULL && st->cng_type == LP_CNG ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -582,7 +564,7 @@ void ApplyFdCng( /* This sets the new CNG levels until a SID update overwrites it */ mvr2r( hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); #else st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame ); @@ -668,7 +650,7 @@ void ApplyFdCng( default: break; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE wmops_sub_end(); #endif @@ -685,7 +667,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure containing all buffers and variables */ @@ -720,7 +702,7 @@ void perform_noise_estimation_dec( float temp, ftemp, delta; float wght; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( !( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) ) { /* Perform STFT analysis */ @@ -962,7 +944,7 @@ void perform_noise_estimation_dec( } else { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) { /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index 55e526d6654fdd5f5d136597d8efdcc543e7a112..fecc8e96df15820c08b5a8eb524ca86bd96bfc18 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -679,7 +679,12 @@ static void IGF_appl( float *pSpectralData, /* i/o: Q31 | MDCT spectrum */ const float *igf_spec, /* i : Q31 | prepared IGF spectrum */ float *virtualSpec, /* o : Q31 | virtual IGF spectrum, used for temp flattening */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + int16_t *flag_sparse, /* o : Q0 | temp flattening indicator */ + const int16_t bfi_apply_damping /* i : flag to indicate if damping for lost frames should be applied */ +#else int16_t *flag_sparse /* o : Q0 | temp flattening indicator */ +#endif ) { H_IGF_GRID hGrid; @@ -855,7 +860,11 @@ static void IGF_appl( for ( sfb = start_sfb; sfb < stop_sfb; sfb++ ) { +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( bfi_apply_damping && hPrivateData->frameLossCounter > 0 ) +#else if ( hPrivateData->frameLossCounter > 0 ) +#endif { gain[sfb] = min( gain[sfb], 12.f ); @@ -1212,7 +1221,11 @@ void IGFDecApplyMono( /* apply IGF in three steps: */ IGF_prep( hPrivateData, igfGridIdx, hIGFDec->infoTCXNoise, igf_spec, hPrivateData->pSpecFlat, element_mode ); IGF_calc( hPrivateData, igfGridIdx, spectrum, igf_spec ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse, 1 ); +#else IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse ); +#endif } /* reset TCX noise indicator vector */ @@ -1238,7 +1251,12 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ + const int16_t bfi_apply_damping +#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ +#endif ) { IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, hPrivateDataR; @@ -1335,8 +1353,13 @@ void IGFDecApplyStereo( IGF_calc( hPrivateDataL, igfGridIdx, spectrumL, igf_specL ); IGF_calc( hPrivateDataR, igfGridIdx, spectrumR, igf_specR ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse, bfi_apply_damping ); + IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse, bfi_apply_damping ); +#else IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse ); IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse ); +#endif } /* reset TCX noise indicator vector */ @@ -1588,3 +1611,34 @@ void init_igf_dec( return; } + +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +int16_t get_igf_startline( + Decoder_State *st, + int16_t L_frame, + int16_t L_frameTCX +) +{ + int16_t igf_startline; + + if ( st->igf == 0 ) + { + if ( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + igf_startline = min( L_frameTCX, L_frame ); + } + else + { + igf_startline = L_frameTCX; + } + } + else + { + igf_startline = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); + } + + return igf_startline; +} +#endif diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 40c65d95033f1b55d0536e2ec0fb2420f89300a2..2e31017eaa9fa823b19ee48354b76e58a1428119 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -54,7 +54,7 @@ ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -691,7 +691,7 @@ ivas_error init_decoder( st->enablePlcWaveadjust = 0; /* Init Core Decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); #else open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, 1 ); @@ -714,7 +714,7 @@ ivas_error init_decoder( * FD-CNG decoder *-----------------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( st->element_mode == IVAS_CPE_MDCT || idchan == 0 ) && mc_mode != MC_MODE_MCT ) #else if ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index de87b4c5577927459ee38dda93879c7a98a9dd41..ad350f4e303b65fe68f533fb564bca9989d9b56d 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -35,7 +35,7 @@ #ifdef DEBUGGING #include "debug.h" #endif -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #include #endif #include @@ -183,7 +183,7 @@ ivas_error ivas_core_dec( st->flagGuidedAcelp = 0; } -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { @@ -201,7 +201,7 @@ ivas_error ivas_core_dec( } #else /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ - if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) ) + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && hMCT == NULL ) { float gain; if ( st->hPlcInfo != NULL ) @@ -428,6 +428,21 @@ ivas_error ivas_core_dec( { updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); } + +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) + { + /* On first good frame after frameloss undo the whitening of the bg noise shape */ + for ( n = 0; n < n_channels; ++n ) + { + if ( sts[n]->last_core_bfi != ACELP_CORE ) + { + TonalMdctConceal_whiten_noise_shape( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + } + } + } +#endif + } /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index d034d08db6cdf2b1a155c5a2b25f00fe7f55eec1..da0911ee5bae74ca2538c15a9df5cc1d1d3c2323 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -718,7 +718,7 @@ ivas_error create_cpe_dec( st->mct_chan_mode = MCT_CHAN_MODE_LFE; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( error = init_decoder( st, n, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, n ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index 00eff03dac152d37204e3626405f79c340a236a5..ec19acb60253b94dcdd3564246ac40ea1cd0cda7 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -283,7 +283,11 @@ void mctStereoIGF_dec( /* stereo IGF decoding */ assert( ( sts[0]->core == sts[1]->core ) || ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi, 1 /* <- is_mct */ ); +#else decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi ); +#endif } else { diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index ed5114c651be2c572fe2db046f7128b2af463185..d05024c56599ce49f335e8e547776551a9b40811 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -102,7 +102,7 @@ static void dec_prm_tcx_sidebits( int16_t p_param[NB_DIV], /* o : pointer to parameters for next round of bs reading*/ int16_t nTnsBitsTCX10[NB_DIV], /* o : number of TNS bits per TCX10 subframe */ Decoder_State *st0, /* i/o: core decoder state handle - for bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t MCT_flag, #endif const int16_t ch /* i : channel */ @@ -134,7 +134,7 @@ static void dec_prm_tcx_sidebits( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st0, MCT_flag ); #else getTCXMode( st, st0 ); @@ -381,7 +381,7 @@ void ivas_mdct_dec_side_bits_frame_channel( tmp = 3; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, MCT_flag, tmp ); #else dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, tmp ); @@ -481,7 +481,7 @@ void ivas_mdct_core_invQ( const int16_t *prm_sqQ; int16_t L_frameTCX_global[CPE_CHANNELS]; float tmp_ms_sig[CPE_CHANNELS][N_MAX]; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[CPE_CHANNELS][L_FRAME48k]; TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode_bfi; #endif @@ -490,7 +490,7 @@ void ivas_mdct_core_invQ( sts = hCPE->hCoreCoder; bfi = sts[0]->bfi; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE noise_gen_mode_bfi = -1; #endif @@ -514,7 +514,7 @@ void ivas_mdct_core_invQ( sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], 0, sts[0]->last_core, sts[1]->last_core, 1 ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi ) { if ( sts[0]->core == sts[1]->core ) @@ -728,15 +728,11 @@ void ivas_mdct_core_invQ( } nf_seed = 0; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, isMCT, k ); -#else decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, k ); -#endif mvr2r( x[ch][k], x_0[ch][k], L_frameTCX[ch] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi && !isMCT ) { TonalMdctConceal_create_concealment_noise( concealment_noise[ch], hCPE, L_frameTCX[ch], L_frame[ch], ch, k, st->core, st->hTcxDec->cummulative_damping_tcx, noise_gen_mode_bfi ); @@ -861,7 +857,7 @@ void ivas_mdct_core_reconstruct( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX[ch] ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, NULL, bfi, isMCT ); #else decoder_tcx_post( st, synth, synthFB, NULL, bfi ); @@ -873,7 +869,7 @@ void ivas_mdct_core_reconstruct( /* PLC: [TCX: TD PLC] */ if ( isMCT ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -881,7 +877,7 @@ void ivas_mdct_core_reconstruct( } else { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); #else con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0 ); @@ -1064,34 +1060,14 @@ void ivas_mdct_core_tns_ns( { sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( isMCT && st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( isMCT && st->hTonalMDCTConc != NULL ) #endif { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - int16_t infoIGFStartLine; - - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); - } - else - { - infoIGFStartLine = L_frameTCX[ch]; - } - } - else - { - infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); - } - - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -1101,17 +1077,18 @@ void ivas_mdct_core_tns_ns( { if ( st->hTonalMDCTConc != NULL ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - if ( st->hTcxDec->cummulative_damping_tcx != 1.f ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( !isMCT && st->hTcxDec->cummulative_damping_tcx != 1.f ) { - float *scf_last; - float *scf_bg; - float fade_in; - float fade_out; + float *scf_last, *scf_bg; + float fade_in, fade_out; scf_last = &st->hTonalMDCTConc->lastBlockData.scaleFactors[0]; scf_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; - fade_out = st->hTcxDec->cummulative_damping_tcx; + + st->hTonalMDCTConc->scf_fadeout *= 0.95f; + + fade_out = st->hTonalMDCTConc->scf_fadeout; fade_in = 1 - fade_out; for ( int16_t i = 0; i < st->hTonalMDCTConc->nScaleFactors; i++ ) @@ -1121,6 +1098,7 @@ void ivas_mdct_core_tns_ns( } else { + st->hTonalMDCTConc->scf_fadeout = 1.0f; mvr2r( st->hTonalMDCTConc->lastBlockData.scaleFactors, &sns_int_scf[0], st->hTonalMDCTConc->nScaleFactors ); } #else diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index b3a73706df11a9f1d72428aae1e7bcf4852cb34f..b24d60505b7f57be4f92f3aa00f9943366b85909 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -350,7 +350,7 @@ ivas_error create_sce_dec( st->total_brate = hSCE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( error = init_decoder( st, 0, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, 0 ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index c773491d410632dc6dfa382db42b70b181d4d913..e5195cba5a74a1b3a7c1765c9f03eb0e7fbc9b2e 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -320,7 +320,7 @@ typedef struct stereo_mdct_dec_data_structure int16_t prev_ms_mask[NB_DIV][MAX_SFB]; float lastCoh; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t noise_seeds_channels[CPE_CHANNELS]; int16_t noise_seed_common; #endif diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 32e9fe103cf66de8b24de30b7cbc1705faaf8232..beb121a1fc207994816a424cf3329a3360ae6563 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -50,7 +50,7 @@ *-------------------------------------------------------------------------*/ static void apply_dmx_weights( CPE_DEC_HANDLE hCPE, float *x[CPE_CHANNELS][NB_DIV], int16_t transform_type_left[NB_DIV], int16_t transform_type_right[NB_DIV] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE static void run_min_stats( Decoder_State **sts, float *x[CPE_CHANNELS][NB_DIV] ); #endif @@ -301,7 +301,11 @@ void stereo_mdct_core_dec( assert( ( sts[0]->core == sts[1]->core ) || ( hCPE->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); /* stereo IGF decoding */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi, 0 /* <- is_mct */ ); +#else decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi ); +#endif } else { @@ -331,34 +335,14 @@ void stereo_mdct_core_dec( sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( st->hTonalMDCTConc != NULL ) #endif { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - int16_t infoIGFStartLine; - - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); - } - else - { - infoIGFStartLine = L_frameTCX[ch]; - } - } - else - { - infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); - } - - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -388,7 +372,7 @@ void stereo_mdct_core_dec( ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE run_min_stats( sts, x ); #endif @@ -609,7 +593,7 @@ static void apply_dmx_weights( return; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /*-------------------------------------------------------------------* * run_min_stats() * diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 80736dd425c13b05baa2fb0d917bd32095faec12..2e32b8e85a496b20b65fea28599b6b473fbef0e0 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -424,7 +424,7 @@ ivas_error stereo_memory_dec( if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { cpy_tcx_ltp_data( hCPE->hCoreCoder[1]->hTcxLtpDec, hCPE->hStereoDft->hTcxLtpDec, output_Fs ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); #endif } @@ -489,7 +489,7 @@ ivas_error stereo_memory_dec( /* deallocated TCX/IGF structures for second channel */ deallocate_CoreCoder_TCX( hCPE->hCoreCoder[1] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); @@ -675,7 +675,7 @@ ivas_error stereo_memory_dec( /* deallocate core-decoder substructures */ deallocate_CoreCoder( st ); -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* deallocate FD_CNG substructure */ deleteFdCngDec( &st->hFdCngDec ); #endif @@ -702,7 +702,7 @@ ivas_error stereo_memory_dec( } } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* allocate Fd-Cng structure for second channel */ if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index e3462f21bc23a0324b7251bd7b18457b728955d2..e46c32ddbbfde5dc0860c95b5e147de28f1b7480 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -150,7 +150,7 @@ void stereo_tcx_init_dec( } /* Reconfigure Core */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct, last_element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct ); @@ -457,7 +457,7 @@ void stereo_tcx_core_dec( } /* PLC: [TCX: TD PLC] */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -589,7 +589,7 @@ void stereo_tcx_core_dec( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); @@ -750,7 +750,7 @@ void stereo_tcx_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -779,7 +779,7 @@ void stereo_tcx_core_dec( if ( st->element_mode == IVAS_CPE_TD && st->idchan == 0 ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -867,7 +867,7 @@ static void dec_prm_tcx( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 8fc8ec5282be03a3345c9c83ff5b20c14c645c61..0c7a836cb43a86a1fc0845635f2ac4af43abddcd 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -204,15 +204,16 @@ typedef struct Float32 *secondLastPcmOut; float *secondLastPowerSpectrum; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float scaleFactorsBackground[FDNS_NPTS]; + float scf_fadeout; PsychoacousticParameters *psychParams; - /* could be stored only once, since the same for all channels (always at 16Khz fs) */ PsychoacousticParameters psychParamsTCX20; PsychoacousticParameters psychParamsTCX10; float last_block_nrg; float curr_noise_nrg; + float faded_signal_nrg; #endif float nFramesLost; diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index b43f85b8f9d51e2979a620c735bbc33aee51d09a..872cf1efa937ae1a6c65f362f338efb30ebc2027 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -93,14 +93,16 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->nSamplesCore = nSamplesCore; hTonalMDCTConc->nScaleFactors = nScaleFactors; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS ); + hTonalMDCTConc->scf_fadeout = 1.0f; PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 ); PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 ); hTonalMDCTConc->psychParams = NULL; hTonalMDCTConc->last_block_nrg = 0.0f; hTonalMDCTConc->curr_noise_nrg = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; #endif /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when @@ -123,7 +125,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t nNewSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t infoIGFStartLine #endif @@ -168,7 +170,7 @@ void TonalMDCTConceal_SaveFreqSignal( if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) ) { /* Store new data */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t i; hTonalMDCTConc->last_block_nrg = 0.0f; @@ -500,8 +502,9 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, const float tiltCompFactor, const float crossfadeGain, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const float concealment_noise[L_FRAME48k], + const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ) { @@ -509,11 +512,18 @@ void TonalMDCTConceal_InsertNoise( float x, y; Word16 rnd; float g, nrgNoiseInLastFrame, nrgWhiteNoise, tiltFactor, tilt; +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + float last_block_nrg_correct; +#endif wmops_sub_start( "InsertNoise" ); g = 1.0f - crossfadeGain; +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) +#else if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) +#endif { rnd = 1977; } @@ -522,13 +532,15 @@ void TonalMDCTConceal_InsertNoise( rnd = *pSeed; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* based on what is done in tcx_noise_filling() */ /* always initialize these to avoid compiler warnings */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; nrgNoiseInLastFrame = 0.0f; nrgWhiteNoise = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; + last_block_nrg_correct = 0.0f; #endif if ( !hTonalMDCTConc->lastBlockData.blockIsValid ) @@ -536,7 +548,7 @@ void TonalMDCTConceal_InsertNoise( /* may just become active if the very first frame is lost */ set_f( mdctSpectrum, 0.0f, hTonalMDCTConc->nSamples ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE else if ( concealment_noise != NULL ) { if ( !tonalConcealmentActive ) @@ -564,7 +576,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); for ( i = 0; i < crossOverFreq; i++ ) { @@ -579,6 +591,8 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[i] = g * y - crossfadeGain * x; } + + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { @@ -599,6 +613,11 @@ void TonalMDCTConceal_InsertNoise( for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) { mdctSpectrum[l] = 0; + if ( l < crossOverFreq ) + { + last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; + hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; + } } } @@ -651,7 +670,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) { @@ -666,6 +685,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) { @@ -682,6 +702,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } } @@ -698,6 +719,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) @@ -706,11 +728,19 @@ void TonalMDCTConceal_InsertNoise( } } } + + if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG ) + { + float nrg_corr_factor; + + nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg ); + v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq ); + } } #endif else { -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* based on what is done in tcx_noise_filling() */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; @@ -962,7 +992,7 @@ void TonalMDCTConceal_SaveTimeSignal( return; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -1049,7 +1079,6 @@ void TonalMdctConceal_create_concealment_noise( c_inv = sqrtf( 1 - hStereoMdct->lastCoh ); /* pre-compute the noise shape for later weighting of the noise spectra */ - /* TODO: optimize by intertwining with later loop */ cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; inc = ( st->core > TCX_20_CORE ) ? 2 : 1; start_idx = hFdCngCom->startBand / inc; @@ -1072,7 +1101,7 @@ void TonalMdctConceal_create_concealment_noise( } /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = 0.001f; + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) ) { /* current channel is TCX20 -> generate noise for "full-length" spectrum */ @@ -1100,6 +1129,14 @@ void TonalMdctConceal_create_concealment_noise( } } + if ( st->tonal_mdct_plc_active ) + { + for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + { + concealment_noise[i] *= 0.0f; + } + } + /* restore common seed - after finishing the first channel - after a first subframe if the current channel is TCX10 */ @@ -1108,8 +1145,68 @@ void TonalMdctConceal_create_concealment_noise( *rnd_c = save_rnd_c; } + st->seed_tcx_plc = *rnd; + wmops_sub_end(); return; } + +void TonalMdctConceal_whiten_noise_shape( + Decoder_State *st, + const int16_t L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode +) +{ + int16_t inc, start_idx, stop_idx; + float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + HANDLE_FD_CNG_COM hFdCngCom; + float whitenend_noise_shape[L_FRAME16k]; + float scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + wmops_sub_start( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + + inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = L_frame / inc; + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + + set_zero( whitenend_noise_shape, start_idx ); + for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) + { + whitenend_noise_shape[j] = *noiseLevelPtr; + } + + if ( whitening_mode == ON_FIRST_LOST_FRAME ) + { + float scf[SNS_NPTS]; + + sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf ); + sns_interpolate_scalefactors( scfs_int, scf, ENC ); + sns_interpolate_scalefactors( scfs_bg, scf, DEC ); + scfs_for_shaping = &scfs_int[0]; + } + else if ( whitening_mode == ON_FIRST_GOOD_FRAME ) + { + scfs_for_shaping = &scfs_bg[0]; + } + + if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) + { + sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); + mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + } + else + { + set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + } + + wmops_sub_end(); +} + #endif diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 062069ceeef99bd821d9e1458568334ebed13656..33c9d6fc7b6dfd7851cdae1dc1831c105e57bffb 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -55,7 +55,7 @@ void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -88,7 +88,7 @@ void writeTCXMode( push_next_indice( hBstr, index, 2 ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !is_mct ) { push_next_indice( hBstr, st->vad_flag, 1 ); @@ -792,7 +792,7 @@ void enc_prm( /* EVS header */ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, st->hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, st->hBstr, &nbits_start ); diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 4d9d1f257780ba86b07286d2b5b59c0b6bde895b..0d2f5817d6dbf1da5ab7c2376b27b94131e0db37 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -63,7 +63,7 @@ static void enc_prm_pre_mdct( int16_t param[], /* i : parameters */ const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ int16_t p_param[2], /* o : pointer to parameters for next round of bs writing */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ @@ -80,7 +80,7 @@ static void enc_prm_pre_mdct( * Header *--------------------------------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, hBstr, is_mct, &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); @@ -1065,7 +1065,7 @@ void ivas_mdct_core_whitening_enc( continue; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], mct_on, hBstr ); #else enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], hBstr ); diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 1aeac19c571d46400258a5d66c564f5e4cf68711..87019b8d91334818db5667102d317d45a0b8811e 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -43,7 +43,7 @@ #endif #include "wmops.h" -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ /*------------------------------------------------------------------- diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 79bb2f04a7f02ee103bfe2f8a04bf5f0be23f838..ce2d74ec9a689f1ef59657fc0180741b6ab6ce13 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -268,7 +268,7 @@ void stereo_tcx_core_enc( *--------------------------------------------------------------------------------*/ /* TCX20/TCX10 and coder type */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py index b03b472ae908aa3d57269d3b9fede4167deb3eeb..46bb452082c7d8a0cca04875bc5bca1dd399ccdf 100755 --- a/scripts/pyaudio3dtools/audiofile.py +++ b/scripts/pyaudio3dtools/audiofile.py @@ -35,7 +35,6 @@ import platform import shutil import struct import subprocess as sp -import warnings from importlib import import_module from tempfile import TemporaryDirectory from typing import Optional, Tuple @@ -74,18 +73,6 @@ def readfile( if file_extension == ".wav": fs, data = wav.read(filename) - if data.dtype == np.int32: - data = np.interp( - data, - (np.iinfo(np.int32).min, np.iinfo(np.int32).max), - (np.iinfo(np.int16).min, np.iinfo(np.int16).max), - ) - elif data.dtype == np.float32: - data = np.interp( - data, - (-1, 1), - (np.iinfo(np.int16).min, np.iinfo(np.int16).max), - ) x = np.array(data, dtype=outdtype) file_len = x.shape[0] if x.ndim == 1: @@ -120,11 +107,9 @@ def writefile(filename: str, x: np.ndarray, fs: int = 48000) -> None: """ _, file_extension = os.path.splitext(os.path.basename(filename)) - clipped_samples = np.sum( - np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max) - ) + clipped_samples = np.sum(np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max)) if clipped_samples > 0: - warnings.warn(f" Warning: {clipped_samples} samples clipped") + print(" Warning: %i samples clipped"%clipped_samples) x = np.clip(x, np.iinfo(np.int16).min, np.iinfo(np.int16).max) if file_extension == ".wav": @@ -504,6 +489,7 @@ def loudnessinfo( in_sig: np.ndarray, in_fs: Optional[int] = 48000, in_format: Optional[str] = "MONO", + in_ls_layout_file: Optional[str] = None, output_loudness: Optional[int] = -26, loudness_tool: Optional[str] = "bs1770demo", use_rms: Optional[bool] = False, @@ -538,10 +524,13 @@ def loudnessinfo( else: null_file = "/dev/null" + # check for binary if shutil.which(loudness_tool) is None: raise FileNotFoundError(f"The binary {loudness_tool} was not found in path!") - in_spfmt = spatialaudioformat.Format(in_format=in_format) + in_spfmt = spatialaudioformat.Format( + in_format=in_format, ls_layout_file=in_ls_layout_file + ) if not (in_spfmt.isheadphones or in_spfmt.isloudspeaker or in_spfmt.ambi_order > 1): raise NotImplementedError( @@ -554,7 +543,7 @@ def loudnessinfo( ) with TemporaryDirectory() as tmp_dir: - tmp_file = os.path.join(tmp_dir, "tmp_loudness.pcm") + tmp_file = os.path.join(tmp_dir, "tmp.pcm") if "bs1770demo" in loudness_tool: """