Commit 6f015791 authored by lefort's avatar lefort
Browse files

Final Update 2.

parent 8f248a4e
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -1660,21 +1660,20 @@ typedef enum
 * Stereo downmix EVS constants
 *----------------------------------------------------------------------------------*/

#define STEREO_DMX_EVS_PHA_LEN_16 24
#define STEREO_DMX_EVS_PHA_LEN_16 48
#define STEREO_DMX_EVS_FAD_LEN_16 160
#define STEREO_DMX_EVS_PHA_LEN_32 48
#define STEREO_DMX_EVS_PHA_LEN_32 96
#define STEREO_DMX_EVS_FAD_LEN_32 320
#define STEREO_DMX_EVS_PHA_LEN_48 48
#define STEREO_DMX_EVS_PHA_LEN_48 96
#define STEREO_DMX_EVS_FAD_LEN_48 480

#define STEREO_DMX_EVS_SUBBAND_SIZE 2
#define STEREO_DMX_EVS_NB_SUBBAND_MAX (L_FRAME48k / (2 * STEREO_DMX_EVS_SUBBAND_SIZE))

#define STEREO_DMX_EVS_PHA_LEN_MAX 48 /* Max of PHA_LEN */
#define STEREO_DMX_EVS_PHA_LEN_MAX 96 /* Max of PHA_LEN */
#define STEREO_DMX_EVS_FAD_LEN_MAX 480 /* Max of FAD_LEN */

#define STEREO_DMX_EVS_DATA_LEN_MAX (L_FRAME48k + STEREO_DMX_EVS_PHA_LEN_MAX)
#define STEREO_DMX_EVS_DATA_LEN2_MAX (L_FRAME48k + STEREO_DMX_EVS_PHA_LEN_MAX/2)
#define STEREO_DMX_EVS_DATA_LEN_MAX (STEREO_DMX_EVS_PHA_LEN_MAX + L_FRAME48k)

