From 0b493cd4a839a4739ef81d984499832f3fd78941 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sat, 2 Mar 2024 22:09:41 +0530 Subject: [PATCH] Fixes stv crash issue due to log(0) computation in sub function of ApplyFdCng_fx() [x] The crash occurs due to computation of log(0) by BASOP_Util_Log2, which was not handled in the EVS implemented scalebands(). [x] Created a separate copy of scalebands() as scalebands_fx() for IVAS path because after making the change in EVS function, many streams got bit-inexact in decoder and encoder for EVS bit-exact testing. --- lib_com/fd_cng_com_fx.c | 142 ++++++++++++++++++++++++++++++++++++++++ lib_com/prot_fx2.h | 10 +++ lib_dec/fd_cng_dec_fx.c | 10 +-- 3 files changed, 157 insertions(+), 5 deletions(-) diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index 73dac2d66..279a0afee 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -1916,6 +1916,148 @@ void scalebands ( } +#ifdef IVAS_FLOAT_FIXED +void scalebands_fx( + const Word32 *partpow, /* i : Power for each partition */ + Word16 *part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + Word16 *midband, /* i : Central band of each partition */ + const Word16 nFFTpart, /* i : Number of FFT partitions */ + const Word16 nband, /* i : Number of bands */ + Word32 *bandpow, /* o : Power for each band */ + const Word16 flag_fft_en ) +{ + Word16 i, j, s, s1, nint, delta, delta_cmp, delta_s; + Word16 startBand, startPart, stopPart, stopPartM1; + Word32 tmp, val, partpowLD64, partpowLD64M1; + + + j = 0; + move16(); + delta = 0; + move16(); + partpowLD64M1 = 0L; /* to avoid compilation warnings */ + + /* Interpolate the bin/band-wise levels from the partition levels */ + IF( EQ_16( nband, npart ) ) + { + Copy32( partpow, bandpow, npart ); + } + ELSE + { + startBand = 0; + move16(); + startPart = 0; + move16(); + stopPart = nFFTpart; + move16(); + + WHILE( LT_16( startBand, nband ) ) + { + stopPartM1 = sub( stopPart, 1 ); + test(); + IF( ( flag_fft_en != 0 ) || ( GE_16( startPart, nFFTpart ) ) ) + { + /* first half partition */ + j = startPart; + move16(); + + FOR( i = startBand; i <= midband[j]; i++ ) + { + bandpow[i] = partpow[j]; + move32(); + } + j = add( j, 1 ); + + /* inner partitions */ + IF( j < stopPart ) + { + partpowLD64M1 = BASOP_Util_Log2( L_add( partpow[j - 1], DELTA_FX ) ); + } + + /* Debug values to check this variable is set. */ + delta = 0x4000; + move16(); + delta_cmp = 0x4000; + move16(); + s1 = 1; + move16(); + s = 1; + move16(); + + FOR( ; j < stopPart; j++ ) + { + nint = sub( midband[j], midband[j - 1] ); + + /* log-linear interpolation */ + partpowLD64 = BASOP_Util_Log2( L_add( partpow[j], DELTA_FX ) ); + tmp = L_sub( partpowLD64, partpowLD64M1 ); + tmp = Mpy_32_16_1( tmp, getNormReciprocalWord16( nint ) ); + + /* scale logarithmic value */ + tmp = L_sub( tmp, DELTA_SHIFT_LD64 ); + delta_s = DELTA_SHIFT; + move16(); + + WHILE( tmp > 0 ) + { + tmp = L_sub( tmp, 33554432l /*0.015625 Q31*/ ); + delta_s = add( delta_s, 1 ); + } + delta_cmp = shl( 1, s_max( -15, sub( WORD16_BITS - 1, delta_s ) ) ); + + tmp = BASOP_Util_InvLog2( tmp ); + s = norm_l( tmp ); + s1 = sub( delta_s, s ); + +#ifdef BASOP_NOGLOB + delta = round_fx_sat( L_shl_sat( tmp, s ) ); +#else + delta = round_fx( L_shl( tmp, s ) ); +#endif + /* Choose scale such that the interpolation start and end point both are representable and add 1 additional bit hr. */ + delta_s = sub( s_min( norm_l( partpow[j - 1] ), norm_l( partpow[j] ) ), 1 ); + val = L_shl( partpow[j - 1], delta_s ); + FOR( ; i < midband[j]; i++ ) + { + val = L_shl( Mpy_32_16_1( val, delta ), s1 ); + bandpow[i] = L_shr( val, delta_s ); + move32(); + } + bandpow[i++] = partpow[j]; + move32(); + partpowLD64M1 = partpowLD64; + move32(); + } + + IF( GT_16( shr( delta, s ), delta_cmp ) ) + { + delta = 0x4000; + move16(); + s1 = 1; + move16(); + } + + /* last half partition */ + val = partpow[stopPartM1]; + move32(); + FOR( ; i <= part[stopPartM1]; i++ ) + { + val = L_shl( Mpy_32_16_1( val, delta ), s1 ); + bandpow[i] = val; + move32(); + } + } + startBand = add( part[stopPartM1], 1 ); + startPart = stopPart; + move16(); + stopPart = npart; + move16(); + } + } +} +#endif // IVAS_FLOAT_FIXED + /*------------------------------------------------------------------- * getmidbands() * diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 87b29ccf3..9c53c320a 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -4708,6 +4708,16 @@ void scalebands( Word32* bandpow, /* o : Power for each band */ const Word16 flag_fft_en ); +void scalebands_fx( + const Word32 *partpow, /* i : Power for each partition */ + Word16 *part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + Word16 *midband, /* i : Central band of each partition */ + const Word16 nFFTpart, /* i : Number of FFT partitions */ + const Word16 nband, /* i : Number of bands */ + Word32 *bandpow, /* o : Power for each band */ + const Word16 flag_fft_en ); + /* STFT analysis filterbank */ void AnalysisSTFT( const Word16* timeDomainInput, /* i : pointer to time signal */ diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index d841330da..fb73cffdf 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -1149,7 +1149,7 @@ Word16 ApplyFdCng_fx( test(); IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { - scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); + scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 ); } hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; move16(); @@ -1465,7 +1465,7 @@ Word16 ApplyFdCng_fx( IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) ) { - scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape, 1 ); + scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape, 1 ); } hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; move16(); @@ -1557,7 +1557,7 @@ Word16 ApplyFdCng_fx( IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 ); *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; move16(); @@ -1572,7 +1572,7 @@ Word16 ApplyFdCng_fx( /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 ); *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; @@ -2654,7 +2654,7 @@ void perform_noise_estimation_dec_fx( hFdCngDec->msPsd_exp_fft = hFdCngDec->msNoiseEst_exp; /* Expand partitions into bins of power spectrum */ - scalebands( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, sub( stopFFTbin, startBand ), hFdCngDec->bandNoiseShape, 1 ); + scalebands_fx( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, sub( stopFFTbin, startBand ), hFdCngDec->bandNoiseShape, 1 ); hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; Copy32( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd_fx[startBand], sub( stopFFTbin, startBand ) ); set32_fx( &hFdCngDec->smoothed_psd_fx[stopFFTbin], 0, sub( L_FRAME16k, stopFFTbin ) ); -- GitLab