Commit bf19243e authored by Michael Sturm's avatar Michael Sturm
Browse files

Unifies IGF_ErodeSpectrum function.

parent c2151367
Loading
Loading
Loading
Loading
+243 −0
Original line number Diff line number Diff line
@@ -403,6 +403,234 @@ static Word16 IGF_WriteEnvelope(
    return totBitCount;
}
#endif
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS
/**********************************************************************/ /*
identifies significant spectral content
**************************************************************************/
void IGF_ErodeSpectrum( const IGF_ENC_INSTANCE_HANDLE hInstance,     /**< in:     | instance handle of IGF Encoder */
                        Word32 *pSpectrum,                           /**< in/out: | MDCT spectrum                  */
                        Word32 *pPowerSpectrum,                      /**< in/out: | power spectrum                 */
                        Word16 pPowerSpectrum_exp,                   /**< in:     | exponent of power spectrum     */
                        const Word16 igfGridIdx,                     /**< in: Q0  | IGF grid index                 */
                        const Word16 mct_on,                         /**< in:     | flag that indicates mct on/off */
                        const Word16 element_mode                    /**< in:     | IVAS element mode type         */
)
{
    IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    H_IGF_GRID hGrid;
    Word16 i;
    Word16 igfBgn;
    Word16 igfEnd;
    Word32 highPassEner; /* Q31 */
    Word32 highPassEner_Ovfl;
    Word32 lastLine;
    Word32 nextLine;
    Word32 L_tmp;
    Word16 highPassEner_exp;
    Word16 s;
    Word16 *swb_offset;
    Word16 sfb;
    Word16 startSfb;
    Word16 stopSfb;
    Word16 line;
    Word16 *igfScaleF;
    Word16 tmp;

    hPrivateData = &hInstance->igfData;
    hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    igfBgn = hGrid->startLine;
    move16();
    igfEnd = hGrid->stopLine;
    move16();
    swb_offset = hGrid->swb_offset;
    move16();
    startSfb = hGrid->startSfb;
    move16();
    stopSfb = hGrid->stopSfb;
    move16();
    igfScaleF = hPrivateData->igfScfQuantized;
    move16();
    highPassEner_exp = 0;
    move16();
    highPassEner = 0;
    move32();
    highPassEner_Ovfl = 0;
    move32();

    IF( NULL == pPowerSpectrum )
    {
        FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
        {
            pSpectrum[i] = 0;
            move32();
        }
        return;
    }

    /* caluculate highpass energy for spectral erosion threshold */
    IF( GT_16( igfBgn, 0 ) )
    {
        Word16 factor;
        Word16 shift = 0;
        move16();
        /* get IGF start line scaling facor depending on the bitrate (used for threshold calculation) */
        IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) ||
            EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) ||
            EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) ||
            EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_16400_CPE ) )
        {
            factor = ONE_IN_Q14;
            move16();
        }
        ELSE IF( mct_on && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) ) )
        {
            factor = 11469; // 0.7f in Q14
            move16();
        }
        ELSE
        {
            factor = 32767; // 2.f in Q14
            shift  = 1;     // x2 multiplicator for EVS
            move16();
            move16();
        }

        /* calculate actual highpass energy */
        IF( EQ_16( element_mode, EVS_MONO ) )
        {
            Word64 W_highPassEner = 0;
            move64();
            FOR( i = 0; i < igfBgn; i++ )
            {
                W_highPassEner = W_add( W_highPassEner, W_deposit32_l( Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) ) /*Q20, pPowerSpectrum_exp*/ );
            }
            highPassEner = w_norm_llQ31( W_highPassEner, &highPassEner_exp ); /*Q20, highPassEner_exp*/
            highPassEner_exp = add( highPassEner_exp, pPowerSpectrum_exp );
            move16();
            test();
            test();

            igfBgn = shl(igfBgn, shift);

            highPassEner = L_deposit_l( BASOP_Util_Divide3216_Scale( highPassEner /*Q20, highPassEner_exp*/, igfBgn /*Q0*/, &s ) ); /*Q15, highPassEner_exp+11-16+s*/
            highPassEner_exp = add( add( highPassEner_exp, s ), 12 - 16 + ( 31 - 15 ) );  /*Q15->Q31,highPassEner_exp*/
            highPassEner_Ovfl = L_shl_sat( L_negate( highPassEner ), sub( highPassEner_exp, pPowerSpectrum_exp ) );
        }
        ELSE
        {
            Word64 sum = 0;
            move64();
            Word32 temp;
            Word16 exp1, exp2, num, den;
            FOR( i = 0; i < igfBgn; i++ )
            {
                sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1
            }
            exp1 = W_norm( sum );
            sum = W_shl( sum, sub( exp1, 1 ) );                // Q: 31-pPowerSpectrum_exp+1+exp1-1
            num = extract_h( W_extract_h( sum ) );             // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17
            exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1

            temp = L_mult( igfBgn, factor ); // exp: 16
            exp2 = norm_l( temp );
            den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2
            exp2 = sub( 16, exp2 );

            highPassEner = L_deposit_h( div_s( num, den ) ); // exp: exp1-exp2

            /* highPassEner is used only for comparison, saturation doesn't effect the outcome */
            highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp
        }

        /* spectral erosion */
        lastLine = pSpectrum[i - 1]; // Qx
        move32();
        nextLine = pSpectrum[i]; // Qx
        move32();

        /* May overflow - just for threshold comparison */
        BASOP_SATURATE_WARNING_OFF_EVS
        L_tmp = L_add_sat( pPowerSpectrum[i - 1], highPassEner_Ovfl );
        BASOP_SATURATE_WARNING_ON_EVS;
        if ( ( LT_32( pPowerSpectrum[i - 1], highPassEner ) && GT_16(element_mode, EVS_MONO ) ) ||
             ( LT_32( L_tmp, 0 ) && EQ_16( element_mode, EVS_MONO ) ) )
        {
            nextLine = 0;
            move32();
        }

        FOR( /*i*/; i < igfEnd - 1; i++ )
        {
            /* May overflow - just for threshold comparison */
            BASOP_SATURATE_WARNING_OFF_EVS
            L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
            BASOP_SATURATE_WARNING_ON_EVS;
            if ( ( LT_32( pPowerSpectrum[i], highPassEner ) && GT_16( element_mode, EVS_MONO ) ) ||
                ( LT_32( L_tmp, 0 ) && EQ_16( element_mode, EVS_MONO ) ) )
            {
                lastLine = pSpectrum[i]; // Qx
                move32();
                pSpectrum[i] = nextLine; // Qx
                move32();
                nextLine = 0;
                move32();
            }
            ELSE
            {
                pSpectrum[i - 1] = lastLine; // Qx
                move32();
                lastLine = pSpectrum[i]; // Qx
                move32();
                nextLine = pSpectrum[i + 1]; // Qx
                move32();
            }
        }

        /* May overflow - just for threshold comparison */
        BASOP_SATURATE_WARNING_OFF_EVS
        L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
        BASOP_SATURATE_WARNING_ON_EVS;
        if ( ( LT_32( pPowerSpectrum[i], highPassEner ) && GT_16( element_mode, EVS_MONO ) ) ||
             ( LT_32( L_tmp, 0 ) && EQ_16( element_mode, EVS_MONO ) ) )
        {
            pSpectrum[i] = 0;
            move32();
        }
    }

    /* delete spectrum above igfEnd: */
    FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
    {
        pSpectrum[i] = 0;
        pPowerSpectrum[i] = 0;
        move32();
        move32();
    }

    FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
    {
        tmp = 0;
        move16();
        FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
        {
            if ( pSpectrum[line] != 0 )
            {
                tmp = add( tmp, 1 );
            }
        }

        Word16 igfScaleF_cnt = igfScaleF[sfb];
        move16();
        test();
        if ( tmp && igfScaleF[sfb] )
        {
            igfScaleF_cnt = sub( igfScaleF[sfb], 1 );
        }
        igfScaleF[sfb] = igfScaleF_cnt;
        move16();
    }
}
#else
/**********************************************************************/ /*
identifies significant spectral content
**************************************************************************/
@@ -753,6 +981,7 @@ void IGF_ErodeSpectrum_ivas_fx(
        }
    }
}
#endif

