Commit 8f248a4e authored by lefort's avatar lefort
Browse files

Corrections of phase compensation filters and algorithmic enhancements.

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

#define STEREO_DMX_EVS_PHA_LEN_16 48
#define STEREO_DMX_EVS_PHA_LEN_16 24
#define STEREO_DMX_EVS_FAD_LEN_16 160
#define STEREO_DMX_EVS_PHA_LEN_32 96
#define STEREO_DMX_EVS_PHA_LEN_32 48
#define STEREO_DMX_EVS_FAD_LEN_32 320
#define STEREO_DMX_EVS_PHA_LEN_48 96
#define STEREO_DMX_EVS_PHA_LEN_48 48
#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 96 /* Max of PHA_LEN */
#define STEREO_DMX_EVS_PHA_LEN_MAX 48 /* Max of PHA_LEN */
#define STEREO_DMX_EVS_FAD_LEN_MAX 480 /* Max of FAD_LEN */

#define STEREO_DMX_EVS_DATA_LEN_MAX (STEREO_DMX_EVS_PHA_LEN_MAX + L_FRAME48k)
#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)

typedef enum
{
+2 −1
Original line number Diff line number Diff line
@@ -985,6 +985,7 @@ 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;
+268 −201
Original line number Diff line number Diff line
@@ -68,10 +68,11 @@
#ifdef ENHANCED_STEREO_DMX

#define STEREO_DMX_EVS_ISD_THRES 1.3f
#define STEREO_DMX_EVS_ISD_DIST_THRES_PHA  0.42f

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

#define STEREO_DMX_EVS_SWTCH_PRC_THRES_16 55
#define STEREO_DMX_EVS_SWTCH_PRC_THRES_32 19
@@ -203,10 +204,12 @@ static void calc_poc(

#ifdef ENHANCED_STEREO_DMX

    int16_t isd_cnt, n, freq8k, nsbd, input_frame_pha;
    float Nr, Ni, Dr, Di, ISD, tPr, tPi, Pn, energy, isd_rate;
    float *Pr, *Pi, *ipd_ff, *p_curr_taps;
    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;
    float rfft_pha_buf[L_FRAME48k], tEr[STEREO_DMX_EVS_NB_SUBBAND_MAX], tEl[STEREO_DMX_EVS_NB_SUBBAND_MAX];

#endif

    /* Initialization */
@@ -221,8 +224,6 @@ static void calc_poc(
    Pi = hPHA->Pi;
    nsbd = n0 / STEREO_DMX_EVS_SUBBAND_SIZE;
    input_frame_pha = input_frame / STEREO_DMX_EVS_SUBBAND_SIZE;
    input_frame_pha = (input_frame_pha == 192) ? 200 : input_frame_pha; // Handle FFT 192
    input_frame_pha = (input_frame_pha == 96) ? 100 : input_frame_pha; // Handle FFT 96
#endif

    igamma = STEREO_DMX_EVS_POC_GAMMA * iN;
@@ -412,23 +413,18 @@ static void calc_poc(
    }

    // ISD
    isd_cnt = 0;
    isd_band = 0.0f;
    for ( i = 1; i <= freq8k; i++ )
    {
        Nr = ( specLr[i] - specRr[i] );
        Ni = ( specLi[i] - specRi[i] );
        Dr = ( specLr[i] + specRr[i] );
        Di = ( specLi[i] + specRi[i] );
        ISD = sqrtf( (Nr*Nr + Ni*Ni) / (Dr*Dr + Di*Di) );
        if (ISD > STEREO_DMX_EVS_ISD_THRES)
        {
            isd_cnt++;
        isd_band += (float) sqrt( ( Nr * Nr + Ni * Ni ) / ( Dr * Dr + Di * Di ) );
    }
    }
    
    isd_rate = (float)isd_cnt / (float)freq8k;

    if (isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_PHA)
    isd_band /= freq8k;
    if ( isd_band > STEREO_DMX_EVS_ISD_THRES )
    {
        if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD )
        {
@@ -488,14 +484,15 @@ static void calc_poc(
                tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
            }

            Pn = 1.0 / (sqrtf(tPr * tPr + tPi * tPi ) + EPSILON);
            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 = 1.0 / (sqrtf(Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON);
                Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
                Pr[n] *= Pn;
                Pi[n] *= Pn;
            }
@@ -506,39 +503,63 @@ static void calc_poc(
            }
        }

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

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

        isd_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] ) )
            {
                rfft_pha_buf[i * 2] = 1.;
                rfft_pha_buf[i * 2 + 1] = 0.;
                isd_cnt++;
                tEr[i] = 1;
            }
            else {
                rfft_pha_buf[i * 2] = Pr[i];
                rfft_pha_buf[i * 2 + 1] = Pi[i];
            else
            {
                tEr[i] = -1;
            }

        }

        // Handle FFT 192/96
        if ((input_frame_pha == 200) || (input_frame_pha == 100))
        if ( isd_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
        {
            tPr = rfft_pha_buf[2*nsbd-2];
            tPi = rfft_pha_buf[2*nsbd-1];
            for (i = 2*nsbd; i < input_frame_pha; i+=2)
            for ( i = 1; i < nsbd; i++ )
            {
                if ( tEr[i] > 0 )
                {
                rfft_pha_buf[i] = tPr;
                rfft_pha_buf[i+1] = tPi;
                    rfft_pha_buf[i * 2] = 1.;
                    rfft_pha_buf[i * 2 + 1] = 0.;
                }
            }
        }

        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++ )
        {
            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;
    }
    else
    {
@@ -559,7 +580,7 @@ static void calc_poc(
                tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
            }

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

@@ -567,7 +588,7 @@ static void calc_poc(
            {
                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 = 1.0 / (sqrtf(Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON);
                Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
                Pr[n] *= Pn;
                Pi[n] *= Pn;
            }
@@ -576,6 +597,9 @@ 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];
        }

        for ( n = 0; n < CPE_CHANNELS; n++ )
@@ -586,64 +610,86 @@ static void calc_poc(
        rfft_pha_buf[0] = 1.;
        rfft_pha_buf[1] = 1.;

        isd_cnt = 0;
        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] );
            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] ) )
            {
                rfft_pha_buf[i * 2] = 1.;
                rfft_pha_buf[i * 2 + 1] = 0.;
                isd_cnt++;
                tEr[i] = 1;
            }
            else
            {
                rfft_pha_buf[i * 2] = sqrtf((1.0f+Pr[i])/2.0f);
                rfft_pha_buf[i * 2 + 1] = sqrtf((1.0f-Pr[i])/2.0f)*sign(Pi[i]);
                rfft_pha_buf[i * 2 + 1] = sqrtf((1.0f-rfft_pha_buf[i * 2])/2.0f)*sign(rfft_pha_buf[i * 2 + 1]);
                rfft_pha_buf[i * 2] = sqrtf((1.0f+rfft_pha_buf[i * 2])/2.0f);
                tEr[i] = -1;
            }
        }

        // Handle FFT 192 / 96
        if ((input_frame_pha == 200) || (input_frame_pha == 100))
        if ( isd_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
        {
            for ( i = 1; i < nsbd; i++ )
            {
            tPr = rfft_pha_buf[2*nsbd-2];
            tPi = rfft_pha_buf[2*nsbd-1];
            for (i = 2*nsbd; i < input_frame_pha; i+=2)
                if ( tEr[i] > 0 )
                {
                rfft_pha_buf[i] = tPr;
                rfft_pha_buf[i+1] = tPi;
                    rfft_pha_buf[i * 2] = 1.;
                    rfft_pha_buf[i * 2 + 1] = 0.;
                }
            }
        }

        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++ )
        {
            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];
        }

        // 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_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-- )
        {
            p_curr_taps[i] = rfft_pha_buf[input_frame_pha-i];
            p_taps_0[i + 1] = p_taps_1[j];
        }
        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++ )
            {
                hPHA->p_curr_taps[n][i] *= hPHA->win[i];
                p_taps_0[i] *= hPHA->win[i];
            }

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

