diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index f4022487cef02de5c4af5479bd408fe3226b8b44..be77c232a7ea7b1a5692a0a3d6abcd8564d54cf3 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1138,4 +1138,9 @@ void FdCngDecodeDiracMDCTStereoSID_fx( CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ ); +//tonalMDCTconcealment.c +void TonalMdctConceal_whiten_noise_shape_ivas_fx( + Decoder_State *st, + const Word16 L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ); #endif diff --git a/lib_com/prot_fx1.h b/lib_com/prot_fx1.h index 6afdb1e167488bde9103a60f73773b8b9434e7f3..fe129eed37dc9869e75f3dbf085da6514b74c654 100644 --- a/lib_com/prot_fx1.h +++ b/lib_com/prot_fx1.h @@ -198,6 +198,10 @@ Word32 sum16_32_fx( /* o : sum of all vector elements const Word16 *vec, /* i : input vector Qx*/ const Word16 lvec /* i : length of input vector */ ); +Word32 sum32_sat( /* o : sum of all vector elements Qx*/ + const Word32 *vec, /* i : input vector Qx*/ + const Word16 lvec /* i : length of input vector */ +); Word32 var_fx_32( /* o: variance of vector Qx+16*/ const Word16 *x, /* i: input vector Qx*/ const Word16 Qx, diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 4b18014ac277b57574109a29c4ab8786f68b8a21..e1c684abd8b87a110f2b8de646fb2985de5bea7a 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -1118,6 +1118,23 @@ Word32 sum16_32_fx( /* o : sum of all vector elements Qx*/ return tmp; } +Word32 sum32_sat( /* o : sum of all vector elements Qx*/ + const Word32 *vec, /* i : input vector Qx*/ + const Word16 lvec /* i : length of input vector */ +) +{ + Word16 i; + Word32 tmp; + tmp = 0; + move16(); + FOR( i = 0; i < lvec; i++ ) + { + tmp = L_add_sat( tmp, vec[i] ); /*Qx */ + } + + return tmp; +} + Word32 var_fx_32( /* o: variance of vector Qx+16*/ const Word16 *x, /* i: input vector Qx*/ const Word16 Qx, diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 39ad23e778a7d64d2976ce96e950b752b0496849..812356c565d177c648975ffd1a699ecb54b45590 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -515,7 +515,27 @@ void ApplyFdCng_flt( { if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) { - TonalMdctConceal_whiten_noise_shape_ivas( st, L_frame, ON_FIRST_LOST_FRAME ); +#ifdef IVAS_FLOAT_FIXED + hFdCngCom->cngNoiseLevelExp = 28; + for ( int p = 0; p < hFdCngCom->stopFFTbin - hFdCngCom->startBand; p++ ) + { + hFdCngCom->cngNoiseLevel[p] = (Word32) (cngNoiseLevel_flt[p] * ( 1u << ( 31 - hFdCngCom->cngNoiseLevelExp ) ) ); + } + + TonalMdctConceal_whiten_noise_shape_ivas_fx( st, L_frame, ON_FIRST_LOST_FRAME ); + + for (int p = 0; p < hFdCngCom->stopFFTbin - hFdCngCom->startBand; p++) + { + cngNoiseLevel_flt[p] = (float)hFdCngCom->cngNoiseLevel[p] / (1u << (31 - hFdCngCom->cngNoiseLevelExp)); + } + for ( int p = 0; p < FDNS_NPTS; p++ ) + { + st->hTonalMDCTConc->scaleFactorsBackground_flt[p] = (float) st->hTonalMDCTConc->scaleFactorsBackground_fx[p] / ONE_IN_Q16; + } +#else + TonalMdctConceal_whiten_noise_shape_ivas(st, L_frame, ON_FIRST_LOST_FRAME); +#endif // IVAS_FLOAT_FIXED + } else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE ) { diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 53966fee43958f6bcdacdc119c1f1168210cbc01..719f67996df65c74d9d1e2a84355988b18dfbcdb 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -591,7 +591,30 @@ ivas_error ivas_core_dec( { if ( sts[n]->last_core_bfi != ACELP_CORE ) { +#ifdef IVAS_FLOAT_FIXED + sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 27; + for ( int p = 0; p < sts[n]->hFdCngDec->hFdCngCom->stopFFTbin - sts[n]->hFdCngDec->hFdCngCom->startBand; p++ ) + { + sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel[p] = (Word32) ( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[p] * ( 1u << ( 31 - sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp ) ) ); + } + for (int p = 0; p < FDNS_NPTS; p++) + { + sts[n]->hTonalMDCTConc->scaleFactorsBackground_fx[p] = (Word32)(sts[n]->hTonalMDCTConc->scaleFactorsBackground_flt[p] * ONE_IN_Q16); + } + + TonalMdctConceal_whiten_noise_shape_ivas_fx( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + + for ( int p = 0; p < sts[n]->hFdCngDec->hFdCngCom->stopFFTbin - sts[n]->hFdCngDec->hFdCngCom->startBand; p++ ) + { + sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[p] = (float) sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel[p] / ( 1u << ( 31 - sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp ) ); + } + for ( int p = 0; p < FDNS_NPTS; p++ ) + { + sts[n]->hTonalMDCTConc->scaleFactorsBackground_flt[p] = (float) sts[n]->hTonalMDCTConc->scaleFactorsBackground_fx[p] / ONE_IN_Q16; + } +#else TonalMdctConceal_whiten_noise_shape_ivas( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); +#endif // IVAS_FLOAT_FIXED } } } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 7584efd4515193b044f22096760e3a918304b393..90e573273eeeadf2bcbb13ae4686ec7346646abf 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -354,6 +354,7 @@ typedef struct tonalmdctconceal float scaleFactorsBackground_flt[FDNS_NPTS]; Word16 scaleFactorsBackground[FDNS_NPTS]; + Word32 scaleFactorsBackground_fx[FDNS_NPTS]; float scf_fadeout_flt; Word16 scf_fadeout; PsychoacousticParameters *psychParams; diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 472de96848400ceb970727b877d6793aa67657a7..32d0c5c11f020bfa082f320293cf84d20c8b0332 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -45,6 +45,7 @@ #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" +#include "prot_fx1.h" #include "prot_fx2.h" #endif // IVAS_FLOAT_FIXED @@ -1246,7 +1247,7 @@ void TonalMdctConceal_create_concealment_noise_ivas( return; } - +#ifndef IVAS_FLOAT_FIXED void TonalMdctConceal_whiten_noise_shape_ivas( Decoder_State *st, const int16_t L_frame, @@ -1387,3 +1388,69 @@ void TonalMdctConceal_whiten_noise_shape_ivas( pop_wmops(); } +#else +void TonalMdctConceal_whiten_noise_shape_ivas_fx( + Decoder_State *st, + const Word16 L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) +{ + Word16 inc, start_idx, stop_idx; + Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + Word16 noiseLevelPtr_exp; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 whitenend_noise_shape[L_FRAME16k]; + Word16 q_wns; + Word32 scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + push_wmops( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + + inc = ( ( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; + start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); + stop_idx = shr( L_frame, sub( inc, 1 ) ); + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; + + set32_fx( whitenend_noise_shape, 0, start_idx ); + FOR( Word16 j = start_idx; j < stop_idx; j++ ) + { + whitenend_noise_shape[j] = *noiseLevelPtr; + noiseLevelPtr += inc; + } + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + Word32 scf[SNS_NPTS]; + + sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, (31 - noiseLevelPtr_exp)); + + sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); + sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); + + scfs_for_shaping = &scfs_int[0]; + } + ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; + } + + IF( GT_32( sum32_sat( scfs_for_shaping, FDNS_NPTS ), 0 ) ) + { + q_wns = sub( 31, noiseLevelPtr_exp ); + sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame ); + + Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + hFdCngCom->cngNoiseLevelExp = sub( 30, q_wns ); + } + ELSE + { + set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); + } + + pop_wmops(); +} +#endif // IVAS_FLOAT_FIXED