/**********************************************************************/ /*
crest factor calculation
@@ -2093,7 +2322,9 @@ void IGFEncApplyMono_fx(
{
    Word32 *pPowerSpectrumParameter;          /* If it is NULL it informs a function that specific handling is needed */
    Word32 *pPowerSpectrumParameterWhitening; /* If it is NULL it informs a function that specific handling is needed */
#ifndef FIX_2346_DUPLICATED_IGF_FUNCTIONS
    Word16 highPassEner_exp;                  /*exponent of highpass energy - maybe not needed*/
#endif

    pPowerSpectrumParameter = NULL;
    test();
@@ -2119,7 +2350,11 @@ void IGFEncApplyMono_fx(
        pPowerSpectrumParameter = pPowerSpectrum;
    }

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS
    IGF_ErodeSpectrum( hInstance, pMDCTSpectrum, pPowerSpectrumParameter, PowerSpectrum_e, igfGridIdx, 0, st->element_mode );
#else
    IGF_ErodeSpectrum( &highPassEner_exp, hInstance, pMDCTSpectrum, pPowerSpectrumParameter, PowerSpectrum_e, igfGridIdx );
#endif

    return;
}
@@ -4632,7 +4867,11 @@ void IGFEncApplyMono_ivas_fx(
        pPowerSpectrumParameter_fx = common_pPowerSpectrum_fx;
    }

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS
    IGF_ErodeSpectrum( st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0, st->element_mode );
