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

Unifies IGF_CalculateEnvelope function.

parent 3b94e993
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@
#define FIX_2480_HARM_TONALMDCT                         /* FhG: basop issue 2480: Harmonize TonalMDCTConceal_Detect_fx() and TonalMDCTConceal_Detect_ivas_fx() */
#define FIX_2479_HARM_PITCH_GAIN                        /* FhG: basop issue 2479: Harmonize tcx_ltp_pitch_search_*(), tcx_ltp_find_gain_*fx() */
#define HARMONIZE_2481_EXTEND_SHRINK                    /* FhG: basop issue 2481: Harmonize extend_frm_*fx() and shrink_frm_*fx() */
#define FIX_2346_DUPLICATED_IGF_FUNCTIONS_2           /* FhG: part 2 of basop issue 2346: Review potentially duplicated IGF functions */

/* #################### End BE switches ################################## */

+251 −45
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ static void IGF_write_bits(
    return;
}


#ifndef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
/**********************************************************************/ /*
   envelope estimation
   **************************************************************************/
@@ -246,6 +246,7 @@ static void IGF_CalculateEnvelope(

    return;
}
#endif


/*-------------------------------------------------------------------*
@@ -2010,7 +2011,11 @@ static Word32 IGF_getTNR_ivas_fx(
 * envelope estimation
 *-------------------------------------------------------------------*/

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
static void IGF_CalculateEnvelope(
#else
static void IGF_CalculateEnvelope_ivas_fx(
#endif
    const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i  : instance handle of IGF Encoder                  */
    Word32 *pMDCTSpectrum_fx,              /* i  : MDCT spectrum                                   */
    Word16 e_mdct,                         /* i  : exp of MDCT spectrum                  */
@@ -2057,10 +2062,22 @@ static void IGF_CalculateEnvelope_ivas_fx(
    Word16 crest_exp; /*Stores the exponent of the result(return value)*/
    Word16 sfm_exp;   /*stores exponent for ouput from sfm*/
    Word16 tmp_e;
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
    Word32 LFMDCTSpectrum[N_MAX];
    Word32 LFPowerSpectrum[N_MAX];
    Word16 sfbEnergyTileR16;
    Word16 sfbEnergyR16;
    Word16 gain16; /* the EVS gain which has to be applied to the source tile to get the destination energy */
    Word16 zeroNrg; /* flag indicating if the signal contains almost no energy */
#endif

    hPrivateData = &hIGFEnc->igfData;
    hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx];
    swb_offset = hGrid->swb_offset;
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
    zeroNrg = 0;
    move16();
#endif

    IF( element_mode > EVS_MONO )
    {
@@ -2094,8 +2111,38 @@ static void IGF_CalculateEnvelope_ivas_fx(
            }
        }
    }
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
    ELSE
    {
        Copy32( pMDCTSpectrum_fx + IGF_START_MN, hIGFEnc->spec_be_igf, hIGFEnc->infoStopLine - IGF_START_MN );
        hIGFEnc->spec_be_igf_e = e_mdct;
        IF( pPowerSpectrum_fx )
        {
            FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
            {
                strt_cpy = hGrid->sbWrap[tile_idx];
                move16();
                FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
                {
                    FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ )
                    {
                        LFMDCTSpectrum[sb] = pMDCTSpectrum_fx[strt_cpy];
                        move32();
                        LFPowerSpectrum[sb] = pPowerSpectrum_fx[strt_cpy];
                        move32();
                        strt_cpy = add( strt_cpy, 1 );
                    }
                }
            }
        }
    }
#endif

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
    IF( pPowerSpectrum_fx && ( element_mode > EVS_MONO ) )
#else
    IF( pPowerSpectrum_fx )
