Commit 0b493cd4 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

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.
parent b7ba8b3d
Loading
Loading
Loading
Loading
Loading
+142 −0
Original line number Diff line number Diff line
@@ -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()
 *
+10 −0
Original line number Diff line number Diff line
@@ -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 */
+5 −5
Original line number Diff line number Diff line
@@ -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 ) );