typedef enum
{
+2 −6
Original line number Diff line number Diff line
@@ -971,6 +971,8 @@ typedef struct stereo_dmx_evs_phase_only_correlation_structure
typedef struct stereo_dmx_evs_correlation_filter_structure
{
    int16_t init_frmCntr;
    float isd_rate_s;
    float iccr_s;
    float ipd_ff[STEREO_DMX_EVS_NB_SUBBAND_MAX];
    float Pr[STEREO_DMX_EVS_NB_SUBBAND_MAX];
    float Pi[STEREO_DMX_EVS_NB_SUBBAND_MAX];
@@ -985,7 +987,6 @@ typedef struct stereo_dmx_evs_correlation_filter_structure
    float *p_curr_taps[CPE_CHANNELS], curr_taps[CPE_CHANNELS][STEREO_DMX_EVS_PHA_LEN_MAX];

    float data_mem[CPE_CHANNELS][STEREO_DMX_EVS_PHA_LEN_MAX];
    float poc_sync_mem[STEREO_DMX_EVS_PHA_LEN_MAX / 2];

    STEREO_DMX_EVS_PHA curr_pha;
    STEREO_DMX_EVS_PHA prev_pha;
@@ -998,11 +999,6 @@ typedef struct stereo_dmx_evs_correlation_filter_structure
    float fad_g_prc[L_FRAME48k];
    int16_t fad_len_prc;

    float dmx_pha_ener;
    float dmx_poc_ener;
    float dmx_pha_old_gain;
    float dmx_poc_old_gain;

    float trns_aux_energy[CPE_CHANNELS];
    float crst_fctr;

+168 −207
Original line number Diff line number Diff line
@@ -67,12 +67,22 @@

#ifdef ENHANCED_STEREO_DMX

#define STEREO_DMX_EVS_ISD_THRES 1.3f
#define STEREO_DMX_EVS_ISD_FORGETTING     0.95f
#define STEREO_DMX_EVS_ISD_THRES_H        1.69f
#define STEREO_DMX_EVS_ISD_THRES_L        0.9f
#define STEREO_DMX_EVS_ISD_DIST_THRES_IPD 0.5f

#define STEREO_DMX_EVS_ISD_DIST_HYST_L 0.36f
#define STEREO_DMX_EVS_ISD_DIST_HYST_H 0.43f

#define STEREO_DMX_EVS_ICCR_FORGETTING 0.7f
#define STEREO_DMX_EVS_ICCR_HYST_L     0.75f
#define STEREO_DMX_EVS_ICCR_HYST_H     0.85f

#define STEREO_DMX_EVS_SWTCH_HYS_THRES 1
#define STEREO_DMX_EVS_LR_EGY          100.0f
#define STEREO_DMX_EVS_LR_EGY          15.0f
#define STEREO_DMX_EVS_ILDS_EGY        10000.0f
#define STEREO_DMX_EVS_ILD_PRC         0.3f
#define STEREO_DMX_EVS_ILD_PRC         0.1f

#define STEREO_DMX_EVS_SWTCH_PRC_THRES_16 55
#define STEREO_DMX_EVS_SWTCH_PRC_THRES_32 19
@@ -88,7 +98,6 @@
#define STEREO_DMX_EVS_CRST_FCTR_48  35.0f

#define STEREO_DMX_EVS_TRNS_EGY_FORGETTING 0.75f
#define STEREO_DMX_EVS_PHA_EGY_FORGETTING  0.79f

#endif

@@ -203,13 +212,11 @@ static void calc_poc(
    float eps_cos, eps_sin, EPS;

#ifdef ENHANCED_STEREO_DMX

    int16_t isd_cnt, n, freq8k, nsbd, input_frame_pha, pha_len2;
    float Nr, Ni, Dr, Di, tPr, tPi, Pn, energy, isd_band;

    float *Pr, *Pi, *ipd_ff, *p_taps_0, *p_taps_1;
    int16_t isd_cnt_h, isd_cnt_l, ild_cnt, n, freq_8k, freq_ipd_max, nsbd, input_frame_pha;
    float Nr, Ni, Dr, Di, tPr, tPi, Pn, energy, isd_rate;
    float eneL, eneR, IPDr, IPDi, tIPDr, tIPDi, ICCr;
    float *Pr, *Pi, *ipd_ff, *p_curr_taps;
    float rfft_pha_buf[L_FRAME48k], tEr[STEREO_DMX_EVS_NB_SUBBAND_MAX], tEl[STEREO_DMX_EVS_NB_SUBBAND_MAX];

#endif

    /* Initialization */
@@ -394,7 +401,8 @@ static void calc_poc(
    {
        hPHA->init_frmCntr = 0;
    }
    freq8k = L_FRAME16k / 2;
    freq_8k = L_FRAME16k / 2;
    freq_ipd_max = (int16_t) ( freq_8k * 5000. / ( 8000 * STEREO_DMX_EVS_SUBBAND_SIZE ) );

    // Memorize the filters N-1
    for ( n = 0; n < CPE_CHANNELS; n++ )
@@ -408,23 +416,31 @@ static void calc_poc(
        {
            hPHA->p_prev_taps[n] = NULL;
        }

        hPHA->p_curr_taps[n] = NULL;
    }

    // ISD
    isd_band = 0.0f;
    for ( i = 1; i <= freq8k; i++ )
    isd_cnt_l = 0;
    isd_cnt_h = 0;
    for ( i = 1; i <= freq_8k; i++ )
    {
        Nr = ( specLr[i] - specRr[i] );
        Ni = ( specLi[i] - specRi[i] );
        Dr = ( specLr[i] + specRr[i] );
        Di = ( specLi[i] + specRi[i] );
        isd_band += (float) sqrt( ( Nr * Nr + Ni * Ni ) / ( Dr * Dr + Di * Di ) );
        if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) )
        {
            isd_cnt_h++;
        }
        if ( ( Nr * Nr + Ni * Ni ) < STEREO_DMX_EVS_ISD_THRES_L * ( Dr * Dr + Di * Di ) )
        {
            isd_cnt_l++;
        }
    }

    isd_rate = (float) isd_cnt_h / (float) freq_8k;
    hPHA->isd_rate_s = STEREO_DMX_EVS_ISD_FORGETTING * hPHA->isd_rate_s + ( 1.0f - STEREO_DMX_EVS_ISD_FORGETTING ) * isd_rate;

    isd_band /= freq8k;
    if ( isd_band > STEREO_DMX_EVS_ISD_THRES )
    if ( hPHA->isd_rate_s > STEREO_DMX_EVS_ISD_DIST_HYST_H )
    {
        if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD )
        {
@@ -442,9 +458,10 @@ static void calc_poc(
                hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
            }
        }

        hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
    }
    else
    else if ( hPHA->isd_rate_s < STEREO_DMX_EVS_ISD_DIST_HYST_L )
    {
        if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD2 )
        {
@@ -465,10 +482,13 @@ static void calc_poc(
        hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD2;
    }

    if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD )
    {
    ipd_ff = hPHA->ipd_ff;

    Nr = 0;
    Ni = 0;
    eneL = 0;
    eneR = 0;

    for ( n = 1, i = 1; n < nsbd; n++ )
    {
        tPr = 0.0f;
@@ -478,10 +498,29 @@ static void calc_poc(

        for ( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; j++, i++ )
        {
                tPr += specLr[i] * specRr[i] + specLi[i] * specRi[i];
                tPi += specLi[i] * specRr[i] - specLr[i] * specRi[i];
            // Energy
            tEl[n] += specLr[i] * specLr[i] + specLi[i] * specLi[i];
            tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];

            // IPD
            IPDr = specLr[i] * specRr[i] + specLi[i] * specRi[i];
            IPDi = specLi[i] * specRr[i] - specLr[i] * specRi[i];
            tPr += IPDr;
            tPi += IPDi;

            // ICCr
            Pn = (float) inv_sqrt( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON );
            IPDr *= Pn;
            IPDi *= Pn;

            tIPDr = ( specRr[i] * IPDr - specRi[i] * IPDi );
            tIPDi = ( specRr[i] * IPDi + specRi[i] * IPDr );

            Nr += ( specLr[i] * tIPDr + specLi[i] * tIPDi );
            Ni += ( specLi[i] * tIPDr - specLr[i] * tIPDi );

            eneL += ( specLr[i] * specLr[i] + specLi[i] * specLi[i] );
            eneR += ( specRr[i] * specRr[i] + specRi[i] * specRi[i] );
        }

        Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON );
@@ -501,25 +540,29 @@ static void calc_poc(
            Pr[n] = tPr;
            Pi[n] = tPi;
        }

        Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n];
        Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n];
    }
    ICCr = sqrt( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) );
    hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr;

        for ( n = 0; n < CPE_CHANNELS; n++ )
    if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD )
    {
            hPHA->p_curr_taps[n] = hPHA->curr_taps[n];
        }
        hPHA->p_curr_taps[0] = NULL;
        hPHA->p_curr_taps[1] = hPHA->curr_taps[1];

        rfft_pha_buf[0] = 1.;
        rfft_pha_buf[1] = 1.;

        isd_cnt = 0;
        ild_cnt = 0;
        for ( i = 1; i < nsbd; i++ )
        {
            rfft_pha_buf[i * 2] = Pr[i];
            rfft_pha_buf[i * 2 + 1] = Pi[i];

            if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
            {
                isd_cnt++;
                ild_cnt++;
                tEr[i] = 1;
            }
            else
@@ -527,8 +570,7 @@ static void calc_poc(
                tEr[i] = -1;
            }
        }

        if ( isd_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
        if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
        {
            for ( i = 1; i < nsbd; i++ )
            {
@@ -541,66 +583,16 @@ static void calc_poc(
        }

        rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );

        pha_len2 = hPHA->pha_len / 2;

        p_taps_1 = hPHA->p_curr_taps[1];
        p_taps_0 = &( rfft_pha_buf[input_frame_pha - pha_len2] );
        for ( i = 0; i < pha_len2; i++ )
        {
            p_taps_1[i] = p_taps_0[i];
        }

        p_taps_1 = &( hPHA->p_curr_taps[1][pha_len2] );
        for ( i = 0; i < pha_len2; i++ )
        {
            p_taps_1[i] = rfft_pha_buf[i];
        }

        p_taps_0 = hPHA->p_curr_taps[0];
        set_zero( p_taps_0, hPHA->pha_len );
        p_taps_0[pha_len2] = 1.0f;
        mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
    }
    else
    {
        ipd_ff = hPHA->ipd_ff;

        for ( n = 1, i = 1; n < nsbd; n++ )
        if ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_L ) || ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_H ) && ( hPHA->p_curr_taps[0] != NULL ) ) )
        {
            tPr = 0.0f;
            tPi = 0.0f;
            tEr[n] = 0.0f;
            tEl[n] = 0.0f;
            // IPDn

            for ( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; j++, i++ )
            {
                tPr += specLr[i] * specRr[i] + specLi[i] * specRi[i];
                tPi += specLi[i] * specRr[i] - specLr[i] * specRi[i];
                tEl[n] += specLr[i] * specLr[i] + specLi[i] * specLi[i];
                tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
            }

            Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON );
            tPr *= Pn;
            tPi *= Pn;

            if ( hPHA->init_frmCntr == 0 )
            {
                Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr;
                Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi;
                Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
                Pr[n] *= Pn;
                Pi[n] *= Pn;
            }
            else
            {
                Pr[n] = tPr;
                Pi[n] = tPi;
            }

            Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n];
            Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n];
        }
            set_f( &( Pr[freq_ipd_max] ), 1.0f, ( nsbd - freq_ipd_max ) );
            set_f( &( Pi[freq_ipd_max] ), 0.0f, ( nsbd - freq_ipd_max ) );

            for ( n = 0; n < CPE_CHANNELS; n++ )
            {
@@ -610,18 +602,21 @@ static void calc_poc(
            rfft_pha_buf[0] = 1.;
            rfft_pha_buf[1] = 1.;

        isd_cnt = 0;
            ild_cnt = 0;
            isd_rate = (float) isd_cnt_l / freq_8k;
            for ( i = 1; i < nsbd; i++ )
            {
                rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + Pr[i] ) / 2.0f );
                rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] );
                if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD )
                {
                    rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] );
                    rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f );

                }

                if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
                {
                isd_cnt++;
                    ild_cnt++;
                    tEr[i] = 1;
                }
                else
