From add7ea914d607596761cd274a74cacf821e93d42 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 20 Feb 2024 11:42:20 +0530 Subject: [PATCH] Converted TonalMdctConceal_whiten_noise_shape_ivas() to fixed point [x] TonalMdctConceal_whiten_noise_shape_ivas() is converted to fixed point and integrated at all call locations. [x] additional functions added: sum32_sat, a tool to return the sum of all elements of a 32 bit vector. --- lib_com/ivas_prot_fx.h | 5 +++ lib_com/prot_fx1.h | 4 ++ lib_com/tools_fx.c | 17 +++++++++ lib_dec/fd_cng_dec.c | 22 ++++++++++- lib_dec/ivas_core_dec.c | 23 ++++++++++++ lib_dec/stat_dec.h | 1 + lib_dec/tonalMDCTconcealment.c | 69 +++++++++++++++++++++++++++++++++- 7 files changed, 139 insertions(+), 2 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index f4022487c..be77c232a 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 6afdb1e16..fe129eed3 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 4b18014ac..e1c684abd 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 39ad23e77..812356c56 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 53966fee4..719f67996 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 7584efd45..90e573273 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 472de9684..32d0c5c11 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 -- GitLab