LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_dmx_evs.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 8834b716eb6d7dfb881d5c69dd21cb18e1692722 Lines: 765 840 91.1 %
Date: 2025-07-09 08:36:12 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <math.h>
      35             : #include "options.h"
      36             : #include "cnst.h"
      37             : #include "ivas_cnst.h"
      38             : #include "rom_com.h"
      39             : #include "prot.h"
      40             : #include "ivas_prot.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "ivas_rom_enc.h"
      43             : #ifdef DEBUGGING
      44             : #include "debug.h"
      45             : #endif
      46             : #include "wmc_auto.h"
      47             : 
      48             : 
      49             : /*-----------------------------------------------------------------------*
      50             :  * Local constants
      51             :  *-----------------------------------------------------------------------*/
      52             : 
      53             : #define STEREO_DMX_EVS_FIND_POC_PEAK_TAU  4
      54             : #define STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 8
      55             : 
      56             : #define STEREO_DMX_EVS_POC_GAMMA             0.75f
      57             : #define STEREO_DMX_EVS_POC_SMOOTH            1.25f
      58             : #define STEREO_DMX_EVS_POC_FORGETTING        0.78f
      59             : #define STEREO_DMX_EVS_TARGET_POC_FORGETTING 0.79f
      60             : #define STEREO_DMX_EVS_POC_W_FORGETTING      0.875f
      61             : #define STEREO_DMX_EVS_SHIFT_LIMIT           STEREO_DFT_ZP_NS_ENC
      62             : 
      63             : #define STEREO_DMX_EVS_DMX_EGY_FORGETTING 0.25f
      64             : #define STEREO_DMX_EVS_CORR_FORGETTING    0.78f
      65             : 
      66             : #define Q_BAND 0.25f
      67             : 
      68             : 
      69             : #define STEREO_DMX_EVS_ISD_FORGETTING     0.95f
      70             : #define STEREO_DMX_EVS_ISD_THRES_H        1.69f
      71             : #define STEREO_DMX_EVS_ISD_THRES_L        0.9f
      72             : #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD 0.5f
      73             : 
      74             : #define STEREO_DMX_EVS_ISD_DIST_HYST_L 0.36f
      75             : #define STEREO_DMX_EVS_ISD_DIST_HYST_H 0.43f
      76             : 
      77             : #define STEREO_DMX_EVS_ICCR_FORGETTING 0.7f
      78             : #define STEREO_DMX_EVS_ICCR_HYST_L     0.75f
      79             : #define STEREO_DMX_EVS_ICCR_HYST_H     0.85f
      80             : 
      81             : #define STEREO_DMX_EVS_SWTCH_HYS_THRES 1
      82             : #define STEREO_DMX_EVS_LR_EGY          15.0f
      83             : #define STEREO_DMX_EVS_ILDS_EGY        10000.0f
      84             : #define STEREO_DMX_EVS_ILD_PRC         0.1f
      85             : 
      86             : #define STEREO_DMX_EVS_SWTCH_PRC_THRES_16 55
      87             : #define STEREO_DMX_EVS_SWTCH_PRC_THRES_32 19
      88             : #define STEREO_DMX_EVS_SWTCH_PRC_THRES_48 29
      89             : 
      90             : #define STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES 1
      91             : #define STEREO_DMX_EVS_IFF_AMIN            0.857696f
      92             : #define STEREO_DMX_EVS_IFF_AMAX            0.944061f
      93             : #define STEREO_DMX_EVS_IFF_FREQ            3000.0f
      94             : #define STEREO_DMX_EVS_PHA_WND_C           1.8f
      95             : 
      96             : #define STEREO_DMX_EVS_NB_SBFRM      5
      97             : #define STEREO_DMX_EVS_TRNS_DTC_INST 75.0f
      98             : #define STEREO_DMX_EVS_CRST_FCTR_16  80.0f
      99             : #define STEREO_DMX_EVS_CRST_FCTR_32  40.0f
     100             : #define STEREO_DMX_EVS_CRST_FCTR_48  35.0f
     101             : 
     102             : #define STEREO_DMX_EVS_TRNS_EGY_FORGETTING 0.75f
     103             : 
     104             : #define STEREO_DMX_EVS_FAD_R              3
     105             : #define STEREO_DMX_EVS_SGC_EGY_FORGETTING 0.9f
     106             : #define STEREO_DMX_EVS_SGC_GR_S           1.00461543f
     107             : #define STEREO_DMX_EVS_SGC_GL             0.9885f
     108             : #define STEREO_DMX_EVS_SGC_GH             1.0116f
     109             : #define STEREO_DMX_EVS_SGC_LEGY_THRES_16  2.5E8
     110             : #define STEREO_DMX_EVS_SGC_LEGY_THRES_32  3.E8
     111             : #define STEREO_DMX_EVS_SGC_LEGY_THRES_48  5.E8
     112             : #define STEREO_DMX_EVS_SGC_GMAX           1.4142f
     113             : #define STEREO_DMX_EVS_SGC_GMIN           0.7071f
     114             : 
     115             : #define STEREO_DMX_EVS_IPD_ILD_THRES 3.16f // 5dB
     116             : #define STEREO_DMX_EVS_IPD_SF_THRES  0.05f
     117             : 
     118             : /*-----------------------------------------------------------------------*
     119             :  * Local function prototypes
     120             :  *-----------------------------------------------------------------------*/
     121             : 
     122             : static void estimate_itd_wnd_fft( const float *input, float *specr, float *speci, const float *rfft_coef, const float *wnd, const int16_t input_frame );
     123             : static void calc_poc( STEREO_DMX_EVS_POC_HANDLE hPOC, STEREO_DMX_EVS_PHA_HANDLE hPHA, const float wnd[], const float rfft_coef[], const float specLr[], const float specLi[], const float specRr[], const float specRi[], const int16_t input_frame );
     124             : static ivas_error estimate_itd( float *corr, STEREO_DMX_EVS_POC_HANDLE hPOC, STEREO_DMX_EVS_PHA_HANDLE hPHA, const float srcL[], const float srcR[], float itd[], const int16_t input_frame );
     125             : static void weighted_ave( const float src1[], const float src2[], float dst[], const float gain, const float old_gain, const int16_t input_frame, const float wnd[] );
     126             : static void adapt_gain( const float src[], float dst[], const float gain, const float old_gain, const int16_t input_frame, const float wnd[] );
     127             : static void create_M_signal( const float srcL[], const float srcR[], float dmx[], const float w_curr, const int16_t input_frame, const float wnd[], float *w_prev, float *dmx_energy, float *src_energy );
     128             : static float find_poc_peak( STEREO_DMX_EVS_POC_HANDLE hPOC, float itd[], const int16_t input_frame, const float ratio );
     129             : static void calc_energy( const float src1[], const float src2[], float energy[], const int16_t input_frame, const float ratio );
     130             : static float spectral_flatness( const float sig[], const int16_t sig_length );
     131             : 
     132             : /*-------------------------------------------------------------------*
     133             :  * estimate_itd_wnd_fft()
     134             :  *
     135             :  * Transforms input signal from time domain into frequency domain.
     136             :  * The input signal is windowed before being transformed.
     137             :  *-------------------------------------------------------------------*/
     138             : 
     139        4200 : void estimate_itd_wnd_fft(
     140             :     const float *input,       /* i  : input signal                     */
     141             :     float *specr,             /* o  : real-part spectra                */
     142             :     float *speci,             /* o  : imaginary-part spectra           */
     143             :     const float *rfft_coef,   /* i  : rfft coef                        */
     144             :     const float *wnd,         /* i  : window coef                      */
     145             :     const int16_t input_frame /* i  : input frame length per channel   */
     146             : )
     147             : {
     148             :     int16_t n0, i;
     149             :     float rfft_buf[L_FRAME48k];
     150             :     int16_t step, bias;
     151             : 
     152        4200 :     n0 = input_frame >> 1;
     153        4200 :     if ( input_frame == L_FRAME16k )
     154             :     {
     155           0 :         step = 3;
     156           0 :         bias = 1;
     157             :     }
     158             :     else
     159             :     {
     160        4200 :         step = 1;
     161        4200 :         bias = 0;
     162             :     }
     163             : 
     164     3364200 :     for ( i = 0; i < input_frame; i++ )
     165             :     {
     166             :         /* window */
     167     3360000 :         rfft_buf[i] = input[i] * wnd[i * step + bias];
     168             :     }
     169             : 
     170        4200 :     rfft( rfft_buf, rfft_coef, input_frame, -1 );
     171             : 
     172     1680000 :     for ( i = 1; i < n0; i++ )
     173             :     {
     174     1675800 :         specr[i] = rfft_buf[i * 2];
     175     1675800 :         speci[i] = rfft_buf[i * 2 + 1];
     176             :     }
     177             : 
     178        4200 :     specr[0] = rfft_buf[0];
     179        4200 :     specr[n0] = rfft_buf[1];
     180        4200 :     speci[0] = 0.f;
     181        4200 :     speci[n0] = 0.f;
     182             : 
     183        4200 :     return;
     184             : }
     185             : 
     186             : 
     187             : /*-------------------------------------------------------------------*
     188             :  * calc_poc()
     189             :  *
     190             :  * calculate phase only correlation
     191             :  *-------------------------------------------------------------------*/
     192             : 
     193        2100 : static void calc_poc(
     194             :     STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */
     195             :     STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure     */
     196             :     const float wnd[],              /* i  : window coef                      */
     197             :     const float rfft_coef[],        /* i  : RFFT coef                        */
     198             :     const float specLr[],           /* i  : Lch real-part spectra            */
     199             :     const float specLi[],           /* i  : Lch imaginary-part input signal  */
     200             :     const float specRr[],           /* i  : Rch real-part spectra            */
     201             :     const float specRi[],           /* i  : Rch imaginary-part input signal  */
     202             :     const int16_t input_frame       /* i  : input frame length per channel   */
     203             : )
     204             : {
     205             :     int16_t i, n1, n2;
     206             :     int16_t n0, *itdLR;
     207             :     const float *s;
     208             :     float *P;
     209             :     float tmp1, tmp2, Lr, Li, Rr, Ri, gamma, igamma, iN;
     210             : 
     211             :     float specPOr[L_FRAME48k / 2 + 1], specPOi[L_FRAME48k / 2]; /*real and imaginary values for searching phase angle*/
     212             :     float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k];
     213             :     float rfft_buf[L_FRAME48k];
     214             :     int16_t step, bias;
     215             :     int16_t mult_angle;
     216             :     int16_t j;
     217             :     int16_t end;
     218             : 
     219             :     int16_t cos_step, cos_max;
     220             :     float eps_cos, eps_sin, EPS;
     221             : 
     222             :     int16_t isd_cnt_h, isd_cnt_l, ild_cnt, n, freq_8k, freq_ipd_max, nsbd, input_frame_pha, pha_ipd_ild_chan2rephase;
     223             :     float Nr, Ni, Dr, Di, tPr, tPi, Pn, energy, isd_rate;
     224             :     float eneL, eneR, IPDr, IPDi, tIPDr, tIPDi, ICCr;
     225             :     float *Pr, *Pi, *ipd_ff, *p_curr_taps;
     226             :     float rfft_pha_buf[L_FRAME48k], tEr[STEREO_DMX_EVS_NB_SUBBAND_MAX], tEl[STEREO_DMX_EVS_NB_SUBBAND_MAX];
     227             : 
     228             :     /* Initialization */
     229        2100 :     iN = 1.0f / (float) input_frame;
     230        2100 :     s = hPOC->sin;
     231        2100 :     P = hPOC->P;
     232        2100 :     n0 = input_frame / 2;
     233        2100 :     itdLR = hPOC->itdLR;
     234             : 
     235        2100 :     Pr = hPHA->Pr;
     236        2100 :     Pi = hPHA->Pi;
     237        2100 :     nsbd = n0 / STEREO_DMX_EVS_SUBBAND_SIZE;
     238        2100 :     input_frame_pha = input_frame / STEREO_DMX_EVS_SUBBAND_SIZE;
     239             : 
     240        2100 :     igamma = STEREO_DMX_EVS_POC_GAMMA * iN;
     241        2100 :     gamma = 1.0f - igamma;
     242             : 
     243        2100 :     step = 1;
     244        2100 :     bias = 0;
     245        2100 :     cos_step = 2;
     246        2100 :     cos_max = n0;
     247        2100 :     mult_angle = 3;
     248             : 
     249        2100 :     if ( input_frame == L_FRAME16k )
     250             :     {
     251           0 :         step = 3;
     252           0 :         bias = 1;
     253           0 :         cos_step = 4;
     254           0 :         cos_max = input_frame;
     255           0 :         mult_angle = 2; /*****/
     256             :     }
     257        2100 :     if ( input_frame == L_FRAME32k )
     258             :     {
     259        1050 :         mult_angle = 2;
     260             :     }
     261             : 
     262        2100 :     end = min( n0, 320 );
     263        2100 :     specPOr[0] = sign( specLr[0] * specRr[0] ) * wnd[bias];
     264        2100 :     specPOi[0] = 0.0f;
     265        2100 :     EPS = hPOC->eps;
     266        2100 :     if ( input_frame == L_FRAME48k )
     267             :     {
     268      252000 :         for ( i = 1; i < n0 / 2; i++ )
     269             :         {
     270      250950 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     271      250950 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     272      250950 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     273      250950 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     274      250950 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     275      250950 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     276             : 
     277      250950 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     278      250950 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     279      250950 :             j = n0 - i;
     280      250950 :             if ( j < 320 )
     281             :             {
     282       82950 :                 Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     283       82950 :                 Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     284       82950 :                 Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     285       82950 :                 Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     286             : 
     287       82950 :                 specPOr[j] = ( Lr * Rr + Li * Ri );
     288       82950 :                 specPOi[j] = ( Lr * Ri - Li * Rr );
     289             :             }
     290             :         }
     291             :     }
     292             :     else /* 16kHz and 32 kHz*/
     293             :     {
     294      168000 :         for ( i = 1; i < n0 / 2; i++ )
     295             :         {
     296      166950 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     297      166950 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     298             : 
     299      166950 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     300      166950 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     301      166950 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     302      166950 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     303      166950 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     304      166950 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     305             : 
     306      166950 :             j = n0 - i;
     307      166950 :             Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     308      166950 :             Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     309      166950 :             Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     310      166950 :             Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     311      166950 :             specPOr[j] = ( Lr * Rr + Li * Ri );
     312      166950 :             specPOi[j] = ( Lr * Ri - Li * Rr );
     313             :         }
     314             :     }
     315             :     {
     316             :         /* i=n0/2*/
     317        2100 :         Lr = specLr[i] + specRi[i] * EPS;
     318        2100 :         Li = specLi[i] - specRr[i] * EPS;
     319        2100 :         Rr = specRr[i] + specLi[i] * EPS;
     320        2100 :         Ri = specRi[i] - specLr[i] * EPS;
     321        2100 :         specPOr[i] = ( Lr * Rr + Li * Ri );
     322        2100 :         specPOi[i] = ( Lr * Ri - Li * Rr );
     323             :     }
     324             :     /* complex spectrum (specPOr[i], specPOi[i]) are placed on an unit circle without using  srqt()*/
     325       21000 :     for ( i = 1; i < 10; i++ ) /*search from 4 angles */
     326             :     {
     327       18900 :         tmp1 = wnd[i * step + bias] * gamma;
     328             : 
     329       18900 :         specPOr[i] = sign( specPOr[i] ) * 0.866f * tmp1; /* low angles are more frequent for low frequency */
     330       18900 :         specPOi[i] = sign( specPOi[i] ) * 0.5f * tmp1;
     331       18900 :         gamma -= igamma;
     332             :     }
     333       33600 :     for ( ; i < n0 >> 4; i++ ) /*search from 4 angles */
     334             :     {
     335       31500 :         tmp1 = wnd[i * step + bias] * gamma * 0.7071f;
     336             : 
     337       31500 :         specPOr[i] = sign( specPOr[i] ) * tmp1;
     338       31500 :         specPOi[i] = sign( specPOi[i] ) * tmp1; /* low accuracy is adequate for low frequency */
     339       31500 :         gamma -= igamma;
     340             :     }
     341             : 
     342       54600 :     for ( ; i < n0 >> 3; i++ ) /* binary search from 8 angles */
     343             :     {
     344       52500 :         tmp1 = wnd[i * step + bias] * gamma;
     345             : 
     346       52500 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     347             :         {
     348       27585 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle]; /*  cos(PI/8)*/
     349       27585 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle];
     350             :         }
     351             :         else
     352             :         {
     353       24915 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle]; /*  cos(PI*3/8)*/
     354       24915 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle];
     355             :         }
     356       52500 :         gamma -= igamma;
     357             :     }
     358      569100 :     for ( ; i < end; i++ ) /* binary search from 16 angles */
     359             :     {
     360      567000 :         tmp1 = wnd[i * step + bias] * gamma;
     361      567000 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     362             :         {
     363      314745 :             if ( ( specPOr[i] * 0.414213f - specPOi[i] ) * ( specPOr[i] * 0.414213f + specPOi[i] ) > 0 ) /*tan(PI/8)*/
     364             :             {
     365      182106 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /*0.980785f */ * s[140 * mult_angle]; /* cos(PI/16)*/
     366      182106 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /*0.195090f */ * s[20 * mult_angle];
     367             :             }
     368             :             else
     369             :             {
     370      132639 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /* 0.831470f */ * s[100 * mult_angle]; /*cos(PI*3/16)*/
     371      132639 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /* 0.555570f*/ * s[60 * mult_angle];
     372             :             }
     373             :         }
     374             :         else
     375             :         {
     376      252255 :             if ( ( specPOr[i] - specPOi[i] * 0.414213f ) * ( specPOr[i] + specPOi[i] * 0.414213f ) > 0 ) /*tan(PI/8)*/
     377             :             {
     378      127636 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.555570f*/ * s[60 * mult_angle]; /*cos(PI*5/16)*/
     379      127636 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.831470f*/ * s[100 * mult_angle];
     380             :             }
     381             :             else
     382             :             {
     383      124619 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.195090f*/ * s[20 * mult_angle]; /*cos(PI*7/16)*/
     384      124619 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.980785f*/ * s[140 * mult_angle];
     385             :             }
     386             :         }
     387      567000 :         gamma -= igamma;
     388             :     }
     389             : 
     390        2100 :     if ( i < n0 )
     391             :     {
     392        1050 :         gamma -= igamma * ( n0 - 320 );
     393             :     }
     394      170100 :     for ( ; i < n0; i++ ) /*neglect higher frequency bins when 48 kHz samplng*/
     395             :     {
     396      168000 :         specPOr[i] = 0.f;
     397      168000 :         specPOi[i] = 0.f;
     398             :     }
     399        2100 :     specPOr[n0] = sign( specLr[n0] * specRr[n0] ) * wnd[i * step + bias] * gamma;
     400             : 
     401        2100 :     freq_8k = L_FRAME16k / 2;
     402        2100 :     freq_ipd_max = (int16_t) ( freq_8k * 5000.0f / ( 8000.0f * STEREO_DMX_EVS_SUBBAND_SIZE ) );
     403             : 
     404             :     /* Memorize the filters N-1 */
     405        6300 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     406             :     {
     407        4200 :         if ( hPHA->p_curr_taps[n] )
     408             :         {
     409        4194 :             hPHA->p_prev_taps[n] = hPHA->prev_taps[n];
     410        4194 :             mvr2r( hPHA->p_curr_taps[n], hPHA->p_prev_taps[n], hPHA->pha_len );
     411             :         }
     412             :         else
     413             :         {
     414           6 :             hPHA->p_prev_taps[n] = NULL;
     415             :         }
     416             :     }
     417             : 
     418             :     /* ISD */
     419        2100 :     isd_cnt_l = 0;
     420        2100 :     isd_cnt_h = 0;
     421      338100 :     for ( i = 1; i <= freq_8k; i++ )
     422             :     {
     423      336000 :         Nr = ( specLr[i] - specRr[i] );
     424      336000 :         Ni = ( specLi[i] - specRi[i] );
     425      336000 :         Dr = ( specLr[i] + specRr[i] );
     426      336000 :         Di = ( specLi[i] + specRi[i] );
     427      336000 :         if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) )
     428             :         {
     429      103332 :             isd_cnt_h++;
     430             :         }
     431      336000 :         if ( ( Nr * Nr + Ni * Ni ) < STEREO_DMX_EVS_ISD_THRES_L * ( Dr * Dr + Di * Di ) )
     432             :         {
     433      179726 :             isd_cnt_l++;
     434             :         }
     435             :     }
     436             : 
     437        2100 :     isd_rate = (float) isd_cnt_h / (float) freq_8k;
     438        2100 :     hPHA->isd_rate_s = STEREO_DMX_EVS_ISD_FORGETTING * hPHA->isd_rate_s + ( 1.0f - STEREO_DMX_EVS_ISD_FORGETTING ) * isd_rate;
     439             : 
     440        2100 :     if ( hPHA->isd_rate_s > STEREO_DMX_EVS_ISD_DIST_HYST_H )
     441             :     {
     442           0 :         if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD )
     443             :         {
     444           0 :             if ( hPHA->prev_pha == STEREO_DMX_EVS_PHA_IPD )
     445             :             {
     446           0 :                 hPHA->pha_hys_cnt += 1;
     447             :             }
     448             :             else
     449             :             {
     450           0 :                 hPHA->pha_hys_cnt = 0;
     451             :             }
     452             : 
     453           0 :             if ( hPHA->pha_hys_cnt >= STEREO_DMX_EVS_SWTCH_HYS_THRES )
     454             :             {
     455           0 :                 hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
     456             :             }
     457             :         }
     458             : 
     459           0 :         hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
     460             :     }
     461        2100 :     else if ( hPHA->isd_rate_s < STEREO_DMX_EVS_ISD_DIST_HYST_L )
     462             :     {
     463        1367 :         if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD2 )
     464             :         {
     465           4 :             if ( hPHA->prev_pha == STEREO_DMX_EVS_PHA_IPD2 )
     466             :             {
     467           2 :                 hPHA->pha_hys_cnt += 1;
     468             :             }
     469             :             else
     470             :             {
     471           2 :                 hPHA->pha_hys_cnt = 0;
     472             :             }
     473             : 
     474           4 :             if ( hPHA->pha_hys_cnt >= STEREO_DMX_EVS_SWTCH_HYS_THRES )
     475             :             {
     476           2 :                 hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD2;
     477             :             }
     478             :         }
     479        1367 :         hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD2;
     480             :     }
     481             : 
     482        2100 :     ipd_ff = hPHA->ipd_ff;
     483             : 
     484        2100 :     Nr = 0;
     485        2100 :     Ni = 0;
     486        2100 :     eneL = 0;
     487        2100 :     eneR = 0;
     488             : 
     489      420000 :     for ( n = 1, i = 1; n < nsbd; n++ )
     490             :     {
     491      417900 :         tPr = 0.0f;
     492      417900 :         tPi = 0.0f;
     493      417900 :         tEr[n] = 0.0f;
     494      417900 :         tEl[n] = 0.0f;
     495             : 
     496     1253700 :         for ( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; j++, i++ )
     497             :         {
     498             :             /* Energy */
     499      835800 :             tEl[n] += specLr[i] * specLr[i] + specLi[i] * specLi[i];
     500      835800 :             tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
     501             : 
     502             :             /* IPD */
     503      835800 :             IPDr = specLr[i] * specRr[i] + specLi[i] * specRi[i];
     504      835800 :             IPDi = specLi[i] * specRr[i] - specLr[i] * specRi[i];
     505      835800 :             tPr += IPDr;
     506      835800 :             tPi += IPDi;
     507             : 
     508             :             /* ICCr */
     509      835800 :             Pn = inv_sqrtf( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON );
     510      835800 :             IPDr *= Pn;
     511      835800 :             IPDi *= Pn;
     512             : 
     513      835800 :             tIPDr = ( specRr[i] * IPDr - specRi[i] * IPDi );
     514      835800 :             tIPDi = ( specRr[i] * IPDi + specRi[i] * IPDr );
     515             : 
     516      835800 :             Nr += ( specLr[i] * tIPDr + specLi[i] * tIPDi );
     517      835800 :             Ni += ( specLi[i] * tIPDr - specLr[i] * tIPDi );
     518             : 
     519      835800 :             eneL += ( specLr[i] * specLr[i] + specLi[i] * specLi[i] );
     520      835800 :             eneR += ( specRr[i] * specRr[i] + specRi[i] * specRi[i] );
     521             :         }
     522      417900 :         Pn = inv_sqrtf( ( tPr * tPr + tPi * tPi ) + EPSILON );
     523             : 
     524      417900 :         tPr *= Pn;
     525      417900 :         tPi *= Pn;
     526             : 
     527             : 
     528      417900 :         Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr;
     529      417900 :         Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi;
     530      417900 :         Pn = inv_sqrtf( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
     531      417900 :         Pr[n] *= Pn;
     532      417900 :         Pi[n] *= Pn;
     533             : 
     534      417900 :         Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n];
     535      417900 :         Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n];
     536             :     }
     537             : 
     538             :     /* Computes Spectral flatness on one channel */
     539        2100 :     tmp1 = spectral_flatness( &tEl[1], nsbd - 1 );
     540        2100 :     if ( tmp1 < hPHA->pha_ipd_sf_Threshold )
     541             :     {
     542        1832 :         hPHA->pha_ipd_chanswitch_allowed = 0;
     543             :     }
     544             :     else
     545             :     {
     546         268 :         hPHA->pha_ipd_chanswitch_allowed = 1;
     547             :     }
     548             : 
     549        2100 :     ICCr = sqrtf( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) );
     550        2100 :     hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr;
     551             : 
     552        2100 :     if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD )
     553             :     {
     554           2 :         hPHA->force_poc = FALSE;
     555           2 :         hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
     556             :     }
     557             :     else
     558             :     {
     559        2098 :         if ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_L ) || ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_H ) && ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 ) && !hPHA->force_poc ) )
     560             :         {
     561         426 :             hPHA->force_poc = FALSE;
     562         426 :             hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD2;
     563             :         }
     564             :         else
     565             :         {
     566        1672 :             hPHA->force_poc = TRUE;
     567             :         }
     568             :     }
     569             : 
     570        2100 :     if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD )
     571             :     {
     572           2 :         rfft_pha_buf[0] = 1.;
     573           2 :         rfft_pha_buf[1] = 1.;
     574             : 
     575           2 :         ild_cnt = 0;
     576         400 :         for ( i = 1; i < nsbd; i++ )
     577             :         {
     578         398 :             rfft_pha_buf[i * 2] = Pr[i];
     579         398 :             rfft_pha_buf[i * 2 + 1] = Pi[i];
     580         398 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     581             :             {
     582          10 :                 ild_cnt++;
     583          10 :                 tEr[i] = 1;
     584             :             }
     585             :             else
     586             :             {
     587         388 :                 tEr[i] = -1;
     588             :             }
     589             :         }
     590           2 :         if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
     591             :         {
     592           0 :             for ( i = 1; i < nsbd; i++ )
     593             :             {
     594           0 :                 if ( tEr[i] > 0 )
     595             :                 {
     596           0 :                     rfft_pha_buf[i * 2] = 1.;
     597           0 :                     rfft_pha_buf[i * 2 + 1] = 0.;
     598             :                 }
     599             :             }
     600             :         }
     601             : 
     602           2 :         rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );
     603             : 
     604             :         /* Choose best channel to phase align */
     605             :         /* Channel selection based on ILD     */
     606           2 :         if ( hPHA->trns_aux_energy[0] > hPHA->trns_aux_energy[1] * hPHA->pha_ipd_ild_thresh )
     607             :         {
     608           0 :             pha_ipd_ild_chan2rephase = 1;
     609             :         }
     610           2 :         else if ( hPHA->trns_aux_energy[1] > hPHA->trns_aux_energy[0] * hPHA->pha_ipd_ild_thresh )
     611             :         {
     612           0 :             pha_ipd_ild_chan2rephase = 0;
     613             :         }
     614             :         else
     615             :         {
     616           2 :             pha_ipd_ild_chan2rephase = -1;
     617             :         }
     618             : 
     619             :         /* Channel selection based on spikyness of R2L/L2R impulse responses */
     620           2 :         tmp1 = spectral_flatness( rfft_pha_buf, hPHA->pha_len );
     621           2 :         rfft_pha_buf[input_frame_pha - hPHA->pha_len] = rfft_pha_buf[0];
     622           2 :         tmp2 = spectral_flatness( &rfft_pha_buf[input_frame_pha - hPHA->pha_len], hPHA->pha_len );
     623             : 
     624             :         /* Combined ILD/SF channel selection with tempo */
     625           2 :         if ( ( ( tmp1 > tmp2 ) && ( pha_ipd_ild_chan2rephase == -1 ) ) || ( pha_ipd_ild_chan2rephase == 0 ) ) /* L => R */
     626             :         {
     627           0 :             if ( hPHA->pha_ipd_previouschan2rephase == 0 )
     628             :             {
     629           0 :                 hPHA->pha_ipd_chan_cnt++;
     630           0 :                 if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh )
     631             :                 {
     632             :                     /* Avoid channel switch in case of too harmonic signals */
     633           0 :                     if ( hPHA->pha_ipd_chanswitch_allowed )
     634             :                     {
     635           0 :                         if ( hPHA->pha_ipd_chan2rephase != 0 )
     636             :                         {
     637           0 :                             hPHA->pha_ipd_chanswitch = 1;
     638             :                         }
     639             :                         else
     640             :                         {
     641           0 :                             hPHA->pha_ipd_chanswitch = 0;
     642             :                         }
     643           0 :                         hPHA->pha_ipd_chan2rephase = 0;
     644             :                     }
     645             :                 }
     646             :             }
     647             :             else
     648             :             {
     649           0 :                 hPHA->pha_ipd_previouschan2rephase = 0;
     650           0 :                 hPHA->pha_ipd_chan_cnt = 1;
     651           0 :                 hPHA->pha_ipd_chanswitch = 0;
     652             :             }
     653             :         }
     654             :         else /* R => L */
     655             :         {
     656           2 :             if ( hPHA->pha_ipd_previouschan2rephase == 1 )
     657             :             {
     658           2 :                 hPHA->pha_ipd_chan_cnt++;
     659           2 :                 if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh )
     660             :                 {
     661             :                     /* Avoid channel switch in case of too harmonic signals */
     662           0 :                     if ( hPHA->pha_ipd_chanswitch_allowed )
     663             :                     {
     664           0 :                         if ( hPHA->pha_ipd_chan2rephase != 1 )
     665             :                         {
     666           0 :                             hPHA->pha_ipd_chanswitch = 1;
     667             :                         }
     668             :                         else
     669             :                         {
     670           0 :                             hPHA->pha_ipd_chanswitch = 0;
     671             :                         }
     672           0 :                         hPHA->pha_ipd_chan2rephase = 1;
     673             :                     }
     674           0 :                     hPHA->pha_ipd_chan_cnt = hPHA->pha_ipd_chan_thresh;
     675             :                 }
     676             :             }
     677             :             else
     678             :             {
     679           0 :                 hPHA->pha_ipd_previouschan2rephase = 1;
     680           0 :                 hPHA->pha_ipd_chan_cnt = 1;
     681           0 :                 hPHA->pha_ipd_chanswitch = 0;
     682             :             }
     683             :         }
     684             : 
     685           2 :         if ( !hPHA->pha_ipd_chanswitch )
     686             :         {
     687           2 :             if ( hPHA->pha_ipd_chan2rephase == 0 )
     688             :             {
     689           0 :                 hPHA->p_curr_taps[1] = NULL;
     690           0 :                 hPHA->p_curr_taps[0] = hPHA->curr_taps[0];
     691           0 :                 p_curr_taps = hPHA->p_curr_taps[0];
     692           0 :                 p_curr_taps[0] = rfft_pha_buf[0];
     693           0 :                 for ( i = 1, j = input_frame_pha - 1; i < hPHA->pha_len; i++, j-- )
     694             :                 {
     695           0 :                     p_curr_taps[i] = rfft_pha_buf[j];
     696             :                 }
     697             :             }
     698             :             else
     699             :             {
     700           2 :                 hPHA->p_curr_taps[0] = NULL;
     701           2 :                 hPHA->p_curr_taps[1] = hPHA->curr_taps[1];
     702           2 :                 mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     703             :             }
     704             :         }
     705             :     }
     706             : 
     707        2100 :     if ( hPHA->pha_ipd_chanswitch )
     708             :     {
     709           0 :         for ( n = 0; n < CPE_CHANNELS; n++ )
     710             :         {
     711           0 :             hPHA->p_curr_taps[n] = NULL;
     712             :         }
     713             :     }
     714        2100 :     else if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 )
     715             :     {
     716             :         /* IPDn */
     717             : 
     718        2098 :         set_f( &( Pr[freq_ipd_max] ), 1.0f, ( nsbd - freq_ipd_max ) );
     719        2098 :         set_f( &( Pi[freq_ipd_max] ), 0.0f, ( nsbd - freq_ipd_max ) );
     720             : 
     721        6294 :         for ( n = 0; n < CPE_CHANNELS; n++ )
     722             :         {
     723        4196 :             hPHA->p_curr_taps[n] = hPHA->curr_taps[n];
     724             :         }
     725             : 
     726        2098 :         rfft_pha_buf[0] = 1.;
     727        2098 :         rfft_pha_buf[1] = 1.;
     728             : 
     729        2098 :         ild_cnt = 0;
     730        2098 :         isd_rate = (float) isd_cnt_l / freq_8k;
     731      419600 :         for ( i = 1; i < nsbd; i++ )
     732             :         {
     733      417502 :             rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + Pr[i] ) / 2.0f );
     734      417502 :             rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] );
     735      417502 :             if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD )
     736             :             {
     737      188893 :                 rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] );
     738      188893 :                 rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f );
     739             :             }
     740      417502 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     741             :             {
     742       40397 :                 ild_cnt++;
     743       40397 :                 tEr[i] = 1;
     744             :             }
     745             :             else
     746             :             {
     747      377105 :                 tEr[i] = -1;
     748             :             }
     749             :         }
     750        2098 :         if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
     751             :         {
     752       97600 :             for ( i = 1; i < nsbd; i++ )
     753             :             {
     754       97102 :                 if ( tEr[i] > 0 )
     755             :                 {
     756       27828 :                     rfft_pha_buf[i * 2] = 1.;
     757       27828 :                     rfft_pha_buf[i * 2 + 1] = 0.;
     758             :                 }
     759             :             }
     760             :         }
     761             : 
     762        2098 :         rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );
     763        2098 :         mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     764             : 
     765             :         /* PHA L2R */
     766        2098 :         p_curr_taps = hPHA->p_curr_taps[0];
     767        2098 :         p_curr_taps[0] = rfft_pha_buf[0];
     768      100704 :         for ( i = 1; i < hPHA->pha_len; i++ )
     769             :         {
     770       98606 :             p_curr_taps[i] = rfft_pha_buf[input_frame_pha - i];
     771             :         }
     772             :     }
     773             : 
     774        6300 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     775             :     {
     776        4200 :         if ( hPHA->p_curr_taps[n] )
     777             :         {
     778      205702 :             for ( i = 0; i < hPHA->pha_len; i++ )
     779             :             {
     780      201504 :                 hPHA->p_curr_taps[n][i] *= hPHA->win[i];
     781             :             }
     782             : 
     783        4198 :             energy = 0.;
     784      205702 :             for ( i = 0; i < hPHA->pha_len; i++ )
     785             :             {
     786      201504 :                 energy += hPHA->p_curr_taps[n][i] * hPHA->p_curr_taps[n][i];
     787             :             }
     788        4198 :             energy = inv_sqrtf( energy + EPSILON );
     789      205702 :             for ( i = 0; i < hPHA->pha_len; i++ )
     790             :             {
     791      201504 :                 hPHA->p_curr_taps[n][i] *= energy;
     792             :             }
     793             :         }
     794             :     }
     795             : 
     796             : 
     797        2100 :     rfft_buf[0] = specPOr[0];
     798        2100 :     rfft_buf[1] = specPOr[n0];
     799      840000 :     for ( i = 1; i < n0; i++ )
     800             :     {
     801      837900 :         rfft_buf[i * 2] = specPOr[i];
     802      837900 :         rfft_buf[i * 2 + 1] = specPOi[i];
     803             :     }
     804             : 
     805        2100 :     rfft( rfft_buf, rfft_coef, input_frame, +1 );
     806             : 
     807        2100 :     tmp1 = rfft_buf[0];
     808        2100 :     tmpPOC1[n0] = tmp1 * tmp1;
     809             : 
     810      474600 :     for ( i = 1; i < hPOC->shift_limit + 1; i++ )
     811             :     {
     812      472500 :         n1 = n0 + i;
     813      472500 :         n2 = n0 - i;
     814             : 
     815      472500 :         tmp1 = rfft_buf[i];
     816      472500 :         tmpPOC1[n1] = tmp1 * tmp1;
     817             : 
     818      472500 :         tmp1 = rfft_buf[input_frame - i];
     819      472500 :         tmpPOC1[n2] = tmp1 * tmp1;
     820             :     }
     821             : 
     822        2100 :     tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n0] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n0 - 1] + tmpPOC1[n0 + 1] );
     823        2100 :     tmpPOC2[n0] = max( tmp1, 0.0f );
     824             : 
     825      472500 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     826             :     {
     827      470400 :         n1 = n0 + i;
     828      470400 :         n2 = n0 - i;
     829      470400 :         tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n1] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n1 - 1] + tmpPOC1[n1 + 1] );
     830      470400 :         tmp2 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n2] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n2 - 1] + tmpPOC1[n2 + 1] );
     831      470400 :         tmpPOC2[n1] = max( tmp1, 0.0f );
     832      470400 :         tmpPOC2[n2] = max( tmp2, 0.0f );
     833             :     }
     834             : 
     835        2100 :     P[n0] = P[n0] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n0] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     836             : 
     837      472500 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     838             :     {
     839      470400 :         n1 = n0 + i;
     840      470400 :         n2 = n0 - i;
     841             : 
     842      470400 :         if ( i == -itdLR[1] )
     843             :         {
     844         735 :             P[n1] = P[n1] * STEREO_DMX_EVS_TARGET_POC_FORGETTING + tmpPOC2[n1] * ( 1.0f - STEREO_DMX_EVS_TARGET_POC_FORGETTING );
     845             :         }
     846             :         else
     847             :         {
     848      469665 :             P[n1] = P[n1] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n1] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     849             :         }
     850             : 
     851      470400 :         if ( i == itdLR[0] )
     852             :         {
     853         671 :             P[n2] = P[n2] * STEREO_DMX_EVS_TARGET_POC_FORGETTING + tmpPOC2[n2] * ( 1.0f - STEREO_DMX_EVS_TARGET_POC_FORGETTING );
     854             :         }
     855             :         else
     856             :         {
     857      469729 :             P[n2] = P[n2] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n2] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     858             :         }
     859             :     }
     860             : 
     861        2100 :     return;
     862             : }
     863             : 
     864             : 
     865             : /*-------------------------------------------------------------------*
     866             :  * find_poc_peak()
     867             :  *
     868             :  * find peak phase only correlation
     869             :  *-------------------------------------------------------------------*/
     870             : 
     871        2100 : static float find_poc_peak(
     872             :     STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */
     873             :     float itd[],                    /* o  : estimated itd                    */
     874             :     const int16_t input_frame,      /* i  : input frame length per channel   */
     875             :     const float ratio               /* i  : adapting ratio                   */
     876             : )
     877             : {
     878             :     int16_t itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS];
     879             :     float Q[CPE_CHANNELS], aQ[CPE_CHANNELS], cQ[CPE_CHANNELS], width, eps, cconfidence, *peak_width, *peakQ;
     880             :     float *P, tmpf;
     881             :     float eps2;
     882             : 
     883             :     /* Initialization */
     884        2100 :     Lh = input_frame / 2;
     885        2100 :     on = hPOC->ispeak;
     886        2100 :     itdLR = hPOC->itdLR;
     887        2100 :     width = 0.38f;
     888        2100 :     eps = 1.0f / (float) input_frame;
     889        2100 :     peak_width = hPOC->peak_width;
     890        2100 :     peakQ = hPOC->peakQ;
     891        2100 :     Q[0] = hPOC->P[Lh];
     892        2100 :     Q[1] = 0.0f;
     893        2100 :     itd_cand[0] = itd_cand[1] = 0;
     894        2100 :     P = hPOC->P;
     895             : 
     896      472500 :     for ( i = 1; i < hPOC->shift_limit; i++ ) /*find peaks of POC P[] with positive and negative ITD */
     897             :     {
     898      470400 :         if ( P[Lh - i] > Q[0] )
     899             :         {
     900        8025 :             Q[0] = P[Lh - i];
     901        8025 :             itd_cand[0] = i;
     902             :         }
     903      470400 :         if ( P[Lh + i] > Q[1] )
     904             :         {
     905       10006 :             Q[1] = P[Lh + i];
     906       10006 :             itd_cand[1] = -i;
     907             :         }
     908             :     }
     909             : 
     910        6300 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     911             :     {
     912        4200 :         prev_off[n] = !on[n];
     913             : 
     914        4200 :         aQ[n] = Q[n] * width;
     915        4200 :         cnt[n] = 0;
     916        4200 :         cQ[n] = P[Lh - itd_cand[n]];
     917             : 
     918        4200 :         peak_range = (int16_t) ( abs( itd_cand[n] ) + hPOC->shift_limit / STEREO_DMX_EVS_FIND_POC_PEAK_TAU ) / STEREO_DMX_EVS_FIND_POC_PEAK_TAU2;
     919             : 
     920       59546 :         for ( i = 1; i <= peak_range; i++ )
     921             :         {
     922       55346 :             cnt[n] += ( P[Lh - itd_cand[n] + i] > aQ[n] ) + ( P[Lh - itd_cand[n] - i] > aQ[n] );
     923       55346 :             cQ[n] += P[Lh - itd_cand[n] + i] + P[Lh - itd_cand[n] - i];
     924             :         }
     925             : 
     926        4200 :         peak_width[n] = peak_width[n] * ratio + (float) cnt[n] * ( 1.0f - ratio );
     927        4200 :         eps2 = eps * peak_width[n] * 0.25f;
     928        4200 :         Q[n] = ( 1.0f - ( cQ[n] / ( peak_range * 2 + 1 ) + eps2 ) / ( Q[n] + eps2 ) );
     929        4200 :         Q[n] = max( Q[n], 0.0f );
     930             : 
     931        4200 :         if ( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/
     932             :         {
     933        1849 :             tmpf = ( 0.3f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit ) * peakQ[n];
     934        1849 :             if ( Q[n] < tmpf )
     935             :             {
     936          15 :                 itdLR[n] = 0;
     937          15 :                 on[n] = 0;
     938          15 :                 peakQ[n] = 0.0f;
     939          15 :                 Q[n] = 0.0f;
     940             :             }
     941        1834 :             else if ( Q[n] > 1.25f * peakQ[n] )
     942             :             {
     943          18 :                 itdLR[n] = itd_cand[n];
     944             :             }
     945             : 
     946        1849 :             peakQ[n] = max( peakQ[n], Q[n] );
     947             :         }
     948             :         else /*if channel n was not active (not likely to be preceding) in the previous frame*/
     949             :         {
     950        2351 :             tmpf = ( 0.75f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit );
     951             : 
     952        2351 :             if ( Q[n] < tmpf )
     953             :             {
     954        2333 :                 itdLR[n] = 0;
     955        2333 :                 Q[n] = 0.0f;
     956             :             }
     957             :             else
     958             :             {
     959          18 :                 itdLR[n] = itd_cand[n];
     960          18 :                 on[n] = 1;
     961             :             }
     962             :         }
     963             :     }
     964             : 
     965        2100 :     if ( ( on[0] && prev_off[0] ) && ( on[1] && prev_off[1] ) ) /*if both channels have newly detected as active (possibility of preceding), select channel by peakness Q[] of POC */
     966             :     {
     967           0 :         *itd = ( Q[0] > Q[1] ) ? (float) itdLR[0] : (float) itdLR[1];
     968             :     }
     969        2100 :     else if ( ( on[0] && prev_off[0] ) && ( Q[0] > ( Q[1] - 0.1 ) ) ) /* if channel 0 becomes active, select channel 0*/
     970             :     {
     971           9 :         *itd = (float) itdLR[0];
     972             :     }
     973        2091 :     else if ( ( on[1] && prev_off[1] ) && ( Q[1] > ( Q[0] - 0.1 ) ) ) /*if channel 1 becomes active, selsect channel 1*/
     974             :     {
     975           6 :         *itd = (float) itdLR[1];
     976             :     }
     977        2085 :     else if ( Q[0] > ( Q[1] + Q_BAND ) ) /* if no status change, use Q[]*/
     978             :     {
     979         786 :         *itd = (float) itdLR[0];
     980             :     }
     981        1299 :     else if ( Q[1] > ( Q[0] + Q_BAND ) ) /* if no status change, use Q[]*/
     982             :     {
     983         367 :         *itd = (float) itdLR[1];
     984             :     }
     985         932 :     else if ( *itd == 0.0 ) /*if no channels are likely to be preceding, follow the status of the previous frame*/
     986             :     {
     987         744 :         *itd = 0;
     988             :     }
     989             :     else /*follow the status of the previous frame*/
     990             :     {
     991         188 :         *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1];
     992             :     }
     993             : 
     994        2100 :     cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); /*higher value indicates higher confidence for one preceding channel*/
     995             : 
     996        2100 :     return hPOC->confidence = hPOC->confidence * STEREO_DMX_EVS_CORR_FORGETTING + cconfidence * ( 1.0f - STEREO_DMX_EVS_CORR_FORGETTING );
     997             : }
     998             : 
     999             : 
    1000             : /*-------------------------------------------------------------------*
    1001             :  * estimate_itd()
    1002             :  *
    1003             :  * estimate itd
    1004             :  *-------------------------------------------------------------------*/
    1005             : 
    1006        2100 : static ivas_error estimate_itd(
    1007             :     float *corr,                    /* o  : correlation                      */
    1008             :     STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */
    1009             :     STEREO_DMX_EVS_PHA_HANDLE hPHA, /* i/o: correlation filter structure     */
    1010             :     const float srcL[],             /* i  : Lch input signal                 */
    1011             :     const float srcR[],             /* i  : Rch input signal                 */
    1012             :     float itd[],                    /* o  : estimated itd                    */
    1013             :     const int16_t input_frame       /* i  : input frame length per channel   */
    1014             : )
    1015             : {
    1016             :     float specLr[L_FRAME48k / 2 + 1], specLi[L_FRAME48k / 2 + 1], specRr[L_FRAME48k / 2 + 1], specRi[L_FRAME48k / 2 + 1];
    1017             :     float rfft_coef[L_FRAME48k];
    1018             :     const float *p_w;
    1019             :     int16_t n, n0, n1;
    1020             :     int16_t rfft_coef_step;
    1021             :     ivas_error error;
    1022             : 
    1023        2100 :     error = IVAS_ERR_OK;
    1024             : 
    1025        2100 :     n0 = input_frame >> 1;
    1026        2100 :     n1 = input_frame >> 2;
    1027             : 
    1028        2100 :     if ( input_frame == L_FRAME16k )
    1029             :     {
    1030           0 :         p_w = dft_trigo_32k;
    1031           0 :         rfft_coef_step = 4;
    1032             :     }
    1033        2100 :     else if ( input_frame == L_FRAME32k )
    1034             :     {
    1035        1050 :         p_w = dft_trigo_32k;
    1036        1050 :         rfft_coef_step = 2;
    1037             :     }
    1038        1050 :     else if ( input_frame == L_FRAME48k )
    1039             :     {
    1040        1050 :         p_w = dft_trigo_48k;
    1041        1050 :         rfft_coef_step = 2;
    1042             :     }
    1043             :     else
    1044             :     {
    1045           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "failed estimate_itd()\n" );
    1046             :     }
    1047             : 
    1048      422100 :     for ( n = 0; n < n1; n++ )
    1049             :     {
    1050      420000 :         rfft_coef[n] = p_w[n * rfft_coef_step];
    1051      420000 :         rfft_coef[n0 - n] = p_w[n * rfft_coef_step];
    1052             :     }
    1053        2100 :     rfft_coef[n1] = p_w[n1 * rfft_coef_step];
    1054             : 
    1055        2100 :     estimate_itd_wnd_fft( srcL, specLr, specLi, rfft_coef, hPOC->wnd, input_frame );
    1056        2100 :     estimate_itd_wnd_fft( srcR, specRr, specRi, rfft_coef, hPOC->wnd, input_frame );
    1057             : 
    1058        2100 :     calc_poc( hPOC, hPHA, hPOC->wnd, rfft_coef, specLr, specLi, specRr, specRi, input_frame );
    1059        2100 :     *corr = find_poc_peak( hPOC, itd, input_frame, STEREO_DMX_EVS_POC_W_FORGETTING );
    1060             : 
    1061        2100 :     return error;
    1062             : }
    1063             : 
    1064             : 
    1065             : /*-------------------------------------------------------------------*
    1066             :  * weighted_ave()
    1067             :  *
    1068             :  * create weighted downmix signal
    1069             :  *-------------------------------------------------------------------*/
    1070             : 
    1071        2100 : static void weighted_ave(
    1072             :     const float src1[],        /* i  : Lch input signal               */
    1073             :     const float src2[],        /* i  : Rch input signal               */
    1074             :     float dst[],               /* o  : output signal                  */
    1075             :     const float gain,          /* i  : adapting gain                  */
    1076             :     const float old_gain,      /* i  : adapting prev gain             */
    1077             :     const int16_t input_frame, /* i  : input frame length per channel */
    1078             :     const float wnd[]          /* i  : window coef                    */
    1079             : )
    1080             : {
    1081             : 
    1082             : 
    1083             :     int16_t i, len, len2;
    1084        2100 :     float gain_tmp = 0.f, gain_sub;
    1085             : 
    1086        2100 :     len = input_frame >> 1;
    1087        2100 :     len2 = input_frame >> 2;
    1088        2100 :     gain_sub = gain - old_gain;
    1089             : 
    1090      422100 :     for ( i = 0; i < len2; i++ )
    1091             :     {
    1092      420000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1093      420000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1094             :     }
    1095      422100 :     for ( ; i < len; i++ )
    1096             :     {
    1097      420000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1098      420000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1099             :     }
    1100      842100 :     for ( ; i < input_frame; i++ )
    1101             :     {
    1102      840000 :         dst[i] = src1[i] * gain + src2[i] * ( 1.0f - gain_tmp );
    1103             :     }
    1104             : 
    1105             : 
    1106        2100 :     return;
    1107             : }
    1108             : 
    1109             : /*-------------------------------------------------------------------*
    1110             :  * spectral_flatness()
    1111             :  *
    1112             :  * computes spectral flatness SF
    1113             :  * SF(x) = exp(mean_i(ln(x_i))) / mean_i(x_i)
    1114             :  *-------------------------------------------------------------------*/
    1115             : 
    1116        2104 : static float spectral_flatness(
    1117             :     const float sig[],      /* i  : input signal               */
    1118             :     const int16_t sigLength /* i  : input signal length        */
    1119             : )
    1120             : {
    1121        2104 :     float geoMean = 0.0f;
    1122        2104 :     float ariMean = 0.0f;
    1123        2104 :     float eps = 1e-10f;
    1124             :     int16_t i;
    1125             : 
    1126             :     /* Initialization */
    1127      420196 :     for ( i = 0; i < sigLength; i++ )
    1128             :     {
    1129      418092 :         ariMean += fabsf( sig[i] ) + eps;
    1130      418092 :         geoMean += logf( fabsf( sig[i] ) + eps );
    1131             :     }
    1132        2104 :     ariMean /= sigLength;
    1133        2104 :     geoMean /= sigLength;
    1134        2104 :     geoMean = expf( geoMean );
    1135             : 
    1136        2104 :     return geoMean / ariMean;
    1137             : }
    1138             : 
    1139             : 
    1140             : /*-------------------------------------------------------------------*
    1141             :  * calc_energy()
    1142             :  *
    1143             :  * calculate energy
    1144             :  *-------------------------------------------------------------------*/
    1145             : 
    1146        6300 : static void calc_energy(
    1147             :     const float src1[],        /* i  : Lch input signal               */
    1148             :     const float src2[],        /* i  : Rch input signal               */
    1149             :     float energy[],            /* o  : calculated energy              */
    1150             :     const int16_t input_frame, /* i  : input frame length per channel */
    1151             :     const float ratio          /* i  : adapting ratio                 */
    1152             : )
    1153             : {
    1154             :     float E, wnd, wnd_diff;
    1155             :     int16_t i, adaptlen;
    1156             : 
    1157             :     /* Initialization */
    1158        6300 :     E = 0.0f;
    1159        6300 :     adaptlen = input_frame >> 4;
    1160        6300 :     wnd = 0.5f / (float) adaptlen;
    1161        6300 :     wnd_diff = 1.0f / (float) adaptlen;
    1162             : 
    1163      321300 :     for ( i = 0; i < adaptlen; i++ )
    1164             :     {
    1165      315000 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1166             : 
    1167      315000 :         wnd += wnd_diff;
    1168             :     }
    1169     4416300 :     for ( ; i < input_frame - adaptlen; i++ )
    1170             :     {
    1171     4410000 :         E += src1[i] * src2[i];
    1172             :     }
    1173      321300 :     for ( ; i < input_frame; i++ )
    1174             :     {
    1175      315000 :         wnd -= wnd_diff;
    1176             : 
    1177      315000 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1178             :     }
    1179             : 
    1180        6300 :     *energy = *energy * ratio + ( E / (float) input_frame ) * ( 1.0f - ratio );
    1181             : 
    1182        6300 :     return;
    1183             : }
    1184             : 
    1185             : 
    1186             : /*-------------------------------------------------------------------*
    1187             :  * calc_energy_sgc()
    1188             :  *
    1189             :  * calculate energy for switch gain control
    1190             :  *-------------------------------------------------------------------*/
    1191        8400 : static void calc_energy_sgc(
    1192             :     const float src[],         /* i  : input signal       */
    1193             :     float *energy,             /* o  : calculated energy  */
    1194             :     const int16_t input_frame, /* i  : input frame length */
    1195             :     const float ratio          /* i  : adapting ratio     */
    1196             : )
    1197             : {
    1198        8400 :     *energy = ratio * *energy + ( 1.0f - ratio ) * sum2_f( src, input_frame );
    1199        8400 :     return;
    1200             : }
    1201             : 
    1202             : 
    1203             : /*-------------------------------------------------------------------*
    1204             :  * adapt_gain()
    1205             :  *
    1206             :  * adapt gain to the signal
    1207             :  *-------------------------------------------------------------------*/
    1208             : 
    1209        4200 : static void adapt_gain(
    1210             :     const float src[],         /* i  : input signal                   */
    1211             :     float dst[],               /* o  : output signal                  */
    1212             :     const float gain,          /* i  : adapting gain                  */
    1213             :     const float old_gain,      /* i  : adapting prev gain             */
    1214             :     const int16_t input_frame, /* i  : input frame length per channel */
    1215             :     const float wnd[]          /* i  : window coef                    */
    1216             : )
    1217             : {
    1218             : 
    1219             : 
    1220             :     int16_t i, len, len2;
    1221             :     float gain_tmp, gain_sub;
    1222             : 
    1223        4200 :     len = input_frame >> 1;
    1224        4200 :     len2 = input_frame >> 2;
    1225        4200 :     gain_sub = gain - old_gain;
    1226             : 
    1227      844200 :     for ( i = 0; i < len2; i++ )
    1228             :     {
    1229      840000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1230      840000 :         dst[i] = src[i] * gain_tmp;
    1231             :     }
    1232      844200 :     for ( ; i < len; i++ )
    1233             :     {
    1234      840000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1235      840000 :         dst[i] = src[i] * gain_tmp;
    1236             :     }
    1237             : 
    1238             : 
    1239     1684200 :     for ( ; i < input_frame; i++ )
    1240             :     {
    1241     1680000 :         dst[i] = src[i] * gain;
    1242             :     }
    1243             : 
    1244             : 
    1245        4200 :     return;
    1246             : }
    1247             : 
    1248             : 
    1249             : /*-------------------------------------------------------------------*
    1250             :  * create_M_signal()
    1251             :  *
    1252             :  * create downmix signal
    1253             :  *-------------------------------------------------------------------*/
    1254             : 
    1255        2100 : static void create_M_signal(
    1256             :     const float srcL[],        /* i  : Lch input signal               */
    1257             :     const float srcR[],        /* i  : Rch input signal               */
    1258             :     float dmx[],               /* o  : output signal                  */
    1259             :     const float w_curr,        /* i  : adapting weight                */
    1260             :     const int16_t input_frame, /* i  : input frame length per channel */
    1261             :     const float wnd[],         /* i  : window coef                    */
    1262             :     float *w_prev,             /* i/o: adapting prev weight           */
    1263             :     float *dmx_energy,         /* i/o: downmix signal energy          */
    1264             :     float *src_energy          /* i/o: input signal energy            */
    1265             : )
    1266             : {
    1267             :     float weighted[L_FRAME48k], eps, amp_mod[CPE_CHANNELS], Lbias;
    1268             : 
    1269             :     /* Initialization */
    1270        2100 :     eps = 1024.0f;
    1271        2100 :     Lbias = ( w_prev[2] == 0 ) ? 4.0f : 0.25f;
    1272             : 
    1273        2100 :     weighted_ave( srcL, srcR, dmx, w_curr, w_prev[0], input_frame, wnd );
    1274             : 
    1275        2100 :     calc_energy( srcL, srcL, src_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1276        2100 :     calc_energy( srcR, srcR, src_energy + 1, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1277        2100 :     calc_energy( dmx, dmx, dmx_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1278             : 
    1279        2100 :     if ( src_energy[0] * Lbias > src_energy[1] )
    1280             :     {
    1281         805 :         amp_mod[0] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[0] + eps ) );
    1282         805 :         amp_mod[0] = max( amp_mod[0], 0.0f );
    1283         805 :         amp_mod[1] = 0.0f;
    1284             :     }
    1285             :     else
    1286             :     {
    1287        1295 :         amp_mod[1] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[1] + eps ) );
    1288        1295 :         amp_mod[1] = max( amp_mod[1], 0.0f );
    1289        1295 :         amp_mod[0] = 0.0f;
    1290             :     }
    1291             : 
    1292        2100 :     adapt_gain( srcL, weighted, amp_mod[0], w_prev[1], input_frame, wnd );
    1293        2100 :     v_add( dmx, weighted, dmx, input_frame );
    1294        2100 :     adapt_gain( srcR, weighted, amp_mod[1], w_prev[2], input_frame, wnd );
    1295        2100 :     v_add( dmx, weighted, dmx, input_frame );
    1296             : 
    1297        2100 :     w_prev[0] = w_curr;
    1298        2100 :     w_prev[1] = amp_mod[0];
    1299        2100 :     w_prev[2] = amp_mod[1];
    1300             : 
    1301        2100 :     return;
    1302             : }
    1303             : 
    1304             : 
    1305             : /*-------------------------------------------------------------------*
    1306             :  * apply_gain_sgc()
    1307             :  *
    1308             :  * Apply gain for switching
    1309             :  *-------------------------------------------------------------------*/
    1310             : 
    1311        4200 : static void apply_gain_sgc(
    1312             :     float data[],             /* i/o  : input signal */
    1313             :     float *gain,              /* i  : gain */
    1314             :     float ratio,              /* i  : ratio */
    1315             :     const int16_t input_frame /* i  : input frame length */
    1316             : )
    1317             : {
    1318             :     int16_t n;
    1319             :     float lr;
    1320             : 
    1321        4200 :     if ( *gain > STEREO_DMX_EVS_SGC_GH )
    1322             :     {
    1323         131 :         lr = 1.0f / ratio;
    1324             :     }
    1325        4069 :     else if ( *gain < STEREO_DMX_EVS_SGC_GL )
    1326             :     {
    1327         192 :         lr = ratio;
    1328             :     }
    1329             :     else
    1330             :     {
    1331        3877 :         return;
    1332             :     }
    1333             : 
    1334      269443 :     for ( n = 0; n < input_frame; n++ )
    1335             :     {
    1336      269120 :         data[n] *= *gain;
    1337             :     }
    1338             : 
    1339         323 :     *gain *= lr;
    1340             : }
    1341             : 
    1342             : 
    1343             : /*-------------------------------------------------------------------*
    1344             :  * stereo_dmx_evs_enc()
    1345             :  *
    1346             :  * Stereo downmix for EVS encoder routine
    1347             :  *-------------------------------------------------------------------*/
    1348             : 
    1349        2100 : void stereo_dmx_evs_enc(
    1350             :     STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS, /* i/o: Stereo downmix for EVS encoder handle   */
    1351             :     const int32_t input_Fs,                  /* i  : input sampling rate                     */
    1352             :     int16_t data[CPE_CHANNELS * L_FRAME48k], /* i/o: input signal                            */
    1353             :     const int16_t n_samples,                 /* i  : number of input samples                 */
    1354             :     const bool is_binaural                   /* i  : indication that input is binaural audio */
    1355             : )
    1356             : {
    1357             : 
    1358             :     float dmx_weight, corr;
    1359             :     int16_t k, m, n, pha_len, fad_len, input_subframe, input_frame, n_fad_r, n_fad_g, m_fad_g, n_fad_cnt, sbfad_len;
    1360             :     float data_f[CPE_CHANNELS][L_FRAME48k];
    1361             :     float mem_prev[STEREO_DMX_EVS_FAD_LEN_MAX], data_mem[STEREO_DMX_EVS_DATA_LEN_MAX];
    1362             :     float dmx_poc_data[L_FRAME48k], dmx_pha_data[L_FRAME48k], subframe_energy[STEREO_DMX_EVS_NB_SBFRM];
    1363             :     float *p_data_mem, *p_prev_taps, *p_curr_taps, *p_data, *p_sub_frame;
    1364             :     float ftmp, *fad_g, *p_dmx_data, *p_dmx_data_fo;
    1365             :     bool is_transient;
    1366             :     STEREO_DMX_EVS_PRC prev_prc;
    1367             :     STEREO_DMX_EVS_PHA_HANDLE hPHA;
    1368             : 
    1369             :     if ( is_binaural )
    1370             :     {
    1371             :         /* use of is_binaural flag is to be considered */
    1372             :     }
    1373             : 
    1374        2100 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1375        2100 :     hPHA = hStereoDmxEVS->hPHA;
    1376             : 
    1377     1682100 :     for ( n = 0; n < input_frame; n++ )
    1378             :     {
    1379     1680000 :         data_f[0][n] = (float) data[2 * n];
    1380     1680000 :         data_f[1][n] = (float) data[2 * n + 1];
    1381             :     }
    1382        2100 :     if ( n_samples < input_frame )
    1383             :     {
    1384           0 :         set_f( data_f[0] + n_samples, 0.0f, input_frame - n_samples );
    1385           0 :         set_f( data_f[1] + n_samples, 0.0f, input_frame - n_samples );
    1386             :     }
    1387             : 
    1388        2100 :     input_subframe = n_samples / STEREO_DMX_EVS_NB_SBFRM;
    1389        2100 :     is_transient = false;
    1390        6300 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1391             :     {
    1392       25200 :         for ( m = 0; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1393             :         {
    1394       21000 :             p_sub_frame = &( data_f[k][m * input_subframe] );
    1395       21000 :             subframe_energy[m] = sum2_f( p_sub_frame, input_subframe );
    1396       21000 :             if ( subframe_energy[m] > hPHA->crst_fctr * ( hPHA->trns_aux_energy[k] + EPSILON ) )
    1397             :             {
    1398          27 :                 is_transient = true;
    1399             :             }
    1400             : 
    1401       21000 :             hPHA->trns_aux_energy[k] = STEREO_DMX_EVS_TRNS_EGY_FORGETTING * hPHA->trns_aux_energy[k] + ( 1.0f - STEREO_DMX_EVS_TRNS_EGY_FORGETTING ) * subframe_energy[m];
    1402             :         }
    1403             : 
    1404       21000 :         for ( m = 1; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1405             :         {
    1406       16800 :             if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST )
    1407             :             {
    1408          23 :                 is_transient = true;
    1409             :             }
    1410             :         }
    1411             :     }
    1412             : 
    1413        2100 :     estimate_itd( &corr, hStereoDmxEVS->hPOC, hPHA, data_f[0], data_f[1], &hStereoDmxEVS->itd, input_frame );
    1414             : 
    1415             :     /* poc */
    1416             : 
    1417        2100 :     if ( hStereoDmxEVS->itd )
    1418             :     {
    1419        1003 :         dmx_weight = ( ( hStereoDmxEVS->itd > 0 ) ? ( -1 ) : 1 ) * 0.5f * corr + 0.5f;
    1420             :     }
    1421             :     else
    1422             :     {
    1423        1097 :         dmx_weight = 0.5f;
    1424             :     }
    1425             : 
    1426        2100 :     create_M_signal( data_f[0], data_f[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd,
    1427        2100 :                      hStereoDmxEVS->dmx_weight, hStereoDmxEVS->pre_dmx_energy, hStereoDmxEVS->aux_dmx_energy );
    1428             : 
    1429             :     /* pha */
    1430             : 
    1431        2100 :     pha_len = hPHA->pha_len;
    1432        2100 :     fad_len = hPHA->fad_len;
    1433        2100 :     fad_g = hPHA->fad_g;
    1434             : 
    1435        2100 :     set_zero( dmx_pha_data, n_samples );
    1436        2100 :     set_zero( mem_prev, fad_len );
    1437             : 
    1438        6300 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1439             :     {
    1440        4200 :         p_data = data_f[k];
    1441        4200 :         mvr2r( hPHA->data_mem[k], data_mem, pha_len );
    1442        4200 :         mvr2r( &( p_data[n_samples - pha_len] ), hPHA->data_mem[k], pha_len );
    1443        4200 :         p_data_mem = &( data_mem[pha_len] );
    1444        4200 :         mvr2r( p_data, p_data_mem, n_samples );
    1445             : 
    1446        4200 :         p_prev_taps = hPHA->p_prev_taps[k];
    1447        4200 :         if ( p_prev_taps )
    1448             :         {
    1449     1681794 :             for ( n = 0; n < fad_len; n++ )
    1450             :             {
    1451    82202400 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1452             :                 {
    1453    80524800 :                     ftmp += p_data_mem[n - m] * p_prev_taps[m];
    1454             :                 }
    1455     1677600 :                 mem_prev[n] += ftmp * INV_SQRT_2;
    1456             :             }
    1457             :         }
    1458             :         else
    1459             :         {
    1460        2406 :             for ( n = 0; n < fad_len; n++ )
    1461             :             {
    1462        2400 :                 mem_prev[n] += p_data[n] * INV_SQRT_2;
    1463             :             }
    1464             :         }
    1465             : 
    1466        4200 :         p_curr_taps = hPHA->p_curr_taps[k];
    1467        4200 :         if ( p_curr_taps )
    1468             :         {
    1469     3362598 :             for ( n = 0; n < n_samples; n++ )
    1470             :             {
    1471   164561600 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1472             :                 {
    1473   161203200 :                     ftmp += p_data_mem[n - m] * p_curr_taps[m];
    1474             :                 }
    1475     3358400 :                 dmx_pha_data[n] += ftmp * INV_SQRT_2;
    1476             :             }
    1477             :         }
    1478             :         else
    1479             :         {
    1480        1602 :             for ( n = 0; n < n_samples; n++ )
    1481             :             {
    1482        1600 :                 dmx_pha_data[n] += p_data[n] * INV_SQRT_2;
    1483             :             }
    1484             :         }
    1485             :     }
    1486             : 
    1487      842100 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- )
    1488             :     {
    1489      840000 :         dmx_pha_data[n] *= fad_g[n];
    1490      840000 :         dmx_pha_data[n] += ( mem_prev[n] ) * fad_g[m];
    1491             :     }
    1492             : 
    1493             :     /* prc switch */
    1494             : 
    1495        2100 :     prev_prc = hPHA->curr_prc;
    1496        2100 :     if ( abs( (int16_t) hStereoDmxEVS->itd ) > hPHA->prc_thres )
    1497             :     {
    1498         561 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_POC )
    1499             :         {
    1500           6 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_POC )
    1501             :             {
    1502           3 :                 hPHA->prc_hys_cnt += 1;
    1503             :             }
    1504             :             else
    1505             :             {
    1506           3 :                 hPHA->prc_hys_cnt = 0;
    1507             :             }
    1508             : 
    1509           6 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1510             :             {
    1511           3 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1512             :             }
    1513             :         }
    1514         561 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1515             :     }
    1516             :     else
    1517             :     {
    1518        1539 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_PHA )
    1519             :         {
    1520        1299 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_PHA )
    1521             :             {
    1522        1290 :                 hPHA->prc_hys_cnt += 1;
    1523             :             }
    1524             :             else
    1525             :             {
    1526           9 :                 hPHA->prc_hys_cnt = 0;
    1527             :             }
    1528             : 
    1529        1299 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1530             :             {
    1531        1290 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_PHA;
    1532             :             }
    1533             :         }
    1534        1539 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_PHA;
    1535             :     }
    1536             : 
    1537        2100 :     if ( is_transient || ( 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] ) || ( hPHA->force_poc ) )
    1538             :     {
    1539        1676 :         hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1540        1676 :         hPHA->prc_hys_cnt = 0;
    1541             :     }
    1542             : 
    1543        2100 :     calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1544        2100 :     calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1545             : 
    1546        2100 :     if ( ( prev_prc != hPHA->curr_prc ) && !is_transient && !( ( hPHA->dmx_pha_ener < hPHA->low_egy_thres_sgc ) && ( hPHA->dmx_poc_ener < hPHA->low_egy_thres_sgc ) ) )
    1547             :     {
    1548          11 :         if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1549             :         {
    1550           6 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1551           6 :             calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1552             : 
    1553           6 :             hPHA->dmx_poc_gain_sgc = sqrtf( hPHA->dmx_pha_ener_sgc / ( hPHA->dmx_poc_ener + EPSILON ) );
    1554           6 :             hPHA->dmx_poc_gain_sgc = min( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1555           6 :             hPHA->dmx_poc_gain_sgc = max( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1556             : 
    1557           6 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1558           6 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1559             :         }
    1560             :         else
    1561             :         {
    1562           5 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1563           5 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1564             : 
    1565           5 :             hPHA->dmx_pha_gain_sgc = sqrtf( hPHA->dmx_poc_ener_sgc / ( hPHA->dmx_pha_ener + EPSILON ) );
    1566           5 :             hPHA->dmx_pha_gain_sgc = min( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1567           5 :             hPHA->dmx_pha_gain_sgc = max( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1568             : 
    1569           5 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1570           5 :             calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1571             :         }
    1572             :     }
    1573             :     else
    1574             :     {
    1575        2089 :         apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1576        2089 :         calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1577             : 
    1578        2089 :         apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1579        2089 :         calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1580             :     }
    1581             : 
    1582        2100 :     if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1583             :     {
    1584        1854 :         p_dmx_data = dmx_poc_data;
    1585        1854 :         p_dmx_data_fo = dmx_pha_data;
    1586             :     }
    1587             :     else
    1588             :     {
    1589         246 :         p_dmx_data = dmx_pha_data;
    1590         246 :         p_dmx_data_fo = dmx_poc_data;
    1591             :     }
    1592             : 
    1593        2100 :     n_fad_r = is_transient ? 1 : STEREO_DMX_EVS_FAD_R;
    1594             : 
    1595        2100 :     if ( prev_prc != hPHA->curr_prc )
    1596             :     {
    1597          32 :         if ( hPHA->n_fad_g == input_frame )
    1598             :         {
    1599          30 :             hPHA->n_fad_g = 0;
    1600          30 :             hPHA->n_fad_cnt = 0;
    1601             :         }
    1602             :         else
    1603             :         {
    1604           2 :             hPHA->n_fad_g = input_frame - hPHA->n_fad_g - 1;
    1605           2 :             hPHA->n_fad_cnt = 0;
    1606             :         }
    1607             :     }
    1608        2068 :     else if ( is_transient )
    1609             :     {
    1610          21 :         hPHA->n_fad_cnt = 0;
    1611             :     }
    1612             : 
    1613        2100 :     fad_len = min( n_samples, ( ( input_frame * n_fad_r ) - ( hPHA->n_fad_g * n_fad_r + hPHA->n_fad_cnt ) ) );
    1614             : 
    1615        2100 :     if ( fad_len != 0 )
    1616             :     {
    1617          90 :         fad_g = hPHA->fad_g_prc;
    1618          90 :         n_fad_g = hPHA->n_fad_g;
    1619          90 :         n_fad_cnt = hPHA->n_fad_cnt;
    1620          90 :         m_fad_g = input_frame - n_fad_g - 1;
    1621             : 
    1622          90 :         if ( n_fad_r == 1 )
    1623             :         {
    1624           2 :             n_fad_cnt = 0;
    1625        1602 :             for ( n = 0; n < fad_len; n++ )
    1626             :             {
    1627        1600 :                 p_dmx_data[n] *= fad_g[n_fad_g++];
    1628        1600 :                 p_dmx_data[n] += fad_g[m_fad_g--] * p_dmx_data_fo[n];
    1629             :             }
    1630             :         }
    1631             :         else
    1632             :         {
    1633          88 :             n = 0;
    1634          88 :             sbfad_len = 0;
    1635          88 :             if ( n_fad_cnt != 0 )
    1636             :             {
    1637          25 :                 sbfad_len = min( fad_len, n_fad_r - n_fad_cnt );
    1638          63 :                 for ( ; n < sbfad_len; n++ )
    1639             :                 {
    1640          38 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1641          38 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1642             :                 }
    1643          25 :                 n_fad_cnt = 0;
    1644          25 :                 n_fad_g++;
    1645          25 :                 m_fad_g--;
    1646             :             }
    1647             : 
    1648          88 :             sbfad_len = (int16_t) ( ( fad_len - sbfad_len ) / n_fad_r );
    1649       23637 :             for ( k = 0; k < sbfad_len; k++ )
    1650             :             {
    1651       94196 :                 for ( m = 0; m < n_fad_r; m++ )
    1652             :                 {
    1653       70647 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1654       70647 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1655       70647 :                     n++;
    1656             :                 }
    1657       23549 :                 n_fad_g++;
    1658       23549 :                 m_fad_g--;
    1659             :             }
    1660             : 
    1661         127 :             for ( ; n < fad_len; n++ )
    1662             :             {
    1663          39 :                 p_dmx_data[n] *= fad_g[n_fad_g];
    1664          39 :                 p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1665          39 :                 if ( ++n_fad_cnt >= n_fad_r )
    1666             :                 {
    1667           0 :                     n_fad_cnt = 0;
    1668           0 :                     n_fad_g++;
    1669           0 :                     m_fad_g--;
    1670             :                 }
    1671             :             }
    1672             :         }
    1673             : 
    1674          90 :         hPHA->n_fad_g = n_fad_g;
    1675          90 :         hPHA->n_fad_cnt = n_fad_cnt;
    1676             :     }
    1677             : 
    1678        2100 :     mvr2s( p_dmx_data, data, n_samples );
    1679             : 
    1680             : 
    1681        2100 :     return;
    1682             : }
    1683             : 
    1684             : 
    1685             : /*-------------------------------------------------------------------*
    1686             :  * stereo_dmx_evs_init_encoder()
    1687             :  *
    1688             :  * open and initialize stereo downmix for EVS encoder
    1689             :  *-------------------------------------------------------------------*/
    1690             : 
    1691           2 : ivas_error stereo_dmx_evs_init_encoder(
    1692             :     STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS_out, /* o  : Stereo downmix for EVS encoder handle   */
    1693             :     const int32_t input_Fs                        /* i  : input sampling rate                     */
    1694             : )
    1695             : {
    1696             :     STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS;
    1697             :     int16_t n, input_frame;
    1698             : 
    1699             :     int16_t m, len, pha_len, fad_len, fad_len2, trans_len, itrh, rfft_ipd_coef_step, n0, input_frame_pha;
    1700             :     float *win, *fad_g, fad_r, tmp_r, a_step, *ipd_ff;
    1701             :     const float *p_ipd_w;
    1702             : 
    1703           2 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1704             : 
    1705           2 :     hStereoDmxEVS = NULL;
    1706           2 :     if ( ( hStereoDmxEVS = (STEREO_DMX_EVS_ENC_HANDLE) malloc( sizeof( STEREO_DMX_EVS_ENC_DATA ) ) ) == NULL )
    1707             :     {
    1708           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for STEREO_DMX_EVS_ENC_DATA\n" ) );
    1709             :     }
    1710             : 
    1711           2 :     hStereoDmxEVS->itd = 0.0f;
    1712           2 :     hStereoDmxEVS->pre_dmx_energy[0] = 0.0f;
    1713           6 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1714             :     {
    1715           4 :         hStereoDmxEVS->aux_dmx_energy[n] = 0.0f;
    1716             :     }
    1717             : 
    1718           2 :     hStereoDmxEVS->dmx_weight[0] = 0.5f;
    1719           2 :     hStereoDmxEVS->dmx_weight[1] = 0.0f;
    1720           2 :     hStereoDmxEVS->dmx_weight[2] = 0.0f;
    1721             : 
    1722           2 :     if ( input_frame == L_FRAME16k )
    1723             :     {
    1724           0 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_16k;
    1725             :     }
    1726           2 :     else if ( input_frame == L_FRAME32k )
    1727             :     {
    1728           1 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_32k;
    1729             :     }
    1730           1 :     else if ( input_frame == L_FRAME48k )
    1731             :     {
    1732           1 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_48k;
    1733             :     }
    1734             :     else
    1735             :     {
    1736           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" );
    1737             :     }
    1738             : 
    1739           2 :     hStereoDmxEVS->hPOC = NULL;
    1740           2 :     if ( ( hStereoDmxEVS->hPOC = (STEREO_DMX_EVS_POC_HANDLE) malloc( sizeof( STEREO_DMX_EVS_POC_DATA ) ) ) == NULL )
    1741             :     {
    1742           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for STEREO_DMX_EVS_POC_DATA\n" ) );
    1743             :     }
    1744             : 
    1745           2 :     hStereoDmxEVS->hPOC->shift_limit = NS2SA( input_Fs, STEREO_DMX_EVS_SHIFT_LIMIT );
    1746             : 
    1747           6 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1748             :     {
    1749           4 :         hStereoDmxEVS->hPOC->peakQ[n] = 0.0f;
    1750           4 :         hStereoDmxEVS->hPOC->peak_width[n] = (float) hStereoDmxEVS->hPOC->shift_limit / 2;
    1751           4 :         hStereoDmxEVS->hPOC->ispeak[n] = 0;
    1752           4 :         hStereoDmxEVS->hPOC->itdLR[n] = 0;
    1753             :     }
    1754           2 :     set_f( hStereoDmxEVS->hPOC->P, 0.0f, L_FRAME48k );
    1755             : 
    1756           2 :     if ( input_frame == L_FRAME16k )
    1757             :     {
    1758           0 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_48k;
    1759             :     }
    1760           2 :     else if ( input_frame == L_FRAME32k )
    1761             :     {
    1762           1 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_32k;
    1763             :     }
    1764           1 :     else if ( input_frame == L_FRAME48k )
    1765             :     {
    1766           1 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_48k;
    1767             :     }
    1768             :     else
    1769             :     {
    1770           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" );
    1771             :     }
    1772           2 :     hStereoDmxEVS->hPOC->eps = 2.0f * EVS_PI / ( (float) input_frame );
    1773             : 
    1774           2 :     if ( input_frame == L_FRAME16k )
    1775             :     {
    1776           0 :         hStereoDmxEVS->hPOC->sin = dft_trigo_32k;
    1777             :     }
    1778           2 :     else if ( input_frame == L_FRAME32k )
    1779             :     {
    1780           1 :         hStereoDmxEVS->hPOC->sin = dft_trigo_32k;
    1781             :     }
    1782           1 :     else if ( input_frame == L_FRAME48k )
    1783             :     {
    1784           1 :         hStereoDmxEVS->hPOC->sin = dft_trigo_48k;
    1785             :     }
    1786             :     else
    1787             :     {
    1788           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" );
    1789             :     }
    1790             : 
    1791           2 :     hStereoDmxEVS->hPOC->confidence = 0.0f;
    1792             : 
    1793           2 :     hStereoDmxEVS->hPHA = NULL;
    1794           2 :     if ( ( hStereoDmxEVS->hPHA = (STEREO_DMX_EVS_PHA_HANDLE) malloc( sizeof( STEREO_DMX_EVS_PHA_DATA ) ) ) == NULL )
    1795             :     {
    1796           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for STEREO_DMX_EVS_CORFILT_DATA\n" ) );
    1797             :     }
    1798             : 
    1799           6 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1800             :     {
    1801           4 :         hStereoDmxEVS->hPHA->p_curr_taps[n] = NULL;
    1802           4 :         hStereoDmxEVS->hPHA->p_prev_taps[n] = NULL;
    1803             : 
    1804           4 :         set_zero( hStereoDmxEVS->hPHA->data_mem[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1805           4 :         set_zero( hStereoDmxEVS->hPHA->curr_taps[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1806             :     }
    1807             : 
    1808           2 :     if ( input_Fs == 16000 )
    1809             :     {
    1810           0 :         len = STEREO_DMX_EVS_PHA_LEN_16;
    1811           0 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_16;
    1812           0 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_16;
    1813           0 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_16;
    1814           0 :         hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_16;
    1815             :     }
    1816           2 :     else if ( input_Fs == 32000 )
    1817             :     {
    1818           1 :         len = STEREO_DMX_EVS_PHA_LEN_32;
    1819           1 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_32;
    1820           1 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_32;
    1821           1 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_32;
    1822           1 :         hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_32;
    1823             :     }
    1824           1 :     else if ( input_Fs == 48000 )
    1825             :     {
    1826           1 :         len = STEREO_DMX_EVS_PHA_LEN_48;
    1827           1 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_48;
    1828           1 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_48;
    1829           1 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_48;
    1830           1 :         hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_48;
    1831             :     }
    1832             :     else
    1833             :     {
    1834           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sampling frequency\n" );
    1835             :     }
    1836             : 
    1837           2 :     hStereoDmxEVS->hPHA->pha_len = len / 2;
    1838           2 :     hStereoDmxEVS->hPHA->isd_rate_s = 0.0f;
    1839           2 :     hStereoDmxEVS->hPHA->iccr_s = 0.0f;
    1840             : 
    1841           2 :     pha_len = hStereoDmxEVS->hPHA->pha_len;
    1842           2 :     fad_len = hStereoDmxEVS->hPHA->fad_len;
    1843             : 
    1844           2 :     trans_len = (int16_t) ( (float) pha_len / 20.0f );
    1845           2 :     set_f( hStereoDmxEVS->hPHA->win, STEREO_DMX_EVS_PHA_WND_C, pha_len - trans_len );
    1846           2 :     hStereoDmxEVS->hPHA->win[0] = 1.0f;
    1847           2 :     tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 );
    1848           2 :     win = &( hStereoDmxEVS->hPHA->win[pha_len - trans_len] );
    1849           6 :     for ( n = 0; n < trans_len; n++ )
    1850             :     {
    1851           4 :         win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * STEREO_DMX_EVS_PHA_WND_C;
    1852             :     }
    1853             : 
    1854           2 :     fad_g = hStereoDmxEVS->hPHA->fad_g;
    1855           2 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1856           2 :     fad_len2 = fad_len / 2;
    1857         402 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1858             :     {
    1859         400 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1860         400 :         fad_g[m] = 1.0f - fad_g[n];
    1861             :     }
    1862             : 
    1863           2 :     hStereoDmxEVS->hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
    1864           2 :     hStereoDmxEVS->hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
    1865           2 :     hStereoDmxEVS->hPHA->pha_hys_cnt = 0;
    1866             : 
    1867             : 
    1868           2 :     hStereoDmxEVS->hPHA->pha_ipd_chan_cnt = 0;
    1869           2 :     hStereoDmxEVS->hPHA->pha_ipd_chan_thresh = 10;
    1870           2 :     hStereoDmxEVS->hPHA->pha_ipd_ild_thresh = STEREO_DMX_EVS_IPD_ILD_THRES;
    1871           2 :     hStereoDmxEVS->hPHA->pha_ipd_chan2rephase = 1;
    1872           2 :     hStereoDmxEVS->hPHA->pha_ipd_previouschan2rephase = 1;
    1873           2 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch = 0;
    1874           2 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch_allowed = 0;
    1875           2 :     hStereoDmxEVS->hPHA->pha_ipd_sf_Threshold = STEREO_DMX_EVS_IPD_SF_THRES;
    1876             : 
    1877           2 :     hStereoDmxEVS->hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
    1878           2 :     hStereoDmxEVS->hPHA->force_poc = FALSE;
    1879             : 
    1880             :     /* Compute the forgetting factor */
    1881           2 :     itrh = (int16_t) ( ( STEREO_DMX_EVS_IFF_FREQ * input_frame ) / ( input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE ) );
    1882           2 :     n0 = L_FRAME16k / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1883           2 :     a_step = ( STEREO_DMX_EVS_IFF_AMIN - STEREO_DMX_EVS_IFF_AMAX ) / ( n0 + 1 - itrh );
    1884           2 :     ipd_ff = hStereoDmxEVS->hPHA->ipd_ff;
    1885          62 :     for ( n = 0; n < itrh; n++ )
    1886             :     {
    1887          60 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX;
    1888             :     }
    1889         104 :     for ( ; n < ( n0 + 1 ); n++ ) /* 8kHz */
    1890             :     {
    1891         102 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX + ( n - itrh ) * a_step;
    1892             :     }
    1893         320 :     for ( ; n < STEREO_DMX_EVS_NB_SUBBAND_MAX; n++ )
    1894             :     {
    1895         318 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMIN;
    1896             :     }
    1897           2 :     set_f( hStereoDmxEVS->hPHA->Pr, 1.0, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1898           2 :     set_zero( hStereoDmxEVS->hPHA->Pi, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1899             : 
    1900           2 :     n0 = input_frame / ( 4 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1901           2 :     input_frame_pha = input_frame / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1902             : 
    1903           2 :     if ( input_frame == L_FRAME16k )
    1904             :     {
    1905           0 :         p_ipd_w = dft_trigo_32k;
    1906           0 :         rfft_ipd_coef_step = 4;
    1907             :     }
    1908           2 :     else if ( input_frame == L_FRAME32k )
    1909             :     {
    1910           1 :         p_ipd_w = dft_trigo_32k;
    1911           1 :         rfft_ipd_coef_step = 2;
    1912             :     }
    1913           1 :     else if ( input_frame == L_FRAME48k )
    1914             :     {
    1915           1 :         p_ipd_w = dft_trigo_48k;
    1916           1 :         rfft_ipd_coef_step = 2;
    1917             :     }
    1918             :     else
    1919             :     {
    1920           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sampling frequency\n" );
    1921             :     }
    1922             : 
    1923           2 :     win = hStereoDmxEVS->hPHA->rfft_ipd_coef;
    1924           2 :     len = rfft_ipd_coef_step * STEREO_DMX_EVS_SUBBAND_SIZE;
    1925         202 :     for ( n = 0; n < n0; n++ )
    1926             :     {
    1927         200 :         win[n] = p_ipd_w[n * len];
    1928         200 :         win[input_frame_pha - n] = p_ipd_w[n * len];
    1929             :     }
    1930           2 :     win[n0] = p_ipd_w[n0 * len];
    1931             : 
    1932           2 :     hStereoDmxEVS->hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1933           2 :     hStereoDmxEVS->hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1934           2 :     hStereoDmxEVS->hPHA->prc_hys_cnt = 0;
    1935             : 
    1936           2 :     fad_len = input_frame;
    1937             : 
    1938           2 :     fad_g = hStereoDmxEVS->hPHA->fad_g_prc;
    1939           2 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1940           2 :     fad_len2 = fad_len / 2;
    1941         802 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1942             :     {
    1943         800 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1944         800 :         fad_g[m] = 1.0f - fad_g[n];
    1945             :     }
    1946             : 
    1947           6 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1948             :     {
    1949           4 :         hStereoDmxEVS->hPHA->trns_aux_energy[n] = 0.0f;
    1950             :     }
    1951             : 
    1952             : 
    1953           2 :     hStereoDmxEVS->hPHA->n_fad_g = input_frame;
    1954           2 :     hStereoDmxEVS->hPHA->n_fad_cnt = 0;
    1955             : 
    1956           2 :     hStereoDmxEVS->hPHA->dmx_pha_ener_sgc = 0.0f;
    1957           2 :     hStereoDmxEVS->hPHA->dmx_poc_ener_sgc = 0.0f;
    1958           2 :     hStereoDmxEVS->hPHA->dmx_pha_gain_sgc = 1.0f;
    1959           2 :     hStereoDmxEVS->hPHA->dmx_poc_gain_sgc = 1.0f;
    1960             : 
    1961           2 :     hStereoDmxEVS->hPHA->dmx_pha_ener = 0.0f;
    1962           2 :     hStereoDmxEVS->hPHA->dmx_poc_ener = 0.0f;
    1963             : 
    1964             : 
    1965           2 :     *hStereoDmxEVS_out = hStereoDmxEVS;
    1966             : 
    1967           2 :     return IVAS_ERR_OK;
    1968             : }
    1969             : 
    1970             : 
    1971             : /*-------------------------------------------------------------------*
    1972             :  * stereo_dmx_evs_close_encoder()
    1973             :  *
    1974             :  * close stereo downmix for EVS encoder
    1975             :  *-------------------------------------------------------------------*/
    1976             : 
    1977         627 : void stereo_dmx_evs_close_encoder(
    1978             :     STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle    */
    1979             : )
    1980             : {
    1981         627 :     if ( hStereoDmxEVS == NULL || *hStereoDmxEVS == NULL )
    1982             :     {
    1983         625 :         return;
    1984             :     }
    1985             : 
    1986           2 :     if ( ( *hStereoDmxEVS )->hPOC != NULL )
    1987             :     {
    1988           2 :         free( ( *hStereoDmxEVS )->hPOC );
    1989           2 :         ( *hStereoDmxEVS )->hPOC = NULL;
    1990             :     }
    1991             : 
    1992           2 :     if ( ( *hStereoDmxEVS )->hPHA != NULL )
    1993             :     {
    1994           2 :         free( ( *hStereoDmxEVS )->hPHA );
    1995           2 :         ( *hStereoDmxEVS )->hPHA = NULL;
    1996             :     }
    1997             : 
    1998           2 :     free( ( *hStereoDmxEVS ) );
    1999           2 :     ( *hStereoDmxEVS ) = NULL;
    2000             : 
    2001           2 :     return;
    2002             : }

Generated by: LCOV version 1.14