@@ -629,8 +624,7 @@ static void calc_poc(
                    tEr[i] = -1;
                }
            }

        if ( isd_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
            if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
            {
                for ( i = 1; i < nsbd; i++ )
                {
@@ -643,53 +637,43 @@ static void calc_poc(
            }

            rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );
            mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );

        pha_len2 = hPHA->pha_len / 2;

        p_taps_1 = hPHA->p_curr_taps[1];
        p_taps_0 = &( rfft_pha_buf[input_frame_pha - pha_len2] );
        for ( i = 0; i < pha_len2; i++ )
            // PHA L2R
            p_curr_taps = hPHA->p_curr_taps[0];
            p_curr_taps[0] = rfft_pha_buf[0];
            for ( i = 1; i < hPHA->pha_len; i++ )
            {
            p_taps_1[i] = p_taps_0[i];
                p_curr_taps[i] = rfft_pha_buf[input_frame_pha - i];
            }

        p_taps_1 = &( hPHA->p_curr_taps[1][pha_len2] );
        for ( i = 0; i < pha_len2; i++ )
        {
            p_taps_1[i] = rfft_pha_buf[i];
        }

        // PHA L2R

        p_taps_0 = hPHA->p_curr_taps[0];
        p_taps_1 = hPHA->p_curr_taps[1];
        for ( i = 0, j = ( hPHA->pha_len - 1 ); i < ( hPHA->pha_len - 1 ); i++, j-- )
        else
        {
            p_taps_0[i + 1] = p_taps_1[j];
            for ( n = 0; n < CPE_CHANNELS; n++ )
            {
                hPHA->p_curr_taps[n] = NULL;
            }
        }
        p_taps_0[0] = rfft_pha_buf[pha_len2];
    }

    for ( n = 0; n < CPE_CHANNELS; n++ )
    {
        if ( hPHA->p_curr_taps[n] )
        {
            p_taps_0 = hPHA->p_curr_taps[n];

            for ( i = 0; i < hPHA->pha_len; i++ )
            {
                p_taps_0[i] *= hPHA->win[i];
                hPHA->p_curr_taps[n][i] *= hPHA->win[i];
            }

            energy = 0.;
            for ( i = 0; i < hPHA->pha_len; i++ )
            {
                energy += p_taps_0[i] * p_taps_0[i];
                energy += hPHA->p_curr_taps[n][i] * hPHA->p_curr_taps[n][i];
            }
            energy = (float) inv_sqrt( energy + EPSILON );
            for ( i = 0; i < hPHA->pha_len; i++ )
            {
                p_taps_0[i] *= energy;
                hPHA->p_curr_taps[n][i] *= energy;
            }
        }
    }
