Commit 9579ccab authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch '3gpp_issue_1003_fix_1' into 'main'

Fix for 3GPP issue 1003: Switching artifacts worse in LTV MASA 2TC DTX FER WB to BINAURAL

See merge request !1278
parents 90ae19af de9a2fff
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1969,6 +1969,7 @@ void ivas_DetectTonalComponents_fx(
    const Word16 scaleFactors_exp[],
    const Word16 scaleFactors_max_e,
    const Word32 secondLastPowerSpectrum[],
    const Word16 secondLastPowerSpectrum_e,
    const Word16 nSamples,
    const Word16 nSamplesCore,
    Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins  */
+1 −0
Original line number Diff line number Diff line
@@ -6456,6 +6456,7 @@ void ivas_RefineTonalComponents_fx(
    const Word16 scaleFactors_exp[],
    const Word16 scaleFactors_max_e,
    const Word32 secondLastPowerSpectrum[],
    const Word16 secondLastPowerSpectrum_e,
    const Word16 nSamples,
    const Word16 nSamplesCore,
    const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins  */
+172 −4
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ static void modifyThresholds( Word16 F0, Word16 origF0, Word16 *thresholdModific
static void RefineThresholdsUsingPitch( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification );
static void ivas_RefineThresholdsUsingPitch_fx( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification );
static void findTonalComponents( Word16 *indexOfTonalPeak, Word16 *lowerIndex, Word16 *upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 *powerSpectrum, Word16 F0, Word16 *thresholdModification, Word16 element_mode );
static void ivas_findTonalComponents_fx( Word16 *indexOfTonalPeak, Word16 *lowerIndex, Word16 *upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 *powerSpectrum, const Word16 powerSpectrum_e, Word16 F0, Word16 *thresholdModification, Word16 element_mode );

/*-------------------------------------------------------------------*
 * DetectTonalComponents()
@@ -52,7 +53,8 @@ void ivas_DetectTonalComponents_fx(
    const Word16 scaleFactors[],
    const Word16 scaleFactors_exp[],
    const Word16 scaleFactors_max_e,
    const Word32 secondLastPowerSpectrum[], /*Qx*/
    const Word32 secondLastPowerSpectrum[], /*Q31-secondLastPowerSpectrum_e*/
    const Word16 secondLastPowerSpectrum_e,
    const Word16 nSamples,
    const Word16 nSamplesCore,
    Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins  Q0*/
@@ -127,7 +129,7 @@ void ivas_DetectTonalComponents_fx(
    ivas_RefineThresholdsUsingPitch_fx( nSamples, nSamplesCore, secondLastPowerSpectrum, lastPitchLag, currentPitchLag, &F0, thresholdModification );

    /* Find peaks in the second last frame */
    findTonalComponents( indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, F0, thresholdModification, element_mode );
    ivas_findTonalComponents_fx( indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, secondLastPowerSpectrum_e, F0, thresholdModification, element_mode );
}

void DetectTonalComponents(
@@ -306,7 +308,8 @@ void ivas_RefineTonalComponents_fx(
    const Word16 scaleFactors[],
    const Word16 scaleFactors_exp[],
    const Word16 scaleFactors_max_e,
    const Word32 secondLastPowerSpectrum[], /*Qx*/
    const Word32 secondLastPowerSpectrum[], /*Q31-secondLastPowerSpectrum_e*/
    const Word16 secondLastPowerSpectrum_e,
    const Word16 nSamples,
    const Word16 nSamplesCore,
    const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins  Q0*/
@@ -322,7 +325,7 @@ void ivas_RefineTonalComponents_fx(


    ivas_DetectTonalComponents_fx( newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum,
                                   lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum,
                                   lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, secondLastPowerSpectrum_e, nSamples, nSamplesCore, floorPowerSpectrum,
                                   psychParamsCurrent, element_mode );

    nPreservedPeaks = 0;
@@ -1280,6 +1283,171 @@ static void RefineThresholdsUsingPitch(
    return;
}

static void ivas_findTonalComponents_fx(
    Word16 *indexOfTonalPeak,    /* OUT Q0*/
    Word16 *lowerIndex,          /* OUT Q0*/
    Word16 *upperIndex,          /* OUT Q0*/
    Word16 *numIndexes,          /* OUT Q0*/
    Word16 nSamples,             /* IN */
    const Word32 *powerSpectrum, /* IN Q31-powerSpectrum_e*/
    const Word16 powerSpectrum_e,
    Word16 F0,                     /* IN */
    Word16 *thresholdModification, /* IN Q10*/
    Word16 element_mode )          /* IN */
{
    Word32 envelope[L_FRAME_MAX];         /*powerSpec_exp + LEVEL_EXP*/
    Word32 smoothedSpectrum[L_FRAME_MAX]; /*powerSpec_exp + LEVEL_EXP*/
    Word16 nrOfFIS;
    Word16 upperIdx, lowerIdx, lowerBound;
    Word16 k, j, m;
    Word32 biggerNeighbor;
    Word16 tmp_loop1, tmp_loop2, tmp_loop3;

    getEnvelope( nSamples, powerSpectrum, F0, envelope, smoothedSpectrum );


    nrOfFIS = 0;
    move16();
    lowerBound = 0;
    move16();

    k = GROUP_LENGTH / 2;
    move16();
    tmp_loop1 = sub( nSamples, ( GROUP_LENGTH - GROUP_LENGTH / 2 ) );
    tmp_loop2 = sub( nSamples, 1 );
    WHILE( LE_16( k, tmp_loop1 ) )
    {
        Word64 mult_64 = W_mult_32_16( envelope[k], thresholdModification[k] ); // (Q31-(powerSpectrum_e+LEVEL_EXP))+1+10
        Word16 lshift = W_norm( mult_64 );
        Word32 mult_32 = W_extract_h( W_shl( mult_64, lshift ) ); //(Q31-(powerSpectrum_e+LEVEL_EXP) + lshift )+11 -32
        Word16 mult_exp = sub( Q31, sub( add( sub( Q31, add( powerSpectrum_e, LEVEL_EXP ) ), add( 10, lshift ) ), 31 ) );
        Word16 flag = BASOP_Util_Cmp_Mant32Exp( smoothedSpectrum[k], ( powerSpectrum_e + LEVEL_EXP ), mult_32, mult_exp );
        /* There is 3 bits headroom in envelope and max of thresholdModification is 16384, so shifting left for 4 would produce overflow only when the result is anyhow close to 1 */
        IF( EQ_16( flag, 1 ) )
        {
            /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */
            /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */
            biggerNeighbor = L_max( powerSpectrum[k - 1], powerSpectrum[k + 1] ); /*Qx*/

            IF( GE_32( powerSpectrum[k], biggerNeighbor ) )
            {
                /* Find the right foot */
                upperIdx = add( k, 1 );
                WHILE( LT_16( upperIdx, tmp_loop2 ) )
                {
                    IF( LT_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx + 1] ) )
                    {
                        /* Side lobes may increase for certain amount */
                        IF( LT_32( L_shl( Mpy_32_16_1( powerSpectrum[upperIdx], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ), powerSpectrum[upperIdx + 1] ) )
                        {
                            BREAK;
                        }
                        /* Check for further decrease after a side lobe increase */
                        FOR( j = add( upperIdx, 1 ); j < tmp_loop2; j++ )
                        {
                            IF( LT_32( powerSpectrum[j], L_shl( Mpy_32_16_1( powerSpectrum[j + 1], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ) ) )
                            {
                                BREAK;
                            }
                        }
                        /* Side lobe increase must be 2 times smaller than the decrease to the foot */
                        /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */
                        test();
                        test();
                        test();
                        IF( ( EQ_16( element_mode, EVS_MONO ) && GT_32( Mpy_32_32( L_shl( powerSpectrum[upperIdx + 1], 1 ), powerSpectrum[j] ), Mpy_32_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx] ) ) ) ||
                            ( NE_16( element_mode, EVS_MONO ) && ( GT_64( W_mult_32_32( L_shl( powerSpectrum[upperIdx + 1], 1 ), powerSpectrum[j] ), W_mult_32_32( powerSpectrum[upperIdx], powerSpectrum[upperIdx] ) ) ) ) )
                        {
                            BREAK;
                        }
                        upperIdx = sub( j, 1 );
                    }
                    upperIdx = add( upperIdx, 1 );
                }
                /* left foot */
                lowerIdx = sub( k, 1 );
                WHILE( GT_16( lowerIdx, lowerBound ) )
                {
                    IF( LT_32( powerSpectrum[lowerIdx], powerSpectrum[lowerIdx - 1] ) )
                    {
                        /* Side lobes may increase for certain amount */
                        IF( LT_32( L_shl( Mpy_32_16_1( powerSpectrum[lowerIdx], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ), powerSpectrum[lowerIdx - 1] ) )
                        {
                            BREAK;
                        }
                        /* Check for further decrease after a side lobe increase */
                        FOR( j = sub( lowerIdx, 1 ); j > 0; j-- )
                        {
                            IF( LT_32( powerSpectrum[j], L_shl( Mpy_32_16_1( powerSpectrum[j - 1], ALLOWED_SIDE_LOBE_FLUCTUATION ), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP ) ) )
                            {
                                BREAK;
                            }
                        }
                        /* Side lobe increase must be 2 times smaller than the decrease to the foot */
                        /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */
                        IF( GT_32( Mpy_32_32( L_shl( powerSpectrum[lowerIdx - 1], 1 ), powerSpectrum[j] ), Mpy_32_32( powerSpectrum[lowerIdx], powerSpectrum[lowerIdx] ) ) )
                        {
                            BREAK;
                        }
                        lowerIdx = add( j, 1 );
                    }
                    lowerIdx = sub( lowerIdx, 1 );
                }

                lowerBound = upperIdx;
                move16();

                /* Check if there is a bigger peak up to the next peak foot */
                tmp_loop3 = s_min( upperIdx, tmp_loop1 );
                FOR( j = s_max( GROUP_LENGTH / 2, lowerIdx ); j <= tmp_loop3; j++ )
                {
                    if ( GT_32( powerSpectrum[j], powerSpectrum[k] ) )
                    {

                        k = j;
                        move16();
                    }
                }

                assert( ( nrOfFIS == 0 ) || ( indexOfTonalPeak[nrOfFIS - 1] < k ) );

                lowerIndex[nrOfFIS] = sub( k, GROUP_LENGTH / 2 );
                move16();

                upperIndex[nrOfFIS] = add( k, ( GROUP_LENGTH - GROUP_LENGTH / 2 - 1 ) );
                move16();

                test();
                IF( ( nrOfFIS > 0 ) && ( LE_16( lowerIndex[nrOfFIS], upperIndex[nrOfFIS - 1] ) ) )
                {
                    m = shr( add( k, indexOfTonalPeak[nrOfFIS - 1] ), 1 );
                    upperIndex[nrOfFIS - 1] = m;
                    move16();
                    lowerIndex[nrOfFIS] = add( m, 1 );
                    move16();
                }

                indexOfTonalPeak[nrOfFIS++] = k;
                move16();

                IF( EQ_16( nrOfFIS, MAX_NUMBER_OF_IDX ) )
                {
                    BREAK;
                }
                /* Jump to the next foot of the peak. */
                k = upperIdx;
                move16();
            }
        }
        k = add( k, 1 );
    }

    *numIndexes = nrOfFIS;
    move16();
    return;
}


static void ivas_RefineThresholdsUsingPitch_fx(
    const Word16 nSamples,
    const Word16 nSamplesCore,
+1 −0
Original line number Diff line number Diff line
@@ -1476,6 +1476,7 @@ ivas_error acelp_core_dec_ivas_fx(
    IF( st->hTcxDec != NULL )
    {
        Copy_Scale_sig( psyn_fx + shr( st->L_frame, 1 ), st->hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, st->Q_syn ) ); /*Q-1*/
        st->hTcxDec->Q_old_syn_Overl = -1;
    }
    Copy_Scale_sig( psyn_fx + sub( st->L_frame, M + 1 ), st->syn, M + 1, sub( 0, st->Q_syn ) ); /*Q0*/

+1 −0
Original line number Diff line number Diff line
@@ -756,6 +756,7 @@ ivas_error amr_wb_dec_fx(

    /* TCX=Q-1, ACELP2 Q0 */
    Copy_Scale_sig( syn_fx + L_FRAME / 2, hTcxDec->old_syn_Overl, L_FRAME / 2, sub( -1, st_fx->Q_syn ) );
    hTcxDec->Q_old_syn_Overl = -1;
    Copy_Scale_sig( syn_fx + L_FRAME - M - 1, st_fx->syn, M + 1, sub( 0, st_fx->Q_syn ) );

    /*------------------------------------------------------------------*
Loading