#endif
    {
        FOR( sb = hGrid->sbWrap[0]; sb < swb_offset[hGrid->sfbWrap[hGrid->nTiles]]; sb++ )
        {
@@ -2137,6 +2184,10 @@ static void IGF_CalculateEnvelope_ivas_fx(
            {
                tmp = strt_cpy;
                move16();
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                IF( element_mode > EVS_MONO )
                {
#endif
                    FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ )
                    {
                        Word16 shift = norm_l( pPowerSpectrum_fx[sb] );
@@ -2155,24 +2206,77 @@ static void IGF_CalculateEnvelope_ivas_fx(

                    sfbEnergyTileR = L_deposit_h( BASOP_Util_Divide3232_Scale( sfbEnergyTileR, width, &tmp_e ) );
                    sfbEnergyTileR_e = add( sub( sfbEnergyTileR_e, Q31 ), tmp_e );
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                }
                ELSE
                {
                    Word32 tmp32[MAX_IGF_SFB_LEN];
                    Word16 tmp16, tmp32_e, s1;

                    sfbEnergyC = sum_array_norm( pPowerSpectrum_fx + swb_offset[sfb], swb_offset[sfb + 1] - swb_offset[sfb], &sfbEnergyC_e );
                    move32();
                    sfbEnergyC_e = add( sfbEnergyC_e, *e_ps );
                    move16();
                    sfbEnergyTileC = sum_array_norm( pPowerSpectrum_fx + strt_cpy, swb_offset[sfb + 1] - swb_offset[sfb], &sfbEnergyTileC_e );
                    move32();
                    sfbEnergyTileC_e = add( sfbEnergyTileC_e, *e_ps );
                    move16();
                    s1 = getScaleFactor32( LFMDCTSpectrum + hGrid->startLine, sub( hGrid->stopLine, hGrid->startLine ) );
                    tmp32_e = add( shl( sub( e_mdct, s1 ), 1 ), 1 );
                    move16();
                    FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ )
                    {
                        tmp16 = round_fx_sat( L_shl_sat( LFMDCTSpectrum[sb], s1 ) ); /*(15 - mdctSpec_e)+ S1*/
                        tmp32[sb - swb_offset[sfb]] = L_mult0( tmp16, tmp16 ); /*31 - mdctSquareSpec_e*/
                        move32();
                    }
                    sfbEnergyTileR = sum_array_norm( tmp32, swb_offset[sfb + 1] - swb_offset[sfb], &sfbEnergyTileR_e );
                    move32();
                    sfbEnergyTileR_e = add( sfbEnergyTileR_e, tmp32_e );
                    move16();

                    BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyTileR ), sfbEnergyTileR_e, width, 15, &sfbEnergyTileR16, &sfbEnergyTileR_e );
                    IF( sfbEnergyTileR16 == 0 )
                    {
                        sfbEnergyTileR16 = 0x00010000;
                        sfbEnergyTileR_e = 0;
                        move16();
                        move16();
                    }

                    strt_cpy += swb_offset[sfb + 1] - swb_offset[sfb];
                }
#endif

                IF( sfbEnergyTileR == 0 )
                {
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                    sfbEnergyTileR = ( element_mode > EVS_MONO ) ? EPSILON_FX : 0x00010000;
#else
                    sfbEnergyTileR = EPSILON_FX;
#endif
                    sfbEnergyTileR_e = 0;
                    move32();
                    move16();
                }
                IF( sfbEnergyC == 0 )
                {
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                    sfbEnergyC = ( element_mode > EVS_MONO ) ? EPSILON_FX : 0x00010000;
#else
                    sfbEnergyC = EPSILON_FX;
#endif
                    sfbEnergyC_e = 0;
                    move32();
                    move16();
                }
                IF( sfbEnergyTileC == 0 )
                {
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                    sfbEnergyTileC = ( element_mode > EVS_MONO ) ? EPSILON_FX : 0x00010000;
#else
                    sfbEnergyTileC = EPSILON_FX;
#endif
                    sfbEnergyTileC_e = 0;
                    temp = BASOP_Util_Divide3232_Scale( sfbEnergyC, sfbEnergyTileC, &tmp_e );
                    tmp_e = add( tmp_e, sub( sfbEnergyC_e, sfbEnergyTileC_e ) );
@@ -2182,11 +2286,33 @@ static void IGF_CalculateEnvelope_ivas_fx(
                ELSE
                {
                    /*gain = (float) ( sfbEnergyTileR * ( sfbEnergyC / sfbEnergyTileC ) );*/
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                    IF( element_mode > EVS_MONO )
                    {
#endif
                        temp = BASOP_Util_Divide3232_Scale( sfbEnergyC, sfbEnergyTileC, &tmp_e );
                        tmp_e = add( tmp_e, sub( sfbEnergyC_e, sfbEnergyTileC_e ) );
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                    }
                    ELSE
                    {
                        BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyC ), sfbEnergyC_e, round_fx_sat( sfbEnergyTileC ), sfbEnergyTileC_e, &tmp, &tmp_e );
                    }
#endif
                }

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                IF( element_mode > EVS_MONO )
                {
#endif
                    gain = Mult_32_16( sfbEnergyTileR, temp ); // gain_e
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                }
                ELSE
                {
                    gain = L_mult( sfbEnergyTileR16, tmp ); // gain_e
                }
#endif
                gain_e = add( tmp_e, sfbEnergyTileR_e );

                IF( element_mode > EVS_MONO )
@@ -2503,6 +2629,10 @@ static void IGF_CalculateEnvelope_ivas_fx(
            }
            ELSE
            {
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                IF( element_mode > EVS_MONO )
                {
#endif
                    tmp_e = e_mdct;
                    move16();
                    sfbEnergyR = add_sat( EPSILON_FX, BASOP_Util_Divide3216_Scale( sum2_32_fx( pMDCTSpectrum_fx + swb_offset[sfb], width, &tmp_e ) /*exp: tmp_e*/, width, &sfbEnergyR_e ) ); // sfbEnergyR_e
@@ -2510,9 +2640,6 @@ static void IGF_CalculateEnvelope_ivas_fx(
                    gain = L_shl( sfbEnergyR, 16 ); // gain_e
                    move32();
                    gain_e = sfbEnergyR_e;

                IF( element_mode > EVS_MONO )
                {
                    hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = 0; // hPrivateData->prevSFB_FIR_TB_e[sfb]
                    hPrivateData->prevSFB_FIR_TB_e[sfb] = 0;
                    hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = 0; // hPrivateData->prevSFB_IIR_TB_e[sfb]
@@ -2535,13 +2662,53 @@ static void IGF_CalculateEnvelope_ivas_fx(
                    move16();
                    move16();
                    move16();
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                }
                ELSE
                {
                    Word32 tmp32[MAX_IGF_SFB_LEN];
                    Word16 tmp32_e, s1;

                    s1 = getScaleFactor32( pMDCTSpectrum_fx + hGrid->startLine, sub( hGrid->stopLine, hGrid->startLine ) );
                    tmp32_e = add( shl( sub( e_mdct, s1 ), 1 ), 1 );
                    move16();
                    FOR( sb = 0; sb < sub(swb_offset[sfb + 1], swb_offset[sfb]); sb++ )
                    {
                        tmp = round_fx_sat( L_shl_sat( pMDCTSpectrum_fx[swb_offset[sfb] + sb], s1 ) ); /*(15 - mdctSpec_e)+ S1*/
                        tmp32[sb] = L_mult0( tmp, tmp ); /*31 - mdctSquareSpec_e*/
                        move32();
                    }
                    sfbEnergyR = sum_array_norm( tmp32, swb_offset[sfb + 1] - swb_offset[sfb], &sfbEnergyR_e );
                    move32();
                    sfbEnergyR_e = add( sfbEnergyR_e, tmp32_e );
                    move16();

                    IF( sfbEnergyR == 0 ) {
                        sfbEnergyR = EPSILON_FX;
                        move32();
                        sfbEnergyR_e = 0;
                        move16();
                        zeroNrg = 1;
                        move16();
                    }
                    BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyR ), sfbEnergyR_e, width, 15, &sfbEnergyR16, &gain_e );
                    gain = L_deposit_h( sfbEnergyR16 );
                }
#endif
            }

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
            IF( element_mode > EVS_MONO )
            {
#endif
                gain = Mult_32_16( gain, att ); // gain_e
                gain_e = add( gain_e, 0 );

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
                /*gain=0.5f+log2f(gain)*2+16 because 2.885390081777927f=2*1/loge(2) so 2*1/loge(2)*loge(x) can be written as 2*log2(x)*/
#else
                /*gain=0.5f+log2f(gain)*2+16 becuase 2.885390081777927f=2*1/loge(2) so 2*1/loge(2)*loge(x) can be written as 2*log2(x)*/
#endif
                gain = L_add( ONE_IN_Q22, L_add( L_add( L_shr( BASOP_Util_Log2( gain ), 1 ), L_shl( gain_e, Q24 ) ), L_shl( 16, Q23 ) ) ); /*Q23*/
                test();
                test();
@@ -2561,6 +2728,41 @@ static void IGF_CalculateEnvelope_ivas_fx(
                move16();
                hPrivateData->igfScfQuantized[sfb] = extract_l( L_shr( gain, Q23 ) ); /*Q0*/
                move16();
#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
            }
            ELSE
            {
                /* gain = 0.5f + (float)((2.885390081777927f * log(gain) + 16.f)); */
                Word16 shift;
                gain = BASOP_Util_Log2( gain );
                gain = L_add( gain, L_deposit_h( shl( gain_e, 15 - 6 ) ) );
                shift = norm_l( gain );
                gain16 = round_fx_sat( L_shl( gain, shift ) );
                gain_e = sub( 7, shift );
                gain_e = BASOP_Util_Add_MantExp( gain16, gain_e, 32767 /*16 Q11*/, 4, &gain16 );
                gain_e = BASOP_Util_Add_MantExp( gain16, gain_e, 0x4000, 0, &gain16 );
                gain16 = shr( gain16, s_min( sub( 15, gain_e ), 15 ) );

                if ( gain16 > 91 )
                {
                    gain16 = s_min( gain16, 91 ); /* 13+15+63, see arithocde encode residual */
                }
                if ( gain16 < 0 )
                {
                    gain16 = s_max( gain16, 0 );
                }

                /* set gain to zero if the signal contains too little energy */
                if ( zeroNrg != 0 )
                {
                    gain16 = 0;
                    move16();
                }

                hPrivateData->igfScfQuantized[sfb] = gain16;
                move16();
            }
#endif
        }
    }

@@ -3332,6 +3534,9 @@ void IGFEncApplyMono_fx(
        calculate_hangover_attenuation_gain_fx( st, &att_fx, vad_hover_flag );
    }

#ifdef FIX_2346_DUPLICATED_IGF_FUNCTIONS_2
    IGF_CalculateEnvelope(st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, st->element_mode, att_fx);
#else
    IF( EQ_16( st->element_mode, EVS_MONO ) )
    {
        IGF_CalculateEnvelope( st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, *e_ps, igfGridIdx );
@@ -3340,6 +3545,7 @@ void IGFEncApplyMono_fx(
    {
        IGF_CalculateEnvelope_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, st->element_mode, att_fx );
    }
#endif

    IF( isTCX20 )
    {