@@ -1161,10 +1145,10 @@ void stereo_dmx_evs_enc(
    float data_f[CPE_CHANNELS][L_FRAME48k];

#ifdef ENHANCED_STEREO_DMX
    int16_t k, m, pha_len, pha_len2, fad_len;
    int16_t k, m, pha_len, fad_len;
    float mem_prev[STEREO_DMX_EVS_FAD_LEN_MAX], data_mem[STEREO_DMX_EVS_DATA_LEN_MAX];
    float *p_data_mem, *p_prev_taps, *p_curr_taps, *fad_g, *p_data;
    float *dmx_poc_data, dmx_poc_data_sync[STEREO_DMX_EVS_DATA_LEN2_MAX], dmx_pha_data[L_FRAME48k], *p_dmx_data, dmx_gain, ftmp;
    float dmx_poc_data[L_FRAME48k], dmx_pha_data[L_FRAME48k], *p_dmx_data, ftmp;
    STEREO_DMX_EVS_PRC curr_prc;
    int16_t input_subframe, is_transient;
    float *p_sub_frame, subframe_energy[STEREO_DMX_EVS_NB_SBFRM];
@@ -1242,21 +1226,9 @@ void stereo_dmx_evs_enc(
        dmx_weight = 0.5f;
    }

    pha_len2 = hStereoDmxEVS->hPHA->pha_len / 2;

    mvr2r( hStereoDmxEVS->hPHA->poc_sync_mem, dmx_poc_data_sync, pha_len2 );
    dmx_poc_data = &( dmx_poc_data_sync[pha_len2] );

    create_M_signal( data_f[0], data_f[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd,
                     hStereoDmxEVS->dmx_weight, hStereoDmxEVS->pre_dmx_energy, hStereoDmxEVS->aux_dmx_energy );

    calc_energy( dmx_poc_data, dmx_poc_data, &( hStereoDmxEVS->hPHA->dmx_poc_ener ), n_samples, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    dmx_gain = INV_SQRT_2 * (float) sqrt( ( hStereoDmxEVS->aux_dmx_energy[0] + hStereoDmxEVS->aux_dmx_energy[1] ) / ( hStereoDmxEVS->hPHA->dmx_poc_ener ) );
    adapt_gain( dmx_poc_data, dmx_poc_data, dmx_gain, hStereoDmxEVS->hPHA->dmx_poc_old_gain, n_samples, hStereoDmxEVS->s_wnd );
    hStereoDmxEVS->hPHA->dmx_poc_old_gain = dmx_gain;

    mvr2r( &( dmx_poc_data[n_samples - pha_len2] ), hStereoDmxEVS->hPHA->poc_sync_mem, pha_len2 );

    // pha

    pha_len = hStereoDmxEVS->hPHA->pha_len;
@@ -1283,14 +1255,14 @@ void stereo_dmx_evs_enc(
                {
                    ftmp += p_data_mem[n - m] * p_prev_taps[m];
                }
                mem_prev[n] += ftmp;
                mem_prev[n] += ftmp * INV_SQRT_2;
            }
        }
        else
        {
            for ( n = 0; n < fad_len; n++ )
            {
                mem_prev[n] += p_data[n];
                mem_prev[n] += p_data[n] * INV_SQRT_2;
            }
        }

@@ -1303,14 +1275,14 @@ void stereo_dmx_evs_enc(
                {
                    ftmp += p_data_mem[n - m] * p_curr_taps[m];
                }
                dmx_pha_data[n] += ftmp;
                dmx_pha_data[n] += ftmp * INV_SQRT_2;
            }
        }
        else
        {
            for ( n = 0; n < n_samples; n++ )
            {
                dmx_pha_data[n] += p_data[n];
                dmx_pha_data[n] += p_data[n] * INV_SQRT_2;
            }
        }
    }