#ifdef ENHANCED_STEREO_DMX
    int16_t k, m, pha_len, fad_len;
    int16_t k, m, pha_len, pha_len2, 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[L_FRAME48k], dmx_pha_data[L_FRAME48k], *p_dmx_data, dmx_gain, ftmp;
    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;
    STEREO_DMX_EVS_PRC curr_prc;
    int16_t input_subframe, is_transient;
    float *p_sub_frame, subframe_energy[STEREO_DMX_EVS_NB_SBFRM];
@@ -1168,7 +1214,7 @@ void stereo_dmx_evs_enc(
            }
            else
            {
                hStereoDmxEVS->hPHA->trns_aux_energy[k] = 0.5 * hStereoDmxEVS->hPHA->trns_aux_energy[k] + 0.5 * subframe_energy[m];
                hStereoDmxEVS->hPHA->trns_aux_energy[k] = 0.5f * hStereoDmxEVS->hPHA->trns_aux_energy[k] + 0.5f * subframe_energy[m];
            }

            ftmp += subframe_energy[m];
@@ -1196,14 +1242,21 @@ 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 * sqrtf((hStereoDmxEVS->aux_dmx_energy[0] + hStereoDmxEVS->aux_dmx_energy[1]) / (hStereoDmxEVS->hPHA->dmx_poc_ener));
    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;
