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 @ b5bd5e0684ad2d9250297e1e7a0ddc986cb7b37e Lines: 784 840 93.3 %
Date: 2025-10-27 07:01:45 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       17700 : 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       17700 :     n0 = input_frame >> 1;
     153       17700 :     if ( input_frame == L_FRAME16k )
     154             :     {
     155        6000 :         step = 3;
     156        6000 :         bias = 1;
     157             :     }
     158             :     else
     159             :     {
     160       11700 :         step = 1;
     161       11700 :         bias = 0;
     162             :     }
     163             : 
     164    11345700 :     for ( i = 0; i < input_frame; i++ )
     165             :     {
     166             :         /* window */
     167    11328000 :         rfft_buf[i] = input[i] * wnd[i * step + bias];
     168             :     }
     169             : 
     170       17700 :     rfft( rfft_buf, rfft_coef, input_frame, -1 );
     171             : 
     172     5664000 :     for ( i = 1; i < n0; i++ )
     173             :     {
     174     5646300 :         specr[i] = rfft_buf[i * 2];
     175     5646300 :         speci[i] = rfft_buf[i * 2 + 1];
     176             :     }
     177             : 
     178       17700 :     specr[0] = rfft_buf[0];
     179       17700 :     specr[n0] = rfft_buf[1];
     180       17700 :     speci[0] = 0.f;
     181       17700 :     speci[n0] = 0.f;
     182             : 
     183       17700 :     return;
     184             : }
     185             : 
     186             : 
     187             : /*-------------------------------------------------------------------*
     188             :  * calc_poc()
     189             :  *
     190             :  * calculate phase only correlation
     191             :  *-------------------------------------------------------------------*/
     192             : 
     193        8850 : 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        8850 :     iN = 1.0f / (float) input_frame;
     230        8850 :     s = hPOC->sin;
     231        8850 :     P = hPOC->P;
     232        8850 :     n0 = input_frame / 2;
     233        8850 :     itdLR = hPOC->itdLR;
     234             : 
     235        8850 :     Pr = hPHA->Pr;
     236        8850 :     Pi = hPHA->Pi;
     237        8850 :     nsbd = n0 / STEREO_DMX_EVS_SUBBAND_SIZE;
     238        8850 :     input_frame_pha = input_frame / STEREO_DMX_EVS_SUBBAND_SIZE;
     239             : 
     240        8850 :     igamma = STEREO_DMX_EVS_POC_GAMMA * iN;
     241        8850 :     gamma = 1.0f - igamma;
     242             : 
     243        8850 :     step = 1;
     244        8850 :     bias = 0;
     245        8850 :     cos_step = 2;
     246        8850 :     cos_max = n0;
     247        8850 :     mult_angle = 3;
     248             : 
     249        8850 :     if ( input_frame == L_FRAME16k )
     250             :     {
     251        3000 :         step = 3;
     252        3000 :         bias = 1;
     253        3000 :         cos_step = 4;
     254        3000 :         cos_max = input_frame;
     255        3000 :         mult_angle = 2; /*****/
     256             :     }
     257        8850 :     if ( input_frame == L_FRAME32k )
     258             :     {
     259        2850 :         mult_angle = 2;
     260             :     }
     261             : 
     262        8850 :     end = min( n0, 320 );
     263        8850 :     specPOr[0] = sign( specLr[0] * specRr[0] ) * wnd[bias];
     264        8850 :     specPOi[0] = 0.0f;
     265        8850 :     EPS = hPOC->eps;
     266        8850 :     if ( input_frame == L_FRAME48k )
     267             :     {
     268      720000 :         for ( i = 1; i < n0 / 2; i++ )
     269             :         {
     270      717000 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     271      717000 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     272      717000 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     273      717000 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     274      717000 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     275      717000 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     276             : 
     277      717000 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     278      717000 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     279      717000 :             j = n0 - i;
     280      717000 :             if ( j < 320 )
     281             :             {
     282      237000 :                 Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     283      237000 :                 Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     284      237000 :                 Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     285      237000 :                 Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     286             : 
     287      237000 :                 specPOr[j] = ( Lr * Rr + Li * Ri );
     288      237000 :                 specPOi[j] = ( Lr * Ri - Li * Rr );
     289             :             }
     290             :         }
     291             :     }
     292             :     else /* 16kHz and 32 kHz*/
     293             :     {
     294      696000 :         for ( i = 1; i < n0 / 2; i++ )
     295             :         {
     296      690150 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     297      690150 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     298             : 
     299      690150 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     300      690150 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     301      690150 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     302      690150 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     303      690150 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     304      690150 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     305             : 
     306      690150 :             j = n0 - i;
     307      690150 :             Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     308      690150 :             Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     309      690150 :             Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     310      690150 :             Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     311      690150 :             specPOr[j] = ( Lr * Rr + Li * Ri );
     312      690150 :             specPOi[j] = ( Lr * Ri - Li * Rr );
     313             :         }
     314             :     }
     315             :     {
     316             :         /* i=n0/2*/
     317        8850 :         Lr = specLr[i] + specRi[i] * EPS;
     318        8850 :         Li = specLi[i] - specRr[i] * EPS;
     319        8850 :         Rr = specRr[i] + specLi[i] * EPS;
     320        8850 :         Ri = specRi[i] - specLr[i] * EPS;
     321        8850 :         specPOr[i] = ( Lr * Rr + Li * Ri );
     322        8850 :         specPOi[i] = ( Lr * Ri - Li * Rr );
     323             :     }
     324             :     /* complex spectrum (specPOr[i], specPOi[i]) are placed on an unit circle without using  srqt()*/
     325       88500 :     for ( i = 1; i < 10; i++ ) /*search from 4 angles */
     326             :     {
     327       79650 :         tmp1 = wnd[i * step + bias] * gamma;
     328             : 
     329       79650 :         specPOr[i] = sign( specPOr[i] ) * 0.866f * tmp1; /* low angles are more frequent for low frequency */
     330       79650 :         specPOi[i] = sign( specPOi[i] ) * 0.5f * tmp1;
     331       79650 :         gamma -= igamma;
     332             :     }
     333       97350 :     for ( ; i < n0 >> 4; i++ ) /*search from 4 angles */
     334             :     {
     335       88500 :         tmp1 = wnd[i * step + bias] * gamma * 0.7071f;
     336             : 
     337       88500 :         specPOr[i] = sign( specPOr[i] ) * tmp1;
     338       88500 :         specPOi[i] = sign( specPOi[i] ) * tmp1; /* low accuracy is adequate for low frequency */
     339       88500 :         gamma -= igamma;
     340             :     }
     341             : 
     342      185850 :     for ( ; i < n0 >> 3; i++ ) /* binary search from 8 angles */
     343             :     {
     344      177000 :         tmp1 = wnd[i * step + bias] * gamma;
     345             : 
     346      177000 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     347             :         {
     348       94302 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle]; /*  cos(PI/8)*/
     349       94302 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle];
     350             :         }
     351             :         else
     352             :         {
     353       82698 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle]; /*  cos(PI*3/8)*/
     354       82698 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle];
     355             :         }
     356      177000 :         gamma -= igamma;
     357             :     }
     358     2006850 :     for ( ; i < end; i++ ) /* binary search from 16 angles */
     359             :     {
     360     1998000 :         tmp1 = wnd[i * step + bias] * gamma;
     361     1998000 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     362             :         {
     363     1047342 :             if ( ( specPOr[i] * 0.414213f - specPOi[i] ) * ( specPOr[i] * 0.414213f + specPOi[i] ) > 0 ) /*tan(PI/8)*/
     364             :             {
     365      563128 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /*0.980785f */ * s[140 * mult_angle]; /* cos(PI/16)*/
     366      563128 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /*0.195090f */ * s[20 * mult_angle];
     367             :             }
     368             :             else
     369             :             {
     370      484214 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /* 0.831470f */ * s[100 * mult_angle]; /*cos(PI*3/16)*/
     371      484214 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /* 0.555570f*/ * s[60 * mult_angle];
     372             :             }
     373             :         }
     374             :         else
     375             :         {
     376      950658 :             if ( ( specPOr[i] - specPOi[i] * 0.414213f ) * ( specPOr[i] + specPOi[i] * 0.414213f ) > 0 ) /*tan(PI/8)*/
     377             :             {
     378      476523 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.555570f*/ * s[60 * mult_angle]; /*cos(PI*5/16)*/
     379      476523 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.831470f*/ * s[100 * mult_angle];
     380             :             }
     381             :             else
     382             :             {
     383      474135 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.195090f*/ * s[20 * mult_angle]; /*cos(PI*7/16)*/
     384      474135 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.980785f*/ * s[140 * mult_angle];
     385             :             }
     386             :         }
     387     1998000 :         gamma -= igamma;
     388             :     }
     389             : 
     390        8850 :     if ( i < n0 )
     391             :     {
     392        3000 :         gamma -= igamma * ( n0 - 320 );
     393             :     }
     394      488850 :     for ( ; i < n0; i++ ) /*neglect higher frequency bins when 48 kHz samplng*/
     395             :     {
     396      480000 :         specPOr[i] = 0.f;
     397      480000 :         specPOi[i] = 0.f;
     398             :     }
     399        8850 :     specPOr[n0] = sign( specLr[n0] * specRr[n0] ) * wnd[i * step + bias] * gamma;
     400             : 
     401        8850 :     freq_8k = L_FRAME16k / 2;
     402        8850 :     freq_ipd_max = (int16_t) ( freq_8k * 5000.0f / ( 8000.0f * STEREO_DMX_EVS_SUBBAND_SIZE ) );
     403             : 
     404             :     /* Memorize the filters N-1 */
     405       26550 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     406             :     {
     407       17700 :         if ( hPHA->p_curr_taps[n] )
     408             :         {
     409       17349 :             hPHA->p_prev_taps[n] = hPHA->prev_taps[n];
     410       17349 :             mvr2r( hPHA->p_curr_taps[n], hPHA->p_prev_taps[n], hPHA->pha_len );
     411             :         }
     412             :         else
     413             :         {
     414         351 :             hPHA->p_prev_taps[n] = NULL;
     415             :         }
     416             :     }
     417             : 
     418             :     /* ISD */
     419        8850 :     isd_cnt_l = 0;
     420        8850 :     isd_cnt_h = 0;
     421     1424850 :     for ( i = 1; i <= freq_8k; i++ )
     422             :     {
     423     1416000 :         Nr = ( specLr[i] - specRr[i] );
     424     1416000 :         Ni = ( specLi[i] - specRi[i] );
     425     1416000 :         Dr = ( specLr[i] + specRr[i] );
     426     1416000 :         Di = ( specLi[i] + specRi[i] );
     427     1416000 :         if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) )
     428             :         {
     429      460932 :             isd_cnt_h++;
     430             :         }
     431     1416000 :         if ( ( Nr * Nr + Ni * Ni ) < STEREO_DMX_EVS_ISD_THRES_L * ( Dr * Dr + Di * Di ) )
     432             :         {
     433      743891 :             isd_cnt_l++;
     434             :         }
     435             :     }
     436             : 
     437        8850 :     isd_rate = (float) isd_cnt_h / (float) freq_8k;
     438        8850 :     hPHA->isd_rate_s = STEREO_DMX_EVS_ISD_FORGETTING * hPHA->isd_rate_s + ( 1.0f - STEREO_DMX_EVS_ISD_FORGETTING ) * isd_rate;
     439             : 
     440        8850 :     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        8850 :     else if ( hPHA->isd_rate_s < STEREO_DMX_EVS_ISD_DIST_HYST_L )
     462             :     {
     463        7752 :         if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD2 )
     464             :         {
     465         234 :             if ( hPHA->prev_pha == STEREO_DMX_EVS_PHA_IPD2 )
     466             :             {
     467         117 :                 hPHA->pha_hys_cnt += 1;
     468             :             }
     469             :             else
     470             :             {
     471         117 :                 hPHA->pha_hys_cnt = 0;
     472             :             }
     473             : 
     474         234 :             if ( hPHA->pha_hys_cnt >= STEREO_DMX_EVS_SWTCH_HYS_THRES )
     475             :             {
     476         117 :                 hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD2;
     477             :             }
     478             :         }
     479        7752 :         hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD2;
     480             :     }
     481             : 
     482        8850 :     ipd_ff = hPHA->ipd_ff;
     483             : 
     484        8850 :     Nr = 0;
     485        8850 :     Ni = 0;
     486        8850 :     eneL = 0;
     487        8850 :     eneR = 0;
     488             : 
     489     1416000 :     for ( n = 1, i = 1; n < nsbd; n++ )
     490             :     {
     491     1407150 :         tPr = 0.0f;
     492     1407150 :         tPi = 0.0f;
     493     1407150 :         tEr[n] = 0.0f;
     494     1407150 :         tEl[n] = 0.0f;
     495             : 
     496     4221450 :         for ( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; j++, i++ )
     497             :         {
     498             :             /* Energy */
     499     2814300 :             tEl[n] += specLr[i] * specLr[i] + specLi[i] * specLi[i];
     500     2814300 :             tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
     501             : 
     502             :             /* IPD */
     503     2814300 :             IPDr = specLr[i] * specRr[i] + specLi[i] * specRi[i];
     504     2814300 :             IPDi = specLi[i] * specRr[i] - specLr[i] * specRi[i];
     505     2814300 :             tPr += IPDr;
     506     2814300 :             tPi += IPDi;
     507             : 
     508             :             /* ICCr */
     509     2814300 :             Pn = inv_sqrtf( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON );
     510     2814300 :             IPDr *= Pn;
     511     2814300 :             IPDi *= Pn;
     512             : 
     513     2814300 :             tIPDr = ( specRr[i] * IPDr - specRi[i] * IPDi );
     514     2814300 :             tIPDi = ( specRr[i] * IPDi + specRi[i] * IPDr );
     515             : 
     516     2814300 :             Nr += ( specLr[i] * tIPDr + specLi[i] * tIPDi );
     517     2814300 :             Ni += ( specLi[i] * tIPDr - specLr[i] * tIPDi );
     518             : 
     519     2814300 :             eneL += ( specLr[i] * specLr[i] + specLi[i] * specLi[i] );
     520     2814300 :             eneR += ( specRr[i] * specRr[i] + specRi[i] * specRi[i] );
     521             :         }
     522     1407150 :         Pn = inv_sqrtf( ( tPr * tPr + tPi * tPi ) + EPSILON );
     523             : 
     524     1407150 :         tPr *= Pn;
     525     1407150 :         tPi *= Pn;
     526             : 
     527             : 
     528     1407150 :         Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr;
     529     1407150 :         Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi;
     530     1407150 :         Pn = inv_sqrtf( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
     531     1407150 :         Pr[n] *= Pn;
     532     1407150 :         Pi[n] *= Pn;
     533             : 
     534     1407150 :         Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n];
     535     1407150 :         Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n];
     536             :     }
     537             : 
     538             :     /* Computes Spectral flatness on one channel */
     539        8850 :     tmp1 = spectral_flatness( &tEl[1], nsbd - 1 );
     540        8850 :     if ( tmp1 < hPHA->pha_ipd_sf_Threshold )
     541             :     {
     542        7269 :         hPHA->pha_ipd_chanswitch_allowed = 0;
     543             :     }
     544             :     else
     545             :     {
     546        1581 :         hPHA->pha_ipd_chanswitch_allowed = 1;
     547             :     }
     548             : 
     549        8850 :     ICCr = sqrtf( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) );
     550        8850 :     hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr;
     551             : 
     552        8850 :     if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD )
     553             :     {
     554         117 :         hPHA->force_poc = FALSE;
     555         117 :         hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
     556             :     }
     557             :     else
     558             :     {
     559        8733 :         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        1323 :             hPHA->force_poc = FALSE;
     562        1323 :             hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD2;
     563             :         }
     564             :         else
     565             :         {
     566        7410 :             hPHA->force_poc = TRUE;
     567             :         }
     568             :     }
     569             : 
     570        8850 :     if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD )
     571             :     {
     572         117 :         rfft_pha_buf[0] = 1.;
     573         117 :         rfft_pha_buf[1] = 1.;
     574             : 
     575         117 :         ild_cnt = 0;
     576       15520 :         for ( i = 1; i < nsbd; i++ )
     577             :         {
     578       15403 :             rfft_pha_buf[i * 2] = Pr[i];
     579       15403 :             rfft_pha_buf[i * 2 + 1] = Pi[i];
     580       15403 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     581             :             {
     582         687 :                 ild_cnt++;
     583         687 :                 tEr[i] = 1;
     584             :             }
     585             :             else
     586             :             {
     587       14716 :                 tEr[i] = -1;
     588             :             }
     589             :         }
     590         117 :         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         117 :         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         117 :         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         117 :         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         117 :             pha_ipd_ild_chan2rephase = -1;
     617             :         }
     618             : 
     619             :         /* Channel selection based on spikyness of R2L/L2R impulse responses */
     620         117 :         tmp1 = spectral_flatness( rfft_pha_buf, hPHA->pha_len );
     621         117 :         rfft_pha_buf[input_frame_pha - hPHA->pha_len] = rfft_pha_buf[0];
     622         117 :         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         117 :         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         117 :             if ( hPHA->pha_ipd_previouschan2rephase == 1 )
     657             :             {
     658         117 :                 hPHA->pha_ipd_chan_cnt++;
     659         117 :                 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         117 :         if ( !hPHA->pha_ipd_chanswitch )
     686             :         {
     687         117 :             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         117 :                 hPHA->p_curr_taps[0] = NULL;
     701         117 :                 hPHA->p_curr_taps[1] = hPHA->curr_taps[1];
     702         117 :                 mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     703             :             }
     704             :         }
     705             :     }
     706             : 
     707        8850 :     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        8850 :     else if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 )
     715             :     {
     716             :         /* IPDn */
     717             : 
     718        8733 :         set_f( &( Pr[freq_ipd_max] ), 1.0f, ( nsbd - freq_ipd_max ) );
     719        8733 :         set_f( &( Pi[freq_ipd_max] ), 0.0f, ( nsbd - freq_ipd_max ) );
     720             : 
     721       26199 :         for ( n = 0; n < CPE_CHANNELS; n++ )
     722             :         {
     723       17466 :             hPHA->p_curr_taps[n] = hPHA->curr_taps[n];
     724             :         }
     725             : 
     726        8733 :         rfft_pha_buf[0] = 1.;
     727        8733 :         rfft_pha_buf[1] = 1.;
     728             : 
     729        8733 :         ild_cnt = 0;
     730        8733 :         isd_rate = (float) isd_cnt_l / freq_8k;
     731     1400480 :         for ( i = 1; i < nsbd; i++ )
     732             :         {
     733     1391747 :             rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + Pr[i] ) / 2.0f );
     734     1391747 :             rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] );
     735     1391747 :             if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD )
     736             :             {
     737      728270 :                 rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] );
     738      728270 :                 rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f );
     739             :             }
     740     1391747 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     741             :             {
     742       87417 :                 ild_cnt++;
     743       87417 :                 tEr[i] = 1;
     744             :             }
     745             :             else
     746             :             {
     747     1304330 :                 tEr[i] = -1;
     748             :             }
     749             :         }
     750        8733 :         if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
     751             :         {
     752      155680 :             for ( i = 1; i < nsbd; i++ )
     753             :             {
     754      154940 :                 if ( tEr[i] > 0 )
     755             :                 {
     756       43422 :                     rfft_pha_buf[i * 2] = 1.;
     757       43422 :                     rfft_pha_buf[i * 2 + 1] = 0.;
     758             :                 }
     759             :             }
     760             :         }
     761             : 
     762        8733 :         rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );
     763        8733 :         mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     764             : 
     765             :         /* PHA L2R */
     766        8733 :         p_curr_taps = hPHA->p_curr_taps[0];
     767        8733 :         p_curr_taps[0] = rfft_pha_buf[0];
     768      348624 :         for ( i = 1; i < hPHA->pha_len; i++ )
     769             :         {
     770      339891 :             p_curr_taps[i] = rfft_pha_buf[input_frame_pha - i];
     771             :         }
     772             :     }
     773             : 
     774       26550 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     775             :     {
     776       17700 :         if ( hPHA->p_curr_taps[n] )
     777             :         {
     778      719007 :             for ( i = 0; i < hPHA->pha_len; i++ )
     779             :             {
     780      701424 :                 hPHA->p_curr_taps[n][i] *= hPHA->win[i];
     781             :             }
     782             : 
     783       17583 :             energy = 0.;
     784      719007 :             for ( i = 0; i < hPHA->pha_len; i++ )
     785             :             {
     786      701424 :                 energy += hPHA->p_curr_taps[n][i] * hPHA->p_curr_taps[n][i];
     787             :             }
     788       17583 :             energy = inv_sqrtf( energy + EPSILON );
     789      719007 :             for ( i = 0; i < hPHA->pha_len; i++ )
     790             :             {
     791      701424 :                 hPHA->p_curr_taps[n][i] *= energy;
     792             :             }
     793             :         }
     794             :     }
     795             : 
     796             : 
     797        8850 :     rfft_buf[0] = specPOr[0];
     798        8850 :     rfft_buf[1] = specPOr[n0];
     799     2832000 :     for ( i = 1; i < n0; i++ )
     800             :     {
     801     2823150 :         rfft_buf[i * 2] = specPOr[i];
     802     2823150 :         rfft_buf[i * 2 + 1] = specPOi[i];
     803             :     }
     804             : 
     805        8850 :     rfft( rfft_buf, rfft_coef, input_frame, +1 );
     806             : 
     807        8850 :     tmp1 = rfft_buf[0];
     808        8850 :     tmpPOC1[n0] = tmp1 * tmp1;
     809             : 
     810     1601850 :     for ( i = 1; i < hPOC->shift_limit + 1; i++ )
     811             :     {
     812     1593000 :         n1 = n0 + i;
     813     1593000 :         n2 = n0 - i;
     814             : 
     815     1593000 :         tmp1 = rfft_buf[i];
     816     1593000 :         tmpPOC1[n1] = tmp1 * tmp1;
     817             : 
     818     1593000 :         tmp1 = rfft_buf[input_frame - i];
     819     1593000 :         tmpPOC1[n2] = tmp1 * tmp1;
     820             :     }
     821             : 
     822        8850 :     tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n0] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n0 - 1] + tmpPOC1[n0 + 1] );
     823        8850 :     tmpPOC2[n0] = max( tmp1, 0.0f );
     824             : 
     825     1593000 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     826             :     {
     827     1584150 :         n1 = n0 + i;
     828     1584150 :         n2 = n0 - i;
     829     1584150 :         tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n1] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n1 - 1] + tmpPOC1[n1 + 1] );
     830     1584150 :         tmp2 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n2] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n2 - 1] + tmpPOC1[n2 + 1] );
     831     1584150 :         tmpPOC2[n1] = max( tmp1, 0.0f );
     832     1584150 :         tmpPOC2[n2] = max( tmp2, 0.0f );
     833             :     }
     834             : 
     835        8850 :     P[n0] = P[n0] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n0] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     836             : 
     837     1593000 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     838             :     {
     839     1584150 :         n1 = n0 + i;
     840     1584150 :         n2 = n0 - i;
     841             : 
     842     1584150 :         if ( i == -itdLR[1] )
     843             :         {
     844        1486 :             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     1582664 :             P[n1] = P[n1] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n1] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     849             :         }
     850             : 
     851     1584150 :         if ( i == itdLR[0] )
     852             :         {
     853        3333 :             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     1580817 :             P[n2] = P[n2] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n2] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     858             :         }
     859             :     }
     860             : 
     861        8850 :     return;
     862             : }
     863             : 
     864             : 
     865             : /*-------------------------------------------------------------------*
     866             :  * find_poc_peak()
     867             :  *
     868             :  * find peak phase only correlation
     869             :  *-------------------------------------------------------------------*/
     870             : 
     871        8850 : 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        8850 :     Lh = input_frame / 2;
     885        8850 :     on = hPOC->ispeak;
     886        8850 :     itdLR = hPOC->itdLR;
     887        8850 :     width = 0.38f;
     888        8850 :     eps = 1.0f / (float) input_frame;
     889        8850 :     peak_width = hPOC->peak_width;
     890        8850 :     peakQ = hPOC->peakQ;
     891        8850 :     Q[0] = hPOC->P[Lh];
     892        8850 :     Q[1] = 0.0f;
     893        8850 :     itd_cand[0] = itd_cand[1] = 0;
     894        8850 :     P = hPOC->P;
     895             : 
     896     1593000 :     for ( i = 1; i < hPOC->shift_limit; i++ ) /*find peaks of POC P[] with positive and negative ITD */
     897             :     {
     898     1584150 :         if ( P[Lh - i] > Q[0] )
     899             :         {
     900       30908 :             Q[0] = P[Lh - i];
     901       30908 :             itd_cand[0] = i;
     902             :         }
     903     1584150 :         if ( P[Lh + i] > Q[1] )
     904             :         {
     905       34790 :             Q[1] = P[Lh + i];
     906       34790 :             itd_cand[1] = -i;
     907             :         }
     908             :     }
     909             : 
     910       26550 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     911             :     {
     912       17700 :         prev_off[n] = !on[n];
     913             : 
     914       17700 :         aQ[n] = Q[n] * width;
     915       17700 :         cnt[n] = 0;
     916       17700 :         cQ[n] = P[Lh - itd_cand[n]];
     917             : 
     918       17700 :         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      167547 :         for ( i = 1; i <= peak_range; i++ )
     921             :         {
     922      149847 :             cnt[n] += ( P[Lh - itd_cand[n] + i] > aQ[n] ) + ( P[Lh - itd_cand[n] - i] > aQ[n] );
     923      149847 :             cQ[n] += P[Lh - itd_cand[n] + i] + P[Lh - itd_cand[n] - i];
     924             :         }
     925             : 
     926       17700 :         peak_width[n] = peak_width[n] * ratio + (float) cnt[n] * ( 1.0f - ratio );
     927       17700 :         eps2 = eps * peak_width[n] * 0.25f;
     928       17700 :         Q[n] = ( 1.0f - ( cQ[n] / ( peak_range * 2 + 1 ) + eps2 ) / ( Q[n] + eps2 ) );
     929       17700 :         Q[n] = max( Q[n], 0.0f );
     930             : 
     931       17700 :         if ( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/
     932             :         {
     933        5482 :             tmpf = ( 0.3f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit ) * peakQ[n];
     934        5482 :             if ( Q[n] < tmpf )
     935             :             {
     936          22 :                 itdLR[n] = 0;
     937          22 :                 on[n] = 0;
     938          22 :                 peakQ[n] = 0.0f;
     939          22 :                 Q[n] = 0.0f;
     940             :             }
     941        5460 :             else if ( Q[n] > 1.25f * peakQ[n] )
     942             :             {
     943         159 :                 itdLR[n] = itd_cand[n];
     944             :             }
     945             : 
     946        5482 :             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       12218 :             tmpf = ( 0.75f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit );
     951             : 
     952       12218 :             if ( Q[n] < tmpf )
     953             :             {
     954       12059 :                 itdLR[n] = 0;
     955       12059 :                 Q[n] = 0.0f;
     956             :             }
     957             :             else
     958             :             {
     959         159 :                 itdLR[n] = itd_cand[n];
     960         159 :                 on[n] = 1;
     961             :             }
     962             :         }
     963             :     }
     964             : 
     965        8850 :     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        8850 :     else if ( ( on[0] && prev_off[0] ) && ( Q[0] > ( Q[1] - 0.1 ) ) ) /* if channel 0 becomes active, select channel 0*/
     970             :     {
     971         110 :         *itd = (float) itdLR[0];
     972             :     }
     973        8740 :     else if ( ( on[1] && prev_off[1] ) && ( Q[1] > ( Q[0] - 0.1 ) ) ) /*if channel 1 becomes active, selsect channel 1*/
     974             :     {
     975          45 :         *itd = (float) itdLR[1];
     976             :     }
     977        8695 :     else if ( Q[0] > ( Q[1] + Q_BAND ) ) /* if no status change, use Q[]*/
     978             :     {
     979        3126 :         *itd = (float) itdLR[0];
     980             :     }
     981        5569 :     else if ( Q[1] > ( Q[0] + Q_BAND ) ) /* if no status change, use Q[]*/
     982             :     {
     983         565 :         *itd = (float) itdLR[1];
     984             :     }
     985        5004 :     else if ( *itd == 0.0 ) /*if no channels are likely to be preceding, follow the status of the previous frame*/
     986             :     {
     987        4408 :         *itd = 0;
     988             :     }
     989             :     else /*follow the status of the previous frame*/
     990             :     {
     991         596 :         *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1];
     992             :     }
     993             : 
     994        8850 :     cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); /*higher value indicates higher confidence for one preceding channel*/
     995             : 
     996        8850 :     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        8850 : 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        8850 :     error = IVAS_ERR_OK;
    1024             : 
    1025        8850 :     n0 = input_frame >> 1;
    1026        8850 :     n1 = input_frame >> 2;
    1027             : 
    1028        8850 :     if ( input_frame == L_FRAME16k )
    1029             :     {
    1030        3000 :         p_w = dft_trigo_32k;
    1031        3000 :         rfft_coef_step = 4;
    1032             :     }
    1033        5850 :     else if ( input_frame == L_FRAME32k )
    1034             :     {
    1035        2850 :         p_w = dft_trigo_32k;
    1036        2850 :         rfft_coef_step = 2;
    1037             :     }
    1038        3000 :     else if ( input_frame == L_FRAME48k )
    1039             :     {
    1040        3000 :         p_w = dft_trigo_48k;
    1041        3000 :         rfft_coef_step = 2;
    1042             :     }
    1043             :     else
    1044             :     {
    1045           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "failed estimate_itd()\n" );
    1046             :     }
    1047             : 
    1048     1424850 :     for ( n = 0; n < n1; n++ )
    1049             :     {
    1050     1416000 :         rfft_coef[n] = p_w[n * rfft_coef_step];
    1051     1416000 :         rfft_coef[n0 - n] = p_w[n * rfft_coef_step];
    1052             :     }
    1053        8850 :     rfft_coef[n1] = p_w[n1 * rfft_coef_step];
    1054             : 
    1055        8850 :     estimate_itd_wnd_fft( srcL, specLr, specLi, rfft_coef, hPOC->wnd, input_frame );
    1056        8850 :     estimate_itd_wnd_fft( srcR, specRr, specRi, rfft_coef, hPOC->wnd, input_frame );
    1057             : 
    1058        8850 :     calc_poc( hPOC, hPHA, hPOC->wnd, rfft_coef, specLr, specLi, specRr, specRi, input_frame );
    1059        8850 :     *corr = find_poc_peak( hPOC, itd, input_frame, STEREO_DMX_EVS_POC_W_FORGETTING );
    1060             : 
    1061        8850 :     return error;
    1062             : }
    1063             : 
    1064             : 
    1065             : /*-------------------------------------------------------------------*
    1066             :  * weighted_ave()
    1067             :  *
    1068             :  * create weighted downmix signal
    1069             :  *-------------------------------------------------------------------*/
    1070             : 
    1071        8850 : 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        8850 :     float gain_tmp = 0.f, gain_sub;
    1085             : 
    1086        8850 :     len = input_frame >> 1;
    1087        8850 :     len2 = input_frame >> 2;
    1088        8850 :     gain_sub = gain - old_gain;
    1089             : 
    1090     1424850 :     for ( i = 0; i < len2; i++ )
    1091             :     {
    1092     1416000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1093     1416000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1094             :     }
    1095     1424850 :     for ( ; i < len; i++ )
    1096             :     {
    1097     1416000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1098     1416000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1099             :     }
    1100     2840850 :     for ( ; i < input_frame; i++ )
    1101             :     {
    1102     2832000 :         dst[i] = src1[i] * gain + src2[i] * ( 1.0f - gain_tmp );
    1103             :     }
    1104             : 
    1105             : 
    1106        8850 :     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        9084 : static float spectral_flatness(
    1117             :     const float sig[],      /* i  : input signal               */
    1118             :     const int16_t sigLength /* i  : input signal length        */
    1119             : )
    1120             : {
    1121        9084 :     float geoMean = 0.0f;
    1122        9084 :     float ariMean = 0.0f;
    1123        9084 :     float eps = 1e-10f;
    1124             :     int16_t i;
    1125             : 
    1126             :     /* Initialization */
    1127     1424586 :     for ( i = 0; i < sigLength; i++ )
    1128             :     {
    1129     1415502 :         ariMean += fabsf( sig[i] ) + eps;
    1130     1415502 :         geoMean += logf( fabsf( sig[i] ) + eps );
    1131             :     }
    1132        9084 :     ariMean /= sigLength;
    1133        9084 :     geoMean /= sigLength;
    1134        9084 :     geoMean = expf( geoMean );
    1135             : 
    1136        9084 :     return geoMean / ariMean;
    1137             : }
    1138             : 
    1139             : 
    1140             : /*-------------------------------------------------------------------*
    1141             :  * calc_energy()
    1142             :  *
    1143             :  * calculate energy
    1144             :  *-------------------------------------------------------------------*/
    1145             : 
    1146       26550 : 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       26550 :     E = 0.0f;
    1159       26550 :     adaptlen = input_frame >> 4;
    1160       26550 :     wnd = 0.5f / (float) adaptlen;
    1161       26550 :     wnd_diff = 1.0f / (float) adaptlen;
    1162             : 
    1163     1088550 :     for ( i = 0; i < adaptlen; i++ )
    1164             :     {
    1165     1062000 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1166             : 
    1167     1062000 :         wnd += wnd_diff;
    1168             :     }
    1169    14894550 :     for ( ; i < input_frame - adaptlen; i++ )
    1170             :     {
    1171    14868000 :         E += src1[i] * src2[i];
    1172             :     }
    1173     1088550 :     for ( ; i < input_frame; i++ )
    1174             :     {
    1175     1062000 :         wnd -= wnd_diff;
    1176             : 
    1177     1062000 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1178             :     }
    1179             : 
    1180       26550 :     *energy = *energy * ratio + ( E / (float) input_frame ) * ( 1.0f - ratio );
    1181             : 
    1182       26550 :     return;
    1183             : }
    1184             : 
    1185             : 
    1186             : /*-------------------------------------------------------------------*
    1187             :  * calc_energy_sgc()
    1188             :  *
    1189             :  * calculate energy for switch gain control
    1190             :  *-------------------------------------------------------------------*/
    1191       35400 : 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       35400 :     *energy = ratio * *energy + ( 1.0f - ratio ) * sum2_f( src, input_frame );
    1199       35400 :     return;
    1200             : }
    1201             : 
    1202             : 
    1203             : /*-------------------------------------------------------------------*
    1204             :  * adapt_gain()
    1205             :  *
    1206             :  * adapt gain to the signal
    1207             :  *-------------------------------------------------------------------*/
    1208             : 
    1209       17700 : 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       17700 :     len = input_frame >> 1;
    1224       17700 :     len2 = input_frame >> 2;
    1225       17700 :     gain_sub = gain - old_gain;
    1226             : 
    1227     2849700 :     for ( i = 0; i < len2; i++ )
    1228             :     {
    1229     2832000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1230     2832000 :         dst[i] = src[i] * gain_tmp;
    1231             :     }
    1232     2849700 :     for ( ; i < len; i++ )
    1233             :     {
    1234     2832000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1235     2832000 :         dst[i] = src[i] * gain_tmp;
    1236             :     }
    1237             : 
    1238             : 
    1239     5681700 :     for ( ; i < input_frame; i++ )
    1240             :     {
    1241     5664000 :         dst[i] = src[i] * gain;
    1242             :     }
    1243             : 
    1244             : 
    1245       17700 :     return;
    1246             : }
    1247             : 
    1248             : 
    1249             : /*-------------------------------------------------------------------*
    1250             :  * create_M_signal()
    1251             :  *
    1252             :  * create downmix signal
    1253             :  *-------------------------------------------------------------------*/
    1254             : 
    1255        8850 : 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        8850 :     eps = 1024.0f;
    1271        8850 :     Lbias = ( w_prev[2] == 0 ) ? 4.0f : 0.25f;
    1272             : 
    1273        8850 :     weighted_ave( srcL, srcR, dmx, w_curr, w_prev[0], input_frame, wnd );
    1274             : 
    1275        8850 :     calc_energy( srcL, srcL, src_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1276        8850 :     calc_energy( srcR, srcR, src_energy + 1, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1277        8850 :     calc_energy( dmx, dmx, dmx_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1278             : 
    1279        8850 :     if ( src_energy[0] * Lbias > src_energy[1] )
    1280             :     {
    1281        5651 :         amp_mod[0] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[0] + eps ) );
    1282        5651 :         amp_mod[0] = max( amp_mod[0], 0.0f );
    1283        5651 :         amp_mod[1] = 0.0f;
    1284             :     }
    1285             :     else
    1286             :     {
    1287        3199 :         amp_mod[1] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[1] + eps ) );
    1288        3199 :         amp_mod[1] = max( amp_mod[1], 0.0f );
    1289        3199 :         amp_mod[0] = 0.0f;
    1290             :     }
    1291             : 
    1292        8850 :     adapt_gain( srcL, weighted, amp_mod[0], w_prev[1], input_frame, wnd );
    1293        8850 :     v_add( dmx, weighted, dmx, input_frame );
    1294        8850 :     adapt_gain( srcR, weighted, amp_mod[1], w_prev[2], input_frame, wnd );
    1295        8850 :     v_add( dmx, weighted, dmx, input_frame );
    1296             : 
    1297        8850 :     w_prev[0] = w_curr;
    1298        8850 :     w_prev[1] = amp_mod[0];
    1299        8850 :     w_prev[2] = amp_mod[1];
    1300             : 
    1301        8850 :     return;
    1302             : }
    1303             : 
    1304             : 
    1305             : /*-------------------------------------------------------------------*
    1306             :  * apply_gain_sgc()
    1307             :  *
    1308             :  * Apply gain for switching
    1309             :  *-------------------------------------------------------------------*/
    1310             : 
    1311       17700 : 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       17700 :     if ( *gain > STEREO_DMX_EVS_SGC_GH )
    1322             :     {
    1323         170 :         lr = 1.0f / ratio;
    1324             :     }
    1325       17530 :     else if ( *gain < STEREO_DMX_EVS_SGC_GL )
    1326             :     {
    1327         348 :         lr = ratio;
    1328             :     }
    1329             :     else
    1330             :     {
    1331       17182 :         return;
    1332             :     }
    1333             : 
    1334      456838 :     for ( n = 0; n < input_frame; n++ )
    1335             :     {
    1336      456320 :         data[n] *= *gain;
    1337             :     }
    1338             : 
    1339         518 :     *gain *= lr;
    1340             : }
    1341             : 
    1342             : 
    1343             : /*-------------------------------------------------------------------*
    1344             :  * stereo_dmx_evs_enc()
    1345             :  *
    1346             :  * Stereo downmix for EVS encoder routine
    1347             :  *-------------------------------------------------------------------*/
    1348             : 
    1349        8850 : 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        8850 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1375        8850 :     hPHA = hStereoDmxEVS->hPHA;
    1376             : 
    1377     5672850 :     for ( n = 0; n < input_frame; n++ )
    1378             :     {
    1379     5664000 :         data_f[0][n] = (float) data[2 * n];
    1380     5664000 :         data_f[1][n] = (float) data[2 * n + 1];
    1381             :     }
    1382        8850 :     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        8850 :     input_subframe = n_samples / STEREO_DMX_EVS_NB_SBFRM;
    1389        8850 :     is_transient = false;
    1390       26550 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1391             :     {
    1392      106200 :         for ( m = 0; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1393             :         {
    1394       88500 :             p_sub_frame = &( data_f[k][m * input_subframe] );
    1395       88500 :             subframe_energy[m] = sum2_f( p_sub_frame, input_subframe );
    1396       88500 :             if ( subframe_energy[m] > hPHA->crst_fctr * ( hPHA->trns_aux_energy[k] + EPSILON ) )
    1397             :             {
    1398         323 :                 is_transient = true;
    1399             :             }
    1400             : 
    1401       88500 :             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       88500 :         for ( m = 1; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1405             :         {
    1406       70800 :             if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST )
    1407             :             {
    1408          34 :                 is_transient = true;
    1409             :             }
    1410             :         }
    1411             :     }
    1412             : 
    1413        8850 :     estimate_itd( &corr, hStereoDmxEVS->hPOC, hPHA, data_f[0], data_f[1], &hStereoDmxEVS->itd, input_frame );
    1414             : 
    1415             :     /* poc */
    1416             : 
    1417        8850 :     if ( hStereoDmxEVS->itd )
    1418             :     {
    1419        3956 :         dmx_weight = ( ( hStereoDmxEVS->itd > 0 ) ? ( -1 ) : 1 ) * 0.5f * corr + 0.5f;
    1420             :     }
    1421             :     else
    1422             :     {
    1423        4894 :         dmx_weight = 0.5f;
    1424             :     }
    1425             : 
    1426        8850 :     create_M_signal( data_f[0], data_f[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd,
    1427        8850 :                      hStereoDmxEVS->dmx_weight, hStereoDmxEVS->pre_dmx_energy, hStereoDmxEVS->aux_dmx_energy );
    1428             : 
    1429             :     /* pha */
    1430             : 
    1431        8850 :     pha_len = hPHA->pha_len;
    1432        8850 :     fad_len = hPHA->fad_len;
    1433        8850 :     fad_g = hPHA->fad_g;
    1434             : 
    1435        8850 :     set_zero( dmx_pha_data, n_samples );
    1436        8850 :     set_zero( mem_prev, fad_len );
    1437             : 
    1438       26550 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1439             :     {
    1440       17700 :         p_data = data_f[k];
    1441       17700 :         mvr2r( hPHA->data_mem[k], data_mem, pha_len );
    1442       17700 :         mvr2r( &( p_data[n_samples - pha_len] ), hPHA->data_mem[k], pha_len );
    1443       17700 :         p_data_mem = &( data_mem[pha_len] );
    1444       17700 :         mvr2r( p_data, p_data_mem, n_samples );
    1445             : 
    1446       17700 :         p_prev_taps = hPHA->p_prev_taps[k];
    1447       17700 :         if ( p_prev_taps )
    1448             :         {
    1449     5588229 :             for ( n = 0; n < fad_len; n++ )
    1450             :             {
    1451   250624320 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1452             :                 {
    1453   245053440 :                     ftmp += p_data_mem[n - m] * p_prev_taps[m];
    1454             :                 }
    1455     5570880 :                 mem_prev[n] += ftmp * INV_SQRT_2;
    1456             :             }
    1457             :         }
    1458             :         else
    1459             :         {
    1460       93471 :             for ( n = 0; n < fad_len; n++ )
    1461             :             {
    1462       93120 :                 mem_prev[n] += p_data[n] * INV_SQRT_2;
    1463             :             }
    1464             :         }
    1465             : 
    1466       17700 :         p_curr_taps = hPHA->p_curr_taps[k];
    1467       17700 :         if ( p_curr_taps )
    1468             :         {
    1469    11283503 :             for ( n = 0; n < n_samples; n++ )
    1470             :             {
    1471   506410880 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1472             :                 {
    1473   495144960 :                     ftmp += p_data_mem[n - m] * p_curr_taps[m];
    1474             :                 }
    1475    11265920 :                 dmx_pha_data[n] += ftmp * INV_SQRT_2;
    1476             :             }
    1477             :         }
    1478             :         else
    1479             :         {
    1480       62197 :             for ( n = 0; n < n_samples; n++ )
    1481             :             {
    1482       62080 :                 dmx_pha_data[n] += p_data[n] * INV_SQRT_2;
    1483             :             }
    1484             :         }
    1485             :     }
    1486             : 
    1487     2840850 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- )
    1488             :     {
    1489     2832000 :         dmx_pha_data[n] *= fad_g[n];
    1490     2832000 :         dmx_pha_data[n] += ( mem_prev[n] ) * fad_g[m];
    1491             :     }
    1492             : 
    1493             :     /* prc switch */
    1494             : 
    1495        8850 :     prev_prc = hPHA->curr_prc;
    1496        8850 :     if ( abs( (int16_t) hStereoDmxEVS->itd ) > hPHA->prc_thres )
    1497             :     {
    1498         725 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_POC )
    1499             :         {
    1500          10 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_POC )
    1501             :             {
    1502           5 :                 hPHA->prc_hys_cnt += 1;
    1503             :             }
    1504             :             else
    1505             :             {
    1506           5 :                 hPHA->prc_hys_cnt = 0;
    1507             :             }
    1508             : 
    1509          10 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1510             :             {
    1511           5 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1512             :             }
    1513             :         }
    1514         725 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1515             :     }
    1516             :     else
    1517             :     {
    1518        8125 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_PHA )
    1519             :         {
    1520        7071 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_PHA )
    1521             :             {
    1522        6943 :                 hPHA->prc_hys_cnt += 1;
    1523             :             }
    1524             :             else
    1525             :             {
    1526         128 :                 hPHA->prc_hys_cnt = 0;
    1527             :             }
    1528             : 
    1529        7071 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1530             :             {
    1531        6943 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_PHA;
    1532             :             }
    1533             :         }
    1534        8125 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_PHA;
    1535             :     }
    1536             : 
    1537        8850 :     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        7530 :         hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1540        7530 :         hPHA->prc_hys_cnt = 0;
    1541             :     }
    1542             : 
    1543        8850 :     calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1544        8850 :     calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1545             : 
    1546        8850 :     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          18 :         if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1549             :         {
    1550          10 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1551          10 :             calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1552             : 
    1553          10 :             hPHA->dmx_poc_gain_sgc = sqrtf( hPHA->dmx_pha_ener_sgc / ( hPHA->dmx_poc_ener + EPSILON ) );
    1554          10 :             hPHA->dmx_poc_gain_sgc = min( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1555          10 :             hPHA->dmx_poc_gain_sgc = max( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1556             : 
    1557          10 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1558          10 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1559             :         }
    1560             :         else
    1561             :         {
    1562           8 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1563           8 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1564             : 
    1565           8 :             hPHA->dmx_pha_gain_sgc = sqrtf( hPHA->dmx_poc_ener_sgc / ( hPHA->dmx_pha_ener + EPSILON ) );
    1566           8 :             hPHA->dmx_pha_gain_sgc = min( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1567           8 :             hPHA->dmx_pha_gain_sgc = max( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1568             : 
    1569           8 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1570           8 :             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        8832 :         apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1576        8832 :         calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1577             : 
    1578        8832 :         apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1579        8832 :         calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1580             :     }
    1581             : 
    1582        8850 :     if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1583             :     {
    1584        7786 :         p_dmx_data = dmx_poc_data;
    1585        7786 :         p_dmx_data_fo = dmx_pha_data;
    1586             :     }
    1587             :     else
    1588             :     {
    1589        1064 :         p_dmx_data = dmx_pha_data;
    1590        1064 :         p_dmx_data_fo = dmx_poc_data;
    1591             :     }
    1592             : 
    1593        8850 :     n_fad_r = is_transient ? 1 : STEREO_DMX_EVS_FAD_R;
    1594             : 
    1595        8850 :     if ( prev_prc != hPHA->curr_prc )
    1596             :     {
    1597         278 :         if ( hPHA->n_fad_g == input_frame )
    1598             :         {
    1599         275 :             hPHA->n_fad_g = 0;
    1600         275 :             hPHA->n_fad_cnt = 0;
    1601             :         }
    1602             :         else
    1603             :         {
    1604           3 :             hPHA->n_fad_g = input_frame - hPHA->n_fad_g - 1;
    1605           3 :             hPHA->n_fad_cnt = 0;
    1606             :         }
    1607             :     }
    1608        8572 :     else if ( is_transient )
    1609             :     {
    1610         199 :         hPHA->n_fad_cnt = 0;
    1611             :     }
    1612             : 
    1613        8850 :     fad_len = min( n_samples, ( ( input_frame * n_fad_r ) - ( hPHA->n_fad_g * n_fad_r + hPHA->n_fad_cnt ) ) );
    1614             : 
    1615        8850 :     if ( fad_len != 0 )
    1616             :     {
    1617         825 :         fad_g = hPHA->fad_g_prc;
    1618         825 :         n_fad_g = hPHA->n_fad_g;
    1619         825 :         n_fad_cnt = hPHA->n_fad_cnt;
    1620         825 :         m_fad_g = input_frame - n_fad_g - 1;
    1621             : 
    1622         825 :         if ( n_fad_r == 1 )
    1623             :         {
    1624           3 :             n_fad_cnt = 0;
    1625        2563 :             for ( n = 0; n < fad_len; n++ )
    1626             :             {
    1627        2560 :                 p_dmx_data[n] *= fad_g[n_fad_g++];
    1628        2560 :                 p_dmx_data[n] += fad_g[m_fad_g--] * p_dmx_data_fo[n];
    1629             :             }
    1630             :         }
    1631             :         else
    1632             :         {
    1633         822 :             n = 0;
    1634         822 :             sbfad_len = 0;
    1635         822 :             if ( n_fad_cnt != 0 )
    1636             :             {
    1637         409 :                 sbfad_len = min( fad_len, n_fad_r - n_fad_cnt );
    1638        1023 :                 for ( ; n < sbfad_len; n++ )
    1639             :                 {
    1640         614 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1641         614 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1642             :                 }
    1643         409 :                 n_fad_cnt = 0;
    1644         409 :                 n_fad_g++;
    1645         409 :                 m_fad_g--;
    1646             :             }
    1647             : 
    1648         822 :             sbfad_len = (int16_t) ( ( fad_len - sbfad_len ) / n_fad_r );
    1649      158708 :             for ( k = 0; k < sbfad_len; k++ )
    1650             :             {
    1651      631544 :                 for ( m = 0; m < n_fad_r; m++ )
    1652             :                 {
    1653      473658 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1654      473658 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1655      473658 :                     n++;
    1656             :                 }
    1657      157886 :                 n_fad_g++;
    1658      157886 :                 m_fad_g--;
    1659             :             }
    1660             : 
    1661        1437 :             for ( ; n < fad_len; n++ )
    1662             :             {
    1663         615 :                 p_dmx_data[n] *= fad_g[n_fad_g];
    1664         615 :                 p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1665         615 :                 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         825 :         hPHA->n_fad_g = n_fad_g;
    1675         825 :         hPHA->n_fad_cnt = n_fad_cnt;
    1676             :     }
    1677             : 
    1678        8850 :     mvr2s( p_dmx_data, data, n_samples );
    1679             : 
    1680             : 
    1681        8850 :     return;
    1682             : }
    1683             : 
    1684             : 
    1685             : /*-------------------------------------------------------------------*
    1686             :  * stereo_dmx_evs_init_encoder()
    1687             :  *
    1688             :  * open and initialize stereo downmix for EVS encoder
    1689             :  *-------------------------------------------------------------------*/
    1690             : 
    1691         117 : 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         117 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1704             : 
    1705         117 :     hStereoDmxEVS = NULL;
    1706         117 :     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         117 :     hStereoDmxEVS->itd = 0.0f;
    1712         117 :     hStereoDmxEVS->pre_dmx_energy[0] = 0.0f;
    1713         351 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1714             :     {
    1715         234 :         hStereoDmxEVS->aux_dmx_energy[n] = 0.0f;
    1716             :     }
    1717             : 
    1718         117 :     hStereoDmxEVS->dmx_weight[0] = 0.5f;
    1719         117 :     hStereoDmxEVS->dmx_weight[1] = 0.0f;
    1720         117 :     hStereoDmxEVS->dmx_weight[2] = 0.0f;
    1721             : 
    1722         117 :     if ( input_frame == L_FRAME16k )
    1723             :     {
    1724          60 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_16k;
    1725             :     }
    1726          57 :     else if ( input_frame == L_FRAME32k )
    1727             :     {
    1728          37 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_32k;
    1729             :     }
    1730          20 :     else if ( input_frame == L_FRAME48k )
    1731             :     {
    1732          20 :         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         117 :     hStereoDmxEVS->hPOC = NULL;
    1740         117 :     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         117 :     hStereoDmxEVS->hPOC->shift_limit = NS2SA( input_Fs, STEREO_DMX_EVS_SHIFT_LIMIT );
    1746             : 
    1747         351 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1748             :     {
    1749         234 :         hStereoDmxEVS->hPOC->peakQ[n] = 0.0f;
    1750         234 :         hStereoDmxEVS->hPOC->peak_width[n] = (float) hStereoDmxEVS->hPOC->shift_limit / 2;
    1751         234 :         hStereoDmxEVS->hPOC->ispeak[n] = 0;
    1752         234 :         hStereoDmxEVS->hPOC->itdLR[n] = 0;
    1753             :     }
    1754         117 :     set_f( hStereoDmxEVS->hPOC->P, 0.0f, L_FRAME48k );
    1755             : 
    1756         117 :     if ( input_frame == L_FRAME16k )
    1757             :     {
    1758          60 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_48k;
    1759             :     }
    1760          57 :     else if ( input_frame == L_FRAME32k )
    1761             :     {
    1762          37 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_32k;
    1763             :     }
    1764          20 :     else if ( input_frame == L_FRAME48k )
    1765             :     {
    1766          20 :         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         117 :     hStereoDmxEVS->hPOC->eps = 2.0f * EVS_PI / ( (float) input_frame );
    1773             : 
    1774         117 :     if ( input_frame == L_FRAME16k )
    1775             :     {
    1776          60 :         hStereoDmxEVS->hPOC->sin = dft_trigo_32k;
    1777             :     }
    1778          57 :     else if ( input_frame == L_FRAME32k )
    1779             :     {
    1780          37 :         hStereoDmxEVS->hPOC->sin = dft_trigo_32k;
    1781             :     }
    1782          20 :     else if ( input_frame == L_FRAME48k )
    1783             :     {
    1784          20 :         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         117 :     hStereoDmxEVS->hPOC->confidence = 0.0f;
    1792             : 
    1793         117 :     hStereoDmxEVS->hPHA = NULL;
    1794         117 :     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         351 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1800             :     {
    1801         234 :         hStereoDmxEVS->hPHA->p_curr_taps[n] = NULL;
    1802         234 :         hStereoDmxEVS->hPHA->p_prev_taps[n] = NULL;
    1803             : 
    1804         234 :         set_zero( hStereoDmxEVS->hPHA->data_mem[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1805         234 :         set_zero( hStereoDmxEVS->hPHA->curr_taps[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1806             :     }
    1807             : 
    1808         117 :     if ( input_Fs == 16000 )
    1809             :     {
    1810          60 :         len = STEREO_DMX_EVS_PHA_LEN_16;
    1811          60 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_16;
    1812          60 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_16;
    1813          60 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_16;
    1814          60 :         hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_16;
    1815             :     }
    1816          57 :     else if ( input_Fs == 32000 )
    1817             :     {
    1818          37 :         len = STEREO_DMX_EVS_PHA_LEN_32;
    1819          37 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_32;
    1820          37 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_32;
    1821          37 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_32;
    1822          37 :         hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_32;
    1823             :     }
    1824          20 :     else if ( input_Fs == 48000 )
    1825             :     {
    1826          20 :         len = STEREO_DMX_EVS_PHA_LEN_48;
    1827          20 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_48;
    1828          20 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_48;
    1829          20 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_48;
    1830          20 :         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         117 :     hStereoDmxEVS->hPHA->pha_len = len / 2;
    1838         117 :     hStereoDmxEVS->hPHA->isd_rate_s = 0.0f;
    1839         117 :     hStereoDmxEVS->hPHA->iccr_s = 0.0f;
    1840             : 
    1841         117 :     pha_len = hStereoDmxEVS->hPHA->pha_len;
    1842         117 :     fad_len = hStereoDmxEVS->hPHA->fad_len;
    1843             : 
    1844         117 :     trans_len = (int16_t) ( (float) pha_len / 20.0f );
    1845         117 :     set_f( hStereoDmxEVS->hPHA->win, STEREO_DMX_EVS_PHA_WND_C, pha_len - trans_len );
    1846         117 :     hStereoDmxEVS->hPHA->win[0] = 1.0f;
    1847         117 :     tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 );
    1848         117 :     win = &( hStereoDmxEVS->hPHA->win[pha_len - trans_len] );
    1849         291 :     for ( n = 0; n < trans_len; n++ )
    1850             :     {
    1851         174 :         win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * STEREO_DMX_EVS_PHA_WND_C;
    1852             :     }
    1853             : 
    1854         117 :     fad_g = hStereoDmxEVS->hPHA->fad_g;
    1855         117 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1856         117 :     fad_len2 = fad_len / 2;
    1857       15637 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1858             :     {
    1859       15520 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1860       15520 :         fad_g[m] = 1.0f - fad_g[n];
    1861             :     }
    1862             : 
    1863         117 :     hStereoDmxEVS->hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
    1864         117 :     hStereoDmxEVS->hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
    1865         117 :     hStereoDmxEVS->hPHA->pha_hys_cnt = 0;
    1866             : 
    1867             : 
    1868         117 :     hStereoDmxEVS->hPHA->pha_ipd_chan_cnt = 0;
    1869         117 :     hStereoDmxEVS->hPHA->pha_ipd_chan_thresh = 10;
    1870         117 :     hStereoDmxEVS->hPHA->pha_ipd_ild_thresh = STEREO_DMX_EVS_IPD_ILD_THRES;
    1871         117 :     hStereoDmxEVS->hPHA->pha_ipd_chan2rephase = 1;
    1872         117 :     hStereoDmxEVS->hPHA->pha_ipd_previouschan2rephase = 1;
    1873         117 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch = 0;
    1874         117 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch_allowed = 0;
    1875         117 :     hStereoDmxEVS->hPHA->pha_ipd_sf_Threshold = STEREO_DMX_EVS_IPD_SF_THRES;
    1876             : 
    1877         117 :     hStereoDmxEVS->hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
    1878         117 :     hStereoDmxEVS->hPHA->force_poc = FALSE;
    1879             : 
    1880             :     /* Compute the forgetting factor */
    1881         117 :     itrh = (int16_t) ( ( STEREO_DMX_EVS_IFF_FREQ * input_frame ) / ( input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE ) );
    1882         117 :     n0 = L_FRAME16k / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1883         117 :     a_step = ( STEREO_DMX_EVS_IFF_AMIN - STEREO_DMX_EVS_IFF_AMAX ) / ( n0 + 1 - itrh );
    1884         117 :     ipd_ff = hStereoDmxEVS->hPHA->ipd_ff;
    1885        3627 :     for ( n = 0; n < itrh; n++ )
    1886             :     {
    1887        3510 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX;
    1888             :     }
    1889        6084 :     for ( ; n < ( n0 + 1 ); n++ ) /* 8kHz */
    1890             :     {
    1891        5967 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX + ( n - itrh ) * a_step;
    1892             :     }
    1893       18720 :     for ( ; n < STEREO_DMX_EVS_NB_SUBBAND_MAX; n++ )
    1894             :     {
    1895       18603 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMIN;
    1896             :     }
    1897         117 :     set_f( hStereoDmxEVS->hPHA->Pr, 1.0, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1898         117 :     set_zero( hStereoDmxEVS->hPHA->Pi, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1899             : 
    1900         117 :     n0 = input_frame / ( 4 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1901         117 :     input_frame_pha = input_frame / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1902             : 
    1903         117 :     if ( input_frame == L_FRAME16k )
    1904             :     {
    1905          60 :         p_ipd_w = dft_trigo_32k;
    1906          60 :         rfft_ipd_coef_step = 4;
    1907             :     }
    1908          57 :     else if ( input_frame == L_FRAME32k )
    1909             :     {
    1910          37 :         p_ipd_w = dft_trigo_32k;
    1911          37 :         rfft_ipd_coef_step = 2;
    1912             :     }
    1913          20 :     else if ( input_frame == L_FRAME48k )
    1914             :     {
    1915          20 :         p_ipd_w = dft_trigo_48k;
    1916          20 :         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         117 :     win = hStereoDmxEVS->hPHA->rfft_ipd_coef;
    1924         117 :     len = rfft_ipd_coef_step * STEREO_DMX_EVS_SUBBAND_SIZE;
    1925        7877 :     for ( n = 0; n < n0; n++ )
    1926             :     {
    1927        7760 :         win[n] = p_ipd_w[n * len];
    1928        7760 :         win[input_frame_pha - n] = p_ipd_w[n * len];
    1929             :     }
    1930         117 :     win[n0] = p_ipd_w[n0 * len];
    1931             : 
    1932         117 :     hStereoDmxEVS->hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1933         117 :     hStereoDmxEVS->hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1934         117 :     hStereoDmxEVS->hPHA->prc_hys_cnt = 0;
    1935             : 
    1936         117 :     fad_len = input_frame;
    1937             : 
    1938         117 :     fad_g = hStereoDmxEVS->hPHA->fad_g_prc;
    1939         117 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1940         117 :     fad_len2 = fad_len / 2;
    1941       31157 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1942             :     {
    1943       31040 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1944       31040 :         fad_g[m] = 1.0f - fad_g[n];
    1945             :     }
    1946             : 
    1947         351 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1948             :     {
    1949         234 :         hStereoDmxEVS->hPHA->trns_aux_energy[n] = 0.0f;
    1950             :     }
    1951             : 
    1952             : 
    1953         117 :     hStereoDmxEVS->hPHA->n_fad_g = input_frame;
    1954         117 :     hStereoDmxEVS->hPHA->n_fad_cnt = 0;
    1955             : 
    1956         117 :     hStereoDmxEVS->hPHA->dmx_pha_ener_sgc = 0.0f;
    1957         117 :     hStereoDmxEVS->hPHA->dmx_poc_ener_sgc = 0.0f;
    1958         117 :     hStereoDmxEVS->hPHA->dmx_pha_gain_sgc = 1.0f;
    1959         117 :     hStereoDmxEVS->hPHA->dmx_poc_gain_sgc = 1.0f;
    1960             : 
    1961         117 :     hStereoDmxEVS->hPHA->dmx_pha_ener = 0.0f;
    1962         117 :     hStereoDmxEVS->hPHA->dmx_poc_ener = 0.0f;
    1963             : 
    1964             : 
    1965         117 :     *hStereoDmxEVS_out = hStereoDmxEVS;
    1966             : 
    1967         117 :     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        5801 : void stereo_dmx_evs_close_encoder(
    1978             :     STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle    */
    1979             : )
    1980             : {
    1981        5801 :     if ( hStereoDmxEVS == NULL || *hStereoDmxEVS == NULL )
    1982             :     {
    1983        5684 :         return;
    1984             :     }
    1985             : 
    1986         117 :     if ( ( *hStereoDmxEVS )->hPOC != NULL )
    1987             :     {
    1988         117 :         free( ( *hStereoDmxEVS )->hPOC );
    1989         117 :         ( *hStereoDmxEVS )->hPOC = NULL;
    1990             :     }
    1991             : 
    1992         117 :     if ( ( *hStereoDmxEVS )->hPHA != NULL )
    1993             :     {
    1994         117 :         free( ( *hStereoDmxEVS )->hPHA );
    1995         117 :         ( *hStereoDmxEVS )->hPHA = NULL;
    1996             :     }
    1997             : 
    1998         117 :     free( ( *hStereoDmxEVS ) );
    1999         117 :     ( *hStereoDmxEVS ) = NULL;
    2000             : 
    2001         117 :     return;
    2002             : }

Generated by: LCOV version 1.14