LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_dmx_evs.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 822 840 97.9 %
Date: 2025-05-28 04:28:20 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       56900 : 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       56900 :     n0 = input_frame >> 1;
     153       56900 :     if ( input_frame == L_FRAME16k )
     154             :     {
     155        6000 :         step = 3;
     156        6000 :         bias = 1;
     157             :     }
     158             :     else
     159             :     {
     160       50900 :         step = 1;
     161       50900 :         bias = 0;
     162             :     }
     163             : 
     164    42408900 :     for ( i = 0; i < input_frame; i++ )
     165             :     {
     166             :         /* window */
     167    42352000 :         rfft_buf[i] = input[i] * wnd[i * step + bias];
     168             :     }
     169             : 
     170       56900 :     rfft( rfft_buf, rfft_coef, input_frame, -1 );
     171             : 
     172    21176000 :     for ( i = 1; i < n0; i++ )
     173             :     {
     174    21119100 :         specr[i] = rfft_buf[i * 2];
     175    21119100 :         speci[i] = rfft_buf[i * 2 + 1];
     176             :     }
     177             : 
     178       56900 :     specr[0] = rfft_buf[0];
     179       56900 :     specr[n0] = rfft_buf[1];
     180       56900 :     speci[0] = 0.f;
     181       56900 :     speci[n0] = 0.f;
     182             : 
     183       56900 :     return;
     184             : }
     185             : 
     186             : 
     187             : /*-------------------------------------------------------------------*
     188             :  * calc_poc()
     189             :  *
     190             :  * calculate phase only correlation
     191             :  *-------------------------------------------------------------------*/
     192             : 
     193       28450 : 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       28450 :     iN = 1.0f / (float) input_frame;
     230       28450 :     s = hPOC->sin;
     231       28450 :     P = hPOC->P;
     232       28450 :     n0 = input_frame / 2;
     233       28450 :     itdLR = hPOC->itdLR;
     234             : 
     235       28450 :     Pr = hPHA->Pr;
     236       28450 :     Pi = hPHA->Pi;
     237       28450 :     nsbd = n0 / STEREO_DMX_EVS_SUBBAND_SIZE;
     238       28450 :     input_frame_pha = input_frame / STEREO_DMX_EVS_SUBBAND_SIZE;
     239             : 
     240       28450 :     igamma = STEREO_DMX_EVS_POC_GAMMA * iN;
     241       28450 :     gamma = 1.0f - igamma;
     242             : 
     243       28450 :     step = 1;
     244       28450 :     bias = 0;
     245       28450 :     cos_step = 2;
     246       28450 :     cos_max = n0;
     247       28450 :     mult_angle = 3;
     248             : 
     249       28450 :     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       28450 :     if ( input_frame == L_FRAME32k )
     258             :     {
     259       13175 :         mult_angle = 2;
     260             :     }
     261             : 
     262       28450 :     end = min( n0, 320 );
     263       28450 :     specPOr[0] = sign( specLr[0] * specRr[0] ) * wnd[bias];
     264       28450 :     specPOi[0] = 0.0f;
     265       28450 :     EPS = hPOC->eps;
     266       28450 :     if ( input_frame == L_FRAME48k )
     267             :     {
     268     2946000 :         for ( i = 1; i < n0 / 2; i++ )
     269             :         {
     270     2933725 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     271     2933725 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     272     2933725 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     273     2933725 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     274     2933725 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     275     2933725 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     276             : 
     277     2933725 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     278     2933725 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     279     2933725 :             j = n0 - i;
     280     2933725 :             if ( j < 320 )
     281             :             {
     282      969725 :                 Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     283      969725 :                 Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     284      969725 :                 Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     285      969725 :                 Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     286             : 
     287      969725 :                 specPOr[j] = ( Lr * Rr + Li * Ri );
     288      969725 :                 specPOi[j] = ( Lr * Ri - Li * Rr );
     289             :             }
     290             :         }
     291             :     }
     292             :     else /* 16kHz and 32 kHz*/
     293             :     {
     294     2348000 :         for ( i = 1; i < n0 / 2; i++ )
     295             :         {
     296     2331825 :             eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
     297     2331825 :             eps_sin = s[i * cos_step /*i_for*/] * EPS;
     298             : 
     299     2331825 :             Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin;
     300     2331825 :             Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos;
     301     2331825 :             Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin;
     302     2331825 :             Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos;
     303     2331825 :             specPOr[i] = ( Lr * Rr + Li * Ri );
     304     2331825 :             specPOi[i] = ( Lr * Ri - Li * Rr );
     305             : 
     306     2331825 :             j = n0 - i;
     307     2331825 :             Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin;
     308     2331825 :             Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos;
     309     2331825 :             Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin;
     310     2331825 :             Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos;
     311     2331825 :             specPOr[j] = ( Lr * Rr + Li * Ri );
     312     2331825 :             specPOi[j] = ( Lr * Ri - Li * Rr );
     313             :         }
     314             :     }
     315             :     {
     316             :         /* i=n0/2*/
     317       28450 :         Lr = specLr[i] + specRi[i] * EPS;
     318       28450 :         Li = specLi[i] - specRr[i] * EPS;
     319       28450 :         Rr = specRr[i] + specLi[i] * EPS;
     320       28450 :         Ri = specRi[i] - specLr[i] * EPS;
     321       28450 :         specPOr[i] = ( Lr * Rr + Li * Ri );
     322       28450 :         specPOi[i] = ( Lr * Ri - Li * Rr );
     323             :     }
     324             :     /* complex spectrum (specPOr[i], specPOi[i]) are placed on an unit circle without using  srqt()*/
     325      284500 :     for ( i = 1; i < 10; i++ ) /*search from 4 angles */
     326             :     {
     327      256050 :         tmp1 = wnd[i * step + bias] * gamma;
     328             : 
     329      256050 :         specPOr[i] = sign( specPOr[i] ) * 0.866f * tmp1; /* low angles are more frequent for low frequency */
     330      256050 :         specPOi[i] = sign( specPOi[i] ) * 0.5f * tmp1;
     331      256050 :         gamma -= igamma;
     332             :     }
     333      405700 :     for ( ; i < n0 >> 4; i++ ) /*search from 4 angles */
     334             :     {
     335      377250 :         tmp1 = wnd[i * step + bias] * gamma * 0.7071f;
     336             : 
     337      377250 :         specPOr[i] = sign( specPOr[i] ) * tmp1;
     338      377250 :         specPOi[i] = sign( specPOi[i] ) * tmp1; /* low accuracy is adequate for low frequency */
     339      377250 :         gamma -= igamma;
     340             :     }
     341             : 
     342      690200 :     for ( ; i < n0 >> 3; i++ ) /* binary search from 8 angles */
     343             :     {
     344      661750 :         tmp1 = wnd[i * step + bias] * gamma;
     345             : 
     346      661750 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     347             :         {
     348      407447 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle]; /*  cos(PI/8)*/
     349      407447 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle];
     350             :         }
     351             :         else
     352             :         {
     353      254303 :             specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle]; /*  cos(PI*3/8)*/
     354      254303 :             specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle];
     355             :         }
     356      661750 :         gamma -= igamma;
     357             :     }
     358     7328950 :     for ( ; i < end; i++ ) /* binary search from 16 angles */
     359             :     {
     360     7300500 :         tmp1 = wnd[i * step + bias] * gamma;
     361     7300500 :         if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 )
     362             :         {
     363     4302226 :             if ( ( specPOr[i] * 0.414213f - specPOi[i] ) * ( specPOr[i] * 0.414213f + specPOi[i] ) > 0 ) /*tan(PI/8)*/
     364             :             {
     365     2627001 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /*0.980785f */ * s[140 * mult_angle]; /* cos(PI/16)*/
     366     2627001 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /*0.195090f */ * s[20 * mult_angle];
     367             :             }
     368             :             else
     369             :             {
     370     1675225 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /* 0.831470f */ * s[100 * mult_angle]; /*cos(PI*3/16)*/
     371     1675225 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /* 0.555570f*/ * s[60 * mult_angle];
     372             :             }
     373             :         }
     374             :         else
     375             :         {
     376     2998274 :             if ( ( specPOr[i] - specPOi[i] * 0.414213f ) * ( specPOr[i] + specPOi[i] * 0.414213f ) > 0 ) /*tan(PI/8)*/
     377             :             {
     378     1524899 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.555570f*/ * s[60 * mult_angle]; /*cos(PI*5/16)*/
     379     1524899 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.831470f*/ * s[100 * mult_angle];
     380             :             }
     381             :             else
     382             :             {
     383     1473375 :                 specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.195090f*/ * s[20 * mult_angle]; /*cos(PI*7/16)*/
     384     1473375 :                 specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.980785f*/ * s[140 * mult_angle];
     385             :             }
     386             :         }
     387     7300500 :         gamma -= igamma;
     388             :     }
     389             : 
     390       28450 :     if ( i < n0 )
     391             :     {
     392       12275 :         gamma -= igamma * ( n0 - 320 );
     393             :     }
     394     1992450 :     for ( ; i < n0; i++ ) /*neglect higher frequency bins when 48 kHz samplng*/
     395             :     {
     396     1964000 :         specPOr[i] = 0.f;
     397     1964000 :         specPOi[i] = 0.f;
     398             :     }
     399       28450 :     specPOr[n0] = sign( specLr[n0] * specRr[n0] ) * wnd[i * step + bias] * gamma;
     400             : 
     401       28450 :     freq_8k = L_FRAME16k / 2;
     402       28450 :     freq_ipd_max = (int16_t) ( freq_8k * 5000.0f / ( 8000.0f * STEREO_DMX_EVS_SUBBAND_SIZE ) );
     403             : 
     404             :     /* Memorize the filters N-1 */
     405       85350 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     406             :     {
     407       56900 :         if ( hPHA->p_curr_taps[n] )
     408             :         {
     409       56182 :             hPHA->p_prev_taps[n] = hPHA->prev_taps[n];
     410       56182 :             mvr2r( hPHA->p_curr_taps[n], hPHA->p_prev_taps[n], hPHA->pha_len );
     411             :         }
     412             :         else
     413             :         {
     414         718 :             hPHA->p_prev_taps[n] = NULL;
     415             :         }
     416             :     }
     417             : 
     418             :     /* ISD */
     419       28450 :     isd_cnt_l = 0;
     420       28450 :     isd_cnt_h = 0;
     421     4580450 :     for ( i = 1; i <= freq_8k; i++ )
     422             :     {
     423     4552000 :         Nr = ( specLr[i] - specRr[i] );
     424     4552000 :         Ni = ( specLi[i] - specRi[i] );
     425     4552000 :         Dr = ( specLr[i] + specRr[i] );
     426     4552000 :         Di = ( specLi[i] + specRi[i] );
     427     4552000 :         if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) )
     428             :         {
     429     1033078 :             isd_cnt_h++;
     430             :         }
     431     4552000 :         if ( ( Nr * Nr + Ni * Ni ) < STEREO_DMX_EVS_ISD_THRES_L * ( Dr * Dr + Di * Di ) )
     432             :         {
     433     2852194 :             isd_cnt_l++;
     434             :         }
     435             :     }
     436             : 
     437       28450 :     isd_rate = (float) isd_cnt_h / (float) freq_8k;
     438       28450 :     hPHA->isd_rate_s = STEREO_DMX_EVS_ISD_FORGETTING * hPHA->isd_rate_s + ( 1.0f - STEREO_DMX_EVS_ISD_FORGETTING ) * isd_rate;
     439             : 
     440       28450 :     if ( hPHA->isd_rate_s > STEREO_DMX_EVS_ISD_DIST_HYST_H )
     441             :     {
     442          11 :         if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD )
     443             :         {
     444           4 :             if ( hPHA->prev_pha == STEREO_DMX_EVS_PHA_IPD )
     445             :             {
     446           2 :                 hPHA->pha_hys_cnt += 1;
     447             :             }
     448             :             else
     449             :             {
     450           2 :                 hPHA->pha_hys_cnt = 0;
     451             :             }
     452             : 
     453           4 :             if ( hPHA->pha_hys_cnt >= STEREO_DMX_EVS_SWTCH_HYS_THRES )
     454             :             {
     455           2 :                 hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
     456             :             }
     457             :         }
     458             : 
     459          11 :         hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
     460             :     }
     461       28439 :     else if ( hPHA->isd_rate_s < STEREO_DMX_EVS_ISD_DIST_HYST_L )
     462             :     {
     463       25677 :         if ( hPHA->curr_pha != STEREO_DMX_EVS_PHA_IPD2 )
     464             :         {
     465         240 :             if ( hPHA->prev_pha == STEREO_DMX_EVS_PHA_IPD2 )
     466             :             {
     467         120 :                 hPHA->pha_hys_cnt += 1;
     468             :             }
     469             :             else
     470             :             {
     471         120 :                 hPHA->pha_hys_cnt = 0;
     472             :             }
     473             : 
     474         240 :             if ( hPHA->pha_hys_cnt >= STEREO_DMX_EVS_SWTCH_HYS_THRES )
     475             :             {
     476         120 :                 hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD2;
     477             :             }
     478             :         }
     479       25677 :         hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD2;
     480             :     }
     481             : 
     482       28450 :     ipd_ff = hPHA->ipd_ff;
     483             : 
     484       28450 :     Nr = 0;
     485       28450 :     Ni = 0;
     486       28450 :     eneL = 0;
     487       28450 :     eneR = 0;
     488             : 
     489     5294000 :     for ( n = 1, i = 1; n < nsbd; n++ )
     490             :     {
     491     5265550 :         tPr = 0.0f;
     492     5265550 :         tPi = 0.0f;
     493     5265550 :         tEr[n] = 0.0f;
     494     5265550 :         tEl[n] = 0.0f;
     495             : 
     496    15796650 :         for ( j = 0; j < STEREO_DMX_EVS_SUBBAND_SIZE; j++, i++ )
     497             :         {
     498             :             /* Energy */
     499    10531100 :             tEl[n] += specLr[i] * specLr[i] + specLi[i] * specLi[i];
     500    10531100 :             tEr[n] += specRr[i] * specRr[i] + specRi[i] * specRi[i];
     501             : 
     502             :             /* IPD */
     503    10531100 :             IPDr = specLr[i] * specRr[i] + specLi[i] * specRi[i];
     504    10531100 :             IPDi = specLi[i] * specRr[i] - specLr[i] * specRi[i];
     505    10531100 :             tPr += IPDr;
     506    10531100 :             tPi += IPDi;
     507             : 
     508             :             /* ICCr */
     509    10531100 :             Pn = inv_sqrtf( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON );
     510    10531100 :             IPDr *= Pn;
     511    10531100 :             IPDi *= Pn;
     512             : 
     513    10531100 :             tIPDr = ( specRr[i] * IPDr - specRi[i] * IPDi );
     514    10531100 :             tIPDi = ( specRr[i] * IPDi + specRi[i] * IPDr );
     515             : 
     516    10531100 :             Nr += ( specLr[i] * tIPDr + specLi[i] * tIPDi );
     517    10531100 :             Ni += ( specLi[i] * tIPDr - specLr[i] * tIPDi );
     518             : 
     519    10531100 :             eneL += ( specLr[i] * specLr[i] + specLi[i] * specLi[i] );
     520    10531100 :             eneR += ( specRr[i] * specRr[i] + specRi[i] * specRi[i] );
     521             :         }
     522     5265550 :         Pn = inv_sqrtf( ( tPr * tPr + tPi * tPi ) + EPSILON );
     523             : 
     524     5265550 :         tPr *= Pn;
     525     5265550 :         tPi *= Pn;
     526             : 
     527             : 
     528     5265550 :         Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr;
     529     5265550 :         Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi;
     530     5265550 :         Pn = inv_sqrtf( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON );
     531     5265550 :         Pr[n] *= Pn;
     532     5265550 :         Pi[n] *= Pn;
     533             : 
     534     5265550 :         Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n];
     535     5265550 :         Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n];
     536             :     }
     537             : 
     538             :     /* Computes Spectral flatness on one channel */
     539       28450 :     tmp1 = spectral_flatness( &tEl[1], nsbd - 1 );
     540       28450 :     if ( tmp1 < hPHA->pha_ipd_sf_Threshold )
     541             :     {
     542       24548 :         hPHA->pha_ipd_chanswitch_allowed = 0;
     543             :     }
     544             :     else
     545             :     {
     546        3902 :         hPHA->pha_ipd_chanswitch_allowed = 1;
     547             :     }
     548             : 
     549       28450 :     ICCr = sqrtf( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) );
     550       28450 :     hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr;
     551             : 
     552       28450 :     if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD )
     553             :     {
     554         241 :         hPHA->force_poc = FALSE;
     555         241 :         hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
     556             :     }
     557             :     else
     558             :     {
     559       28209 :         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        3693 :             hPHA->force_poc = FALSE;
     562        3693 :             hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD2;
     563             :         }
     564             :         else
     565             :         {
     566       24516 :             hPHA->force_poc = TRUE;
     567             :         }
     568             :     }
     569             : 
     570       28450 :     if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD )
     571             :     {
     572         471 :         rfft_pha_buf[0] = 1.;
     573         471 :         rfft_pha_buf[1] = 1.;
     574             : 
     575         471 :         ild_cnt = 0;
     576       86400 :         for ( i = 1; i < nsbd; i++ )
     577             :         {
     578       85929 :             rfft_pha_buf[i * 2] = Pr[i];
     579       85929 :             rfft_pha_buf[i * 2 + 1] = Pi[i];
     580       85929 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     581             :             {
     582        3574 :                 ild_cnt++;
     583        3574 :                 tEr[i] = 1;
     584             :             }
     585             :             else
     586             :             {
     587       82355 :                 tEr[i] = -1;
     588             :             }
     589             :         }
     590         471 :         if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
     591             :         {
     592        3920 :             for ( i = 1; i < nsbd; i++ )
     593             :             {
     594        3900 :                 if ( tEr[i] > 0 )
     595             :                 {
     596         823 :                     rfft_pha_buf[i * 2] = 1.;
     597         823 :                     rfft_pha_buf[i * 2 + 1] = 0.;
     598             :                 }
     599             :             }
     600             :         }
     601             : 
     602         471 :         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         471 :         if ( hPHA->trns_aux_energy[0] > hPHA->trns_aux_energy[1] * hPHA->pha_ipd_ild_thresh )
     607             :         {
     608           6 :             pha_ipd_ild_chan2rephase = 1;
     609             :         }
     610         465 :         else if ( hPHA->trns_aux_energy[1] > hPHA->trns_aux_energy[0] * hPHA->pha_ipd_ild_thresh )
     611             :         {
     612          34 :             pha_ipd_ild_chan2rephase = 0;
     613             :         }
     614             :         else
     615             :         {
     616         431 :             pha_ipd_ild_chan2rephase = -1;
     617             :         }
     618             : 
     619             :         /* Channel selection based on spikyness of R2L/L2R impulse responses */
     620         471 :         tmp1 = spectral_flatness( rfft_pha_buf, hPHA->pha_len );
     621         471 :         rfft_pha_buf[input_frame_pha - hPHA->pha_len] = rfft_pha_buf[0];
     622         471 :         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         471 :         if ( ( ( tmp1 > tmp2 ) && ( pha_ipd_ild_chan2rephase == -1 ) ) || ( pha_ipd_ild_chan2rephase == 0 ) ) /* L => R */
     626             :         {
     627         207 :             if ( hPHA->pha_ipd_previouschan2rephase == 0 )
     628             :             {
     629         164 :                 hPHA->pha_ipd_chan_cnt++;
     630         164 :                 if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh )
     631             :                 {
     632             :                     /* Avoid channel switch in case of too harmonic signals */
     633          71 :                     if ( hPHA->pha_ipd_chanswitch_allowed )
     634             :                     {
     635           8 :                         if ( hPHA->pha_ipd_chan2rephase != 0 )
     636             :                         {
     637           2 :                             hPHA->pha_ipd_chanswitch = 1;
     638             :                         }
     639             :                         else
     640             :                         {
     641           6 :                             hPHA->pha_ipd_chanswitch = 0;
     642             :                         }
     643           8 :                         hPHA->pha_ipd_chan2rephase = 0;
     644             :                     }
     645             :                 }
     646             :             }
     647             :             else
     648             :             {
     649          43 :                 hPHA->pha_ipd_previouschan2rephase = 0;
     650          43 :                 hPHA->pha_ipd_chan_cnt = 1;
     651          43 :                 hPHA->pha_ipd_chanswitch = 0;
     652             :             }
     653             :         }
     654             :         else /* R => L */
     655             :         {
     656         264 :             if ( hPHA->pha_ipd_previouschan2rephase == 1 )
     657             :             {
     658         223 :                 hPHA->pha_ipd_chan_cnt++;
     659         223 :                 if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh )
     660             :                 {
     661             :                     /* Avoid channel switch in case of too harmonic signals */
     662          13 :                     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          13 :                     hPHA->pha_ipd_chan_cnt = hPHA->pha_ipd_chan_thresh;
     675             :                 }
     676             :             }
     677             :             else
     678             :             {
     679          41 :                 hPHA->pha_ipd_previouschan2rephase = 1;
     680          41 :                 hPHA->pha_ipd_chan_cnt = 1;
     681          41 :                 hPHA->pha_ipd_chanswitch = 0;
     682             :             }
     683             :         }
     684             : 
     685         471 :         if ( !hPHA->pha_ipd_chanswitch )
     686             :         {
     687         460 :             if ( hPHA->pha_ipd_chan2rephase == 0 )
     688             :             {
     689         112 :                 hPHA->p_curr_taps[1] = NULL;
     690         112 :                 hPHA->p_curr_taps[0] = hPHA->curr_taps[0];
     691         112 :                 p_curr_taps = hPHA->p_curr_taps[0];
     692         112 :                 p_curr_taps[0] = rfft_pha_buf[0];
     693        5376 :                 for ( i = 1, j = input_frame_pha - 1; i < hPHA->pha_len; i++, j-- )
     694             :                 {
     695        5264 :                     p_curr_taps[i] = rfft_pha_buf[j];
     696             :                 }
     697             :             }
     698             :             else
     699             :             {
     700         348 :                 hPHA->p_curr_taps[0] = NULL;
     701         348 :                 hPHA->p_curr_taps[1] = hPHA->curr_taps[1];
     702         348 :                 mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     703             :             }
     704             :         }
     705             :     }
     706             : 
     707       28450 :     if ( hPHA->pha_ipd_chanswitch )
     708             :     {
     709          33 :         for ( n = 0; n < CPE_CHANNELS; n++ )
     710             :         {
     711          22 :             hPHA->p_curr_taps[n] = NULL;
     712             :         }
     713             :     }
     714       28439 :     else if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 )
     715             :     {
     716             :         /* IPDn */
     717             : 
     718       27979 :         set_f( &( Pr[freq_ipd_max] ), 1.0f, ( nsbd - freq_ipd_max ) );
     719       27979 :         set_f( &( Pi[freq_ipd_max] ), 0.0f, ( nsbd - freq_ipd_max ) );
     720             : 
     721       83937 :         for ( n = 0; n < CPE_CHANNELS; n++ )
     722             :         {
     723       55958 :             hPHA->p_curr_taps[n] = hPHA->curr_taps[n];
     724             :         }
     725             : 
     726       27979 :         rfft_pha_buf[0] = 1.;
     727       27979 :         rfft_pha_buf[1] = 1.;
     728             : 
     729       27979 :         ild_cnt = 0;
     730       27979 :         isd_rate = (float) isd_cnt_l / freq_8k;
     731     5207600 :         for ( i = 1; i < nsbd; i++ )
     732             :         {
     733     5179621 :             rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + Pr[i] ) / 2.0f );
     734     5179621 :             rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] );
     735     5179621 :             if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD )
     736             :             {
     737     3719224 :                 rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] );
     738     3719224 :                 rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f );
     739             :             }
     740     5179621 :             if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) )
     741             :             {
     742      545193 :                 ild_cnt++;
     743      545193 :                 tEr[i] = 1;
     744             :             }
     745             :             else
     746             :             {
     747     4634428 :                 tEr[i] = -1;
     748             :             }
     749             :         }
     750       27979 :         if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC )
     751             :         {
     752     1085120 :             for ( i = 1; i < nsbd; i++ )
     753             :             {
     754     1079630 :                 if ( tEr[i] > 0 )
     755             :                 {
     756      411338 :                     rfft_pha_buf[i * 2] = 1.;
     757      411338 :                     rfft_pha_buf[i * 2 + 1] = 0.;
     758             :                 }
     759             :             }
     760             :         }
     761             : 
     762       27979 :         rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 );
     763       27979 :         mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len );
     764             : 
     765             :         /* PHA L2R */
     766       27979 :         p_curr_taps = hPHA->p_curr_taps[0];
     767       27979 :         p_curr_taps[0] = rfft_pha_buf[0];
     768     1272432 :         for ( i = 1; i < hPHA->pha_len; i++ )
     769             :         {
     770     1244453 :             p_curr_taps[i] = rfft_pha_buf[input_frame_pha - i];
     771             :         }
     772             :     }
     773             : 
     774       85350 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     775             :     {
     776       56900 :         if ( hPHA->p_curr_taps[n] )
     777             :         {
     778     2621922 :             for ( i = 0; i < hPHA->pha_len; i++ )
     779             :             {
     780     2565504 :                 hPHA->p_curr_taps[n][i] *= hPHA->win[i];
     781             :             }
     782             : 
     783       56418 :             energy = 0.;
     784     2621922 :             for ( i = 0; i < hPHA->pha_len; i++ )
     785             :             {
     786     2565504 :                 energy += hPHA->p_curr_taps[n][i] * hPHA->p_curr_taps[n][i];
     787             :             }
     788       56418 :             energy = inv_sqrtf( energy + EPSILON );
     789     2621922 :             for ( i = 0; i < hPHA->pha_len; i++ )
     790             :             {
     791     2565504 :                 hPHA->p_curr_taps[n][i] *= energy;
     792             :             }
     793             :         }
     794             :     }
     795             : 
     796             : 
     797       28450 :     rfft_buf[0] = specPOr[0];
     798       28450 :     rfft_buf[1] = specPOr[n0];
     799    10588000 :     for ( i = 1; i < n0; i++ )
     800             :     {
     801    10559550 :         rfft_buf[i * 2] = specPOr[i];
     802    10559550 :         rfft_buf[i * 2 + 1] = specPOi[i];
     803             :     }
     804             : 
     805       28450 :     rfft( rfft_buf, rfft_coef, input_frame, +1 );
     806             : 
     807       28450 :     tmp1 = rfft_buf[0];
     808       28450 :     tmpPOC1[n0] = tmp1 * tmp1;
     809             : 
     810     5984200 :     for ( i = 1; i < hPOC->shift_limit + 1; i++ )
     811             :     {
     812     5955750 :         n1 = n0 + i;
     813     5955750 :         n2 = n0 - i;
     814             : 
     815     5955750 :         tmp1 = rfft_buf[i];
     816     5955750 :         tmpPOC1[n1] = tmp1 * tmp1;
     817             : 
     818     5955750 :         tmp1 = rfft_buf[input_frame - i];
     819     5955750 :         tmpPOC1[n2] = tmp1 * tmp1;
     820             :     }
     821             : 
     822       28450 :     tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n0] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n0 - 1] + tmpPOC1[n0 + 1] );
     823       28450 :     tmpPOC2[n0] = max( tmp1, 0.0f );
     824             : 
     825     5955750 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     826             :     {
     827     5927300 :         n1 = n0 + i;
     828     5927300 :         n2 = n0 - i;
     829     5927300 :         tmp1 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n1] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n1 - 1] + tmpPOC1[n1 + 1] );
     830     5927300 :         tmp2 = STEREO_DMX_EVS_POC_SMOOTH * tmpPOC1[n2] + 0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH ) * ( tmpPOC1[n2 - 1] + tmpPOC1[n2 + 1] );
     831     5927300 :         tmpPOC2[n1] = max( tmp1, 0.0f );
     832     5927300 :         tmpPOC2[n2] = max( tmp2, 0.0f );
     833             :     }
     834             : 
     835       28450 :     P[n0] = P[n0] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n0] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     836             : 
     837     5955750 :     for ( i = 1; i < hPOC->shift_limit; i++ )
     838             :     {
     839     5927300 :         n1 = n0 + i;
     840     5927300 :         n2 = n0 - i;
     841             : 
     842     5927300 :         if ( i == -itdLR[1] )
     843             :         {
     844        4785 :             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     5922515 :             P[n1] = P[n1] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n1] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     849             :         }
     850             : 
     851     5927300 :         if ( i == itdLR[0] )
     852             :         {
     853        4775 :             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     5922525 :             P[n2] = P[n2] * STEREO_DMX_EVS_POC_FORGETTING + tmpPOC2[n2] * ( 1.0f - STEREO_DMX_EVS_POC_FORGETTING );
     858             :         }
     859             :     }
     860             : 
     861       28450 :     return;
     862             : }
     863             : 
     864             : 
     865             : /*-------------------------------------------------------------------*
     866             :  * find_poc_peak()
     867             :  *
     868             :  * find peak phase only correlation
     869             :  *-------------------------------------------------------------------*/
     870             : 
     871       28450 : 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       28450 :     Lh = input_frame / 2;
     885       28450 :     on = hPOC->ispeak;
     886       28450 :     itdLR = hPOC->itdLR;
     887       28450 :     width = 0.38f;
     888       28450 :     eps = 1.0f / (float) input_frame;
     889       28450 :     peak_width = hPOC->peak_width;
     890       28450 :     peakQ = hPOC->peakQ;
     891       28450 :     Q[0] = hPOC->P[Lh];
     892       28450 :     Q[1] = 0.0f;
     893       28450 :     itd_cand[0] = itd_cand[1] = 0;
     894       28450 :     P = hPOC->P;
     895             : 
     896     5955750 :     for ( i = 1; i < hPOC->shift_limit; i++ ) /*find peaks of POC P[] with positive and negative ITD */
     897             :     {
     898     5927300 :         if ( P[Lh - i] > Q[0] )
     899             :         {
     900       50146 :             Q[0] = P[Lh - i];
     901       50146 :             itd_cand[0] = i;
     902             :         }
     903     5927300 :         if ( P[Lh + i] > Q[1] )
     904             :         {
     905       90210 :             Q[1] = P[Lh + i];
     906       90210 :             itd_cand[1] = -i;
     907             :         }
     908             :     }
     909             : 
     910       85350 :     for ( n = 0; n < CPE_CHANNELS; n++ )
     911             :     {
     912       56900 :         prev_off[n] = !on[n];
     913             : 
     914       56900 :         aQ[n] = Q[n] * width;
     915       56900 :         cnt[n] = 0;
     916       56900 :         cQ[n] = P[Lh - itd_cand[n]];
     917             : 
     918       56900 :         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      544634 :         for ( i = 1; i <= peak_range; i++ )
     921             :         {
     922      487734 :             cnt[n] += ( P[Lh - itd_cand[n] + i] > aQ[n] ) + ( P[Lh - itd_cand[n] - i] > aQ[n] );
     923      487734 :             cQ[n] += P[Lh - itd_cand[n] + i] + P[Lh - itd_cand[n] - i];
     924             :         }
     925             : 
     926       56900 :         peak_width[n] = peak_width[n] * ratio + (float) cnt[n] * ( 1.0f - ratio );
     927       56900 :         eps2 = eps * peak_width[n] * 0.25f;
     928       56900 :         Q[n] = ( 1.0f - ( cQ[n] / ( peak_range * 2 + 1 ) + eps2 ) / ( Q[n] + eps2 ) );
     929       56900 :         Q[n] = max( Q[n], 0.0f );
     930             : 
     931       56900 :         if ( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/
     932             :         {
     933       24022 :             tmpf = ( 0.3f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit ) * peakQ[n];
     934       24022 :             if ( Q[n] < tmpf )
     935             :             {
     936          99 :                 itdLR[n] = 0;
     937          99 :                 on[n] = 0;
     938          99 :                 peakQ[n] = 0.0f;
     939          99 :                 Q[n] = 0.0f;
     940             :             }
     941       23923 :             else if ( Q[n] > 1.25f * peakQ[n] )
     942             :             {
     943         237 :                 itdLR[n] = itd_cand[n];
     944             :             }
     945             : 
     946       24022 :             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       32878 :             tmpf = ( 0.75f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit );
     951             : 
     952       32878 :             if ( Q[n] < tmpf )
     953             :             {
     954       32642 :                 itdLR[n] = 0;
     955       32642 :                 Q[n] = 0.0f;
     956             :             }
     957             :             else
     958             :             {
     959         236 :                 itdLR[n] = itd_cand[n];
     960         236 :                 on[n] = 1;
     961             :             }
     962             :         }
     963             :     }
     964             : 
     965       28450 :     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           1 :         *itd = ( Q[0] > Q[1] ) ? (float) itdLR[0] : (float) itdLR[1];
     968             :     }
     969       28449 :     else if ( ( on[0] && prev_off[0] ) && ( Q[0] > ( Q[1] - 0.1 ) ) ) /* if channel 0 becomes active, select channel 0*/
     970             :     {
     971         147 :         *itd = (float) itdLR[0];
     972             :     }
     973       28302 :     else if ( ( on[1] && prev_off[1] ) && ( Q[1] > ( Q[0] - 0.1 ) ) ) /*if channel 1 becomes active, selsect channel 1*/
     974             :     {
     975          70 :         *itd = (float) itdLR[1];
     976             :     }
     977       28232 :     else if ( Q[0] > ( Q[1] + Q_BAND ) ) /* if no status change, use Q[]*/
     978             :     {
     979       16560 :         *itd = (float) itdLR[0];
     980             :     }
     981       11672 :     else if ( Q[1] > ( Q[0] + Q_BAND ) ) /* if no status change, use Q[]*/
     982             :     {
     983        1788 :         *itd = (float) itdLR[1];
     984             :     }
     985        9884 :     else if ( *itd == 0.0 ) /*if no channels are likely to be preceding, follow the status of the previous frame*/
     986             :     {
     987        8349 :         *itd = 0;
     988             :     }
     989             :     else /*follow the status of the previous frame*/
     990             :     {
     991        1535 :         *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1];
     992             :     }
     993             : 
     994       28450 :     cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); /*higher value indicates higher confidence for one preceding channel*/
     995             : 
     996       28450 :     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       28450 : 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       28450 :     error = IVAS_ERR_OK;
    1024             : 
    1025       28450 :     n0 = input_frame >> 1;
    1026       28450 :     n1 = input_frame >> 2;
    1027             : 
    1028       28450 :     if ( input_frame == L_FRAME16k )
    1029             :     {
    1030        3000 :         p_w = dft_trigo_32k;
    1031        3000 :         rfft_coef_step = 4;
    1032             :     }
    1033       25450 :     else if ( input_frame == L_FRAME32k )
    1034             :     {
    1035       13175 :         p_w = dft_trigo_32k;
    1036       13175 :         rfft_coef_step = 2;
    1037             :     }
    1038       12275 :     else if ( input_frame == L_FRAME48k )
    1039             :     {
    1040       12275 :         p_w = dft_trigo_48k;
    1041       12275 :         rfft_coef_step = 2;
    1042             :     }
    1043             :     else
    1044             :     {
    1045           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "failed estimate_itd()\n" );
    1046             :     }
    1047             : 
    1048     5322450 :     for ( n = 0; n < n1; n++ )
    1049             :     {
    1050     5294000 :         rfft_coef[n] = p_w[n * rfft_coef_step];
    1051     5294000 :         rfft_coef[n0 - n] = p_w[n * rfft_coef_step];
    1052             :     }
    1053       28450 :     rfft_coef[n1] = p_w[n1 * rfft_coef_step];
    1054             : 
    1055       28450 :     estimate_itd_wnd_fft( srcL, specLr, specLi, rfft_coef, hPOC->wnd, input_frame );
    1056       28450 :     estimate_itd_wnd_fft( srcR, specRr, specRi, rfft_coef, hPOC->wnd, input_frame );
    1057             : 
    1058       28450 :     calc_poc( hPOC, hPHA, hPOC->wnd, rfft_coef, specLr, specLi, specRr, specRi, input_frame );
    1059       28450 :     *corr = find_poc_peak( hPOC, itd, input_frame, STEREO_DMX_EVS_POC_W_FORGETTING );
    1060             : 
    1061       28450 :     return error;
    1062             : }
    1063             : 
    1064             : 
    1065             : /*-------------------------------------------------------------------*
    1066             :  * weighted_ave()
    1067             :  *
    1068             :  * create weighted downmix signal
    1069             :  *-------------------------------------------------------------------*/
    1070             : 
    1071       28450 : 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       28450 :     float gain_tmp = 0.f, gain_sub;
    1085             : 
    1086       28450 :     len = input_frame >> 1;
    1087       28450 :     len2 = input_frame >> 2;
    1088       28450 :     gain_sub = gain - old_gain;
    1089             : 
    1090     5322450 :     for ( i = 0; i < len2; i++ )
    1091             :     {
    1092     5294000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1093     5294000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1094             :     }
    1095     5322450 :     for ( ; i < len; i++ )
    1096             :     {
    1097     5294000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1098     5294000 :         dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp );
    1099             :     }
    1100    10616450 :     for ( ; i < input_frame; i++ )
    1101             :     {
    1102    10588000 :         dst[i] = src1[i] * gain + src2[i] * ( 1.0f - gain_tmp );
    1103             :     }
    1104             : 
    1105             : 
    1106       28450 :     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       29392 : static float spectral_flatness(
    1117             :     const float sig[],      /* i  : input signal               */
    1118             :     const int16_t sigLength /* i  : input signal length        */
    1119             : )
    1120             : {
    1121       29392 :     float geoMean = 0.0f;
    1122       29392 :     float ariMean = 0.0f;
    1123       29392 :     float eps = 1e-10f;
    1124             :     int16_t i;
    1125             : 
    1126             :     /* Initialization */
    1127     5337278 :     for ( i = 0; i < sigLength; i++ )
    1128             :     {
    1129     5307886 :         ariMean += fabsf( sig[i] ) + eps;
    1130     5307886 :         geoMean += logf( fabsf( sig[i] ) + eps );
    1131             :     }
    1132       29392 :     ariMean /= sigLength;
    1133       29392 :     geoMean /= sigLength;
    1134       29392 :     geoMean = expf( geoMean );
    1135             : 
    1136       29392 :     return geoMean / ariMean;
    1137             : }
    1138             : 
    1139             : 
    1140             : /*-------------------------------------------------------------------*
    1141             :  * calc_energy()
    1142             :  *
    1143             :  * calculate energy
    1144             :  *-------------------------------------------------------------------*/
    1145             : 
    1146       85350 : 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       85350 :     E = 0.0f;
    1159       85350 :     adaptlen = input_frame >> 4;
    1160       85350 :     wnd = 0.5f / (float) adaptlen;
    1161       85350 :     wnd_diff = 1.0f / (float) adaptlen;
    1162             : 
    1163     4055850 :     for ( i = 0; i < adaptlen; i++ )
    1164             :     {
    1165     3970500 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1166             : 
    1167     3970500 :         wnd += wnd_diff;
    1168             :     }
    1169    55672350 :     for ( ; i < input_frame - adaptlen; i++ )
    1170             :     {
    1171    55587000 :         E += src1[i] * src2[i];
    1172             :     }
    1173     4055850 :     for ( ; i < input_frame; i++ )
    1174             :     {
    1175     3970500 :         wnd -= wnd_diff;
    1176             : 
    1177     3970500 :         E += ( src1[i] * wnd ) * ( src2[i] * wnd );
    1178             :     }
    1179             : 
    1180       85350 :     *energy = *energy * ratio + ( E / (float) input_frame ) * ( 1.0f - ratio );
    1181             : 
    1182       85350 :     return;
    1183             : }
    1184             : 
    1185             : 
    1186             : /*-------------------------------------------------------------------*
    1187             :  * calc_energy_sgc()
    1188             :  *
    1189             :  * calculate energy for switch gain control
    1190             :  *-------------------------------------------------------------------*/
    1191      113800 : 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      113800 :     *energy = ratio * *energy + ( 1.0f - ratio ) * sum2_f( src, input_frame );
    1199      113800 :     return;
    1200             : }
    1201             : 
    1202             : 
    1203             : /*-------------------------------------------------------------------*
    1204             :  * adapt_gain()
    1205             :  *
    1206             :  * adapt gain to the signal
    1207             :  *-------------------------------------------------------------------*/
    1208             : 
    1209       56900 : 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       56900 :     len = input_frame >> 1;
    1224       56900 :     len2 = input_frame >> 2;
    1225       56900 :     gain_sub = gain - old_gain;
    1226             : 
    1227    10644900 :     for ( i = 0; i < len2; i++ )
    1228             :     {
    1229    10588000 :         gain_tmp = old_gain + gain_sub * wnd[i];
    1230    10588000 :         dst[i] = src[i] * gain_tmp;
    1231             :     }
    1232    10644900 :     for ( ; i < len; i++ )
    1233             :     {
    1234    10588000 :         gain_tmp = old_gain + gain_sub * ( 1.0f - wnd[len - i - 1] );
    1235    10588000 :         dst[i] = src[i] * gain_tmp;
    1236             :     }
    1237             : 
    1238             : 
    1239    21232900 :     for ( ; i < input_frame; i++ )
    1240             :     {
    1241    21176000 :         dst[i] = src[i] * gain;
    1242             :     }
    1243             : 
    1244             : 
    1245       56900 :     return;
    1246             : }
    1247             : 
    1248             : 
    1249             : /*-------------------------------------------------------------------*
    1250             :  * create_M_signal()
    1251             :  *
    1252             :  * create downmix signal
    1253             :  *-------------------------------------------------------------------*/
    1254             : 
    1255       28450 : 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       28450 :     eps = 1024.0f;
    1271       28450 :     Lbias = ( w_prev[2] == 0 ) ? 4.0f : 0.25f;
    1272             : 
    1273       28450 :     weighted_ave( srcL, srcR, dmx, w_curr, w_prev[0], input_frame, wnd );
    1274             : 
    1275       28450 :     calc_energy( srcL, srcL, src_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1276       28450 :     calc_energy( srcR, srcR, src_energy + 1, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1277       28450 :     calc_energy( dmx, dmx, dmx_energy, input_frame, STEREO_DMX_EVS_DMX_EGY_FORGETTING );
    1278             : 
    1279       28450 :     if ( src_energy[0] * Lbias > src_energy[1] )
    1280             :     {
    1281       18858 :         amp_mod[0] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[0] + eps ) );
    1282       18858 :         amp_mod[0] = max( amp_mod[0], 0.0f );
    1283       18858 :         amp_mod[1] = 0.0f;
    1284             :     }
    1285             :     else
    1286             :     {
    1287        9592 :         amp_mod[1] = 1.0f - sqrtf( ( dmx_energy[0] + eps ) / ( src_energy[1] + eps ) );
    1288        9592 :         amp_mod[1] = max( amp_mod[1], 0.0f );
    1289        9592 :         amp_mod[0] = 0.0f;
    1290             :     }
    1291             : 
    1292       28450 :     adapt_gain( srcL, weighted, amp_mod[0], w_prev[1], input_frame, wnd );
    1293       28450 :     v_add( dmx, weighted, dmx, input_frame );
    1294       28450 :     adapt_gain( srcR, weighted, amp_mod[1], w_prev[2], input_frame, wnd );
    1295       28450 :     v_add( dmx, weighted, dmx, input_frame );
    1296             : 
    1297       28450 :     w_prev[0] = w_curr;
    1298       28450 :     w_prev[1] = amp_mod[0];
    1299       28450 :     w_prev[2] = amp_mod[1];
    1300             : 
    1301       28450 :     return;
    1302             : }
    1303             : 
    1304             : 
    1305             : /*-------------------------------------------------------------------*
    1306             :  * apply_gain_sgc()
    1307             :  *
    1308             :  * Apply gain for switching
    1309             :  *-------------------------------------------------------------------*/
    1310             : 
    1311       56900 : 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       56900 :     if ( *gain > STEREO_DMX_EVS_SGC_GH )
    1322             :     {
    1323        1350 :         lr = 1.0f / ratio;
    1324             :     }
    1325       55550 :     else if ( *gain < STEREO_DMX_EVS_SGC_GL )
    1326             :     {
    1327        1176 :         lr = ratio;
    1328             :     }
    1329             :     else
    1330             :     {
    1331       54374 :         return;
    1332             :     }
    1333             : 
    1334     2042526 :     for ( n = 0; n < input_frame; n++ )
    1335             :     {
    1336     2040000 :         data[n] *= *gain;
    1337             :     }
    1338             : 
    1339        2526 :     *gain *= lr;
    1340             : }
    1341             : 
    1342             : 
    1343             : /*-------------------------------------------------------------------*
    1344             :  * stereo_dmx_evs_enc()
    1345             :  *
    1346             :  * Stereo downmix for EVS encoder routine
    1347             :  *-------------------------------------------------------------------*/
    1348             : 
    1349       28450 : 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       28450 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1375       28450 :     hPHA = hStereoDmxEVS->hPHA;
    1376             : 
    1377    21204450 :     for ( n = 0; n < input_frame; n++ )
    1378             :     {
    1379    21176000 :         data_f[0][n] = (float) data[2 * n];
    1380    21176000 :         data_f[1][n] = (float) data[2 * n + 1];
    1381             :     }
    1382       28450 :     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       28450 :     input_subframe = n_samples / STEREO_DMX_EVS_NB_SBFRM;
    1389       28450 :     is_transient = false;
    1390       85350 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1391             :     {
    1392      341400 :         for ( m = 0; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1393             :         {
    1394      284500 :             p_sub_frame = &( data_f[k][m * input_subframe] );
    1395      284500 :             subframe_energy[m] = sum2_f( p_sub_frame, input_subframe );
    1396      284500 :             if ( subframe_energy[m] > hPHA->crst_fctr * ( hPHA->trns_aux_energy[k] + EPSILON ) )
    1397             :             {
    1398         446 :                 is_transient = true;
    1399             :             }
    1400             : 
    1401      284500 :             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      284500 :         for ( m = 1; m < STEREO_DMX_EVS_NB_SBFRM; m++ )
    1405             :         {
    1406      227600 :             if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST )
    1407             :             {
    1408         139 :                 is_transient = true;
    1409             :             }
    1410             :         }
    1411             :     }
    1412             : 
    1413       28450 :     estimate_itd( &corr, hStereoDmxEVS->hPOC, hPHA, data_f[0], data_f[1], &hStereoDmxEVS->itd, input_frame );
    1414             : 
    1415             :     /* poc */
    1416             : 
    1417       28450 :     if ( hStereoDmxEVS->itd )
    1418             :     {
    1419        7185 :         dmx_weight = ( ( hStereoDmxEVS->itd > 0 ) ? ( -1 ) : 1 ) * 0.5f * corr + 0.5f;
    1420             :     }
    1421             :     else
    1422             :     {
    1423       21265 :         dmx_weight = 0.5f;
    1424             :     }
    1425             : 
    1426       28450 :     create_M_signal( data_f[0], data_f[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd,
    1427       28450 :                      hStereoDmxEVS->dmx_weight, hStereoDmxEVS->pre_dmx_energy, hStereoDmxEVS->aux_dmx_energy );
    1428             : 
    1429             :     /* pha */
    1430             : 
    1431       28450 :     pha_len = hPHA->pha_len;
    1432       28450 :     fad_len = hPHA->fad_len;
    1433       28450 :     fad_g = hPHA->fad_g;
    1434             : 
    1435       28450 :     set_zero( dmx_pha_data, n_samples );
    1436       28450 :     set_zero( mem_prev, fad_len );
    1437             : 
    1438       85350 :     for ( k = 0; k < CPE_CHANNELS; k++ )
    1439             :     {
    1440       56900 :         p_data = data_f[k];
    1441       56900 :         mvr2r( hPHA->data_mem[k], data_mem, pha_len );
    1442       56900 :         mvr2r( &( p_data[n_samples - pha_len] ), hPHA->data_mem[k], pha_len );
    1443       56900 :         p_data_mem = &( data_mem[pha_len] );
    1444       56900 :         mvr2r( p_data, p_data_mem, n_samples );
    1445             : 
    1446       56900 :         p_prev_taps = hPHA->p_prev_taps[k];
    1447       56900 :         if ( p_prev_taps )
    1448             :         {
    1449    20991542 :             for ( n = 0; n < fad_len; n++ )
    1450             :             {
    1451  1003483840 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1452             :                 {
    1453   982548480 :                     ftmp += p_data_mem[n - m] * p_prev_taps[m];
    1454             :                 }
    1455    20935360 :                 mem_prev[n] += ftmp * INV_SQRT_2;
    1456             :             }
    1457             :         }
    1458             :         else
    1459             :         {
    1460      241358 :             for ( n = 0; n < fad_len; n++ )
    1461             :             {
    1462      240640 :                 mem_prev[n] += p_data[n] * INV_SQRT_2;
    1463             :             }
    1464             :         }
    1465             : 
    1466       56900 :         p_curr_taps = hPHA->p_curr_taps[k];
    1467       56900 :         if ( p_curr_taps )
    1468             :         {
    1469    42052578 :             for ( n = 0; n < n_samples; n++ )
    1470             :             {
    1471  2012192640 :                 for ( ftmp = 0, m = 0; m < pha_len; m++ )
    1472             :                 {
    1473  1970196480 :                     ftmp += p_data_mem[n - m] * p_curr_taps[m];
    1474             :                 }
    1475    41996160 :                 dmx_pha_data[n] += ftmp * INV_SQRT_2;
    1476             :             }
    1477             :         }
    1478             :         else
    1479             :         {
    1480      356322 :             for ( n = 0; n < n_samples; n++ )
    1481             :             {
    1482      355840 :                 dmx_pha_data[n] += p_data[n] * INV_SQRT_2;
    1483             :             }
    1484             :         }
    1485             :     }
    1486             : 
    1487    10616450 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- )
    1488             :     {
    1489    10588000 :         dmx_pha_data[n] *= fad_g[n];
    1490    10588000 :         dmx_pha_data[n] += ( mem_prev[n] ) * fad_g[m];
    1491             :     }
    1492             : 
    1493             :     /* prc switch */
    1494             : 
    1495       28450 :     prev_prc = hPHA->curr_prc;
    1496       28450 :     if ( abs( (int16_t) hStereoDmxEVS->itd ) > hPHA->prc_thres )
    1497             :     {
    1498        2389 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_POC )
    1499             :         {
    1500           8 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_POC )
    1501             :             {
    1502           4 :                 hPHA->prc_hys_cnt += 1;
    1503             :             }
    1504             :             else
    1505             :             {
    1506           4 :                 hPHA->prc_hys_cnt = 0;
    1507             :             }
    1508             : 
    1509           8 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1510             :             {
    1511           4 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1512             :             }
    1513             :         }
    1514        2389 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1515             :     }
    1516             :     else
    1517             :     {
    1518       26061 :         if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_PHA )
    1519             :         {
    1520       23432 :             if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_PHA )
    1521             :             {
    1522       23289 :                 hPHA->prc_hys_cnt += 1;
    1523             :             }
    1524             :             else
    1525             :             {
    1526         143 :                 hPHA->prc_hys_cnt = 0;
    1527             :             }
    1528             : 
    1529       23432 :             if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES )
    1530             :             {
    1531       23289 :                 hPHA->curr_prc = STEREO_DMX_EVS_PRC_PHA;
    1532             :             }
    1533             :         }
    1534       26061 :         hPHA->prev_prc = STEREO_DMX_EVS_PRC_PHA;
    1535             :     }
    1536             : 
    1537       28450 :     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       25222 :         hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1540       25222 :         hPHA->prc_hys_cnt = 0;
    1541             :     }
    1542             : 
    1543       28450 :     calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1544       28450 :     calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1545             : 
    1546       28450 :     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          90 :         if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1549             :         {
    1550          46 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1551          46 :             calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1552             : 
    1553          46 :             hPHA->dmx_poc_gain_sgc = sqrtf( hPHA->dmx_pha_ener_sgc / ( hPHA->dmx_poc_ener + EPSILON ) );
    1554          46 :             hPHA->dmx_poc_gain_sgc = min( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1555          46 :             hPHA->dmx_poc_gain_sgc = max( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1556             : 
    1557          46 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1558          46 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1559             :         }
    1560             :         else
    1561             :         {
    1562          44 :             apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1563          44 :             calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1564             : 
    1565          44 :             hPHA->dmx_pha_gain_sgc = sqrtf( hPHA->dmx_poc_ener_sgc / ( hPHA->dmx_pha_ener + EPSILON ) );
    1566          44 :             hPHA->dmx_pha_gain_sgc = min( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMAX );
    1567          44 :             hPHA->dmx_pha_gain_sgc = max( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMIN );
    1568             : 
    1569          44 :             apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1570          44 :             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       28360 :         apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1576       28360 :         calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1577             : 
    1578       28360 :         apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples );
    1579       28360 :         calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING );
    1580             :     }
    1581             : 
    1582       28450 :     if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC )
    1583             :     {
    1584       25813 :         p_dmx_data = dmx_poc_data;
    1585       25813 :         p_dmx_data_fo = dmx_pha_data;
    1586             :     }
    1587             :     else
    1588             :     {
    1589        2637 :         p_dmx_data = dmx_pha_data;
    1590        2637 :         p_dmx_data_fo = dmx_poc_data;
    1591             :     }
    1592             : 
    1593       28450 :     n_fad_r = is_transient ? 1 : STEREO_DMX_EVS_FAD_R;
    1594             : 
    1595       28450 :     if ( prev_prc != hPHA->curr_prc )
    1596             :     {
    1597         506 :         if ( hPHA->n_fad_g == input_frame )
    1598             :         {
    1599         483 :             hPHA->n_fad_g = 0;
    1600         483 :             hPHA->n_fad_cnt = 0;
    1601             :         }
    1602             :         else
    1603             :         {
    1604          23 :             hPHA->n_fad_g = input_frame - hPHA->n_fad_g - 1;
    1605          23 :             hPHA->n_fad_cnt = 0;
    1606             :         }
    1607             :     }
    1608       27944 :     else if ( is_transient )
    1609             :     {
    1610         285 :         hPHA->n_fad_cnt = 0;
    1611             :     }
    1612             : 
    1613       28450 :     fad_len = min( n_samples, ( ( input_frame * n_fad_r ) - ( hPHA->n_fad_g * n_fad_r + hPHA->n_fad_cnt ) ) );
    1614             : 
    1615       28450 :     if ( fad_len != 0 )
    1616             :     {
    1617        1425 :         fad_g = hPHA->fad_g_prc;
    1618        1425 :         n_fad_g = hPHA->n_fad_g;
    1619        1425 :         n_fad_cnt = hPHA->n_fad_cnt;
    1620        1425 :         m_fad_g = input_frame - n_fad_g - 1;
    1621             : 
    1622        1425 :         if ( n_fad_r == 1 )
    1623             :         {
    1624          31 :             n_fad_cnt = 0;
    1625       18068 :             for ( n = 0; n < fad_len; n++ )
    1626             :             {
    1627       18037 :                 p_dmx_data[n] *= fad_g[n_fad_g++];
    1628       18037 :                 p_dmx_data[n] += fad_g[m_fad_g--] * p_dmx_data_fo[n];
    1629             :             }
    1630             :         }
    1631             :         else
    1632             :         {
    1633        1394 :             n = 0;
    1634        1394 :             sbfad_len = 0;
    1635        1394 :             if ( n_fad_cnt != 0 )
    1636             :             {
    1637         602 :                 sbfad_len = min( fad_len, n_fad_r - n_fad_cnt );
    1638        1509 :                 for ( ; n < sbfad_len; n++ )
    1639             :                 {
    1640         907 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1641         907 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1642             :                 }
    1643         602 :                 n_fad_cnt = 0;
    1644         602 :                 n_fad_g++;
    1645         602 :                 m_fad_g--;
    1646             :             }
    1647             : 
    1648        1394 :             sbfad_len = (int16_t) ( ( fad_len - sbfad_len ) / n_fad_r );
    1649      308100 :             for ( k = 0; k < sbfad_len; k++ )
    1650             :             {
    1651     1226824 :                 for ( m = 0; m < n_fad_r; m++ )
    1652             :                 {
    1653      920118 :                     p_dmx_data[n] *= fad_g[n_fad_g];
    1654      920118 :                     p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1655      920118 :                     n++;
    1656             :                 }
    1657      306706 :                 n_fad_g++;
    1658      306706 :                 m_fad_g--;
    1659             :             }
    1660             : 
    1661        2313 :             for ( ; n < fad_len; n++ )
    1662             :             {
    1663         919 :                 p_dmx_data[n] *= fad_g[n_fad_g];
    1664         919 :                 p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n];
    1665         919 :                 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        1425 :         hPHA->n_fad_g = n_fad_g;
    1675        1425 :         hPHA->n_fad_cnt = n_fad_cnt;
    1676             :     }
    1677             : 
    1678       28450 :     mvr2s( p_dmx_data, data, n_samples );
    1679             : 
    1680             : 
    1681       28450 :     return;
    1682             : }
    1683             : 
    1684             : 
    1685             : /*-------------------------------------------------------------------*
    1686             :  * stereo_dmx_evs_init_encoder()
    1687             :  *
    1688             :  * open and initialize stereo downmix for EVS encoder
    1689             :  *-------------------------------------------------------------------*/
    1690             : 
    1691         118 : 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         118 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
    1704             : 
    1705         118 :     hStereoDmxEVS = NULL;
    1706         118 :     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         118 :     hStereoDmxEVS->itd = 0.0f;
    1712         118 :     hStereoDmxEVS->pre_dmx_energy[0] = 0.0f;
    1713         354 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1714             :     {
    1715         236 :         hStereoDmxEVS->aux_dmx_energy[n] = 0.0f;
    1716             :     }
    1717             : 
    1718         118 :     hStereoDmxEVS->dmx_weight[0] = 0.5f;
    1719         118 :     hStereoDmxEVS->dmx_weight[1] = 0.0f;
    1720         118 :     hStereoDmxEVS->dmx_weight[2] = 0.0f;
    1721             : 
    1722         118 :     if ( input_frame == L_FRAME16k )
    1723             :     {
    1724          60 :         hStereoDmxEVS->s_wnd = Stereo_dmx_s_wnd_coef_16k;
    1725             :     }
    1726          58 :     else if ( input_frame == L_FRAME32k )
    1727             :     {
    1728          38 :         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         118 :     hStereoDmxEVS->hPOC = NULL;
    1740         118 :     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         118 :     hStereoDmxEVS->hPOC->shift_limit = NS2SA( input_Fs, STEREO_DMX_EVS_SHIFT_LIMIT );
    1746             : 
    1747         354 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1748             :     {
    1749         236 :         hStereoDmxEVS->hPOC->peakQ[n] = 0.0f;
    1750         236 :         hStereoDmxEVS->hPOC->peak_width[n] = (float) hStereoDmxEVS->hPOC->shift_limit / 2;
    1751         236 :         hStereoDmxEVS->hPOC->ispeak[n] = 0;
    1752         236 :         hStereoDmxEVS->hPOC->itdLR[n] = 0;
    1753             :     }
    1754         118 :     set_f( hStereoDmxEVS->hPOC->P, 0.0f, L_FRAME48k );
    1755             : 
    1756         118 :     if ( input_frame == L_FRAME16k )
    1757             :     {
    1758          60 :         hStereoDmxEVS->hPOC->wnd = Stereo_dmx_wnd_coef_48k;
    1759             :     }
    1760          58 :     else if ( input_frame == L_FRAME32k )
    1761             :     {
    1762          38 :         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         118 :     hStereoDmxEVS->hPOC->eps = 2.0f * EVS_PI / ( (float) input_frame );
    1773             : 
    1774         118 :     if ( input_frame == L_FRAME16k )
    1775             :     {
    1776          60 :         hStereoDmxEVS->hPOC->sin = dft_trigo_32k;
    1777             :     }
    1778          58 :     else if ( input_frame == L_FRAME32k )
    1779             :     {
    1780          38 :         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         118 :     hStereoDmxEVS->hPOC->confidence = 0.0f;
    1792             : 
    1793         118 :     hStereoDmxEVS->hPHA = NULL;
    1794         118 :     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         354 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1800             :     {
    1801         236 :         hStereoDmxEVS->hPHA->p_curr_taps[n] = NULL;
    1802         236 :         hStereoDmxEVS->hPHA->p_prev_taps[n] = NULL;
    1803             : 
    1804         236 :         set_zero( hStereoDmxEVS->hPHA->data_mem[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1805         236 :         set_zero( hStereoDmxEVS->hPHA->curr_taps[n], STEREO_DMX_EVS_PHA_LEN_MAX );
    1806             :     }
    1807             : 
    1808         118 :     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          58 :     else if ( input_Fs == 32000 )
    1817             :     {
    1818          38 :         len = STEREO_DMX_EVS_PHA_LEN_32;
    1819          38 :         hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_32;
    1820          38 :         hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_32;
    1821          38 :         hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_32;
    1822          38 :         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         118 :     hStereoDmxEVS->hPHA->pha_len = len / 2;
    1838         118 :     hStereoDmxEVS->hPHA->isd_rate_s = 0.0f;
    1839         118 :     hStereoDmxEVS->hPHA->iccr_s = 0.0f;
    1840             : 
    1841         118 :     pha_len = hStereoDmxEVS->hPHA->pha_len;
    1842         118 :     fad_len = hStereoDmxEVS->hPHA->fad_len;
    1843             : 
    1844         118 :     trans_len = (int16_t) ( (float) pha_len / 20.0f );
    1845         118 :     set_f( hStereoDmxEVS->hPHA->win, STEREO_DMX_EVS_PHA_WND_C, pha_len - trans_len );
    1846         118 :     hStereoDmxEVS->hPHA->win[0] = 1.0f;
    1847         118 :     tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 );
    1848         118 :     win = &( hStereoDmxEVS->hPHA->win[pha_len - trans_len] );
    1849         294 :     for ( n = 0; n < trans_len; n++ )
    1850             :     {
    1851         176 :         win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * STEREO_DMX_EVS_PHA_WND_C;
    1852             :     }
    1853             : 
    1854         118 :     fad_g = hStereoDmxEVS->hPHA->fad_g;
    1855         118 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1856         118 :     fad_len2 = fad_len / 2;
    1857       15798 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1858             :     {
    1859       15680 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1860       15680 :         fad_g[m] = 1.0f - fad_g[n];
    1861             :     }
    1862             : 
    1863         118 :     hStereoDmxEVS->hPHA->curr_pha = STEREO_DMX_EVS_PHA_IPD;
    1864         118 :     hStereoDmxEVS->hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD;
    1865         118 :     hStereoDmxEVS->hPHA->pha_hys_cnt = 0;
    1866             : 
    1867             : 
    1868         118 :     hStereoDmxEVS->hPHA->pha_ipd_chan_cnt = 0;
    1869         118 :     hStereoDmxEVS->hPHA->pha_ipd_chan_thresh = 10;
    1870         118 :     hStereoDmxEVS->hPHA->pha_ipd_ild_thresh = STEREO_DMX_EVS_IPD_ILD_THRES;
    1871         118 :     hStereoDmxEVS->hPHA->pha_ipd_chan2rephase = 1;
    1872         118 :     hStereoDmxEVS->hPHA->pha_ipd_previouschan2rephase = 1;
    1873         118 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch = 0;
    1874         118 :     hStereoDmxEVS->hPHA->pha_ipd_chanswitch_allowed = 0;
    1875         118 :     hStereoDmxEVS->hPHA->pha_ipd_sf_Threshold = STEREO_DMX_EVS_IPD_SF_THRES;
    1876             : 
    1877         118 :     hStereoDmxEVS->hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD;
    1878         118 :     hStereoDmxEVS->hPHA->force_poc = FALSE;
    1879             : 
    1880             :     /* Compute the forgetting factor */
    1881         118 :     itrh = (int16_t) ( ( STEREO_DMX_EVS_IFF_FREQ * input_frame ) / ( input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE ) );
    1882         118 :     n0 = L_FRAME16k / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1883         118 :     a_step = ( STEREO_DMX_EVS_IFF_AMIN - STEREO_DMX_EVS_IFF_AMAX ) / ( n0 + 1 - itrh );
    1884         118 :     ipd_ff = hStereoDmxEVS->hPHA->ipd_ff;
    1885        3658 :     for ( n = 0; n < itrh; n++ )
    1886             :     {
    1887        3540 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX;
    1888             :     }
    1889        6136 :     for ( ; n < ( n0 + 1 ); n++ ) /* 8kHz */
    1890             :     {
    1891        6018 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX + ( n - itrh ) * a_step;
    1892             :     }
    1893       18880 :     for ( ; n < STEREO_DMX_EVS_NB_SUBBAND_MAX; n++ )
    1894             :     {
    1895       18762 :         ipd_ff[n] = STEREO_DMX_EVS_IFF_AMIN;
    1896             :     }
    1897         118 :     set_f( hStereoDmxEVS->hPHA->Pr, 1.0, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1898         118 :     set_zero( hStereoDmxEVS->hPHA->Pi, STEREO_DMX_EVS_NB_SUBBAND_MAX );
    1899             : 
    1900         118 :     n0 = input_frame / ( 4 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1901         118 :     input_frame_pha = input_frame / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE );
    1902             : 
    1903         118 :     if ( input_frame == L_FRAME16k )
    1904             :     {
    1905          60 :         p_ipd_w = dft_trigo_32k;
    1906          60 :         rfft_ipd_coef_step = 4;
    1907             :     }
    1908          58 :     else if ( input_frame == L_FRAME32k )
    1909             :     {
    1910          38 :         p_ipd_w = dft_trigo_32k;
    1911          38 :         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         118 :     win = hStereoDmxEVS->hPHA->rfft_ipd_coef;
    1924         118 :     len = rfft_ipd_coef_step * STEREO_DMX_EVS_SUBBAND_SIZE;
    1925        7958 :     for ( n = 0; n < n0; n++ )
    1926             :     {
    1927        7840 :         win[n] = p_ipd_w[n * len];
    1928        7840 :         win[input_frame_pha - n] = p_ipd_w[n * len];
    1929             :     }
    1930         118 :     win[n0] = p_ipd_w[n0 * len];
    1931             : 
    1932         118 :     hStereoDmxEVS->hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC;
    1933         118 :     hStereoDmxEVS->hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC;
    1934         118 :     hStereoDmxEVS->hPHA->prc_hys_cnt = 0;
    1935             : 
    1936         118 :     fad_len = input_frame;
    1937             : 
    1938         118 :     fad_g = hStereoDmxEVS->hPHA->fad_g_prc;
    1939         118 :     fad_r = 1.0f / (float) ( fad_len + 1 );
    1940         118 :     fad_len2 = fad_len / 2;
    1941       31478 :     for ( n = 0, m = ( fad_len - 1 ); n < fad_len2; n++, m-- )
    1942             :     {
    1943       31360 :         fad_g[n] = (float) ( n + 1 ) * fad_r;
    1944       31360 :         fad_g[m] = 1.0f - fad_g[n];
    1945             :     }
    1946             : 
    1947         354 :     for ( n = 0; n < CPE_CHANNELS; n++ )
    1948             :     {
    1949         236 :         hStereoDmxEVS->hPHA->trns_aux_energy[n] = 0.0f;
    1950             :     }
    1951             : 
    1952             : 
    1953         118 :     hStereoDmxEVS->hPHA->n_fad_g = input_frame;
    1954         118 :     hStereoDmxEVS->hPHA->n_fad_cnt = 0;
    1955             : 
    1956         118 :     hStereoDmxEVS->hPHA->dmx_pha_ener_sgc = 0.0f;
    1957         118 :     hStereoDmxEVS->hPHA->dmx_poc_ener_sgc = 0.0f;
    1958         118 :     hStereoDmxEVS->hPHA->dmx_pha_gain_sgc = 1.0f;
    1959         118 :     hStereoDmxEVS->hPHA->dmx_poc_gain_sgc = 1.0f;
    1960             : 
    1961         118 :     hStereoDmxEVS->hPHA->dmx_pha_ener = 0.0f;
    1962         118 :     hStereoDmxEVS->hPHA->dmx_poc_ener = 0.0f;
    1963             : 
    1964             : 
    1965         118 :     *hStereoDmxEVS_out = hStereoDmxEVS;
    1966             : 
    1967         118 :     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        4269 : void stereo_dmx_evs_close_encoder(
    1978             :     STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle    */
    1979             : )
    1980             : {
    1981        4269 :     if ( hStereoDmxEVS == NULL || *hStereoDmxEVS == NULL )
    1982             :     {
    1983        4151 :         return;
    1984             :     }
    1985             : 
    1986         118 :     if ( ( *hStereoDmxEVS )->hPOC != NULL )
    1987             :     {
    1988         118 :         free( ( *hStereoDmxEVS )->hPOC );
    1989         118 :         ( *hStereoDmxEVS )->hPOC = NULL;
    1990             :     }
    1991             : 
    1992         118 :     if ( ( *hStereoDmxEVS )->hPHA != NULL )
    1993             :     {
    1994         118 :         free( ( *hStereoDmxEVS )->hPHA );
    1995         118 :         ( *hStereoDmxEVS )->hPHA = NULL;
    1996             :     }
    1997             : 
    1998         118 :     free( ( *hStereoDmxEVS ) );
    1999         118 :     ( *hStereoDmxEVS ) = NULL;
    2000             : 
    2001         118 :     return;
    2002             : }

Generated by: LCOV version 1.14