@@ -1221,13 +1274,13 @@ void stereo_dmx_evs_enc(
        p_data_mem = &( data_mem[pha_len] );
        mvr2r( p_data, p_data_mem, n_samples );


        p_prev_taps = hStereoDmxEVS->hPHA->p_prev_taps[k];
        if ( p_prev_taps )
        {
            for ( n = 0; n < fad_len; n++ )
            {
                for (ftmp = 0, m = 0; m < pha_len; m++) {
                for ( ftmp = 0, m = 0; m < pha_len; m++ )
                {
                    ftmp += p_data_mem[n - m] * p_prev_taps[m];
                }
                mem_prev[n] += ftmp;
@@ -1242,7 +1295,8 @@ void stereo_dmx_evs_enc(
        }

        p_curr_taps = hStereoDmxEVS->hPHA->p_curr_taps[k];
        if (p_curr_taps) {
        if ( p_curr_taps )
        {
            for ( n = 0; n < n_samples; n++ )
            {
                for ( ftmp = 0, m = 0; m < pha_len; m++ )
@@ -1261,13 +1315,14 @@ void stereo_dmx_evs_enc(
        }
    }

    for (n = 0, m = (fad_len - 1); n < fad_len; n++, m--) {
    for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- )
    {
        dmx_pha_data[n] *= fad_g[n];
        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 * sqrtf((hStereoDmxEVS->aux_dmx_energy[0] + hStereoDmxEVS->aux_dmx_energy[1]) / (hStereoDmxEVS->hPHA->dmx_pha_ener));
    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;

@@ -1315,16 +1370,15 @@ 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->curr_prc = STEREO_DMX_EVS_PRC_POC;
        hStereoDmxEVS->hPHA->prc_hys_cnt = 0;
    }

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

        if ( curr_prc != hStereoDmxEVS->hPHA->curr_prc )
        {
@@ -1350,8 +1404,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[n];

                p_dmx_data[n] += fad_g[m] * dmx_poc_data_sync[n];
            }
        }
    }
@@ -1508,6 +1561,8 @@ 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;
@@ -1534,25 +1589,28 @@ ivas_error stereo_dmx_evs_init_encoder(
        return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sampling frequency\n" );
    }

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

    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.8f, pha_len - trans_len);
    hStereoDmxEVS->hPHA->win[0] = 1.0f;
    set_f( hStereoDmxEVS->hPHA->win, 1.0f, pha_len );
    tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 );
    win = &(hStereoDmxEVS->hPHA->win[pha_len - trans_len]);
    for (n = 0; n < trans_len; n++) {
        win[n] = (0.5f * (1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ))*1.8;
    win = hStereoDmxEVS->hPHA->win;
    for ( n = 0, m = ( trans_len - 1 ); n < trans_len; n++, m-- )
    {
        itrh = pha_len - trans_len + n;
        win[itrh] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) );
        win[m] = win[itrh];
    }

    fad_g = hStereoDmxEVS->hPHA->fad_g;
    fad_r = 1.0f / (float) ( fad_len + 1 );
    fad_len2 = fad_len / 2;
    for (n = 0, m=(fad_len-1); n < fad_len2; n++, m--) {
    for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    {
        fad_g[n] = (float) ( n + 1 ) * fad_r;
        fad_g[m] = 1.0f - fad_g[n];
    }
@@ -1564,7 +1622,7 @@ ivas_error stereo_dmx_evs_init_encoder(
    // Compute the forgetting factor
    a_min = 0.8576958985908941f;
    a_max = 0.9440608762859234f;
    itrh = (3000 * input_frame) / (input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE); // 3kHz
    itrh = (int16_t) ( ( 3000 * input_frame ) / ( input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE ) ); // 3kHz
    n0 = L_FRAME16k / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    a_step = ( a_min - a_max ) / ( n0 + 1 - itrh );
    ipd_ff = hStereoDmxEVS->hPHA->ipd_ff;
@@ -1586,22 +1644,30 @@ ivas_error stereo_dmx_evs_init_encoder(
    n0 = input_frame / ( 4 * STEREO_DMX_EVS_SUBBAND_SIZE );
    input_frame_pha = input_frame / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );

    if (input_frame == L_FRAME16k) {
    if ( input_frame == L_FRAME16k )
    {
        p_ipd_w = dft_trigo_32k;
        rfft_ipd_coef_step = 4;
    } else if (input_frame == L_FRAME32k) {
    }
    else if ( input_frame == L_FRAME32k )
    {
        p_ipd_w = dft_trigo_32k;
        rfft_ipd_coef_step = 2;
    } else if (input_frame == L_FRAME48k) {
    }
    else if ( input_frame == L_FRAME48k )
    {
        p_ipd_w = dft_trigo_48k;
        rfft_ipd_coef_step = 2;
    } else {
    }
    else
    {
        return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sampling frequency\n" );
    }

    win = hStereoDmxEVS->hPHA->rfft_ipd_coef;
    len = rfft_ipd_coef_step * STEREO_DMX_EVS_SUBBAND_SIZE;
    for (n = 0; n < n0; n++) {
    for ( n = 0; n < n0; n++ )
    {
        win[n] = p_ipd_w[n * len];
        win[input_frame_pha - n] = p_ipd_w[n * len];
    }
@@ -1616,7 +1682,8 @@ ivas_error stereo_dmx_evs_init_encoder(
    fad_g = hStereoDmxEVS->hPHA->fad_g_prc;
    fad_r = 1.0f / (float) ( fad_len + 1 );
    fad_len2 = fad_len / 2;
    for (n = 0, m=(fad_len-1); n < fad_len2; n++, m--) {
    for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    {
        fad_g[n] = (float) ( n + 1 ) * fad_r;
        fad_g[m] = 1.0f - fad_g[n];
    }