@@ -1321,11 +1293,6 @@ void stereo_dmx_evs_enc(
        dmx_pha_data[n] += ( mem_prev[n] ) * fad_g[m];
    }

    calc_energy( dmx_pha_data, dmx_pha_data, &( hStereoDmxEVS->hPHA->dmx_pha_ener ), n_samples, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    dmx_gain = INV_SQRT_2 * (float) sqrt( ( hStereoDmxEVS->aux_dmx_energy[0] + hStereoDmxEVS->aux_dmx_energy[1] ) / ( hStereoDmxEVS->hPHA->dmx_pha_ener + EPSILON ) );
    adapt_gain( dmx_pha_data, dmx_pha_data, dmx_gain, hStereoDmxEVS->hPHA->dmx_pha_old_gain, n_samples, hStereoDmxEVS->s_wnd );
    hStereoDmxEVS->hPHA->dmx_pha_old_gain = dmx_gain;

    // prc switch

    curr_prc = hStereoDmxEVS->hPHA->curr_prc;
@@ -1370,7 +1337,7 @@ void stereo_dmx_evs_enc(
        hStereoDmxEVS->hPHA->prev_prc = STEREO_DMX_EVS_PRC_PHA;
    }

    if ( ( is_transient == 1 ) || ( hStereoDmxEVS->aux_dmx_energy[0] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[1] ) || ( hStereoDmxEVS->aux_dmx_energy[1] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[0] ) )
    if ( ( is_transient == 1 ) || ( hStereoDmxEVS->aux_dmx_energy[0] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[1] ) || ( hStereoDmxEVS->aux_dmx_energy[1] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[0] ) || ( ( hStereoDmxEVS->hPHA->p_curr_taps[0] == NULL ) && ( hStereoDmxEVS->hPHA->p_curr_taps[1] == NULL ) ) )
    {
        hStereoDmxEVS->hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
        hStereoDmxEVS->hPHA->prc_hys_cnt = 0;
@@ -1378,7 +1345,7 @@ void stereo_dmx_evs_enc(

    if ( hStereoDmxEVS->hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    {
        p_dmx_data = dmx_poc_data_sync;
        p_dmx_data = dmx_poc_data;

        if ( curr_prc != hStereoDmxEVS->hPHA->curr_prc )
        {
@@ -1404,7 +1371,7 @@ void stereo_dmx_evs_enc(
            for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- )
            {
                p_dmx_data[n] *= fad_g[n];
                p_dmx_data[n] += fad_g[m] * dmx_poc_data_sync[n];
                p_dmx_data[n] += fad_g[m] * dmx_poc_data[n];
            }
        }
    }
@@ -1561,8 +1528,6 @@ ivas_error stereo_dmx_evs_init_encoder(
        set_zero( hStereoDmxEVS->hPHA->curr_taps[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    }

    set_zero( hStereoDmxEVS->hPHA->poc_sync_mem, STEREO_DMX_EVS_PHA_LEN_MAX / 2 );

    if ( input_Fs == 16000 )
    {
        len = STEREO_DMX_EVS_PHA_LEN_16;
@@ -1589,21 +1554,22 @@ ivas_error stereo_dmx_evs_init_encoder(
        return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sampling frequency\n" );
    }

    hStereoDmxEVS->hPHA->pha_len = len;
    hStereoDmxEVS->hPHA->init_frmCntr = (int16_t) ( FRAMES_PER_SEC * 0.2f );
    hStereoDmxEVS->hPHA->pha_len = len / 2;
    hStereoDmxEVS->hPHA->init_frmCntr = (int16_t) FRAMES_PER_SEC * 0.2f;
    hStereoDmxEVS->hPHA->isd_rate_s = 0.0f;
    hStereoDmxEVS->hPHA->iccr_s = 0.0f;

    pha_len = hStereoDmxEVS->hPHA->pha_len;
    fad_len = hStereoDmxEVS->hPHA->fad_len;

    trans_len = (int16_t) ( (float) pha_len / 20.0f );
    set_f( hStereoDmxEVS->hPHA->win, 1.0f, pha_len );
    set_f( hStereoDmxEVS->hPHA->win, 1.8f, pha_len - trans_len );
    hStereoDmxEVS->hPHA->win[0] = 1.0f;
    tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 );
    win = hStereoDmxEVS->hPHA->win;
    for ( n = 0, m = ( trans_len - 1 ); n < trans_len; n++, m-- )
    win = &( hStereoDmxEVS->hPHA->win[pha_len - trans_len] );
    for ( n = 0; n < trans_len; n++ )
    {
        itrh = pha_len - trans_len + n;
        win[itrh] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) );
        win[m] = win[itrh];
        win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * 1.8f;
    }

    fad_g = hStereoDmxEVS->hPHA->fad_g;
@@ -1688,11 +1654,6 @@ ivas_error stereo_dmx_evs_init_encoder(
        fad_g[m] = 1.0f - fad_g[n];
    }

    hStereoDmxEVS->hPHA->dmx_pha_ener = 0;
    hStereoDmxEVS->hPHA->dmx_poc_ener = 0;
    hStereoDmxEVS->hPHA->dmx_pha_old_gain = 1.;
    hStereoDmxEVS->hPHA->dmx_poc_old_gain = 1.;

    for ( n = 0; n < CPE_CHANNELS; n++ )
    {
        hStereoDmxEVS->hPHA->trns_aux_energy[n] = 0.0f;