LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_ica_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 1216 1311 92.8 %
Date: 2025-06-27 02:59:36 Functions: 13 13 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 <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "ivas_cnst.h"
      39             : #include "prot_fx.h"
      40             : #include "wmc_auto.h"
      41             : #include "rom_com.h"
      42             : #include "ivas_rom_com.h"
      43             : 
      44             : #include "ivas_prot_fx.h"
      45             : #include "ivas_rom_com_fx.h"
      46             : 
      47             : /*---------------------------------------------------------------
      48             :  * Local function prototypes
      49             :  * ---------------------------------------------------------------*/
      50             : static void unclr_calc_corr_features_fx(
      51             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle                             */
      52             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: ICA Stereo Encoder handle                            */
      53             :     Word32 buf1[],                        /* i  : left channel                                         q_com*/
      54             :     Word32 buf2[],                        /* i  : right channel                                        q_com*/
      55             :     Word16 q_com,
      56             :     const Word16 length, /* i  : length of input signal buffers                       Q0*/
      57             :     Word32 corrEst[],    /* i  : buffer containing inter-channel correlation values   Q31-corrEst_exp*/
      58             :     Word16 corrEst_exp,
      59             :     const Word16 lagSearchRange[], /* i  : minimum and maximum lags for corrEst[]               Q0*/
      60             :     Word32 *corrEst_ncorr,         /* o  : norm. x-correlation btw. current and previous correlation buffers Q31-corrEst_ncorr_exp*/
      61             :     Word16 *corrEst_ncorr_exp );
      62             : 
      63             : 
      64             : #define XL_BIAS_FX_Q15            6554
      65             : #define XH_BIAS_FX_Q15            13107
      66             : #define XL_WIDTH_FX_Q15           3932
      67             : #define XH_WIDTH_FX_Q15           4915
      68             : #define SMOOTH_DIST_FACTOR_FX_Q15 13107
      69             : #define A_BIAS_FX_Q15             3277
      70             : #define B_BIAS_FX_Q15             -16384
      71             : #define A_WIDTH_FX_Q31            32212264
      72             : #define B_WIDTH_FX_Q31            32212192
      73             : #define SMOOTH_ENV_FACTOR_FX_Q15  19661
      74             : 
      75             : 
      76             : /*---------------------------------------------------------------
      77             :  * tcaTargetCh_LA()
      78             :  *
      79             :  * Temporal channel adjustment of LA samples in target channel
      80             :  * ---------------------------------------------------------------*/
      81          94 : static void tcaTargetCh_LA_fx(
      82             :     STEREO_TCA_ENC_HANDLE hStereoTCA,
      83             :     Word32 *ptrChanL, /* q_com */
      84             :     Word32 *ptrChanR, /* q_com */
      85             :     Word16 *q_com,
      86             :     const Word16 currentNCShift, /* Q0 */
      87             :     const Word16 input_frame /* Q0 */ )
      88             : {
      89             :     Word16 i, j;
      90             :     Word16 tempS, temp, sine_inp;
      91             :     Word32 tempF1, tempF2, gAdj;
      92             :     Word16 tempF1_exp, tempF2_exp, gAdj_exp;
      93             : 
      94             :     Word32 *ref, *target;
      95             :     Word16 ref_exp, target_exp, target_exp_temp[L_FRAME48k + L_FRAME48k];
      96             :     Word16 win[240]; /* 5 ms at 48 kHz */
      97             : 
      98          94 :     ref_exp = sub( 31, *q_com );
      99          94 :     target_exp = sub( 31, *q_com );
     100          94 :     set16_fx( target_exp_temp, target_exp, L_FRAME48k + currentNCShift );
     101             : 
     102          94 :     IF( EQ_16( hStereoTCA->refChanIndx, L_CH_INDX ) )
     103             :     {
     104          76 :         ref = ptrChanL;
     105          76 :         target = ptrChanR;
     106             :     }
     107             :     ELSE
     108             :     {
     109          18 :         ref = ptrChanR;
     110          18 :         target = ptrChanL;
     111             :     }
     112             : 
     113          94 :     tempS = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS );
     114          94 :     tempF1 = 0;
     115          94 :     move32();
     116          94 :     tempF1_exp = 0;
     117          94 :     move32();
     118          94 :     tempF2 = 0;
     119          94 :     move32();
     120          94 :     tempF2_exp = 0;
     121          94 :     move16();
     122       55668 :     FOR( i = 0; i < ( input_frame - currentNCShift ); i++ )
     123             :     {
     124       55574 :         tempF1 = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, L_abs( ref[i] ), ref_exp, &tempF1_exp );                        /* Q31-tempF1_exp */
     125       55574 :         tempF2 = BASOP_Util_Add_Mant32Exp( tempF2, tempF2_exp, L_abs( target[i + currentNCShift] ), target_exp, &tempF2_exp ); /* Q31-tempF2_exp */
     126             :     }
     127             : 
     128          94 :     IF( tempF1 == 0 )
     129             :     {
     130           0 :         gAdj = ONE_IN_Q31; /* Q31 */
     131           0 :         move32();
     132           0 :         gAdj_exp = 0;
     133           0 :         move16();
     134             :     }
     135             :     ELSE
     136             :     {
     137          94 :         Word32 deno = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, -21475 /*0.00001f in Q31*/, 0, &temp ); /* Q31-temp */
     138             :         Word16 deno_exp;
     139          94 :         IF( deno > 0 )
     140             :         {
     141          94 :             deno = tempF1;
     142          94 :             move32();
     143          94 :             deno_exp = tempF1_exp;
     144          94 :             move16();
     145             :         }
     146             :         ELSE
     147             :         {
     148           0 :             deno = 21475;
     149           0 :             move32();
     150           0 :             deno_exp = 0;
     151           0 :             move16();
     152             :         }
     153          94 :         gAdj = BASOP_Util_Divide3232_Scale_newton( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */
     154          94 :         gAdj_exp = add( gAdj_exp, sub( tempF2_exp, deno_exp ) );
     155             :     }
     156             : 
     157        2034 :     FOR( i = 0; i < tempS; i++ )
     158             :     {
     159        1940 :         sine_inp = BASOP_Util_Divide1616_Scale( add( shl( i, 10 ), 512 /* 0.5 Q10 */ ), shl( tempS, 1 ), &temp ); /* Q15-(temp+(15-10)) */
     160        1940 :         sine_inp = shl_sat( sine_inp, add( temp, -10 ) );                                                         /*Q0*/
     161        1940 :         win[i] = getSineWord16R2( shr( sine_inp, 1 ) );                                                           /*Q15*/
     162        1940 :         move16();
     163             :     }
     164             : 
     165          94 :     j = 0;
     166          94 :     move16();
     167             : 
     168          94 :     Word16 exp_com = target_exp_temp[0];
     169          94 :     move16();
     170        2034 :     FOR( i = ( input_frame - ( currentNCShift + tempS ) ); i < ( input_frame - currentNCShift ); ( i++, j++ ) )
     171             :     {
     172        1940 :         target[i + currentNCShift] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( Mpy_32_16_1( gAdj, win[j] ), ref[i] ), add( ref_exp, gAdj_exp ), Mpy_32_16_1( target[i + currentNCShift], sub( MAX_16, win[j] ) ), target_exp, &temp ); /* Q31-temp */
     173        1940 :         move32();
     174        1940 :         target_exp_temp[i + currentNCShift] = temp;
     175        1940 :         move16();
     176        1940 :         exp_com = s_max( exp_com, temp );
     177             :     }
     178             : 
     179        6600 :     FOR( ; i < input_frame; i++ )
     180             :     {
     181        6506 :         target[i + currentNCShift] = Mpy_32_32( gAdj, ref[i] ); /* Q31-target_exp_temp */
     182        6506 :         move32();
     183        6506 :         target_exp_temp[i + currentNCShift] = add( gAdj_exp, ref_exp );
     184        6506 :         move16();
     185        6506 :         exp_com = s_max( exp_com, target_exp_temp[i + currentNCShift] );
     186             :     }
     187             : 
     188       68680 :     FOR( i = 0; i < input_frame + currentNCShift; i++ )
     189             :     {
     190       68586 :         target[i] = L_shl( target[i], sub( target_exp_temp[i], exp_com ) ); /* Q31-exp_com */
     191       68586 :         move32();
     192       68586 :         ref[i] = L_shl( ref[i], sub( ref_exp, exp_com ) ); /* Q31-exp_com */
     193       68586 :         move32();
     194             :     }
     195          94 :     *q_com = sub( 31, exp_com );
     196          94 :     move16();
     197             : 
     198          94 :     return;
     199             : }
     200             : /*---------------------------------------------------------------
     201             :  * spectral_balancer()
     202             :  *
     203             :  * Spectral-balancer to take care of the low-freq rumble and
     204             :  * compensate for the pre-emphasis.
     205             :  * ---------------------------------------------------------------*/
     206         148 : void spectral_balancer_fx16(
     207             :     Word16 *signal,        /* i/o  : signal  Qx                   */
     208             :     Word16 *mem,           /* i/o  : mem  Qx                      */
     209             :     const Word16 lg,       /* i  : input signal length            Q0*/
     210             :     const Word16 coeff_set /* i  : coefficient set                Q0*/
     211             : )
     212             : {
     213             :     Word16 i;
     214             :     Word16 x0, x1, x2, y0, y1, y2;
     215             :     Word32 a1, a2, b0, b1, b2;
     216             : 
     217         148 :     y1 = mem[0];
     218         148 :     y2 = mem[1];
     219         148 :     x0 = mem[2];
     220         148 :     x1 = mem[3];
     221         148 :     move16();
     222         148 :     move16();
     223         148 :     move16();
     224         148 :     move16();
     225             : 
     226             :     /* hp filter 60Hz at 3dB for 8000KHz sampling rate
     227             :             1. [b,a] = butter(1, 60.0/8000.0, 'high');
     228             :             2. spectral_balancing_filter
     229             :             <<gain = 0.97697627795388164   -> maybe not needed>>
     230             :             b =[1, -1] [1, -0.6]
     231             :             a =[1, -0.95395255590776329] [1, 0.5] */
     232         148 :     IF( coeff_set == 0 )
     233             :     {
     234             :         // a1 = 0.747789178258504f;
     235             :         // a2 = -0.272214937925007f;
     236             :         // b0 = 0.505001029045878f;
     237             :         // b1 = -1.01000205809176f;
     238             :         // b2 = 0.505001029045878f;
     239           0 :         a1 = 401466258; // Q29
     240           0 :         move32();
     241           0 :         a2 = -146144282; // Q29
     242           0 :         move32();
     243           0 :         b0 = 271120363; // Q29
     244           0 :         move32();
     245           0 :         b1 = -542240726; // Q29
     246           0 :         move32();
     247           0 :         b2 = 271120363; // Q29
     248           0 :         move32();
     249             :     }
     250             :     ELSE
     251             :     {
     252             :         // a1 = -0.13456126833218354f;
     253             :         // a2 = -0.38813694706072926f;
     254             :         // b0 = 1.0f;
     255             :         // b1 = -1.9980666374183167f;
     256             :         // b2 = 1.0f;
     257         148 :         a1 = -72242031; // Q29
     258         148 :         move32();
     259         148 :         a2 = -208379437; // Q29
     260         148 :         move32();
     261         148 :         b0 = 536870912; // Q29
     262         148 :         move32();
     263         148 :         b1 = -1072703858; // Q29
     264         148 :         move32();
     265         148 :         b2 = 536870912; // Q29
     266         148 :         move32();
     267             :     }
     268             : 
     269       96148 :     FOR( i = 0; i < lg; i++ )
     270             :     {
     271       96000 :         x2 = x1; /*Qx*/
     272       96000 :         move16();
     273       96000 :         x1 = x0; /*Qx*/
     274       96000 :         move16();
     275       96000 :         x0 = signal[i]; /*Qx*/
     276       96000 :         move16();
     277             :         // y0 = (y1 * a1) + (y2 * a2) + (x0 * b0) + (x1 * b1) + (x2 * b2);
     278       96000 :         y0 = extract_l( W_extract_l( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx
     279       96000 :         signal[i] = y0;                                                                                                                                                   /*Qx*/
     280       96000 :         move16();
     281       96000 :         y2 = y1; /*Qx*/
     282       96000 :         move16();
     283       96000 :         y1 = y0; /*Qx*/
     284       96000 :         move16();
     285             :     }
     286             : 
     287         148 :     mem[0] = y1; /*Qx*/
     288         148 :     mem[1] = y2; /*Qx*/
     289         148 :     mem[2] = x0; /*Qx*/
     290         148 :     mem[3] = x1; /*Qx*/
     291         148 :     move16();
     292         148 :     move16();
     293         148 :     move16();
     294         148 :     move16();
     295             : 
     296         148 :     return;
     297             : }
     298             : 
     299        7622 : void spectral_balancer_fx(
     300             :     Word32 *signal,        /* i/o  : signal  Qx                   */
     301             :     Word32 *mem,           /* i/o  : mem  Qx                      */
     302             :     const Word16 lg,       /* i  : input signal length            Q0*/
     303             :     const Word16 coeff_set /* i  : coefficient set                Q0*/
     304             : )
     305             : {
     306             :     Word16 i;
     307             :     Word32 x0, x1, x2, y0, y1, y2;
     308             :     Word32 a1, a2, b0, b1, b2;
     309             : 
     310        7622 :     y1 = mem[0]; /*Qx*/
     311        7622 :     y2 = mem[1]; /*Qx*/
     312        7622 :     x0 = mem[2]; /*Qx*/
     313        7622 :     x1 = mem[3]; /*Qx*/
     314        7622 :     move32();
     315        7622 :     move32();
     316        7622 :     move32();
     317        7622 :     move32();
     318             : 
     319             :     /* hp filter 60Hz at 3dB for 8000KHz sampling rate
     320             :             1. [b,a] = butter(1, 60.0/8000.0, 'high');
     321             :             2. spectral_balancing_filter
     322             :             <<gain = 0.97697627795388164   -> maybe not needed>>
     323             :             b =[1, -1] [1, -0.6]
     324             :             a =[1, -0.95395255590776329] [1, 0.5] */
     325        7622 :     IF( coeff_set == 0 )
     326             :     {
     327        7622 :         a1 = 401466258; // Q29
     328        7622 :         move32();
     329        7622 :         a2 = -146144282; // Q29
     330        7622 :         move32();
     331        7622 :         b0 = 271120363; // Q29
     332        7622 :         move32();
     333        7622 :         b1 = -542240726; // Q29
     334        7622 :         move32();
     335        7622 :         b2 = 271120363; // Q29
     336        7622 :         move32();
     337             :     }
     338             :     ELSE
     339             :     {
     340           0 :         a1 = -72242031; // Q29
     341           0 :         move32();
     342           0 :         a2 = -208379437; // Q29
     343           0 :         move32();
     344           0 :         b0 = 536870912; // Q29
     345           0 :         move32();
     346           0 :         b1 = -1072703858; // Q29
     347           0 :         move32();
     348           0 :         b2 = 536870912; // Q29
     349           0 :         move32();
     350             :     }
     351             : 
     352     1227142 :     FOR( i = 0; i < lg; i++ )
     353             :     {
     354     1219520 :         x2 = x1; /*Qx*/
     355     1219520 :         move16();
     356     1219520 :         x1 = x0; /*Qx*/
     357     1219520 :         move16();
     358     1219520 :         x0 = signal[i]; /*Qx*/
     359     1219520 :         move16();
     360     1219520 :         y0 = W_extract_l( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx
     361     1219520 :         signal[i] = y0;                                                                                                                                      /*Qx*/
     362     1219520 :         move16();
     363     1219520 :         y2 = y1; /*Qx*/
     364     1219520 :         move16();
     365     1219520 :         y1 = y0; /*Qx*/
     366     1219520 :         move16();
     367             :     }
     368             : 
     369        7622 :     mem[0] = y1; /*Qx*/
     370        7622 :     move32();
     371        7622 :     mem[1] = y2; /*Qx*/
     372        7622 :     move32();
     373        7622 :     mem[2] = x0; /*Qx*/
     374        7622 :     move32();
     375        7622 :     mem[3] = x1; /*Qx*/
     376        7622 :     move32();
     377             : 
     378        7622 :     return;
     379             : }
     380             : 
     381             : 
     382             : /*---------------------------------------------------------------
     383             :  * deEmphResample()
     384             :  *
     385             :  * De-emphasize and resample the L and R channels.
     386             :  * ---------------------------------------------------------------*/
     387        3811 : static void deEmphResample_fx(
     388             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle   */
     389             :     const Word32 *tempChan1_fx,       /* i  : Stereo data                 Qx*/
     390             :     const Word32 *tempChan2_fx,       /* i  : Stereo data                  Qx*/
     391             :     Word32 *chan1_fx,                 /*Qx*/
     392             :     Word32 *chan2_fx,                 /*Qx*/
     393             :     const Word16 input_frame,         /*Q0*/
     394             :     const Word16 dsFactor /*Q0*/ )
     395             : {
     396             :     Word32 buf1_fx[L_FRAME48k], buf2_fx[L_FRAME48k];
     397             :     Word32 tempBuf1_fx[2 * L_FRAME_DS], tempBuf2_fx[2 * L_FRAME_DS];
     398             :     Word16 i;
     399             :     Word16 dsFac1, dsFac2;
     400             : 
     401             :     /* Estimate first and second stage downsample factors */
     402        3811 :     dsFac1 = shr( dsFactor, 1 );           /*Qx*/
     403        3811 :     dsFac2 = idiv1616( dsFactor, dsFac1 ); /*Qx*/
     404             : 
     405             :     /* convert stereo data to two distinct channels, e.g., L, R */
     406        3811 :     Copy32( tempChan1_fx, buf1_fx, input_frame ); /*Qx*/
     407        3811 :     Copy32( tempChan2_fx, buf2_fx, input_frame ); /*Qx*/
     408             : 
     409             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
     410             : 
     411        3811 :     deemph_fx_32( buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] );
     412        3811 :     deemph_fx_32( buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] );
     413             : 
     414     1223331 :     FOR( i = 0; i < ( input_frame / dsFac1 ); i++ )
     415             :     {
     416     1219520 :         tempBuf1_fx[i] = buf1_fx[i * dsFac1]; /*Qx*/
     417     1219520 :         move32();
     418     1219520 :         tempBuf2_fx[i] = buf2_fx[i * dsFac1]; /*Qx*/
     419     1219520 :         move32();
     420             :     }
     421             : 
     422             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
     423        3811 :     deemph_fx_32( tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] );
     424        3811 :     deemph_fx_32( tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] );
     425             : 
     426      613571 :     FOR( i = 0; i < ( input_frame / dsFactor ); i++ )
     427             :     {
     428      609760 :         chan1_fx[i] = tempBuf1_fx[i * dsFac2]; /*Qx*/
     429      609760 :         move32();
     430      609760 :         chan2_fx[i] = tempBuf2_fx[i * dsFac2]; /*Qx*/
     431      609760 :         move32();
     432             :     }
     433             : 
     434        3811 :     spectral_balancer_fx( chan1_fx, &hStereoTCA->memdecim_fx[4], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
     435        3811 :     spectral_balancer_fx( chan2_fx, &hStereoTCA->memdecim_fx[8], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
     436             : 
     437        3811 :     return;
     438             : }
     439             : /*---------------------------------------------------------------
     440             :  * utilCrossCorr_mod()
     441             :  *
     442             :  * Biased crossCorr estimation between buf1, buf2 over the
     443             :  * lag range of (lagSearchRange[0], lagSearchRange[1]).
     444             :  * ---------------------------------------------------------------*/
     445        3811 : static void utilCrossCorr_mod_fx(
     446             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle   */
     447             :     Word32 *buf1,                     /*q_com*/
     448             :     Word32 *buf2,                     /*q_com*/
     449             :     const Word16 q_com,
     450             :     Word32 *corrEst,              /* o  : correlation estimate          Q31-corrEst_Exp*/
     451             :     Word16 *corrEst_Exp,          /* o  : correlation estimate          Q31-corrEst_Exp*/
     452             :     const Word16 *lagSearchRange, /*Q0*/
     453             :     const Word16 len /*Q0*/ )
     454             : {
     455             :     Word32 C, E1, E2, C_C_mem;
     456             :     Word16 i, j, E1_exp, E2_exp, Inv_Tot_E_exp, k, C_exp, exp, gb;
     457             :     Word16 Inv_Tot_E, corrEst_exp[2 * L_NCSHIFT_DS + 1];
     458             :     Word64 L64_sum;
     459             : 
     460        3811 :     set16_fx( corrEst_exp, -1000, 2 * L_NCSHIFT_DS + 1 );
     461        3811 :     E1_exp = sub( 31, q_com );
     462        3811 :     E2_exp = sub( 31, q_com );
     463             : 
     464        3811 :     gb = 0;
     465        3811 :     move16();
     466        3811 :     IF( LT_16( L_norm_arr( buf1, len ), 2 ) )
     467             :     {
     468           0 :         gb = 2;
     469           0 :         move16();
     470             :     }
     471        3811 :     E1 = sum2_32_exp_fx( buf1, len, &E1_exp, gb ); /* Q31-E1_exp */
     472             : 
     473        3811 :     gb = 0;
     474        3811 :     move16();
     475        3811 :     IF( LT_16( L_norm_arr( buf2, len ), 2 ) )
     476             :     {
     477           0 :         gb = 2;
     478           0 :         move16();
     479             :     }
     480        3811 :     E2 = sum2_32_exp_fx( buf2, len, &E2_exp, gb ); /* Q31-E2_exp */
     481             : 
     482             :     Word16 temp1, temp2;
     483        3811 :     Word32 E1_mul = BASOP_Util_Add_Mant32Exp( E1, E1_exp, hStereoTCA->E1_mem_fx, hStereoTCA->E1_mem_exp, &temp1 ); /* Q31-temp1 */
     484        3811 :     Word32 E2_mul = BASOP_Util_Add_Mant32Exp( E2, E2_exp, hStereoTCA->E2_mem_fx, hStereoTCA->E2_mem_exp, &temp2 ); /* Q31-temp2 */
     485        3811 :     Word32 sqr_inp = Mpy_32_32( E1_mul, E2_mul );
     486        3811 :     Word16 sq_exp = add( temp1, temp2 );
     487             : 
     488        3811 :     IF( sqr_inp )
     489             :     {
     490        3811 :         sqr_inp = Sqrt32( sqr_inp, &sq_exp );                       /* Q31-sq_exp */
     491        3811 :         sqr_inp = Mpy_32_32( sqr_inp, 1342177280 /* 320 in Q22*/ ); /* Q31-sq_exp+22-31 */
     492        3811 :         sq_exp = add( sq_exp, 9 );
     493        3811 :         Inv_Tot_E = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, sqr_inp, &Inv_Tot_E_exp ); /* Q15-Inv_Tot_E_exp */
     494        3811 :         Inv_Tot_E_exp = add( Inv_Tot_E_exp, sub( 0, sq_exp ) );
     495             :     }
     496             :     ELSE
     497             :     {
     498           0 :         Inv_Tot_E = 25088; /* 98.82 in Q8 */
     499           0 :         move16();
     500           0 :         Inv_Tot_E_exp = 7;
     501           0 :         move16();
     502             :     }
     503             : 
     504        3811 :     hStereoTCA->E1_mem_fx = E1; /* Q31-E1_exp */
     505        3811 :     move32();
     506        3811 :     hStereoTCA->E2_mem_fx = E2; /* Q31-E2_exp */
     507        3811 :     move32();
     508        3811 :     hStereoTCA->E1_mem_exp = E1_exp;
     509        3811 :     move16();
     510        3811 :     hStereoTCA->E2_mem_exp = E2_exp;
     511        3811 :     move16();
     512        3811 :     *corrEst_Exp = corrEst_exp[0];
     513        3811 :     move16();
     514             : 
     515      160062 :     FOR( ( i = lagSearchRange[0], j = 0 ); i <= 0; ( i++, j++ ) )
     516             :     {
     517      156251 :         L64_sum = 1;
     518      156251 :         move64();
     519    25156411 :         FOR( k = 0; k < len; k++ )
     520             :         {
     521    25000160 :             L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* 2*q_com+1 */
     522             :         }
     523      156251 :         k = W_norm( L64_sum );
     524      156251 :         L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
     525      156251 :         C = W_extract_h( L64_sum );    // ener_side_q
     526      156251 :         C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
     527      156251 :         C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
     528      156251 :         corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E );                                                          /* Q31-corrEst_exp */
     529      156251 :         move32();
     530      156251 :         corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
     531      156251 :         move16();
     532      156251 :         *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
     533      156251 :         move16();
     534      156251 :         hStereoTCA->C_mem_fx[j] = C;
     535      156251 :         move32();
     536      156251 :         hStereoTCA->C_mem_exp[j] = C_exp;
     537      156251 :         move16();
     538             :     }
     539             : 
     540      156251 :     FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
     541             :     {
     542      152440 :         L64_sum = 1;
     543      152440 :         move64();
     544    24542840 :         FOR( k = 0; k < len; k++ )
     545             :         {
     546    24390400 :             L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* 2*q_com+1 */
     547             :         }
     548      152440 :         k = W_norm( L64_sum );
     549      152440 :         L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
     550      152440 :         C = W_extract_h( L64_sum );    // ener_side_q
     551      152440 :         C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
     552      152440 :         C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
     553      152440 :         corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E );                                                          /* Q31-corrEst_exp */
     554      152440 :         move32();
     555      152440 :         corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
     556      152440 :         move16();
     557      152440 :         *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
     558      152440 :         move16();
     559      152440 :         hStereoTCA->C_mem_fx[j] = C;
     560      152440 :         move32();
     561      152440 :         hStereoTCA->C_mem_exp[j] = C_exp;
     562      152440 :         move16();
     563             :     }
     564             : 
     565             :     /* Rescaling buffers */
     566             : 
     567      312502 :     FOR( i = 0; i < ( 2 * L_NCSHIFT_DS + 1 ); i++ )
     568             :     {
     569      308691 :         corrEst[i] = L_shl( corrEst[i], sub( corrEst_exp[i], *corrEst_Exp ) ); /* Q31-corrEst_Exp */
     570      308691 :         move32();
     571             :     }
     572             : 
     573        3811 :     return;
     574             : }
     575             : /*---------------------------------------------------------------
     576             :  * utilCrossCorr()
     577             :  *
     578             :  * crossCorr estimation between buf1, buf2 over the
     579             :  * lag range of (lagSearchRange[0], lagSearchRange[1]).
     580             :  * ---------------------------------------------------------------*/
     581         241 : static void utilCrossCorr_fx(
     582             :     const Word32 *buf1, // buf1_q
     583             :     Word16 buf1_q,
     584             :     const Word32 *buf2, // buf2_q
     585             :     Word16 buf2_q,
     586             :     const Word32 *win, /*Qx*/
     587             :     Word32 *corrEst,   /* o  : correlation estimate     corrEst_e */
     588             :     Word16 *corrEst_e,
     589             :     const Word16 *lagSearchRange, /*Q0*/
     590             :     const Word16 len,             /*Q0*/
     591             :     const Word16 winSymmFlag /*Q0*/ )
     592             : {
     593             :     Word32 tempBuf1[L_FRAME48k];
     594             :     Word32 tempBuf2[L_FRAME48k];
     595             :     Word32 temp, scale;
     596             :     Word16 res_e, tmp_e;
     597             :     Word64 L64_sum;
     598             :     Word16 i, j, k;
     599             :     Word16 corrEstTemp_e[N_MAX_SHIFT_CHANGE + 1];
     600         241 :     Word16 max_e = MIN16B;
     601         241 :     move16();
     602             : 
     603         241 :     Word16 gb1 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf1, len ) ) );
     604         241 :     Word16 gb2 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf2, len ) ) );
     605             : 
     606             :     /* Apply windowing */
     607         241 :     IF( win != NULL )
     608             :     {
     609           0 :         IF( EQ_16( winSymmFlag, 0 ) )
     610             :         {
     611           0 :             v_mult_fixed( buf1, win, tempBuf1, len );
     612           0 :             v_mult_fixed( buf2, win, tempBuf2, len );
     613             :         }
     614             :         ELSE
     615             :         {
     616           0 :             v_mult_fixed( buf1, win, tempBuf1, ( len >> 1 ) );
     617           0 :             v_mult_fixed( buf2, win, tempBuf2, ( len >> 1 ) );
     618             : 
     619           0 :             FOR( i = shr( len, 1 ); i < len; i++ )
     620             :             {
     621           0 :                 tempBuf1[i] = Mpy_32_32( win[len - 1 - i], buf1[i] ); /* Qx+buf1_q-31 */
     622           0 :                 move32();
     623           0 :                 tempBuf2[i] = Mpy_32_32( win[len - 1 - i], buf2[i] ); /* Qx+buf2_q-31 */
     624           0 :                 move32();
     625             :             }
     626             :         }
     627             :     }
     628             :     ELSE
     629             :     {
     630         241 :         Copy32( buf1, tempBuf1, len ); /* buf1_q */
     631         241 :         Copy32( buf2, tempBuf2, len ); /* buf2_q */
     632             :     }
     633             : 
     634         241 :     Word16 temp1_e = sub( Q31, buf1_q );
     635         241 :     Word16 temp2_e = sub( Q31, buf2_q );
     636             : 
     637         241 :     temp = sum2_32_exp_fx( tempBuf1, len, &temp1_e, gb1 );                    // temp1_e
     638         241 :     temp = Mpy_32_32( temp, sum2_32_exp_fx( tempBuf2, len, &temp2_e, gb2 ) ); // temp2_e
     639         241 :     temp2_e = add( temp1_e, temp2_e );
     640             : 
     641         241 :     IF( temp == 0 )
     642             :     {
     643           0 :         scale = MAXVAL_WORD32;
     644           0 :         move32();
     645             :     }
     646             :     ELSE
     647             :     {
     648         241 :         scale = ISqrt32( temp, &temp2_e ); // temp2_e
     649             :     }
     650             : 
     651             :     /* starting point of lag search range should be less than the ending point */
     652         241 :     assert( lagSearchRange[0] <= lagSearchRange[1] );
     653             : 
     654             :     /* first part of noncausal corr est. */
     655         406 :     FOR( ( i = lagSearchRange[0], j = 0 ); i <= s_min( 0, lagSearchRange[1] ); ( i++, j++ ) )
     656             :     {
     657         165 :         L64_sum = 0;
     658         165 :         move64();
     659      111349 :         FOR( k = 0; k < ( len + i ); k++ )
     660             :         {
     661      111184 :             L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* buf1_q+buf2_q+1 */
     662             :         }
     663         165 :         k = W_norm( L64_sum );
     664         165 :         L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
     665         165 :         temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
     666         165 :         res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
     667             : 
     668         165 :         corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len + i ), &tmp_e ) ); /* Q31-max_e */
     669         165 :         move32();
     670         165 :         corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
     671         165 :         move16();
     672         165 :         max_e = s_max( max_e, corrEstTemp_e[j] );
     673             :     }
     674             : 
     675             :     /* second part of noncausal corr est. */
     676         656 :     FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
     677             :     {
     678         415 :         L64_sum = 1;
     679         415 :         move64();
     680      250969 :         FOR( k = 0; k < sub( len, i ); k++ )
     681             :         {
     682      250554 :             L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* buf1_q+buf2_q+1 */
     683             :         }
     684         415 :         k = W_norm( L64_sum );
     685         415 :         L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
     686         415 :         temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
     687         415 :         res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
     688             : 
     689         415 :         corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len - i ), &tmp_e ) ); /* Q31-max_e */
     690         415 :         move32();
     691         415 :         corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
     692         415 :         move16();
     693         415 :         max_e = s_max( max_e, corrEstTemp_e[j] );
     694         415 :         move16();
     695             :     }
     696             : 
     697             : 
     698         821 :     FOR( i = 0; i < j; i++ )
     699             :     {
     700         580 :         corrEst[i] = L_shr( corrEst[i], sub( max_e, corrEstTemp_e[i] ) ); /* Q31-corrEstTemp_e */
     701         580 :         move32();
     702             :     }
     703             : 
     704         241 :     *corrEst_e = max_e;
     705         241 :     move16();
     706         241 :     v_multc_fixed( corrEst, scale, corrEst, j );
     707         241 :     *corrEst_e = add( *corrEst_e, temp2_e );
     708         241 :     move16();
     709             : 
     710         241 :     return;
     711             : }
     712             : /*---------------------------------------------------------------
     713             :  *  corrStatsEst()
     714             :  *
     715             :  *  Non-causal shift estimation to encode future samples.
     716             :  * ---------------------------------------------------------------*/
     717             : 
     718       11485 : static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp )
     719             : {
     720             :     Word16 ouptut;
     721             :     Word32 temp;
     722             : 
     723       11485 :     temp = L_shr( inp, sub( 31, exp ) ); /*Q0*/
     724       11485 :     test();
     725       11485 :     IF( GT_32( temp, 32767 ) || LT_32( temp, -32768 ) )
     726             :     {
     727           0 :         test();
     728           0 :         IF( temp < 0 )
     729             :         {
     730           0 :             ouptut = -32768; /*Q0*/
     731             :         }
     732             :         ELSE
     733             :         {
     734           0 :             ouptut = 32767; /*Q0*/
     735             :         }
     736           0 :         move16();
     737             :     }
     738             :     ELSE
     739             :     {
     740       11485 :         IF( NE_32( temp, L_shl_sat( 1, sub( 31, exp ) ) ) )
     741             :         {
     742       11485 :             Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */
     743       11485 :             ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) );                      /*Q0*/
     744             : 
     745       11485 :             IF( temp < 0 )
     746             :             {
     747        6630 :                 ouptut = add( ouptut, 1 ); /*Q0*/
     748             :             }
     749             :         }
     750             :         ELSE
     751             :         {
     752           0 :             ouptut = extract_l( temp ); /*Q0*/
     753           0 :             move16();
     754             :         }
     755             :     }
     756       11485 :     return ouptut; /*Q0*/
     757             : }
     758        3811 : static void corrStatsEst_fx(
     759             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle   */
     760             :     Word32 *buf1_fx,                  /* i  : channel 1                   q_com*/
     761             :     Word32 *buf2_fx,                  /* i  : channel 2                   q_com*/
     762             :     Word16 q_com,
     763             :     const Word16 bufLenDS,               /* i  : buffer length               Q0*/
     764             :     const Word16 dsFactor,               /* i  : buffer length               Q0*/
     765             :     const Word16 vad_flag1,              /* i  : VAD flag channel 1          Q0*/
     766             :     const Word16 vad_flag2,              /* i  : VAD flag channel 2          Q0*/
     767             :     STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle    */
     768             : )
     769             : {
     770             :     Word16 lagSearchRange[2];
     771             :     Word32 corrEst_fx[2 * L_NCSHIFT_DS + 1];
     772             :     Word16 corrLagStats[3];
     773             :     Word32 *tempRK_fx;
     774             :     const Word32 *winInterp_fx;
     775             :     Word32 rInterp_fx[MAX_INTERPOLATE];
     776             :     Word16 rInterp_exp[MAX_INTERPOLATE];
     777             :     Word16 interpMin, interpMax, interpLen;
     778             :     Word16 i, j, k, m;
     779             :     Word16 win_bias_fx;
     780             :     Word16 tempLen, win_width;
     781             :     Word16 loc_weight_win_fx[4 * L_NCSHIFT_DS + 1];
     782             :     Word32 X_hat_fx, Y_hat_fx, XY_hat_fx, X_SQR_hat_fx;
     783             :     Word32 alpha_reg_fx, beta_reg_fx, reg_prv_corr_fx, dist_reg_prv_corr_fx, bias_par_fx, width_par_fx;
     784             :     Word16 alpha_reg_exp, beta_reg_exp, reg_prv_corr_exp, dist_reg_prv_corr_exp, bias_par_exp, width_par_exp;
     785             : 
     786             :     Word16 alpha_fx;
     787             :     Word16 k1_fx, k2_fx;
     788             :     Word32 temp_A_fx, temp_B_fx, tempF_fx;
     789             :     Word16 stmp;
     790             :     Word32 corrEst_ncorr_fx, temp32;
     791             :     Word16 corrEst_exp, corrEst_ncorr_exp, temp;
     792             :     Word16 X_hat_exp, Y_hat_exp, XY_hat_exp, X_SQR_hat_exp, exp;
     793             : 
     794             :     /* init of regression parameters*/
     795        3811 :     X_hat_fx = 0;
     796        3811 :     move32();
     797        3811 :     X_hat_exp = 0;
     798        3811 :     move16();
     799        3811 :     X_SQR_hat_fx = 0;
     800        3811 :     move32();
     801        3811 :     X_SQR_hat_exp = 0;
     802        3811 :     move16();
     803        3811 :     XY_hat_fx = 0;
     804        3811 :     move32();
     805        3811 :     XY_hat_exp = 0;
     806        3811 :     move16();
     807             : 
     808             :     /* Initializations */
     809        3811 :     alpha_fx = 22938; /* 0.7 in Q15*/
     810        3811 :     move16();
     811        3811 :     lagSearchRange[0] = -L_NCSHIFT_DS;
     812        3811 :     move16();
     813        3811 :     lagSearchRange[1] = L_NCSHIFT_DS;
     814        3811 :     move16();
     815        3811 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
     816        3811 :     move16();
     817             : 
     818        3811 :     set16_fx( corrLagStats, 0, 3 );
     819             : 
     820             :     /* First iteration of xcorr estimation */
     821        3811 :     utilCrossCorr_mod_fx( hStereoTCA, buf1_fx, buf2_fx, q_com, corrEst_fx, &corrEst_exp, lagSearchRange, sub( bufLenDS, L_XCORRMEM_DS ) );
     822             : 
     823             :     /* calculate features for the UNCLR classifier */
     824        3811 :     unclr_calc_corr_features_fx( hStereoClassif, hStereoTCA, buf1_fx, buf2_fx, q_com, sub( bufLenDS, L_XCORRMEM_DS ), corrEst_fx, corrEst_exp, lagSearchRange, &corrEst_ncorr_fx, &corrEst_ncorr_exp );
     825             : 
     826       11433 :     FOR( i = 1; i < 3; i++ )
     827             :     {
     828        7622 :         v_add_32( hStereoTCA->corrEstPrev_fx[i], hStereoTCA->corrEstPrev_fx[0], hStereoTCA->corrEstPrev_fx[0], tempLen );
     829             :     }
     830             : 
     831             :     /* back up the corrEst */
     832       11433 :     FOR( i = 0; i < 2; i++ )
     833             :     {
     834        7622 :         Copy32( hStereoTCA->corrEstPrev_fx[i + 1], hStereoTCA->corrEstPrev_fx[i], tempLen ); /* Q31-hStereoTCA->corrEstPrev_exp */
     835             :     }
     836             : 
     837        3811 :     temp = getScaleFactor32( corrEst_fx, 2 * L_NCSHIFT_DS + 1 );
     838        3811 :     scale_sig32( corrEst_fx, 2 * L_NCSHIFT_DS + 1, temp ); /* Q31-corrEst_exp */
     839        3811 :     corrEst_exp = sub( corrEst_exp, temp );
     840             : 
     841        3811 :     Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); /* Q31-corrEst_exp */
     842        3811 :     hStereoTCA->corrEstPrev_exp = corrEst_exp;
     843        3811 :     move16();
     844        3811 :     Word16 gb = find_guarded_bits_fx( 2 * L_NCSHIFT_DS + 1 );
     845             : 
     846        3811 :     scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, -gb ); /* Q31-hStereoTCA->corrEstPrev_exp-1 */
     847        3811 :     hStereoTCA->corrEstPrev_exp = add( hStereoTCA->corrEstPrev_exp, gb );
     848        3811 :     move16();
     849             :     Word32 buf1_fx_temp[L_FRAME_DS];
     850             :     Word32 buf2_fx_temp[L_FRAME_DS];
     851             : 
     852        3811 :     Copy32( buf1_fx, buf1_fx_temp, L_FRAME_DS ); /* q_com */
     853        3811 :     Copy32( buf2_fx, buf2_fx_temp, L_FRAME_DS ); /* q_com */
     854             : 
     855        3811 :     scale_sig32( buf1_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
     856        3811 :     scale_sig32( buf2_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
     857             : 
     858        3811 :     temp_A_fx = L_add( sumAbs_fx( buf1_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ) );
     859        3811 :     temp_B_fx = L_add( sumAbs_fx( buf1_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) );
     860             : 
     861        3811 :     tempF_fx = BASOP_Util_Add_Mant32Exp( L_add( temp_A_fx, temp_B_fx ), sub( 31, sub( q_com, 4 ) ), hStereoTCA->mem_tempF_fx, hStereoTCA->mem_tempF_exp, &temp ); /* Q31-tempF_exp */
     862        3811 :     Word16 tempF_exp = temp;
     863        3811 :     hStereoTCA->mem_tempF_fx = temp_B_fx; /* Q31-hStereoTCA->mem_tempF_exp  */
     864        3811 :     move32();
     865        3811 :     hStereoTCA->mem_tempF_exp = sub( 31, sub( q_com, 4 ) );
     866        3811 :     move16();
     867             : 
     868        3811 :     alpha_fx = 30474 /* 0.93f in Q15*/;
     869        3811 :     move16();
     870        3811 :     IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 2 ), &temp ) > 0 )
     871             :     {
     872         120 :         alpha_fx = 27197 /* 0.83f in Q15*/;
     873             :     }
     874        3691 :     ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 1 ), &temp ) > 0 )
     875             :     {
     876         315 :         alpha_fx = 27853 /* 0.85f in Q15*/;
     877             :     }
     878        3376 :     ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, hStereoTCA->ica_envVarLT_exp, &temp ) > 0 )
     879             :     {
     880        1070 :         alpha_fx = 29491 /* 0.9f in Q15*/;
     881             :     }
     882        3811 :     move16();
     883        3811 :     hStereoTCA->corrStatsSmoothFac_fx = alpha_fx;
     884        3811 :     move32();
     885             : 
     886             :     /* long term corr Stats estimation */
     887        3811 :     v_multc_fixed_16( hStereoTCA->corrEstLT_fx, alpha_fx, hStereoTCA->corrEstLT_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
     888        3811 :     v_multc_fixed_16( corrEst_fx, sub( MAX_16, alpha_fx ), corrEst_fx, 2 * L_NCSHIFT_DS + 1 );              /* Q31-corrEst_exp */
     889        3811 :     v_add_fixed_me( hStereoTCA->corrEstLT_fx, hStereoTCA->corrEstLT_exp, corrEst_fx, corrEst_exp, hStereoTCA->corrEstLT_fx, &hStereoTCA->corrEstLT_exp, 2 * L_NCSHIFT_DS + 1, 0 );
     890             : 
     891        3811 :     hStereoTCA->ica_envVarLT_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->ica_envVarLT_fx, SMOOTH_ENV_FACTOR_FX_Q15 ), hStereoTCA->ica_envVarLT_exp, Mpy_32_16_1( tempF_fx, ONE_IN_Q15 - SMOOTH_ENV_FACTOR_FX_Q15 ), tempF_exp, &hStereoTCA->ica_envVarLT_exp ); // SMOOTH_ENV_FACTOR_FX_Q15 (Q31-hStereoTCA->ica_envVarLT_exp)
     892        3811 :     move32();
     893             : 
     894        3811 :     Copy32( hStereoTCA->corrEstLT_fx, corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
     895        3811 :     corrEst_exp = hStereoTCA->corrEstLT_exp;
     896        3811 :     move16();
     897             : 
     898        3811 :     Y_hat_fx = hStereoTCA->delay_0_mem_fx[0]; /* Q31-hStereoTCA->delay_0_mem_exp */
     899        3811 :     move32();
     900        3811 :     Y_hat_exp = hStereoTCA->delay_0_mem_exp;
     901        3811 :     move16();
     902             : 
     903             :     /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
     904       45732 :     FOR( i = 1; i < MAX_DELAYREGLEN; i++ )
     905             :     {
     906       41921 :         X_hat_fx = BASOP_Util_Add_Mant32Exp( X_hat_fx, X_hat_exp, L_shl( i, 27 ), 4, &X_hat_exp );                                                                                     /* Q31-X_hat_exp */
     907       41921 :         Y_hat_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, hStereoTCA->delay_0_mem_fx[i], hStereoTCA->delay_0_mem_exp, &Y_hat_exp );                                            /* Q31-Y_hat_exp */
     908       41921 :         XY_hat_fx = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, Mpy_32_32( hStereoTCA->delay_0_mem_fx[i], L_shl( i, 27 ) ), add( 4, hStereoTCA->delay_0_mem_exp ), &XY_hat_exp ); /* Q31-XY_hat_exp */
     909       41921 :         X_SQR_hat_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, Mpy_32_32( L_shl( i, 27 ), L_shl( i, 27 ) ), 8, &X_SQR_hat_exp );                                        /* Q31-X_SQR_hat_exp */
     910             :     }
     911             : 
     912        3811 :     X_hat_fx = Mpy_32_16_1( X_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );         /* Q31-X_hat_exp */
     913        3811 :     Y_hat_fx = Mpy_32_16_1( Y_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );         /* Q31-Y_hat_exp */
     914        3811 :     XY_hat_fx = Mpy_32_16_1( XY_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );       /* Q31-XY_hat_exp */
     915        3811 :     X_SQR_hat_fx = Mpy_32_16_1( X_SQR_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_SQR_hat_exp */
     916             : 
     917        3811 :     beta_reg_fx = 0;
     918        3811 :     move32();
     919        3811 :     beta_reg_exp = 0;
     920        3811 :     move16();
     921        3811 :     tempF_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, L_negate( Mpy_32_32( X_hat_fx, X_hat_fx ) ), shl( X_hat_exp, 1 ), &tempF_exp ); /* Q31-tempF_exp */
     922             : 
     923        3811 :     IF( tempF_fx != 0 )
     924             :     {
     925        3811 :         temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); /* Q31-exp */
     926        3811 :         beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp );                                                        /* Q31-beta_reg_exp */
     927        3811 :         if ( beta_reg_fx )
     928             :         {
     929        3654 :             beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) );
     930             :         }
     931             :     }
     932             : 
     933        3811 :     alpha_reg_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, L_negate( Mpy_32_32( X_hat_fx, beta_reg_fx ) ), add( X_hat_exp, beta_reg_exp ), &alpha_reg_exp );               /* Q31-alpha_reg_exp */
     934        3811 :     reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( alpha_reg_fx, alpha_reg_exp, Mpy_32_32( beta_reg_fx, L_shl( MAX_DELAYREGLEN, 27 ) ), add( 4, beta_reg_exp ), &reg_prv_corr_exp ); /* Q31-reg_prv_corr_exp */
     935             : 
     936        3811 :     reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
     937        3811 :     reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
     938        3811 :     IF( LE_16( TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ), -L_NCSHIFT_DS ) )
     939             :     {
     940           0 :         reg_prv_corr_fx = -L_NCSHIFT_DS + 1;
     941           0 :         move32();
     942           0 :         reg_prv_corr_exp = 31;
     943           0 :         move16();
     944             :     }
     945             : 
     946        3811 :     IF( GE_16( TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ), L_NCSHIFT_DS ) )
     947             :     {
     948           2 :         reg_prv_corr_fx = L_NCSHIFT_DS - 1;
     949           2 :         move32();
     950           2 :         reg_prv_corr_exp = 31;
     951           2 :         move16();
     952             :     }
     953             : 
     954        3811 :     bias_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_BIAS_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, L_shl( B_BIAS_FX_Q15, Q16 ), 0, &bias_par_exp ); /* Q31-bias_par_exp */
     955             : 
     956        3811 :     Word32 XH_BIAS_tmp = L_shl( XH_BIAS_FX_Q15, Q16 ); /* Q31 */
     957        3811 :     Word32 XL_BIAS_tmp = L_shl( XL_BIAS_FX_Q15, Q16 ); /* Q31 */
     958             : 
     959        3811 :     IF( bias_par_exp < 0 )
     960             :     {
     961        3496 :         bias_par_fx = L_shl( bias_par_fx, bias_par_exp ); /* Q31 */
     962        3496 :         bias_par_exp = 0;
     963        3496 :         move16();
     964             :     }
     965             :     ELSE
     966             :     {
     967         315 :         XH_BIAS_tmp = L_shr( XH_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
     968         315 :         XL_BIAS_tmp = L_shr( XL_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
     969             :     }
     970             : 
     971        3811 :     bias_par_fx = L_min( bias_par_fx, XH_BIAS_tmp );
     972        3811 :     bias_par_fx = L_max( bias_par_fx, XL_BIAS_tmp );
     973        3811 :     bias_par_fx = L_shr( bias_par_fx, bias_par_exp );
     974        3811 :     bias_par_exp = 0;
     975        3811 :     move16();
     976             : 
     977        3811 :     width_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_WIDTH_FX_Q31 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, B_WIDTH_FX_Q31, 0, &width_par_exp ); /* Q31-width_par_exp */
     978        3811 :     Word32 XH_WIDTH_tmp = L_shl( XH_WIDTH_FX_Q15, Q16 );                                                                                                                                          /* Q31 */
     979        3811 :     Word32 XL_WIDTH_tmp = L_shl( XL_WIDTH_FX_Q15, Q16 );                                                                                                                                          /* Q31 */
     980             : 
     981        3811 :     IF( width_par_exp < 0 )
     982             :     {
     983        3811 :         width_par_fx = L_shl( width_par_fx, width_par_exp ); /* Q31 */
     984        3811 :         width_par_exp = 0;
     985        3811 :         move16();
     986             :     }
     987             :     ELSE
     988             :     {
     989           0 :         XH_WIDTH_tmp = L_shr( XH_WIDTH_tmp, width_par_exp );
     990           0 :         XL_WIDTH_tmp = L_shr( XL_WIDTH_tmp, width_par_exp );
     991             :     }
     992        3811 :     width_par_fx = L_min( width_par_fx, XH_WIDTH_tmp );
     993        3811 :     width_par_fx = L_max( width_par_fx, XL_WIDTH_tmp );
     994        3811 :     width_par_fx = L_shl( width_par_fx, width_par_exp );
     995        3811 :     width_par_exp = 0;
     996        3811 :     move16();
     997             : 
     998        3811 :     win_width = (Word16) L_shr( Mpy_32_32( width_par_fx, 1350565888 /* ( 4L_NCSHIFT_DS + 1 ) in Q23 */ ), sub( 31, add( width_par_exp, 8 ) ) ); /* Q23-(31-(width_par_exp-8)) */
     999             : 
    1000        3811 :     win_bias_fx = round_fx( bias_par_fx ); // Q15
    1001             : 
    1002        3811 :     k1_fx = add( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
    1003        3811 :     k2_fx = sub( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
    1004             : 
    1005      159379 :     FOR( i = 0; i < ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i++ )
    1006             :     {
    1007      155568 :         loc_weight_win_fx[i] = win_bias_fx; // Q15
    1008      155568 :         move16();
    1009             :     }
    1010             : 
    1011      306246 :     FOR( i = ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i <= ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i++ )
    1012             :     {
    1013      302435 :         Word16 cos_inp = BASOP_Util_Divide1616_Scale( sub( i, 2 * L_NCSHIFT_DS ), shl( win_width, 1 ), &exp ); /* Q15-exp */
    1014      302435 :         cos_inp = shr_sat( cos_inp, sub( 0, exp ) );
    1015      302435 :         cos_inp = getCosWord16R2( shr( cos_inp, 1 ) );               // Q15
    1016      302435 :         loc_weight_win_fx[i] = add( k1_fx, mult( k2_fx, cos_inp ) ); // Q15
    1017      302435 :         move16();
    1018             :     }
    1019             : 
    1020      163190 :     FOR( i = ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
    1021             :     {
    1022      159379 :         loc_weight_win_fx[i] = win_bias_fx; // Q15
    1023      159379 :         move16();
    1024             :     }
    1025        3811 :     reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
    1026        3811 :     reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
    1027        3811 :     Word16 x = TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ); /* Q0 */
    1028        3811 :     move16();
    1029      312502 :     for ( i = 0, j = ( L_NCSHIFT_DS - x ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
    1030             :     {
    1031      308691 :         corrEst_fx[i] = Mpy_32_16_1( corrEst_fx[i], loc_weight_win_fx[j] ); /* Q31-corrEst_exp */
    1032      308691 :         move32();
    1033             :     }
    1034        3811 :     test();
    1035        3811 :     test();
    1036        3811 :     IF( LT_32( hStereoTCA->prevTargetGain_fx, 429496730 /*0.8f in Q29*/ ) && vad_flag1 )
    1037             :     {
    1038             :         /* ch 2 is prev reference channel */
    1039           0 :         v_multc_fixed( corrEst_fx, 644245095 /*1.2f in Q29*/, corrEst_fx, L_NCSHIFT_DS + 1 );                                     /* Q31-corrEst_exp */
    1040           0 :         v_multc_fixed( corrEst_fx + L_NCSHIFT_DS + 1, 447213470 /* 0.833 in Q29*/, corrEst_fx + L_NCSHIFT_DS + 1, L_NCSHIFT_DS ); /* Q31-corrEst_exp */
    1041           0 :         corrEst_exp = add( corrEst_exp, 2 );
    1042             :     }
    1043        3811 :     ELSE IF( GT_32( hStereoTCA->prevTargetGain_fx, 644245094 /*1.2f in Q29*/ ) && vad_flag1 )
    1044             :     {
    1045             :         /* ch 1 is prev reference channel */
    1046           0 :         v_multc_fixed( corrEst_fx, 447213470 /* 0.833 f in Q29*/, corrEst_fx, L_NCSHIFT_DS );                               /* Q31-corrEst_exp */
    1047           0 :         v_multc_fixed( corrEst_fx + L_NCSHIFT_DS, 644245095 /*1.2f in Q29*/, corrEst_fx + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */
    1048           0 :         corrEst_exp = add( corrEst_exp, 2 );
    1049             :     }
    1050        3811 :     test();
    1051        3811 :     IF( BASOP_Util_Add_Mant32Exp( corrEst_ncorr_fx, corrEst_ncorr_exp, -429496730 /*0.8f in Q29*/, 2, &exp ) > 0 && vad_flag1 )
    1052             :     {
    1053        1586 :         i = s_max( 0, add( hStereoTCA->prevCorrLagStats[0], -1 + L_NCSHIFT_DS ) );
    1054        1586 :         j = s_min( 2 * L_NCSHIFT_DS, add( hStereoTCA->prevCorrLagStats[0], 1 + L_NCSHIFT_DS ) );
    1055        1586 :         k = add( sub( j, i ), 1 );
    1056             : 
    1057        1586 :         v_multc_fixed( corrEst_fx, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx, i );                                                  // to allign in same exp (Q31-corrEst_exp)
    1058        1586 :         v_multc_fixed( corrEst_fx + i, 644245095 /*1.2f in Q29*/, corrEst_fx + i, k );                                           /* Q31-corrEst_exp */
    1059        1586 :         v_multc_fixed( corrEst_fx + i + k, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx + i + k, sub( 2 * L_NCSHIFT_DS + 1, i + k ) ); // to allign in same exp (Q31-corrEst_exp)
    1060        1586 :         corrEst_exp = add( corrEst_exp, 2 );
    1061             :     }
    1062             : 
    1063             :     /* Initial corr lag estimate */
    1064        3811 :     corrLagStats[0] = maximum_32_fx( corrEst_fx, add( sub( lagSearchRange[1], lagSearchRange[0] ), 1 ), &tempF_fx );
    1065        3811 :     move16();
    1066        3811 :     tempF_exp = corrEst_exp;
    1067        3811 :     move16();
    1068        3811 :     corrLagStats[0] = add( corrLagStats[0], lagSearchRange[0] );
    1069        3811 :     move16();
    1070             : 
    1071        3811 :     stmp = i_mult( corrLagStats[0], dsFactor );                        /* Q0 */
    1072        3811 :     hStereoClassif->unclr_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
    1073        3811 :     move32();
    1074        3811 :     hStereoClassif->xtalk_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
    1075        3811 :     move32();
    1076        3811 :     hStereoClassif->xtalk_fv_fx[E_ica_corr_value0] = L_shl( tempF_fx, sub( tempF_exp, Q16 ) ); /* Q15 */
    1077        3811 :     move32();
    1078             : 
    1079        3811 :     test();
    1080        3811 :     IF( vad_flag1 == 0 && GT_16( alpha_fx, 22938 /* 0.7f in Q15 */ ) )
    1081             :     {
    1082          15 :         corrLagStats[0] = 0;
    1083          15 :         move16();
    1084             :     }
    1085             : 
    1086        3811 :     dist_reg_prv_corr_fx = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -corrLagStats[0], Q31, &dist_reg_prv_corr_exp ) ); /* Q31-dist_reg_prv_corr_exp */
    1087        3811 :     test();
    1088        3811 :     IF( EQ_16( vad_flag1, 1 ) && EQ_16( vad_flag2, 1 ) )
    1089        3759 :     {
    1090             : 
    1091        3759 :         hStereoTCA->smooth_dist_reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, SMOOTH_DIST_FACTOR_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, Mpy_32_16_1( dist_reg_prv_corr_fx, MAX_16 - SMOOTH_DIST_FACTOR_FX_Q15 ), dist_reg_prv_corr_exp, &hStereoTCA->smooth_dist_reg_prv_corr_exp ); /* Q31-hStereoTCA->smooth_dist_reg_prv_corr_exp */
    1092        3759 :         move32();
    1093        3759 :         Copy32( &( hStereoTCA->delay_0_mem_fx[1] ), &( hStereoTCA->delay_0_mem_fx[0] ), MAX_DELAYREGLEN - 1 ); /* Q31-hStereoTCA->delay_0_mem_exp */
    1094             : 
    1095        3759 :         hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */
    1096        3759 :         move32();
    1097        3759 :         Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */
    1098        3759 :         inpp = L_shl_sat( inpp, sub( exp, 5 ) );                                                                                                                            /* Q26 */
    1099        3759 :         IF( GT_32( inpp, 1677721600 ) )                                                                                                                                     // 25 in Q26
    1100             :         {
    1101          86 :             set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
    1102          86 :             hStereoTCA->delay_0_mem_exp = temp;
    1103          86 :             move16();
    1104             :         }
    1105             :         ELSE
    1106             :         {
    1107        3673 :             IF( GT_16( temp, hStereoTCA->delay_0_mem_exp ) )
    1108             :             {
    1109         179 :                 scale_sig32( hStereoTCA->delay_0_mem_fx, MAX_DELAYREGLEN - 1, sub( hStereoTCA->delay_0_mem_exp, temp ) ); /* Q31-hStereoTCA->delay_0_mem_exp */
    1110         179 :                 hStereoTCA->delay_0_mem_exp = temp;
    1111         179 :                 move16();
    1112             :             }
    1113             :             ELSE
    1114             :             {
    1115        3494 :                 hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = L_shl( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], sub( temp, hStereoTCA->delay_0_mem_exp ) ); /* Q31-temp */
    1116        3494 :                 move32();
    1117             :             }
    1118             :         }
    1119             :     }
    1120             :     ELSE
    1121             :     {
    1122          52 :         hStereoTCA->smooth_dist_reg_prv_corr_fx = 0;
    1123          52 :         move32();
    1124          52 :         hStereoTCA->smooth_dist_reg_prv_corr_exp = 0;
    1125          52 :         move16();
    1126             :     }
    1127        3811 :     test();
    1128        3811 :     IF( vad_flag1 == 0 || vad_flag2 == 0 )
    1129             :     {
    1130          52 :         Word32 tmp_delay = L_shr( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 1 );
    1131          52 :         Word16 tmp_delay_e = add( hStereoTCA->delay_0_mem_exp, 1 );
    1132          52 :         corrLagStats[0] = TRUNC_FX( tmp_delay, tmp_delay_e ); /* Q0 */
    1133          52 :         move32();
    1134             :     }
    1135             : 
    1136             :     /* second iteration of xcorr update @ inputFs with interp*/
    1137        3811 :     tempRK_fx = hStereoTCA->corrEstLT_fx + add( -lagSearchRange[0], corrLagStats[0] );
    1138        3811 :     set32_fx( rInterp_fx, 0, MAX_INTERPOLATE );
    1139        3811 :     set16_fx( rInterp_exp, 0, MAX_INTERPOLATE );
    1140             : 
    1141             :     /* select the Rk interp sinc window */
    1142        3811 :     winInterp_fx = ica_sincInterp4_fx + SINC_ORDER1;
    1143             : 
    1144        3811 :     IF( EQ_16( dsFactor, 2 ) )
    1145             :     {
    1146         757 :         winInterp_fx = ica_sincInterp2_fx + SINC_ORDER1;
    1147             :     }
    1148        3054 :     ELSE IF( EQ_16( dsFactor, 6 ) )
    1149             :     {
    1150        1022 :         winInterp_fx = ica_sincInterp6_fx + SINC_ORDER1;
    1151             :     }
    1152             : 
    1153        3811 :     corrLagStats[1] = i_mult( corrLagStats[0], dsFactor ); /* Q0 */
    1154        3811 :     move16();
    1155        3811 :     interpMin = s_max( -sub( dsFactor, 1 ), -add( corrLagStats[1], i_mult( L_NCSHIFT_DS, dsFactor ) ) );
    1156        3811 :     interpMax = s_min( sub( dsFactor, 1 ), sub( i_mult( L_NCSHIFT_DS, dsFactor ), corrLagStats[1] ) );
    1157        3811 :     interpLen = add( sub( interpMax, interpMin ), 1 );
    1158             : 
    1159       31548 :     for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
    1160             :     {
    1161       27737 :         rInterp_fx[k] = 0;
    1162       27737 :         move32();
    1163      370602 :         FOR( j = -( SINC_ORDER1 / dsFactor ); j <= ( SINC_ORDER1 / dsFactor ); j++ )
    1164             :         {
    1165      342865 :             m = i_mult( j, dsFactor ); /* Q0 */
    1166      342865 :             test();
    1167      342865 :             IF( GE_16( sub( m, i ), -SINC_ORDER1 ) && LE_16( sub( m, i ), SINC_ORDER1 ) )
    1168             :             {
    1169      318939 :                 IF( GT_16( j, sub( lagSearchRange[1], corrLagStats[0] ) ) )
    1170             :                 {
    1171          50 :                     rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[1] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
    1172          50 :                     move32();
    1173          50 :                     rInterp_exp[k] = temp;
    1174          50 :                     move16();
    1175             :                 }
    1176      318889 :                 ELSE IF( LT_16( j, sub( lagSearchRange[0], corrLagStats[0] ) ) )
    1177             :                 {
    1178         176 :                     rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[0] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
    1179         176 :                     move32();
    1180         176 :                     rInterp_exp[k] = temp;
    1181         176 :                     move16();
    1182             :                 }
    1183             :                 ELSE
    1184             :                 {
    1185      318713 :                     rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[j], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
    1186      318713 :                     move32();
    1187      318713 :                     rInterp_exp[k] = temp;
    1188      318713 :                     move16();
    1189             :                 }
    1190             :             }
    1191             :         }
    1192             :     }
    1193        3811 :     temp = rInterp_exp[0];
    1194        3811 :     move16();
    1195       45732 :     FOR( i = 0; i < MAX_INTERPOLATE; i++ )
    1196             :     {
    1197       41921 :         temp = s_max( temp, rInterp_exp[i] );
    1198             :     }
    1199             : 
    1200       45732 :     FOR( i = 0; i < MAX_INTERPOLATE; i++ )
    1201             :     {
    1202       41921 :         rInterp_fx[i] = L_shl( rInterp_fx[i], sub( rInterp_exp[i], temp ) ); /* Q31-rInterp_exp[i] */
    1203       41921 :         move32();
    1204             :     }
    1205             : 
    1206        3811 :     corrLagStats[1] = add( corrLagStats[1], add( maximum_32_fx( rInterp_fx, interpLen, &tempF_fx ), interpMin ) ); /* Q0 */
    1207        3811 :     move16();
    1208             : 
    1209             :     /* save corr lag stats for the current frame */
    1210        3811 :     Copy( corrLagStats, hStereoTCA->corrLagStats, 3 ); /* Q0 */
    1211             : 
    1212        3811 :     return;
    1213             : }
    1214             : 
    1215             : /*---------------------------------------------------------------
    1216             :  *  Function estDownmixGain_fx()
    1217             :  *
    1218             :  *  Down mix gain estimation module; convert L/R to M/S.
    1219             :  * ---------------------------------------------------------------*/
    1220             : 
    1221       63470 : static void estDownmixGain_fx(
    1222             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: Stereo TCA Encoder handle   */
    1223             :     const Word32 *chan1,                  /* i  : reference signal           q_chan */
    1224             :     const Word32 *chan2,                  /* i/o: target signal to be scaled q_chan */
    1225             :     const Word16 q_chan,                  /* i  : Q of the channel signal     Q0*/
    1226             :     const Word16 ncShift,                 /* i  : shift                       Q0*/
    1227             :     const Word16 length,                  /* i  : input frame length          Q0*/
    1228             :     const Word16 element_mode,            /* i  : element mode                Q0*/
    1229             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle    */
    1230             :     const Word16 tdm_LRTD_flag            /* i  : LRTD stereo mode flag       Q0*/
    1231             : )
    1232             : {
    1233             :     Word16 i, i1, i2;
    1234             :     Word32 tempN, tempD;
    1235             :     Word16 alpha, temp;
    1236             :     Word16 currentGain, currentGain_e;
    1237             :     Word32 currentGain_log10;
    1238             :     Word32 unclr_instTargetGain;
    1239             :     Word32 prevTargetGain_log10;
    1240       63470 :     Word16 exp = 0;
    1241       63470 :     Word16 shift = 0;
    1242       63470 :     move16(); // exp
    1243       63470 :     move16(); // shift
    1244             : 
    1245       63470 :     IF( hStereoTCA->refChanIndx == L_CH_INDX )
    1246             :     {
    1247       63452 :         i1 = 0;
    1248       63452 :         move16();
    1249       63452 :         i2 = ncShift; /* Q0 */
    1250       63452 :         move16();
    1251             :     }
    1252             :     ELSE
    1253             :     {
    1254          18 :         i1 = ncShift; /* Q0 */
    1255          18 :         move16();
    1256          18 :         i2 = 0;
    1257          18 :         move16();
    1258             :     }
    1259             : 
    1260             :     /* abs sample sum estimation */
    1261       63470 :     tempN = 0;
    1262       63470 :     move32();
    1263       63470 :     tempD = 0;
    1264       63470 :     move32();
    1265    43752964 :     FOR( i = 0; i < length; i++ )
    1266             :     {
    1267    43689494 :         tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); /* q_chan */
    1268    43689494 :         tempD = L_add( tempD, L_abs( chan2[i2 + i] ) ); /* q_chan */
    1269             :     }
    1270             : 
    1271       63470 :     alpha = hStereoTCA->corrStatsSmoothFac_fx; /* Q15 */
    1272       63470 :     move16();
    1273       63470 :     IF( tempD == 0 )
    1274             :     {
    1275           0 :         currentGain_e = norm_l( hStereoTCA->prevTargetGain_fx );
    1276           0 :         currentGain = extract_h( L_shl( hStereoTCA->prevTargetGain_fx, currentGain_e ) );
    1277           0 :         currentGain_e = add( currentGain_e, 2 );
    1278             :     }
    1279             :     ELSE
    1280             :     {
    1281       63470 :         currentGain = BASOP_Util_Divide3232_Scale( tempN, tempD, &exp ); /* Q31-exp */
    1282       63470 :         currentGain_e = exp;
    1283       63470 :         move16();
    1284       63470 :         if ( currentGain == 0 )
    1285             :         {
    1286           0 :             currentGain_e = 0;
    1287           0 :             move16();
    1288             :         }
    1289             :     }
    1290             : 
    1291       63470 :     IF( GT_32( EPSILON_FX, currentGain ) )
    1292             :     {
    1293           0 :         currentGain = EPSILON_FX;
    1294           0 :         move16();
    1295           0 :         currentGain_e = 0;
    1296           0 :         move16();
    1297             :     }
    1298       63470 :     hStereoTCA->instTargetGain_fx = L_shl_sat( L_deposit_h( currentGain ), sub( currentGain_e, 2 ) );
    1299       63470 :     move32();
    1300       63470 :     prevTargetGain_log10 = BASOP_Util_Log10( hStereoTCA->prevTargetGain_fx, 2 );       // Output in Q25
    1301       63470 :     currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25
    1302             :     // multiplication result will be Q25 should be fit to Q15 hence right shift by 10.
    1303             :     // Q25 - Q10 = Q15
    1304       63470 :     currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */
    1305       63470 :     currentGain_e = 0;
    1306       63470 :     move16();
    1307             : 
    1308       63470 :     test();
    1309       63470 :     IF( EQ_16( element_mode, IVAS_CPE_TD ) && hStereoClassif != NULL )
    1310             :     {
    1311        3811 :         Word16 exp_chan = sub( Q31, q_chan );
    1312             :         Word16 exp_div;
    1313             :         // tempD = powf( 10, currentGain );
    1314             :         //  10 ^ currentGain = 2 ^ (3.32192809488 * currentGain)
    1315             :         //  3.32192809488 in Q13 27213
    1316        3811 :         tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp );                          /* Q31-exp */
    1317        3811 :         unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); /* Q31-exp */
    1318        3811 :         exp = add( sub( exp_chan, exp ), exp_div );
    1319        3811 :         if ( unclr_instTargetGain == 0 )
    1320             :         {
    1321           0 :             exp = 0;
    1322           0 :             move16();
    1323             :         }
    1324        3811 :         unclr_instTargetGain = BASOP_Util_Log10( L_add( unclr_instTargetGain, L_shr( MAX_32, sub( Q31, exp ) ) ), exp );
    1325             :         // unclr_fv_fx is expected in Q15 - log result will be in Q25 - hence rightshift by 10.
    1326        3811 :         hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); /* Q15 */
    1327        3811 :         move32();
    1328             :     }
    1329             : 
    1330       63470 :     test();
    1331       63470 :     IF( EQ_16( tdm_LRTD_flag, 1 ) )
    1332             :     {
    1333        3690 :         currentGain = 0;
    1334        3690 :         move32();
    1335             :     }
    1336       59780 :     ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
    1337             :     {
    1338         211 :         currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, &exp );
    1339         211 :         currentGain_e = add( exp, sub( currentGain_e, 15 ) );
    1340             :     }
    1341             : 
    1342       63470 :     IF( GE_16( norm_s( currentGain ), sub( currentGain_e, 1 ) ) )
    1343             :     {
    1344             :         /* convert currentGain into Q14 */
    1345       63470 :         currentGain = shl( currentGain, sub( currentGain_e, 1 ) ); /* Q14 */
    1346       63470 :         currentGain_e = 1;
    1347       63470 :         move16();
    1348             :     }
    1349             :     ELSE
    1350             :     {
    1351           0 :         shift = sub( currentGain_e, 1 );
    1352           0 :         move16();
    1353             :     }
    1354             : 
    1355             :     /* quantize the target gain */
    1356       63470 :     hStereoTCA->indx_ica_gD = usquant_fx( currentGain, &temp, shr( STEREO_TCA_GDMIN_FX_Q14, shift ), shr( STEREO_TCA_GDSTEP_FX_Q13, shift ), ( 1 << STEREO_BITS_TCA_GD ) ); /* Q13 */
    1357       63470 :     move16();
    1358             :     // hStereoTCA->targetGain_fx = powf( 10, temp );
    1359             :     //  10 ^ temp = 2 ^ (3.32192809488 * temp)
    1360             :     //  3.32192809488 in Q13 27213
    1361             :     //  exponent of power function input will be 2 more since constant is in Q13
    1362       63470 :     exp = 2;
    1363       63470 :     move16();
    1364       63470 :     hStereoTCA->targetGain_fx = BASOP_util_Pow2( L_mult( temp, 27213 ), add( currentGain_e, 2 ), &exp ); /* Q31-exp */
    1365       63470 :     move32();
    1366       63470 :     hStereoTCA->targetGain_fx = L_shl( hStereoTCA->targetGain_fx, sub( exp, 2 ) ); // Q29
    1367       63470 :     move32();
    1368       63470 :     return;
    1369             : }
    1370             : 
    1371             : /*---------------------------------------------------------------
    1372             :  *  Function icaMemUpdate()
    1373             :  *
    1374             :  *  Recalculates the memories corresponding to the previous frame.
    1375             :  * ---------------------------------------------------------------*/
    1376        3811 : static void icaMemUpdate_fx(
    1377             :     Encoder_State **sts, /* i/o: encoder state structure                 */
    1378             :     CPE_ENC_HANDLE hCPE, /* i  : CPE encoder structure                   */
    1379             :     Word32 *bufChanL,    /* i/o: L signal correction from previous frame q_com*/
    1380             :     Word32 *bufChanR,    /* i/o: R signal correction from previous frame q_com*/
    1381             :     Word16 q_com,
    1382             :     const Word16 lMemRecalc,     /* i  : memory length at input Sampling Rate     Q0*/
    1383             :     const Word16 lMemRecalc_SCh, /* i  : SCh memory length at input Sampling Rate Q0*/
    1384             :     const Word16 input_frame     /* i  : frame length                             Q0*/
    1385             : )
    1386             : {
    1387             :     Word32 *ptr1, *ptr2;
    1388             :     Word16 i;
    1389             :     Word32 ratio_L, One_m_Ratio;
    1390             : 
    1391        3811 :     IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
    1392             :     {
    1393             :         /* Recalc of the memories - Downmix @ inputFs */
    1394             :         /*----------------------------------------------------------------*
    1395             :          * Create first part of the mixture using the old ratios
    1396             :          *----------------------------------------------------------------*/
    1397             : 
    1398        3811 :         IF( hCPE->hStereoTD->tdm_last_SM_flag )
    1399             :         {
    1400           0 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM_fx; /* Q31 */
    1401           0 :             move32();
    1402           0 :             One_m_Ratio = L_sub( ratio_L, MAX_32 );
    1403             :         }
    1404             :         ELSE
    1405             :         {
    1406        3811 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio_fx; /* Q31 */
    1407        3811 :             move32();
    1408        3811 :             One_m_Ratio = L_sub( MAX_32, ratio_L );
    1409             :         }
    1410             : 
    1411        3811 :         ptr1 = sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[0]->q_inp32 */
    1412        3811 :         ptr2 = sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[1]->q_inp32 */
    1413             : 
    1414        3811 :         IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
    1415             :         {
    1416        3751 :             IF( hCPE->hStereoTD->flag_skip_DMX )
    1417             :             {
    1418       30932 :                 FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
    1419             :                 {
    1420       30840 :                     ptr1[i] = bufChanL[i]; /* q_com */
    1421       30840 :                     move32();
    1422       30840 :                     ptr2[i] = bufChanR[i]; /* q_com */
    1423       30840 :                     move32();
    1424             :                 }
    1425             :             }
    1426             :             ELSE
    1427             :             {
    1428      903299 :                 FOR( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
    1429             :                 {
    1430      899640 :                     ptr1[i] = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
    1431      899640 :                     move32();
    1432      899640 :                     ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1433      899640 :                     move32();
    1434             :                 }
    1435             :             }
    1436             :         }
    1437             :         ELSE
    1438             :         {
    1439             :             Word16 fac, incr;
    1440             :             Word32 tmp1, tmp2;
    1441             : 
    1442             :             /* reset the past input signal (the signal is used in SWB BWE) */
    1443          60 :             set32_fx( sts[1]->input32_fx - input_frame, 0, input_frame );
    1444             : 
    1445          60 :             IF( hCPE->hStereoTD->flag_skip_DMX )
    1446             :             {
    1447             :                 /* reconstruction of the Secondary channel past segment */
    1448         813 :                 FOR( i = 0; i < lMemRecalc_SCh; i++ )
    1449             :                 {
    1450         805 :                     ptr2[i] = L_add( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1451         805 :                     move32();
    1452             :                 }
    1453             : 
    1454             :                 /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
    1455           8 :                 fac = div_s( 1, lMemRecalc ); // Q15
    1456           8 :                 incr = fac;                   // Q15
    1457           8 :                 move16();
    1458             : 
    1459        2768 :                 FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
    1460             :                 {
    1461        2760 :                     tmp1 = bufChanL[i]; /* q_com */
    1462        2760 :                     move32();
    1463        2760 :                     tmp2 = bufChanR[i]; /* q_com */
    1464        2760 :                     move32();
    1465             : 
    1466        2760 :                     ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */
    1467        2760 :                     move32();
    1468             : 
    1469             :                     /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
    1470        2760 :                     ptr2[i] = tmp2;                                    /* q_com */
    1471        2760 :                     move32();
    1472             : 
    1473        2760 :                     fac = add_sat( fac, incr );
    1474             :                 }
    1475             :             }
    1476             :             ELSE
    1477             :             {
    1478             :                 /* reconstruction of the Secondary channel past segment */
    1479        3902 :                 FOR( i = 0; i < lMemRecalc_SCh; i++ )
    1480             :                 {
    1481        3850 :                     ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1482        3850 :                     move32();
    1483             :                 }
    1484             : 
    1485             :                 /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
    1486          52 :                 fac = div_s( 1, lMemRecalc ); // Q15
    1487          52 :                 incr = fac;                   // Q15
    1488          52 :                 move16();
    1489       13252 :                 FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
    1490             :                 {
    1491       13200 :                     tmp1 = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
    1492       13200 :                     tmp2 = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1493             : 
    1494       13200 :                     ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */
    1495       13200 :                     move32();
    1496             :                     /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
    1497       13200 :                     ptr2[i] = tmp2;                                    /* q_com */
    1498       13200 :                     move32();
    1499             : 
    1500       13200 :                     fac = add_sat( fac, incr );
    1501             :                 }
    1502             :             }
    1503             :         }
    1504             :     }
    1505             : 
    1506        3811 :     IF( hCPE->hStereoICBWE != NULL )
    1507             :     {
    1508             :         assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
    1509         121 :         i = NS2SA_FX2( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
    1510         121 :         Copy_Scale_sig_32_16( bufChanL + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], i, -Q16 ); /* q_com-16 */
    1511         121 :         Copy_Scale_sig_32_16( bufChanR + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], i, -Q16 ); /* q_com-16 */
    1512         121 :         hCPE->hStereoICBWE->q_dataChan_fx = sub( q_com, Q16 );
    1513         121 :         move16();
    1514             :     }
    1515             : 
    1516        3811 :     return;
    1517             : }
    1518             : /*---------------------------------------------------------------
    1519             :  *  stereo_tca_enc()
    1520             :  *
    1521             :  *     Stereo temporal inter-channel adjustment/allocation processing module;
    1522             :  *     Downmix, convert L/R to M/S.
    1523             :  * ---------------------------------------------------------------*/
    1524      410255 : void stereo_tca_enc_fx(
    1525             :     CPE_ENC_HANDLE hCPE,     /* i  : CPE encoder structure           */
    1526             :     const Word16 input_frame /* i  : length of a frame per channel   Q0*/
    1527             : )
    1528             : {
    1529             :     /* temp variables */
    1530             :     Word16 i, dsFactor, lMemRecalc;
    1531             :     Encoder_State **sts;
    1532             :     STEREO_TCA_ENC_HANDLE hStereoTCA;
    1533             : 
    1534             :     /* Buffers, input Left and right channels  @ input_Fs*/
    1535             :     Word16 lMemRecalc_SCh;
    1536             :     Word32 input_mem_loc_fx[2][NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS )];
    1537             :     Word32 bufChanL_fx[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
    1538             :     Word32 bufChanR_fx[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
    1539             :     Word32 *ptrChanL_fx, *ptrChanR_fx;
    1540             : 
    1541      410255 :     set32_fx( bufChanL_fx, 0, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );
    1542      410255 :     set32_fx( bufChanR_fx, 0, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );
    1543      410255 :     set32_fx( input_mem_loc_fx[0], 0, NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ) );
    1544      410255 :     set32_fx( input_mem_loc_fx[1], 0, NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ) );
    1545             :     /* Buffers at internal sampling rate, i.e., CORR_INTER_FS */
    1546             :     Word32 bufChanL_DS_fx[L_FRAME_DS + ADDED_MEM_DS];
    1547             :     Word32 bufChanR_DS_fx[L_FRAME_DS + ADDED_MEM_DS];
    1548             :     Word32 *ptrChanL_DS_fx, *ptrChanR_DS_fx;
    1549             :     Word32 *target_fx;
    1550             :     Word16 target_idx;
    1551             : 
    1552             :     Word16 prevNCShift, currentNCShift;
    1553             :     Word16 tempLag[2];
    1554             :     Word32 corrEstStage2_fx[N_MAX_SHIFT_CHANGE + 1];
    1555             :     Word16 corrEstStage2_exp;
    1556             :     Word16 q_com, bufChan_q, input_mem_loc_q;
    1557             :     /* temp variables */
    1558             :     Word32 tempF1_fx, tempF_fx;
    1559             :     Word16 tempF1_exp;
    1560             :     Word16 tempS, tempS_buff[3];
    1561             :     Word16 maxCorrStatsDev, L_shift_adapt;
    1562      410255 :     Word16 musicMode = 0, neighborLimit;
    1563      410255 :     move16();
    1564             :     Word32 input_Fs;
    1565             :     Word16 prev_ICA_flag;
    1566             : 
    1567             :     /* initialization */
    1568      410255 :     sts = hCPE->hCoreCoder;
    1569      410255 :     hStereoTCA = hCPE->hStereoTCA;
    1570             : 
    1571      410255 :     input_Fs = sts[0]->input_Fs;
    1572      410255 :     move32();
    1573             : 
    1574      410255 :     q_com = sts[0]->q_inp32;
    1575      410255 :     move16();
    1576             : 
    1577      410255 :     lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS );
    1578      410255 :     move16();
    1579      410255 :     lMemRecalc_SCh = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS );
    1580      410255 :     move16();
    1581             : 
    1582      410255 :     IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) )
    1583             :     {
    1584      346785 :         return;
    1585             :     }
    1586             : 
    1587             :     /* populate L/R memories into current buffers */
    1588       63470 :     Word16 tempp_scale = L_norm_arr( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
    1589       63470 :     tempp_scale = s_min( tempp_scale, L_norm_arr( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH ) );
    1590       63470 :     scale_sig32( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */
    1591       63470 :     scale_sig32( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */
    1592       63470 :     hStereoTCA->memChan_q = add( hStereoTCA->memChan_q, tempp_scale );
    1593       63470 :     move16();
    1594       63470 :     Copy32( hStereoTCA->memChanL_fx, bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */
    1595       63470 :     Copy32( hStereoTCA->memChanR_fx, bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */
    1596       63470 :     bufChan_q = hStereoTCA->memChan_q;
    1597       63470 :     move16();
    1598             :     /* pointers to the current frame */
    1599       63470 :     ptrChanL_fx = bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ); // Q:bufChan_q
    1600       63470 :     ptrChanR_fx = bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ); // Q:bufChan_q
    1601             : 
    1602             :     /* copy interleaved stereo data to two channels, e.g., L, R */
    1603       63470 :     Copy32( sts[0]->input32_fx, ptrChanL_fx, input_frame ); /* sts[0]->q_inp32 */
    1604       63470 :     Copy32( sts[1]->input32_fx, ptrChanR_fx, input_frame ); /* sts[1]->q_inp32 */
    1605             : 
    1606             :     /* Scaling buffers to common Q*/
    1607       63470 :     scale_sig32( ptrChanL_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) );                           /* s_min( q_com, bufChan_q ) */
    1608       63470 :     scale_sig32( ptrChanR_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) );                           /* s_min( q_com, bufChan_q ) */
    1609       63470 :     scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */
    1610       63470 :     scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */
    1611       63470 :     bufChan_q = s_min( q_com, bufChan_q );
    1612       63470 :     q_com = bufChan_q;
    1613       63470 :     move16();
    1614             :     /* UNCLR classifier update */
    1615       63470 :     IF( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
    1616             :     {
    1617       59440 :         hStereoTCA->LRTD_G_ATT_cnt = 1;
    1618       59440 :         move16();
    1619             :     }
    1620        4030 :     ELSE IF( hCPE->hStereoTD != NULL )
    1621             :     {
    1622        3811 :         IF( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
    1623             :         {
    1624         121 :             hStereoTCA->LRTD_G_ATT_cnt = add( hStereoTCA->LRTD_G_ATT_cnt, 1 );
    1625         121 :             move16();
    1626         121 :             hStereoTCA->LRTD_G_ATT_cnt = s_min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
    1627         121 :             move16();
    1628             :         }
    1629             :     }
    1630             : 
    1631       63470 :     IF( NE_16( hCPE->element_mode, IVAS_CPE_TD ) )
    1632             :     {
    1633       59659 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1634       59659 :         move16();
    1635       59659 :         hStereoTCA->corrStatsSmoothFac_fx = 22938 /*0.7 in Q15 */;
    1636       59659 :         move16();
    1637       59659 :         estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, NULL, 0 );
    1638       59659 :         hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx;
    1639       59659 :         move16();
    1640             : 
    1641             :         /* back up the L/R missing target */
    1642       59659 :         Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
    1643       59659 :         Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
    1644       59659 :         hStereoTCA->memChan_q = q_com;
    1645       59659 :         move16();
    1646       59659 :         hStereoTCA->lMemRecalc = 0;
    1647       59659 :         move16();
    1648       59659 :         hStereoTCA->lMemRecalc_12k8 = 0;
    1649       59659 :         move16();
    1650       59659 :         hStereoTCA->lMemRecalc_16k = 0;
    1651       59659 :         move16();
    1652             : 
    1653       59659 :         return;
    1654             :     }
    1655        3811 :     ELSE IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
    1656             :     {
    1657          60 :         tempF_fx = hStereoTCA->targetGain_fx; // Q29
    1658          60 :         move32();
    1659          60 :         tempF1_fx = hStereoTCA->prevTargetGain_fx; // Q29
    1660          60 :         move32();
    1661          60 :         tempS = hStereoTCA->prevRefChanIndx;
    1662          60 :         move16();
    1663             : 
    1664          60 :         Copy( hStereoTCA->prevCorrLagStats, tempS_buff, 3 ); /* Q0 */
    1665             : 
    1666          60 :         stereo_tca_init_enc_fx( hStereoTCA, input_Fs );
    1667             : 
    1668          60 :         hStereoTCA->targetGain_fx = tempF_fx; // Q29
    1669          60 :         move32();
    1670          60 :         hStereoTCA->prevTargetGain_fx = tempF1_fx; // Q29
    1671          60 :         move32();
    1672             : 
    1673          60 :         IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
    1674             :         {
    1675          60 :             hStereoTCA->targetGain_fx = L_min( hStereoTCA->targetGain_fx, ONE_IN_Q29 ); // Q29
    1676          60 :             move32();
    1677          60 :             hStereoTCA->prevTargetGain_fx = L_min( hStereoTCA->prevTargetGain_fx, ONE_IN_Q29 ); // Q29
    1678          60 :             move32();
    1679             : 
    1680          60 :             hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
    1681          60 :             move32();
    1682             :         }
    1683             : 
    1684          60 :         hStereoTCA->prevRefChanIndx = tempS;
    1685          60 :         move16();
    1686          60 :         Copy( tempS_buff, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
    1687             : 
    1688             :         /* populate memory */
    1689          60 :         IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) )
    1690             :         {
    1691           8 :             Copy32( sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[0]->q_inp32 */
    1692           8 :             Copy32( sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[1]->q_inp32 */
    1693             :         }
    1694             :     }
    1695             : 
    1696             :     /* populate L/R DS memories into current buffers */
    1697        3811 :     Copy32( hStereoTCA->memChanL_DS_fx, bufChanL_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
    1698        3811 :     Copy32( hStereoTCA->memChanR_DS_fx, bufChanR_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
    1699             : 
    1700        3811 :     scale_sig32( bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), bufChan_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
    1701        3811 :     scale_sig32( bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), bufChan_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
    1702             : 
    1703        3811 :     scale_sig32( bufChanL_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
    1704        3811 :     scale_sig32( bufChanR_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
    1705        3811 :     scale_sig32( hStereoTCA->memdecim_fx, 12, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) );  // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
    1706             : 
    1707        3811 :     bufChan_q = s_min( hStereoTCA->memChan_DS_q, bufChan_q );
    1708        3811 :     q_com = bufChan_q;
    1709        3811 :     move16();
    1710        3811 :     hStereoTCA->memChan_DS_q = bufChan_q;
    1711        3811 :     move16();
    1712             : 
    1713             :     /* pointers to the current frame of DS */
    1714             : 
    1715        3811 :     ptrChanL_DS_fx = bufChanL_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
    1716        3811 :     ptrChanR_DS_fx = bufChanR_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
    1717             : 
    1718             :     /* resample factor */
    1719        3811 :     dsFactor = extract_l( Mpy_32_32( input_Fs, 268436 /* 1/CORR_INTER_FS in Q31*/ ) ); // Q0
    1720             : 
    1721             :     /* resample the stereo channels */
    1722        3811 :     deEmphResample_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, ptrChanL_DS_fx, ptrChanR_DS_fx, input_frame, dsFactor );
    1723             : 
    1724             :     /**********************NEED to Allign first 40 index in each channel ************************************/
    1725             :     /* inter-channel corrStats estimation */
    1726        3811 :     corrStatsEst_fx( hStereoTCA, bufChanL_DS_fx + ADDED_MEM_DS, bufChanR_DS_fx + ADDED_MEM_DS, q_com, ( L_FRAME_DS + L_XCORRMEM_DS ), dsFactor, hCPE->hCoreCoder[0]->vad_flag, hCPE->hCoreCoder[1]->vad_flag, hCPE->hStereoClassif );
    1727             : 
    1728             :     /*-----------------------------------------------------------------*
    1729             :      * refine the ICA stats
    1730             :      *-----------------------------------------------------------------*/
    1731             : 
    1732        3811 :     prev_ICA_flag = 0;
    1733        3811 :     move16();
    1734        3811 :     test();
    1735        3811 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 )
    1736             :     {
    1737          33 :         prev_ICA_flag = 1;
    1738          33 :         move16();
    1739             :     }
    1740             : 
    1741        3811 :     test();
    1742        3811 :     IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
    1743         206 :     {
    1744             :         /* initialize the refinement search for NC-shift */
    1745         206 :         hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
    1746         206 :         move16();
    1747         206 :         maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
    1748         206 :         move16();
    1749         206 :         IF( LE_16( hStereoTCA->corrStatsSmoothFac_fx, 22938 /*0.7f*/ ) )
    1750             :         {
    1751           0 :             maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
    1752           0 :             move16();
    1753             :         }
    1754             : 
    1755         206 :         IF( LT_32( input_Fs, 32000 ) )
    1756             :         {
    1757          35 :             maxCorrStatsDev = extract_l( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0
    1758             :         }
    1759             : 
    1760         206 :         musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
    1761         206 :         move16();
    1762             : 
    1763         206 :         IF( musicMode )
    1764             :         {
    1765          56 :             maxCorrStatsDev = 1;
    1766          56 :             move16();
    1767          56 :             set16_fx( hStereoTCA->corrLagStats + 1, 0, 2 );
    1768             :         }
    1769             : 
    1770         206 :         tempS = sub( hStereoTCA->corrLagStats[1], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1771             : 
    1772         206 :         IF( GT_16( abs_s( tempS ), maxCorrStatsDev ) )
    1773             :         {
    1774          85 :             IF( tempS > 0 )
    1775             :             {
    1776          24 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], maxCorrStatsDev ); /* Q0 */
    1777             :             }
    1778             :             ELSE
    1779             :             {
    1780          61 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], -maxCorrStatsDev ); /* Q0 */
    1781             :             }
    1782          85 :             move16();
    1783             :         }
    1784             : 
    1785         206 :         neighborLimit = maxCorrStatsDev;
    1786         206 :         move16();
    1787             :         /* refine and search based on the corrlag stats */
    1788         206 :         test();
    1789         206 :         test();
    1790         206 :         IF( tempS != 0 && NE_16( dsFactor, 1 ) && prev_ICA_flag == 0 )
    1791             :         {
    1792         147 :             tempF_fx = 0;
    1793         147 :             move32();
    1794         147 :             corrEstStage2_exp = 0;
    1795         147 :             move16();
    1796         147 :             IF( !musicMode )
    1797             :             {
    1798         126 :                 tempLag[0] = s_min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1799         126 :                 move16();
    1800         126 :                 tempLag[1] = s_max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1801         126 :                 move16();
    1802             : 
    1803         126 :                 neighborLimit = s_min( 3, maxCorrStatsDev );
    1804             : 
    1805         126 :                 IF( LT_16( hStereoTCA->prevCorrLagStats[2], hStereoTCA->corrLagStats[2] ) )
    1806             :                 {
    1807          96 :                     tempLag[1] = s_min( tempLag[1], add( tempLag[0], neighborLimit ) ); /* Q0 */
    1808             :                 }
    1809             :                 ELSE
    1810             :                 {
    1811          30 :                     tempLag[0] = s_max( tempLag[0], sub( tempLag[1], neighborLimit ) ); /* Q0 */
    1812             :                 }
    1813         126 :                 move16();
    1814         126 :                 utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, corrEstStage2_fx, &corrEstStage2_exp, tempLag, input_frame, 0 );
    1815             : 
    1816         126 :                 hStereoTCA->corrLagStats[2] = maximum_l( corrEstStage2_fx, add( sub( tempLag[1], tempLag[0] ), 1 ), &tempF_fx );
    1817         126 :                 move16();
    1818         126 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->corrLagStats[2], tempLag[0] );
    1819         126 :                 move16();
    1820             :             }
    1821             : 
    1822         147 :             IF( GT_16( abs_s( tempS ), neighborLimit ) )
    1823             :             {
    1824         115 :                 tempLag[0] = hStereoTCA->corrLagStats[1]; /* Q0 */
    1825         115 :                 move16();
    1826         115 :                 tempLag[1] = hStereoTCA->corrLagStats[1]; /* Q0 */
    1827         115 :                 move16();
    1828         115 :                 utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, &tempF1_fx, &tempF1_exp, tempLag, input_frame, 0 );
    1829             : 
    1830         115 :                 test();
    1831         115 :                 IF( ( BASOP_Util_Cmp_Mant32Exp( tempF1_fx, tempF1_exp, tempF_fx, corrEstStage2_exp ) > 0 ) || musicMode )
    1832             :                 {
    1833          32 :                     IF( tempS > 0 )
    1834             :                     {
    1835           8 :                         hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_min( abs_s( tempS ), maxCorrStatsDev ) ); /* Q0 */
    1836             :                     }
    1837             :                     ELSE
    1838             :                     {
    1839          24 :                         hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_max( -abs_s( tempS ), -maxCorrStatsDev ) ); /* Q0 */
    1840             :                     }
    1841          32 :                     move16();
    1842             :                 }
    1843             :             }
    1844             : 
    1845             :             /* restrict the reference channel for +/- variation */
    1846         147 :             test();
    1847         147 :             test();
    1848         147 :             test();
    1849         147 :             if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
    1850             :             {
    1851           1 :                 hStereoTCA->corrLagStats[2] = 0;
    1852           1 :                 move16();
    1853             :             }
    1854             :         }
    1855             : 
    1856         206 :         IF( EQ_16( hCPE->hStereoTD->prev_fr_LRTD_TD_dec /*hCPE->hStereoClassif->lrtd_mode*/, 1 ) ) /* Content is considered as uncorrelated -> ICA shift is turned off  */
    1857             :         {
    1858          33 :             hStereoTCA->corrLagStats[2] = 0;
    1859          33 :             move16();
    1860             : 
    1861          33 :             test();
    1862          33 :             if ( EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 1 ) && prev_ICA_flag == 0 )
    1863             :             {
    1864           0 :                 hStereoTCA->prevCorrLagStats[2] = 0;
    1865           0 :                 move16();
    1866             :             }
    1867             :         }
    1868             : 
    1869             :         /* Perform the following:
    1870             :            1. adjust samples,
    1871             :            2. interp shift variation,
    1872             :            3. gain estimation */
    1873         206 :         prevNCShift = abs_s( hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1874         206 :         currentNCShift = abs_s( hStereoTCA->corrLagStats[2] );  /* Q0 */
    1875             : 
    1876         206 :         IF( EQ_16( hStereoTCA->prevRefChanIndx, L_CH_INDX ) )
    1877             :         {
    1878         188 :             v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );                                                  /* TO make in common Q bufChan_q - 2*/
    1879         188 :             Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                                                           // bufChan_q - 2
    1880         188 :             v_multc_fixed( ptrChanR_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q-2
    1881         188 :             v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );                                                  /* TO make in common Q bufChan_q -2*/
    1882             :         }
    1883             :         ELSE
    1884             :         {
    1885          18 :             v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );                              /* TO make in common Q bufChan_q -2*/
    1886          18 :             Copy32( ptrChanL_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                   // bufChan_q -2
    1887          18 :             v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
    1888          18 :             v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );                              /* TO make in common Q bufChan_q -2*/
    1889             :         }
    1890         206 :         bufChan_q = sub( bufChan_q, 2 );
    1891         206 :         q_com = bufChan_q;
    1892         206 :         move16();
    1893         206 :         input_mem_loc_q = bufChan_q;
    1894         206 :         move16();
    1895         206 :         target_fx = ptrChanR_fx; /* bufChan_q -2 */
    1896         206 :         target_idx = R_CH_INDX;  /* Q0 */
    1897         206 :         move16();
    1898             :         /* identify target signal to correct for shift variations */
    1899         206 :         test();
    1900         206 :         test();
    1901         206 :         IF( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || EQ_16( hStereoTCA->prevRefChanIndx, R_CH_INDX ) )
    1902             :         {
    1903          35 :             target_fx = ptrChanL_fx; /* bufChan_q - 2 */
    1904          35 :             target_idx = L_CH_INDX;
    1905          35 :             move16();
    1906             :         }
    1907             : 
    1908             :         /* target signal adjustment for temporal shift variations */
    1909         206 :         IF( sub( prevNCShift, currentNCShift ) != 0 )
    1910             :         {
    1911         110 :             L_shift_adapt = L_SHIFT_ADAPT_16k;
    1912         110 :             move16();
    1913         110 :             if ( GT_32( input_Fs, INT_FS_16k ) )
    1914             :             {
    1915          92 :                 L_shift_adapt = L_SHIFT_ADAPT_MAX;
    1916          92 :                 move16();
    1917             :             }
    1918             : 
    1919             :             /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */
    1920         110 :             tempS = shr( currentNCShift, 1 ); /* Q0 */
    1921             : 
    1922         110 :             IF( LE_32( abs_s( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) )
    1923             :             {
    1924          93 :                 adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
    1925             :             }
    1926             :             ELSE
    1927             :             {
    1928          17 :                 tempS = s_min( s_max( tempS, add( sub( prevNCShift, currentNCShift ), sub( L_shift_adapt, input_frame ) ) ), add( sub( prevNCShift, currentNCShift ), lMemRecalc ) ); /* Q0 */
    1929             : 
    1930          17 :                 adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
    1931             :             }
    1932             : 
    1933         110 :             IF( target_idx == L_CH_INDX )
    1934             :             {
    1935          34 :                 Copy32( target_fx - tempS, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */
    1936             :             }
    1937             :             ELSE
    1938             :             {
    1939          76 :                 v_multc_fixed( target_fx - tempS, hStereoTCA->prevTargetGain_fx, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */
    1940          76 :                 scale_sig32( input_mem_loc_fx[target_idx], sub( sub( add( lMemRecalc, lMemRecalc_SCh ), tempS ), currentNCShift ), -2 );
    1941          76 :                 scale_sig32( &input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh], sub( NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), add( lMemRecalc, lMemRecalc_SCh ) ), -2 );
    1942          76 :                 scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), -2 );
    1943          76 :                 input_mem_loc_q = sub( bufChan_q, 2 );
    1944             :             }
    1945             :         }
    1946             : 
    1947             :         /* reference channel index */
    1948         206 :         IF( hStereoTCA->corrLagStats[2] >= 0 )
    1949             :         {
    1950         188 :             hStereoTCA->refChanIndx = L_CH_INDX;
    1951             :         }
    1952             :         ELSE
    1953             :         {
    1954          18 :             hStereoTCA->refChanIndx = R_CH_INDX;
    1955             :         }
    1956         206 :         move16();
    1957             : 
    1958             :         /* Estimate and quantize the gain for scaling */
    1959             : 
    1960         206 :         estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, currentNCShift, sub( input_frame, currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
    1961             : 
    1962             :         /* quantize the corrStats */
    1963             : 
    1964             :         Word16 temp_exp, tempF_16fx;
    1965         206 :         Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */
    1966             : 
    1967         206 :         scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) );                                                                          /*Q10*/
    1968         206 :         hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */
    1969             : 
    1970         206 :         tempF_fx = tempF_16fx;
    1971         206 :         move32();
    1972             :     }
    1973             :     ELSE
    1974             :     {
    1975        3605 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1976        3605 :         move16();
    1977        3605 :         hStereoTCA->corrLagStats[2] = 0;
    1978        3605 :         move16();
    1979        3605 :         hStereoTCA->prevCorrLagStats[2] = 0;
    1980        3605 :         move16();
    1981        3605 :         hStereoTCA->indx_ica_NCShift = 0;
    1982        3605 :         move16();
    1983             : 
    1984        3605 :         currentNCShift = 0; /* only to avoid compilation warning */
    1985        3605 :         move16();
    1986        3605 :         target_fx = ptrChanL_fx; /* only to avoid compilation warning bufChan_q*/
    1987        3605 :         move16();
    1988        3605 :         target_idx = L_CH_INDX; /* only to avoid compilation warning */
    1989        3605 :         move16();
    1990             : 
    1991        3605 :         v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/
    1992             : 
    1993        3605 :         Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                                       // bufChan_q -2
    1994        3605 :         v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
    1995             : 
    1996        3605 :         v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2 */
    1997        3605 :         bufChan_q = sub( bufChan_q, 2 );
    1998        3605 :         q_com = bufChan_q;
    1999        3605 :         move16();
    2000        3605 :         input_mem_loc_q = bufChan_q;
    2001        3605 :         move16();
    2002             :         /* Estimate and quantize the gain for scaling */
    2003             : 
    2004        3605 :         estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
    2005             :     }
    2006             : 
    2007             :     /*-----------------------------------------------------------------*
    2008             :      * updates and memory backups
    2009             :      *-----------------------------------------------------------------*/
    2010             : 
    2011             :     /* back up the L/R missing target */
    2012        3811 :     Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
    2013        3811 :     Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
    2014        3811 :     hStereoTCA->memChan_q = bufChan_q;
    2015             : 
    2016        3811 :     IF( currentNCShift != 0 )
    2017             :     {
    2018             :         /* Temporal channel adjustment of the LA samples based on the NC shift */
    2019          94 :         tcaTargetCh_LA_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, &q_com, currentNCShift, input_frame );
    2020             : 
    2021          94 :         scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) );                                                                                                                                                                                                       // s_min( q_com, bufChan_q )
    2022          94 :         scale_sig32( bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) );                                                                                                                                                                      // s_min( q_com, bufChan_q )
    2023          94 :         scale_sig32( bufChanL_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
    2024             : 
    2025             :         /* Scaling to common Q*/
    2026          94 :         scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) );                                                                                                                                                                                                       // s_min( q_com, bufChan_q )
    2027          94 :         scale_sig32( bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) );                                                                                                                                                                      // s_min( q_com, bufChan_q )
    2028          94 :         scale_sig32( bufChanR_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
    2029          94 :         bufChan_q = s_min( q_com, bufChan_q );
    2030          94 :         q_com = bufChan_q;
    2031             :     }
    2032             : 
    2033             :     /* Update of changed samples corresponding to the memory */
    2034             :     /* Scaling to common Q*/
    2035        3811 :     scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), input_mem_loc_q ) );              // s_min( input_mem_loc_q, sts[0]->q_inp32 )
    2036        3811 :     scale_sig32( input_mem_loc_fx[1], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), input_mem_loc_q ) );              // s_min( input_mem_loc_q, sts[0]->q_inp32 )
    2037        3811 :     scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), sts[0]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
    2038        3811 :     scale_sig32( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[1]->q_inp32 ), sts[1]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
    2039             : 
    2040        3811 :     input_mem_loc_q = s_min( input_mem_loc_q, sts[0]->q_inp32 ); /* sts[0]->q_inp32 */
    2041        3811 :     sts[0]->q_inp32 = input_mem_loc_q;
    2042        3811 :     move16();
    2043        3811 :     sts[1]->q_inp32 = input_mem_loc_q;
    2044        3811 :     move16();
    2045             : 
    2046        3811 :     icaMemUpdate_fx( sts, hCPE, input_mem_loc_fx[0], input_mem_loc_fx[1], input_mem_loc_q, lMemRecalc, lMemRecalc_SCh, input_frame );
    2047             : 
    2048             :     /* populate the st->input target buffer */
    2049        3811 :     test();
    2050        3811 :     IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
    2051             :     {
    2052         206 :         Word16 shift = sub( q_com, sts[target_idx]->q_inp32 );
    2053      133326 :         FOR( Word16 idx = 0; idx < input_frame; idx++ )
    2054             :         {
    2055      133120 :             sts[target_idx]->input32_fx[idx] = L_shr( target_fx[currentNCShift + idx], shift );
    2056      133120 :             move32();
    2057             :         }
    2058             :     }
    2059             : 
    2060        3811 :     IF( NE_16( hCPE->element_mode, IVAS_CPE_DFT ) )
    2061             :     {
    2062             :         /* Scale the Right channel with the gain */
    2063             :         Word16 j;
    2064        3811 :         Word16 l_ica_ovl = NS2SA_FX2( input_Fs, STEREO_L_TCA_OVLP_NS );
    2065             : 
    2066        3811 :         Word16 winSlope = div_s( 1, l_ica_ovl ); // Q15
    2067             : 
    2068        3811 :         tempF1_fx = hStereoTCA->targetGain_fx; // Q29
    2069        3811 :         move32();
    2070        3811 :         tempF_fx = hStereoTCA->prevTargetGain_fx; // Q29
    2071        3811 :         move32();
    2072             : 
    2073      634771 :         FOR( ( i = 0, j = 0 ); i < l_ica_ovl; ( i++, j++ ) )
    2074             :         {
    2075      630960 :             sts[1]->input32_fx[i] = L_add( Mpy_32_32( sts[1]->input32_fx[i], Mpy_32_16_1( tempF_fx, sub( MAX_16, imult1616( j, winSlope ) ) ) ), Mpy_32_32( sts[1]->input32_fx[i], Mpy_32_16_1( tempF1_fx, imult1616( j, winSlope ) ) ) ); // inpq-2
    2076      630960 :             move32();
    2077             :         }
    2078             : 
    2079     1896691 :         FOR( ; i < input_frame; i++ )
    2080             :         {
    2081     1892880 :             sts[1]->input32_fx[i] = Mpy_32_32( sts[1]->input32_fx[i], tempF1_fx ); // inpq-2
    2082     1892880 :             move32();
    2083             :         }
    2084             : 
    2085        3811 :         scale_sig32( sts[1]->input_buff32_fx, (Word16) Mpy_32_32( input_Fs, 42949673 ) /* 1/50 in Q31*/, -2 );      // inpq-2
    2086        3811 :         scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), -2 ); // inpq-2
    2087        3811 :         sts[0]->q_inp32 = sub( sts[0]->q_inp32, 2 );
    2088        3811 :         move16();
    2089        3811 :         sts[1]->q_inp32 = sub( sts[1]->q_inp32, 2 );
    2090        3811 :         move16();
    2091        3811 :         sts[0]->q_old_inp32 = sub( sts[0]->q_old_inp32, 2 );
    2092        3811 :         move16();
    2093        3811 :         sts[1]->q_old_inp32 = sub( sts[1]->q_old_inp32, 2 );
    2094        3811 :         move16();
    2095             :     }
    2096             : 
    2097             :     /* update L/R DS memories */
    2098        3811 :     Copy32( bufChanL_DS_fx + L_FRAME_DS, hStereoTCA->memChanL_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
    2099        3811 :     Copy32( bufChanR_DS_fx + L_FRAME_DS, hStereoTCA->memChanR_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
    2100             : 
    2101             :     /* save the reference channel index for next frame */
    2102        3811 :     hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; /* Q0 */
    2103        3811 :     move16();
    2104             :     /* save the corr lag stats for next frame */
    2105        3811 :     Copy( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
    2106             : 
    2107             :     /* save the target gain for next frame */
    2108        3811 :     hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx; // Q29
    2109        3811 :     move32();
    2110        3811 :     return;
    2111             : }
    2112             : /*-------------------------------------------------------------------*
    2113             :  * stereo_tca_init_enc()
    2114             :  *
    2115             :  * Stereo temporal inter-channel adjustment (ICA) encoder initialization
    2116             :  *-------------------------------------------------------------------*/
    2117         891 : void stereo_tca_init_enc_fx(
    2118             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle           */
    2119             :     const Word32 input_Fs             /* i  : input sampling frequency    Q0*/
    2120             : )
    2121             : {
    2122             :     Word16 div1;
    2123             :     Word16 div_e;
    2124         891 :     hStereoTCA->lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS );
    2125         891 :     move16();
    2126         891 :     div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_12k8 ), input_Fs, &div_e ); /* Q15-div_e */
    2127         891 :     hStereoTCA->lMemRecalc_12k8 = shr( div1, 1 + sub( 15, div_e ) );
    2128         891 :     move16();
    2129             : 
    2130         891 :     div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_16k ), input_Fs, &div_e ); /* Q15-div_e */
    2131         891 :     hStereoTCA->lMemRecalc_16k = shr( div1, 1 + sub( 15, div_e ) );
    2132         891 :     move16();
    2133             : 
    2134         891 :     hStereoTCA->refChanIndx = L_CH_INDX;
    2135         891 :     hStereoTCA->prevRefChanIndx = L_CH_INDX;
    2136         891 :     move16();
    2137         891 :     move16();
    2138             : 
    2139         891 :     hStereoTCA->targetGain_fx = ONE_IN_Q29;     // Q29
    2140         891 :     hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
    2141         891 :     hStereoTCA->instTargetGain_fx = ONE_IN_Q29; // Q29
    2142         891 :     move32();
    2143         891 :     move32();
    2144         891 :     move32();
    2145         891 :     hStereoTCA->corrStatsSmoothFac_fx = 22938; // Q15
    2146         891 :     move16();
    2147             : 
    2148         891 :     set16_fx( hStereoTCA->corrLagStats, 0, 3 );
    2149         891 :     set16_fx( hStereoTCA->prevCorrLagStats, 0, 3 );
    2150             : 
    2151         891 :     set32_fx( hStereoTCA->memChanL_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
    2152         891 :     set32_fx( hStereoTCA->memChanR_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
    2153         891 :     hStereoTCA->memChan_q = 31;
    2154         891 :     move16();
    2155         891 :     set32_fx( hStereoTCA->memChanL_DS_fx, 0, ADDED_MEM_DS );
    2156         891 :     set32_fx( hStereoTCA->memChanR_DS_fx, 0, ADDED_MEM_DS );
    2157         891 :     hStereoTCA->memChan_DS_q = Q31;
    2158         891 :     move16();
    2159         891 :     hStereoTCA->mem_tempF_fx = 0;
    2160         891 :     move32();
    2161         891 :     hStereoTCA->mem_tempF_exp = 0;
    2162         891 :     move16();
    2163         891 :     set32_fx( hStereoTCA->corrEstPrev_fx[0], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2164         891 :     set32_fx( hStereoTCA->corrEstPrev_fx[1], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2165         891 :     set32_fx( hStereoTCA->corrEstPrev_fx[2], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2166         891 :     hStereoTCA->corrEstPrev_exp = 0;
    2167         891 :     move16();
    2168         891 :     set32_fx( hStereoTCA->corrEstLT_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2169         891 :     hStereoTCA->corrEstLT_exp = 0;
    2170         891 :     move16();
    2171         891 :     set32_fx( hStereoTCA->memdecim_fx, 0, 12 );
    2172         891 :     hStereoTCA->ica_envVarLT_fx = 2097152000; // 2000 in Q20
    2173         891 :     move32();
    2174         891 :     hStereoTCA->ica_envVarLT_exp = 11; // 2000 in Q20
    2175         891 :     move16();
    2176             : 
    2177         891 :     set32_fx( hStereoTCA->C_mem_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2178         891 :     set16_fx( hStereoTCA->C_mem_exp, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2179         891 :     hStereoTCA->E1_mem_fx = 0;
    2180         891 :     move32();
    2181         891 :     hStereoTCA->E2_mem_fx = 0;
    2182         891 :     move32();
    2183         891 :     hStereoTCA->E1_mem_exp = 0;
    2184         891 :     move16();
    2185         891 :     hStereoTCA->E2_mem_exp = 0;
    2186         891 :     move16();
    2187         891 :     set32_fx( hStereoTCA->delay_0_mem_fx, 0, MAX_DELAYREGLEN );
    2188         891 :     hStereoTCA->delay_0_mem_exp = 0;
    2189         891 :     move16();
    2190         891 :     hStereoTCA->smooth_dist_reg_prv_corr_fx = MAX_32; // Q15
    2191         891 :     hStereoTCA->smooth_dist_reg_prv_corr_exp = 0;     // Q15
    2192         891 :     hStereoTCA->LRTD_G_ATT_cnt = 1;
    2193         891 :     move16();
    2194         891 :     move16();
    2195             : 
    2196         891 :     return;
    2197             : }
    2198             : /*-------------------------------------------------------------------*
    2199             :  * Function unclr_calc_corr_features()
    2200             :  *
    2201             :  *-------------------------------------------------------------------*/
    2202        3811 : static void unclr_calc_corr_features_fx(
    2203             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle                             */
    2204             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: ICA Stereo Encoder handle                            */
    2205             :     Word32 buf1[],                        /* i  : left channel                                     q_com*/
    2206             :     Word32 buf2[],                        /* i  : right channel                                    q_com*/
    2207             :     Word16 q_com,
    2208             :     const Word16 length, /* i  : length of input signal buffers                       Q0*/
    2209             :     Word32 corrEst[],    /* i  : buffer containing inter-channel correlation values   corrEst_exp*/
    2210             :     Word16 corrEst_exp,
    2211             :     const Word16 lagSearchRange[], /* i  : minimum and maximum lags for corrEst[]               Q0*/
    2212             :     Word32 *corrEst_ncorr,         /* o  : norm. x-correlation btw. current and previous correlation buffers corrEst_ncorr_exp*/
    2213             :     Word16 *corrEst_ncorr_exp )
    2214             : {
    2215             :     Word16 i, corrLagMax, d_corrLagMax, tempLen, k;
    2216             :     Word32 num, den;
    2217             :     Word32 corrL, corrR, ener, ener_side, mono_i, side_i, ic_Lm, ic_Rm, tdm_es_em, m_corrL_corrR, d_corrL_corrR;
    2218             :     Word32 sum_prod, corrEstMax;
    2219             :     Word16 corrL_exp, corrR_exp, ener_exp, ener_side_exp, sum_prod_exp, exp, exp1, exp2, num_exp, den_exp;
    2220             : 
    2221        3811 :     corrL = ONE_IN_Q31;
    2222        3811 :     move32();
    2223        3811 :     corrL_exp = 0;
    2224        3811 :     move16();
    2225        3811 :     corrR = ONE_IN_Q31;
    2226        3811 :     move32();
    2227        3811 :     corrR_exp = 0;
    2228        3811 :     move16();
    2229        3811 :     ener = ONE_IN_Q31;
    2230        3811 :     move32();
    2231        3811 :     ener_exp = 0;
    2232        3811 :     move16();
    2233        3811 :     ener_side = ONE_IN_Q31;
    2234        3811 :     move32();
    2235        3811 :     ener_side_exp = 0;
    2236        3811 :     move16();
    2237        3811 :     sum_prod = 0;
    2238        3811 :     move32();
    2239        3811 :     sum_prod_exp = 0;
    2240        3811 :     move16();
    2241             : 
    2242      613571 :     FOR( i = 0; i < length; i++ )
    2243             :     {
    2244      609760 :         mono_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_shr( buf2[i], 1 ), sub( 31, q_com ), &exp );      /* Q31-exp */
    2245      609760 :         corrL = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, Mpy_32_32( buf1[i], mono_i ), add( sub( 31, q_com ), exp ), &corrL_exp ); /* Q31-corrL_exp */
    2246      609760 :         corrR = BASOP_Util_Add_Mant32Exp( corrR, corrR_exp, Mpy_32_32( buf2[i], mono_i ), add( sub( 31, q_com ), exp ), &corrR_exp ); /* Q31-corrR_exp */
    2247      609760 :         ener = BASOP_Util_Add_Mant32Exp( ener, ener_exp, Mpy_32_32( mono_i, mono_i ), shl( exp, 1 ), &ener_exp );
    2248             : 
    2249      609760 :         side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */
    2250      609760 :         ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp );        /* Q31-ener_side_exp */
    2251             : 
    2252             :         Word16 n1, n2, prod_i_exp;
    2253             :         Word32 x, y, prod_i;
    2254      609760 :         n1 = norm_l( buf1[i] );
    2255      609760 :         n2 = norm_l( buf2[i] );
    2256      609760 :         x = L_shl( buf1[i], n1 );   // q: q_com + n1
    2257      609760 :         y = L_shl( buf2[i], n2 );   // q: q_com + n2
    2258      609760 :         prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31
    2259      609760 :         prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) );
    2260      609760 :         sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */
    2261             :     }
    2262             : 
    2263             :     /* average energy of L and R channels */
    2264        3811 :     hStereoClassif->ave_ener_L_fx = Mpy_32_32( hStereoTCA->E1_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_L_fx_e */
    2265        3811 :     move32();
    2266        3811 :     hStereoClassif->ave_ener_L_fx_e = hStereoTCA->E1_mem_exp;
    2267        3811 :     move16();
    2268        3811 :     hStereoClassif->ave_ener_R_fx = Mpy_32_32( hStereoTCA->E2_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_R_fx_e */
    2269        3811 :     move32();
    2270        3811 :     hStereoClassif->ave_ener_R_fx_e = hStereoTCA->E2_mem_exp;
    2271        3811 :     move16();
    2272             : 
    2273             :     /* unnormalized L/R correlation */
    2274        3811 :     IF( sum_prod )
    2275             :     {
    2276        3811 :         sum_prod = BASOP_Util_Log10( L_abs( sum_prod ), sum_prod_exp ); /* Q31-sum_prod_exp */
    2277        3811 :         sum_prod_exp = 6;
    2278        3811 :         move16();
    2279             :     }
    2280             :     ELSE
    2281             :     {
    2282           0 :         sum_prod = 0;
    2283           0 :         move32();
    2284           0 :         sum_prod_exp = 0;
    2285           0 :         move16();
    2286             :     }
    2287             : 
    2288        3811 :     hStereoClassif->unclr_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
    2289        3811 :     move32();
    2290        3811 :     hStereoClassif->xtalk_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
    2291        3811 :     move32();
    2292             :     /* S/M energy ratio */
    2293        3811 :     Word32 inp1 = Sqrt32( Mpy_32_32( ener_side, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_side_exp ); /* Q31-ener_side_exp */
    2294        3811 :     inp1 = BASOP_Util_Log10( inp1, ener_side_exp );                                                    /* Q31-ener_side_exp */
    2295        3811 :     Word16 temp = ener_exp;
    2296        3811 :     move16();
    2297        3811 :     Word32 inp2 = Sqrt32( Mpy_32_32( ener, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_exp ); /* Q31-ener_exp */
    2298        3811 :     inp2 = BASOP_Util_Log10( inp2, ener_exp );                                               /* Q31-ener_exp */
    2299        3811 :     ener_exp = temp;
    2300        3811 :     move16();
    2301             : 
    2302        3811 :     tdm_es_em = L_abs( Mpy_32_32( L_sub( inp1, inp2 ), 1342177280 ) ); /* Q25 + Q27 - Q31 = 21*/
    2303             : 
    2304        3811 :     hStereoClassif->unclr_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
    2305        3811 :     move32();
    2306        3811 :     hStereoClassif->xtalk_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
    2307        3811 :     move32();
    2308             : 
    2309             :     /* L/R correlation values (zero lag, maximum) */
    2310        3811 :     corrLagMax = maximum_l( corrEst, sub( lagSearchRange[1], add( lagSearchRange[0], 1 ) ), &corrEstMax );
    2311        3811 :     d_corrLagMax = sub( corrLagMax, hStereoClassif->unclr_corrLagMax_prev );
    2312             : 
    2313        3811 :     hStereoClassif->unclr_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
    2314        3811 :     move32();
    2315        3811 :     hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
    2316        3811 :     move32();
    2317        3811 :     hStereoClassif->xtalk_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
    2318        3811 :     move32();
    2319             : 
    2320        3811 :     if ( corrEstMax < 0 )
    2321             :     {
    2322           0 :         corrEstMax = 0;
    2323           0 :         move32();
    2324             :     }
    2325             : 
    2326        3811 :     hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
    2327        3811 :     move32();
    2328        3811 :     hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
    2329        3811 :     move32();
    2330        3811 :     hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */
    2331        3811 :     move32();
    2332        3811 :     hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
    2333        3811 :     move32();
    2334        3811 :     hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
    2335        3811 :     move32();
    2336        3811 :     hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */
    2337        3811 :     move32();
    2338             : 
    2339             :     /* L/M and R/M correlation */
    2340        3811 :     if ( corrL < 0 )
    2341             :     {
    2342         113 :         corrL = 0;
    2343         113 :         move32();
    2344             :     }
    2345             : 
    2346        3811 :     if ( corrR < 0 )
    2347             :     {
    2348          58 :         corrR = 0;
    2349          58 :         move32();
    2350             :     }
    2351             : 
    2352        3811 :     ic_Lm = BASOP_Util_Divide3232_Scale_newton( corrL, ener, &exp1 ); /* Q31-exp1 */
    2353        3811 :     exp1 = add( exp1, sub( corrL_exp, ener_exp ) );
    2354        3811 :     ic_Rm = BASOP_Util_Divide3232_Scale_newton( corrR, ener, &exp2 ); /* Q31-exp2 */
    2355        3811 :     exp2 = add( exp2, sub( corrR_exp, ener_exp ) );
    2356             : 
    2357        3811 :     m_corrL_corrR = L_sub( L_max( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ), L_min( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ) ); // s_max(exp1, exp2)
    2358             : 
    2359        3811 :     inp1 = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, L_negate( corrR ), corrR_exp, &exp ); /* Q31-exp */
    2360        3811 :     IF( inp1 )
    2361             :     {
    2362        3811 :         d_corrL_corrR = BASOP_Util_Log10( L_abs( inp1 ), exp ); // Q25
    2363             :     }
    2364             :     ELSE
    2365             :     {
    2366           0 :         d_corrL_corrR = 0;
    2367           0 :         move32();
    2368             :     }
    2369             : 
    2370        3811 :     hStereoClassif->unclr_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
    2371        3811 :     move32();
    2372        3811 :     hStereoClassif->unclr_fv_fx[E_d_corrL_corrR] = L_shr( d_corrL_corrR, 10 ); // Q15
    2373        3811 :     move32();
    2374        3811 :     hStereoClassif->xtalk_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
    2375        3811 :     move32();
    2376             : 
    2377             :     /* norm. x-correlation btw. current and previous correlation buffers */
    2378        3811 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
    2379        3811 :     move16();
    2380             : 
    2381        3811 :     Word64 L64_sum = 0;
    2382        3811 :     move64();
    2383      312502 :     FOR( k = 0; k < tempLen; k++ )
    2384             :     {
    2385      308691 :         L64_sum = W_mac_32_32( L64_sum, corrEst[k], hStereoTCA->corrEstPrev_fx[2][k] ); /* 2*(Q31-corrEst_exp)+1 */
    2386             :     }
    2387        3811 :     k = W_norm( L64_sum );
    2388        3811 :     L64_sum = W_shl( L64_sum, k ); /* 2*(Q31-corrEst_exp)+1+k */
    2389        3811 :     num = W_extract_h( L64_sum );  // ener_side_q
    2390        3811 :     num_exp = sub( 31, sub( add( add( add( sub( 31, corrEst_exp ), sub( 31, hStereoTCA->corrEstPrev_exp ) ), 1 ), k ), 32 ) );
    2391             : 
    2392        3811 :     exp1 = corrEst_exp;
    2393        3811 :     move16();
    2394        3811 :     inp1 = sum2_32_exp_fx( corrEst, tempLen, &exp1, 3 );
    2395             : 
    2396        3811 :     exp2 = hStereoTCA->corrEstPrev_exp;
    2397        3811 :     move16();
    2398        3811 :     inp2 = sum2_32_exp_fx( hStereoTCA->corrEstPrev_fx[2], tempLen, &exp2, 3 );
    2399             : 
    2400        3811 :     den_exp = add( exp1, exp2 );
    2401        3811 :     den = Sqrt32( Mpy_32_32( inp1, inp2 ), &den_exp ); /* Q31-den_exp */
    2402             : 
    2403        3811 :     IF( den == 0 )
    2404             :     {
    2405          60 :         *corrEst_ncorr = 0;
    2406          60 :         move32();
    2407          60 :         *corrEst_ncorr_exp = 0;
    2408          60 :         move16();
    2409             :     }
    2410             :     ELSE
    2411             :     {
    2412        3751 :         *corrEst_ncorr = BASOP_Util_Divide3232_Scale_newton( num, den, &exp ); /* Q31-corrEst_ncorr_exp */
    2413        3751 :         *corrEst_ncorr_exp = add( exp, sub( num_exp, den_exp ) );
    2414        3751 :         move32();
    2415        3751 :         move16();
    2416             :     }
    2417             : 
    2418        3811 :     hStereoClassif->unclr_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
    2419        3811 :     move32();
    2420        3811 :     hStereoClassif->xtalk_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
    2421        3811 :     move32();
    2422             : 
    2423        3811 :     return;
    2424             : }

Generated by: LCOV version 1.14