#else
    IGF_ErodeSpectrum_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0 );
#endif

    return;
}
@@ -4772,7 +5011,11 @@ void IGFEncApplyStereo_fx(
            }
            pPowerSpectrumParameter_fx[ch] = common_pPowerSpectrum_fx;
        }
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS
        IGF_ErodeSpectrum( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], common_pPowerSpectrum_exp, igfGridIdx, mct_on, sts[ch]->element_mode );
#else
        IGF_ErodeSpectrum_ivas_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], common_pPowerSpectrum_exp, igfGridIdx, mct_on );
#endif
    }

    return;
+15 −0
Original line number Diff line number Diff line
@@ -2721,6 +2721,20 @@ Word16 IGF_getSFM_ivas_fx(
);
#endif

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS
/**********************************************************************/ /*
identifies significant spectral content
**************************************************************************/
void IGF_ErodeSpectrum(
    const IGF_ENC_INSTANCE_HANDLE hInstance,     /* i  : instance handle of IGF Encoder */
    Word32 *pSpectrum,                           /* i/o: MDCT spectrum                  */
    Word32 *pPowerSpectrum,                      /* i/o: power spectrum                 */
    Word16 pPowerSpectrum_exp,                   /* i  : exponent of power spectrum     */
    const Word16 igfGridIdx,                     /* i  : IGF grid index                 */
    const Word16 mct_on,                         /* i  : flag that indicates mct on/off */
    const Word16 element_mode                    /* i  : IVAS element mode type         */
);
#else
void IGF_ErodeSpectrum(
    Word16 *highPassEner_exp,                /* o  : exponent of highPassEner       */
    const IGF_ENC_INSTANCE_HANDLE hInstance, /* i  : instance handle of IGF Encoder */
@@ -2737,6 +2751,7 @@ void IGF_ErodeSpectrum_ivas_fx(
    Word16 pPowerSpectrum_exp,               /* i  : exponent of power spectrum     */
    const Word16 igfGridIdx,                 /* i  : IGF grid index                 */
    const Word16 mct_on );
#endif

void IGFEncApplyMono_fx(
    const IGF_ENC_INSTANCE_HANDLE hInstance, /* i  :     | instance handle of IGF Encoder                         */