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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1212 1307 92.7 %
Date: 2025-05-03 01:55:50 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          96 : 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          96 :     ref_exp = sub( 31, *q_com );
      99          96 :     target_exp = sub( 31, *q_com );
     100          96 :     set16_fx( target_exp_temp, target_exp, L_FRAME48k + currentNCShift );
     101             : 
     102          96 :     IF( EQ_16( hStereoTCA->refChanIndx, L_CH_INDX ) )
     103             :     {
     104          66 :         ref = ptrChanL;
     105          66 :         target = ptrChanR;
     106             :     }
     107             :     ELSE
     108             :     {
     109          30 :         ref = ptrChanR;
     110          30 :         target = ptrChanL;
     111             :     }
     112             : 
     113          96 :     tempS = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS );
     114          96 :     tempF1 = 0;
     115          96 :     move32();
     116          96 :     tempF1_exp = 0;
     117          96 :     move32();
     118          96 :     tempF2 = 0;
     119          96 :     move32();
     120          96 :     tempF2_exp = 0;
     121          96 :     move16();
     122       52975 :     FOR( i = 0; i < ( input_frame - currentNCShift ); i++ )
     123             :     {
     124       52879 :         tempF1 = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, L_abs( ref[i] ), ref_exp, &tempF1_exp );                        /* Q31-tempF1_exp */
     125       52879 :         tempF2 = BASOP_Util_Add_Mant32Exp( tempF2, tempF2_exp, L_abs( target[i + currentNCShift] ), target_exp, &tempF2_exp ); /* Q31-tempF2_exp */
     126             :     }
     127             : 
     128          96 :     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          96 :         Word32 deno = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, -21475 /*0.00001f in Q31*/, 0, &temp ); /* Q31-temp */
     138             :         Word16 deno_exp;
     139          96 :         IF( deno > 0 )
     140             :         {
     141          96 :             deno = tempF1;
     142          96 :             move32();
     143          96 :             deno_exp = tempF1_exp;
     144          96 :             move16();
     145             :         }
     146             :         ELSE
     147             :         {
     148           0 :             deno = 21475;
     149           0 :             move32();
     150           0 :             deno_exp = 0;
     151           0 :             move16();
     152             :         }
     153          96 :         gAdj = BASOP_Util_Divide3232_Scale_newton( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */
     154          96 :         gAdj_exp = add( gAdj_exp, sub( tempF2_exp, deno_exp ) );
     155             :     }
     156             : 
     157        1956 :     FOR( i = 0; i < tempS; i++ )
     158             :     {
     159        1860 :         sine_inp = BASOP_Util_Divide1616_Scale( add( shl( i, 10 ), 512 /* 0.5 Q10 */ ), shl( tempS, 1 ), &temp ); /* Q15-(temp+(15-10)) */
     160        1860 :         sine_inp = shl_sat( sine_inp, add( temp, -10 ) );                                                         /*Q0*/
     161        1860 :         win[i] = getSineWord16R2( shr( sine_inp, 1 ) );                                                           /*Q15*/
     162        1860 :         move16();
     163             :     }
     164             : 
     165          96 :     j = 0;
     166          96 :     move16();
     167             : 
     168          96 :     Word16 exp_com = target_exp_temp[0];
     169          96 :     move16();
     170        1956 :     FOR( i = ( input_frame - ( currentNCShift + tempS ) ); i < ( input_frame - currentNCShift ); ( i++, j++ ) )
     171             :     {
     172        1860 :         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        1860 :         move32();
     174        1860 :         target_exp_temp[i + currentNCShift] = temp;
     175        1860 :         move16();
     176        1860 :         exp_com = s_max( exp_com, temp );
     177             :     }
     178             : 
     179        6737 :     FOR( ; i < input_frame; i++ )
     180             :     {
     181        6641 :         target[i + currentNCShift] = Mpy_32_32( gAdj, ref[i] ); /* Q31-target_exp_temp */
     182        6641 :         move32();
     183        6641 :         target_exp_temp[i + currentNCShift] = add( gAdj_exp, ref_exp );
     184        6641 :         move16();
     185        6641 :         exp_com = s_max( exp_com, target_exp_temp[i + currentNCShift] );
     186             :     }
     187             : 
     188       66257 :     FOR( i = 0; i < input_frame + currentNCShift; i++ )
     189             :     {
     190       66161 :         target[i] = L_shl( target[i], sub( target_exp_temp[i], exp_com ) ); /* Q31-exp_com */
     191       66161 :         move32();
     192       66161 :         ref[i] = L_shl( ref[i], sub( ref_exp, exp_com ) ); /* Q31-exp_com */
     193       66161 :         move32();
     194             :     }
     195          96 :     *q_com = sub( 31, exp_com );
     196          96 :     move16();
     197             : 
     198          96 :     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        7654 : 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        7654 :     y1 = mem[0]; /*Qx*/
     311        7654 :     y2 = mem[1]; /*Qx*/
     312        7654 :     x0 = mem[2]; /*Qx*/
     313        7654 :     x1 = mem[3]; /*Qx*/
     314        7654 :     move32();
     315        7654 :     move32();
     316        7654 :     move32();
     317        7654 :     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        7654 :     IF( coeff_set == 0 )
     326             :     {
     327        7654 :         a1 = 401466258; // Q29
     328        7654 :         move32();
     329        7654 :         a2 = -146144282; // Q29
     330        7654 :         move32();
     331        7654 :         b0 = 271120363; // Q29
     332        7654 :         move32();
     333        7654 :         b1 = -542240726; // Q29
     334        7654 :         move32();
     335        7654 :         b2 = 271120363; // Q29
     336        7654 :         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     1232294 :     FOR( i = 0; i < lg; i++ )
     353             :     {
     354     1224640 :         x2 = x1; /*Qx*/
     355     1224640 :         move16();
     356     1224640 :         x1 = x0; /*Qx*/
     357     1224640 :         move16();
     358     1224640 :         x0 = signal[i]; /*Qx*/
     359     1224640 :         move16();
     360     1224640 :         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     1224640 :         signal[i] = y0;                                                                                                                                      /*Qx*/
     362     1224640 :         move16();
     363     1224640 :         y2 = y1; /*Qx*/
     364     1224640 :         move16();
     365     1224640 :         y1 = y0; /*Qx*/
     366     1224640 :         move16();
     367             :     }
     368             : 
     369        7654 :     mem[0] = y1; /*Qx*/
     370        7654 :     move32();
     371        7654 :     mem[1] = y2; /*Qx*/
     372        7654 :     move32();
     373        7654 :     mem[2] = x0; /*Qx*/
     374        7654 :     move32();
     375        7654 :     mem[3] = x1; /*Qx*/
     376        7654 :     move32();
     377             : 
     378        7654 :     return;
     379             : }
     380             : 
     381             : 
     382             : /*---------------------------------------------------------------
     383             :  * deEmphResample()
     384             :  *
     385             :  * De-emphasize and resample the L and R channels.
     386             :  * ---------------------------------------------------------------*/
     387        3827 : 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        3827 :     dsFac1 = shr( dsFactor, 1 );           /*Qx*/
     403        3827 :     dsFac2 = idiv1616( dsFactor, dsFac1 ); /*Qx*/
     404             : 
     405             :     /* convert stereo data to two distinct channels, e.g., L, R */
     406        3827 :     Copy32( tempChan1_fx, buf1_fx, input_frame ); /*Qx*/
     407        3827 :     Copy32( tempChan2_fx, buf2_fx, input_frame ); /*Qx*/
     408             : 
     409             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
     410             : 
     411        3827 :     deemph_fx_32( buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] );
     412        3827 :     deemph_fx_32( buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] );
     413             : 
     414     1228467 :     FOR( i = 0; i < ( input_frame / dsFac1 ); i++ )
     415             :     {
     416     1224640 :         tempBuf1_fx[i] = buf1_fx[i * dsFac1]; /*Qx*/
     417     1224640 :         move32();
     418     1224640 :         tempBuf2_fx[i] = buf2_fx[i * dsFac1]; /*Qx*/
     419     1224640 :         move32();
     420             :     }
     421             : 
     422             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
     423        3827 :     deemph_fx_32( tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] );
     424        3827 :     deemph_fx_32( tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] );
     425             : 
     426      616147 :     FOR( i = 0; i < ( input_frame / dsFactor ); i++ )
     427             :     {
     428      612320 :         chan1_fx[i] = tempBuf1_fx[i * dsFac2]; /*Qx*/
     429      612320 :         move32();
     430      612320 :         chan2_fx[i] = tempBuf2_fx[i * dsFac2]; /*Qx*/
     431      612320 :         move32();
     432             :     }
     433             : 
     434        3827 :     spectral_balancer_fx( chan1_fx, &hStereoTCA->memdecim_fx[4], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
     435        3827 :     spectral_balancer_fx( chan2_fx, &hStereoTCA->memdecim_fx[8], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
     436             : 
     437        3827 :     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        3827 : 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        3827 :     set16_fx( corrEst_exp, -1000, 2 * L_NCSHIFT_DS + 1 );
     461        3827 :     E1_exp = sub( 31, q_com );
     462        3827 :     E2_exp = sub( 31, q_com );
     463             : 
     464        3827 :     gb = 0;
     465        3827 :     move16();
     466        3827 :     IF( LT_16( L_norm_arr( buf1, len ), 2 ) )
     467             :     {
     468           0 :         gb = 2;
     469           0 :         move16();
     470             :     }
     471        3827 :     E1 = sum2_32_exp_fx( buf1, len, &E1_exp, gb ); /* Q31-E1_exp */
     472             : 
     473        3827 :     gb = 0;
     474        3827 :     move16();
     475        3827 :     IF( LT_16( L_norm_arr( buf2, len ), 2 ) )
     476             :     {
     477           0 :         gb = 2;
     478           0 :         move16();
     479             :     }
     480        3827 :     E2 = sum2_32_exp_fx( buf2, len, &E2_exp, gb ); /* Q31-E2_exp */
     481             : 
     482             :     Word16 temp1, temp2;
     483        3827 :     Word32 E1_mul = BASOP_Util_Add_Mant32Exp( E1, E1_exp, hStereoTCA->E1_mem_fx, hStereoTCA->E1_mem_exp, &temp1 ); /* Q31-temp1 */
     484        3827 :     Word32 E2_mul = BASOP_Util_Add_Mant32Exp( E2, E2_exp, hStereoTCA->E2_mem_fx, hStereoTCA->E2_mem_exp, &temp2 ); /* Q31-temp2 */
     485        3827 :     Word32 sqr_inp = Mpy_32_32( E1_mul, E2_mul );
     486        3827 :     Word16 sq_exp = add( temp1, temp2 );
     487             : 
     488        3827 :     IF( sqr_inp )
     489             :     {
     490        3827 :         sqr_inp = Sqrt32( sqr_inp, &sq_exp );                       /* Q31-sq_exp */
     491        3827 :         sqr_inp = Mpy_32_32( sqr_inp, 1342177280 /* 320 in Q22*/ ); /* Q31-sq_exp+22-31 */
     492        3827 :         sq_exp = add( sq_exp, 9 );
     493        3827 :         Inv_Tot_E = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, sqr_inp, &Inv_Tot_E_exp ); /* Q15-Inv_Tot_E_exp */
     494        3827 :         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        3827 :     hStereoTCA->E1_mem_fx = E1; /* Q31-E1_exp */
     505        3827 :     move32();
     506        3827 :     hStereoTCA->E2_mem_fx = E2; /* Q31-E2_exp */
     507        3827 :     move32();
     508        3827 :     hStereoTCA->E1_mem_exp = E1_exp;
     509        3827 :     move16();
     510        3827 :     hStereoTCA->E2_mem_exp = E2_exp;
     511        3827 :     move16();
     512        3827 :     *corrEst_Exp = corrEst_exp[0];
     513        3827 :     move16();
     514             : 
     515      160734 :     FOR( ( i = lagSearchRange[0], j = 0 ); i <= 0; ( i++, j++ ) )
     516             :     {
     517      156907 :         L64_sum = 1;
     518      156907 :         move64();
     519    25262027 :         FOR( k = 0; k < len; k++ )
     520             :         {
     521    25105120 :             L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* 2*q_com+1 */
     522             :         }
     523      156907 :         k = W_norm( L64_sum );
     524      156907 :         L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
     525      156907 :         C = W_extract_h( L64_sum );    // ener_side_q
     526      156907 :         C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
     527      156907 :         C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
     528      156907 :         corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E );                                                          /* Q31-corrEst_exp */
     529      156907 :         move32();
     530      156907 :         corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
     531      156907 :         move16();
     532      156907 :         *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
     533      156907 :         move16();
     534      156907 :         hStereoTCA->C_mem_fx[j] = C;
     535      156907 :         move32();
     536      156907 :         hStereoTCA->C_mem_exp[j] = C_exp;
     537      156907 :         move16();
     538             :     }
     539             : 
     540      156907 :     FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
     541             :     {
     542      153080 :         L64_sum = 1;
     543      153080 :         move64();
     544    24645880 :         FOR( k = 0; k < len; k++ )
     545             :         {
     546    24492800 :             L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* 2*q_com+1 */
     547             :         }
     548      153080 :         k = W_norm( L64_sum );
     549      153080 :         L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
     550      153080 :         C = W_extract_h( L64_sum );    // ener_side_q
     551      153080 :         C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
     552      153080 :         C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
     553      153080 :         corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E );                                                          /* Q31-corrEst_exp */
     554      153080 :         move32();
     555      153080 :         corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
     556      153080 :         move16();
     557      153080 :         *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
     558      153080 :         move16();
     559      153080 :         hStereoTCA->C_mem_fx[j] = C;
     560      153080 :         move32();
     561      153080 :         hStereoTCA->C_mem_exp[j] = C_exp;
     562      153080 :         move16();
     563             :     }
     564             : 
     565             :     /* Rescaling buffers */
     566             : 
     567      313814 :     FOR( i = 0; i < ( 2 * L_NCSHIFT_DS + 1 ); i++ )
     568             :     {
     569      309987 :         corrEst[i] = L_shl( corrEst[i], sub( corrEst_exp[i], *corrEst_Exp ) ); /* Q31-corrEst_Exp */
     570      309987 :         move32();
     571             :     }
     572             : 
     573        3827 :     return;
     574             : }
     575             : /*---------------------------------------------------------------
     576             :  * utilCrossCorr()
     577             :  *
     578             :  * crossCorr estimation between buf1, buf2 over the
     579             :  * lag range of (lagSearchRange[0], lagSearchRange[1]).
     580             :  * ---------------------------------------------------------------*/
     581         243 : 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         243 :     Word16 max_e = MIN16B;
     601         243 :     move16();
     602             : 
     603         243 :     Word16 gb1 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf1, len ) ) );
     604         243 :     Word16 gb2 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf2, len ) ) );
     605             : 
     606             :     /* Apply windowing */
     607         243 :     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         243 :         Copy32( buf1, tempBuf1, len ); /* buf1_q */
     631         243 :         Copy32( buf2, tempBuf2, len ); /* buf2_q */
     632             :     }
     633             : 
     634         243 :     Word16 temp1_e = sub( Q31, buf1_q );
     635         243 :     Word16 temp2_e = sub( Q31, buf2_q );
     636             : 
     637         243 :     temp = sum2_32_exp_fx( tempBuf1, len, &temp1_e, gb1 );                    // temp1_e
     638         243 :     temp = Mpy_32_32( temp, sum2_32_exp_fx( tempBuf2, len, &temp2_e, gb2 ) ); // temp2_e
     639         243 :     temp2_e = add( temp1_e, temp2_e );
     640             : 
     641         243 :     IF( temp == 0 )
     642             :     {
     643           0 :         scale = MAXVAL_WORD32;
     644           0 :         move32();
     645             :     }
     646             :     ELSE
     647             :     {
     648         243 :         scale = ISqrt32( temp, &temp2_e ); // temp2_e
     649             :     }
     650             : 
     651             :     /* starting point of lag search range should be less than the ending point */
     652         243 :     assert( lagSearchRange[0] <= lagSearchRange[1] );
     653             : 
     654             :     /* first part of noncausal corr est. */
     655         413 :     FOR( ( i = lagSearchRange[0], j = 0 ); i <= s_min( 0, lagSearchRange[1] ); ( i++, j++ ) )
     656             :     {
     657         170 :         L64_sum = 0;
     658         170 :         move64();
     659      109748 :         FOR( k = 0; k < ( len + i ); k++ )
     660             :         {
     661      109578 :             L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* buf1_q+buf2_q+1 */
     662             :         }
     663         170 :         k = W_norm( L64_sum );
     664         170 :         L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
     665         170 :         temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
     666         170 :         res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
     667             : 
     668         170 :         corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len + i ), &tmp_e ) ); /* Q31-max_e */
     669         170 :         move32();
     670         170 :         corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
     671         170 :         move16();
     672         170 :         max_e = s_max( max_e, corrEstTemp_e[j] );
     673             :     }
     674             : 
     675             :     /* second part of noncausal corr est. */
     676         660 :     FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
     677             :     {
     678         417 :         L64_sum = 1;
     679         417 :         move64();
     680      251229 :         FOR( k = 0; k < sub( len, i ); k++ )
     681             :         {
     682      250812 :             L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* buf1_q+buf2_q+1 */
     683             :         }
     684         417 :         k = W_norm( L64_sum );
     685         417 :         L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
     686         417 :         temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
     687         417 :         res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
     688             : 
     689         417 :         corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len - i ), &tmp_e ) ); /* Q31-max_e */
     690         417 :         move32();
     691         417 :         corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
     692         417 :         move16();
     693         417 :         max_e = s_max( max_e, corrEstTemp_e[j] );
     694         417 :         move16();
     695             :     }
     696             : 
     697             : 
     698         830 :     FOR( i = 0; i < j; i++ )
     699             :     {
     700         587 :         corrEst[i] = L_shr( corrEst[i], sub( max_e, corrEstTemp_e[i] ) ); /* Q31-corrEstTemp_e */
     701         587 :         move32();
     702             :     }
     703             : 
     704         243 :     *corrEst_e = max_e;
     705         243 :     move16();
     706         243 :     v_multc_fixed( corrEst, scale, corrEst, j );
     707         243 :     *corrEst_e = add( *corrEst_e, temp2_e );
     708         243 :     move16();
     709             : 
     710         243 :     return;
     711             : }
     712             : /*---------------------------------------------------------------
     713             :  *  corrStatsEst()
     714             :  *
     715             :  *  Non-causal shift estimation to encode future samples.
     716             :  * ---------------------------------------------------------------*/
     717             : 
     718       11535 : static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp )
     719             : {
     720             :     Word16 ouptut;
     721             :     Word32 temp;
     722             : 
     723       11535 :     temp = L_shr( inp, sub( 31, exp ) ); /*Q0*/
     724       11535 :     test();
     725       11535 :     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       11535 :         IF( NE_32( temp, L_shl_sat( 1, sub( 31, exp ) ) ) )
     741             :         {
     742       11535 :             Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */
     743       11535 :             ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) );                      /*Q0*/
     744             : 
     745       11535 :             IF( temp < 0 )
     746             :             {
     747        6456 :                 ouptut = add( ouptut, 1 ); /*Q0*/
     748             :             }
     749             :         }
     750             :         ELSE
     751             :         {
     752           0 :             ouptut = extract_l( temp ); /*Q0*/
     753           0 :             move16();
     754             :         }
     755             :     }
     756       11535 :     return ouptut; /*Q0*/
     757             : }
     758        3827 : 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        3827 :     X_hat_fx = 0;
     796        3827 :     move32();
     797        3827 :     X_hat_exp = 0;
     798        3827 :     move16();
     799        3827 :     X_SQR_hat_fx = 0;
     800        3827 :     move32();
     801        3827 :     X_SQR_hat_exp = 0;
     802        3827 :     move16();
     803        3827 :     XY_hat_fx = 0;
     804        3827 :     move32();
     805        3827 :     XY_hat_exp = 0;
     806        3827 :     move16();
     807             : 
     808             :     /* Initializations */
     809        3827 :     alpha_fx = 22938; /* 0.7 in Q15*/
     810        3827 :     move16();
     811        3827 :     lagSearchRange[0] = -L_NCSHIFT_DS;
     812        3827 :     move16();
     813        3827 :     lagSearchRange[1] = L_NCSHIFT_DS;
     814        3827 :     move16();
     815        3827 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
     816        3827 :     move16();
     817             : 
     818        3827 :     set16_fx( corrLagStats, 0, 3 );
     819             : 
     820             :     /* First iteration of xcorr estimation */
     821        3827 :     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        3827 :     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       11481 :     FOR( i = 1; i < 3; i++ )
     827             :     {
     828        7654 :         v_add_32( hStereoTCA->corrEstPrev_fx[i], hStereoTCA->corrEstPrev_fx[0], hStereoTCA->corrEstPrev_fx[0], tempLen );
     829             :     }
     830             : 
     831             :     /* back up the corrEst */
     832       11481 :     FOR( i = 0; i < 2; i++ )
     833             :     {
     834        7654 :         Copy32( hStereoTCA->corrEstPrev_fx[i + 1], hStereoTCA->corrEstPrev_fx[i], tempLen ); /* Q31-hStereoTCA->corrEstPrev_exp */
     835             :     }
     836             : 
     837        3827 :     temp = getScaleFactor32( corrEst_fx, 2 * L_NCSHIFT_DS + 1 );
     838        3827 :     scale_sig32( corrEst_fx, 2 * L_NCSHIFT_DS + 1, temp ); /* Q31-corrEst_exp */
     839        3827 :     corrEst_exp = sub( corrEst_exp, temp );
     840             : 
     841        3827 :     Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); /* Q31-corrEst_exp */
     842        3827 :     hStereoTCA->corrEstPrev_exp = corrEst_exp;
     843        3827 :     move16();
     844        3827 :     Word16 gb = find_guarded_bits_fx( 2 * L_NCSHIFT_DS + 1 );
     845             : 
     846        3827 :     scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, -gb ); /* Q31-hStereoTCA->corrEstPrev_exp-1 */
     847        3827 :     hStereoTCA->corrEstPrev_exp = add( hStereoTCA->corrEstPrev_exp, gb );
     848        3827 :     move16();
     849             :     Word32 buf1_fx_temp[L_FRAME_DS];
     850             :     Word32 buf2_fx_temp[L_FRAME_DS];
     851             : 
     852        3827 :     Copy32( buf1_fx, buf1_fx_temp, L_FRAME_DS ); /* q_com */
     853        3827 :     Copy32( buf2_fx, buf2_fx_temp, L_FRAME_DS ); /* q_com */
     854             : 
     855        3827 :     scale_sig32( buf1_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
     856        3827 :     scale_sig32( buf2_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
     857             : 
     858        3827 :     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        3827 :     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        3827 :     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        3827 :     Word16 tempF_exp = temp;
     863        3827 :     hStereoTCA->mem_tempF_fx = temp_B_fx; /* Q31-hStereoTCA->mem_tempF_exp  */
     864        3827 :     move32();
     865        3827 :     hStereoTCA->mem_tempF_exp = sub( 31, sub( q_com, 4 ) );
     866        3827 :     move16();
     867             : 
     868        3827 :     alpha_fx = 30474 /* 0.93f in Q15*/;
     869        3827 :     move16();
     870        3827 :     IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 2 ), &temp ) > 0 )
     871             :     {
     872         127 :         alpha_fx = 27197 /* 0.83f in Q15*/;
     873             :     }
     874        3700 :     ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 1 ), &temp ) > 0 )
     875             :     {
     876         323 :         alpha_fx = 27853 /* 0.85f in Q15*/;
     877             :     }
     878        3377 :     ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, hStereoTCA->ica_envVarLT_exp, &temp ) > 0 )
     879             :     {
     880        1088 :         alpha_fx = 29491 /* 0.9f in Q15*/;
     881             :     }
     882        3827 :     move16();
     883        3827 :     hStereoTCA->corrStatsSmoothFac_fx = alpha_fx;
     884        3827 :     move32();
     885             : 
     886             :     /* long term corr Stats estimation */
     887        3827 :     v_multc_fixed_16( hStereoTCA->corrEstLT_fx, alpha_fx, hStereoTCA->corrEstLT_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
     888        3827 :     v_multc_fixed_16( corrEst_fx, sub( MAX_16, alpha_fx ), corrEst_fx, 2 * L_NCSHIFT_DS + 1 );              /* Q31-corrEst_exp */
     889        3827 :     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        3827 :     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        3827 :     move32();
     893             : 
     894        3827 :     Copy32( hStereoTCA->corrEstLT_fx, corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
     895        3827 :     corrEst_exp = hStereoTCA->corrEstLT_exp;
     896        3827 :     move16();
     897             : 
     898        3827 :     Y_hat_fx = hStereoTCA->delay_0_mem_fx[0]; /* Q31-hStereoTCA->delay_0_mem_exp */
     899        3827 :     move32();
     900        3827 :     Y_hat_exp = hStereoTCA->delay_0_mem_exp;
     901        3827 :     move16();
     902             : 
     903             :     /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
     904       45924 :     FOR( i = 1; i < MAX_DELAYREGLEN; i++ )
     905             :     {
     906       42097 :         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       42097 :         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       42097 :         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       42097 :         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        3827 :     X_hat_fx = Mpy_32_16_1( X_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );         /* Q31-X_hat_exp */
     913        3827 :     Y_hat_fx = Mpy_32_16_1( Y_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );         /* Q31-Y_hat_exp */
     914        3827 :     XY_hat_fx = Mpy_32_16_1( XY_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 );       /* Q31-XY_hat_exp */
     915        3827 :     X_SQR_hat_fx = Mpy_32_16_1( X_SQR_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_SQR_hat_exp */
     916             : 
     917        3827 :     beta_reg_fx = 0;
     918        3827 :     move32();
     919        3827 :     beta_reg_exp = 0;
     920        3827 :     move16();
     921        3827 :     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        3827 :     IF( tempF_fx != 0 )
     924             :     {
     925        3827 :         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        3827 :         beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp );                                                        /* Q31-beta_reg_exp */
     927        3827 :         if ( beta_reg_fx )
     928             :         {
     929        3603 :             beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) );
     930             :         }
     931             :     }
     932             : 
     933        3827 :     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        3827 :     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        3827 :     reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
     937        3827 :     reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
     938        3827 :     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        3827 :     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        3827 :     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        3827 :     Word32 XH_BIAS_tmp = L_shl( XH_BIAS_FX_Q15, Q16 ); /* Q31 */
     957        3827 :     Word32 XL_BIAS_tmp = L_shl( XL_BIAS_FX_Q15, Q16 ); /* Q31 */
     958             : 
     959        3827 :     IF( bias_par_exp < 0 )
     960             :     {
     961        3544 :         bias_par_fx = L_shl( bias_par_fx, bias_par_exp ); /* Q31 */
     962        3544 :         bias_par_exp = 0;
     963        3544 :         move16();
     964             :     }
     965             :     ELSE
     966             :     {
     967         283 :         XH_BIAS_tmp = L_shr( XH_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
     968         283 :         XL_BIAS_tmp = L_shr( XL_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
     969             :     }
     970             : 
     971        3827 :     bias_par_fx = L_min( bias_par_fx, XH_BIAS_tmp );
     972        3827 :     bias_par_fx = L_max( bias_par_fx, XL_BIAS_tmp );
     973        3827 :     bias_par_fx = L_shr( bias_par_fx, bias_par_exp );
     974        3827 :     bias_par_exp = 0;
     975        3827 :     move16();
     976             : 
     977        3827 :     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        3827 :     Word32 XH_WIDTH_tmp = L_shl( XH_WIDTH_FX_Q15, Q16 );                                                                                                                                          /* Q31 */
     979        3827 :     Word32 XL_WIDTH_tmp = L_shl( XL_WIDTH_FX_Q15, Q16 );                                                                                                                                          /* Q31 */
     980             : 
     981        3827 :     IF( width_par_exp < 0 )
     982             :     {
     983        3827 :         width_par_fx = L_shl( width_par_fx, width_par_exp ); /* Q31 */
     984        3827 :         width_par_exp = 0;
     985        3827 :         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        3827 :     width_par_fx = L_min( width_par_fx, XH_WIDTH_tmp );
     993        3827 :     width_par_fx = L_max( width_par_fx, XL_WIDTH_tmp );
     994        3827 :     width_par_fx = L_shl( width_par_fx, width_par_exp );
     995        3827 :     width_par_exp = 0;
     996        3827 :     move16();
     997             : 
     998        3827 :     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        3827 :     win_bias_fx = round_fx( bias_par_fx ); // Q15
    1001             : 
    1002        3827 :     k1_fx = add( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
    1003        3827 :     k2_fx = sub( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
    1004             : 
    1005      160373 :     FOR( i = 0; i < ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i++ )
    1006             :     {
    1007      156546 :         loc_weight_win_fx[i] = win_bias_fx; // Q15
    1008      156546 :         move16();
    1009             :     }
    1010             : 
    1011      306882 :     FOR( i = ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i <= ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i++ )
    1012             :     {
    1013      303055 :         Word16 cos_inp = BASOP_Util_Divide1616_Scale( sub( i, 2 * L_NCSHIFT_DS ), shl( win_width, 1 ), &exp ); /* Q15-exp */
    1014      303055 :         cos_inp = shr_sat( cos_inp, sub( 0, exp ) );
    1015      303055 :         cos_inp = getCosWord16R2( shr( cos_inp, 1 ) );               // Q15
    1016      303055 :         loc_weight_win_fx[i] = add( k1_fx, mult( k2_fx, cos_inp ) ); // Q15
    1017      303055 :         move16();
    1018             :     }
    1019             : 
    1020      164200 :     FOR( i = ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
    1021             :     {
    1022      160373 :         loc_weight_win_fx[i] = win_bias_fx; // Q15
    1023      160373 :         move16();
    1024             :     }
    1025        3827 :     reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
    1026        3827 :     reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
    1027        3827 :     Word16 x = TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ); /* Q0 */
    1028        3827 :     move16();
    1029      313814 :     for ( i = 0, j = ( L_NCSHIFT_DS - x ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
    1030             :     {
    1031      309987 :         corrEst_fx[i] = Mpy_32_16_1( corrEst_fx[i], loc_weight_win_fx[j] ); /* Q31-corrEst_exp */
    1032      309987 :         move32();
    1033             :     }
    1034        3827 :     test();
    1035        3827 :     test();
    1036        3827 :     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        3827 :     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        3827 :     test();
    1051        3827 :     IF( BASOP_Util_Add_Mant32Exp( corrEst_ncorr_fx, corrEst_ncorr_exp, -429496730 /*0.8f in Q29*/, 2, &exp ) > 0 && vad_flag1 )
    1052             :     {
    1053        1604 :         i = s_max( 0, add( hStereoTCA->prevCorrLagStats[0], -1 + L_NCSHIFT_DS ) );
    1054        1604 :         j = s_min( 2 * L_NCSHIFT_DS, add( hStereoTCA->prevCorrLagStats[0], 1 + L_NCSHIFT_DS ) );
    1055        1604 :         k = add( sub( j, i ), 1 );
    1056             : 
    1057        1604 :         v_multc_fixed( corrEst_fx, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx, i );                                                  // to allign in same exp (Q31-corrEst_exp)
    1058        1604 :         v_multc_fixed( corrEst_fx + i, 644245095 /*1.2f in Q29*/, corrEst_fx + i, k );                                           /* Q31-corrEst_exp */
    1059        1604 :         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        1604 :         corrEst_exp = add( corrEst_exp, 2 );
    1061             :     }
    1062             : 
    1063             :     /* Initial corr lag estimate */
    1064        3827 :     corrLagStats[0] = maximum_32_fx( corrEst_fx, add( sub( lagSearchRange[1], lagSearchRange[0] ), 1 ), &tempF_fx );
    1065        3827 :     move16();
    1066        3827 :     tempF_exp = corrEst_exp;
    1067        3827 :     move16();
    1068        3827 :     corrLagStats[0] = add( corrLagStats[0], lagSearchRange[0] );
    1069        3827 :     move16();
    1070             : 
    1071        3827 :     stmp = i_mult( corrLagStats[0], dsFactor );                        /* Q0 */
    1072        3827 :     hStereoClassif->unclr_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
    1073        3827 :     move32();
    1074        3827 :     hStereoClassif->xtalk_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
    1075        3827 :     move32();
    1076        3827 :     hStereoClassif->xtalk_fv_fx[E_ica_corr_value0] = L_shl( tempF_fx, sub( tempF_exp, Q16 ) ); /* Q15 */
    1077        3827 :     move32();
    1078             : 
    1079        3827 :     test();
    1080        3827 :     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        3827 :     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        3827 :     test();
    1088        3827 :     IF( EQ_16( vad_flag1, 1 ) && EQ_16( vad_flag2, 1 ) )
    1089        3773 :     {
    1090             : 
    1091        3773 :         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        3773 :         move32();
    1093        3773 :         Copy32( &( hStereoTCA->delay_0_mem_fx[1] ), &( hStereoTCA->delay_0_mem_fx[0] ), MAX_DELAYREGLEN - 1 ); /* Q31-hStereoTCA->delay_0_mem_exp */
    1094             : 
    1095        3773 :         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        3773 :         move32();
    1097        3773 :         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        3773 :         inpp = L_shl_sat( inpp, sub( exp, 5 ) );                                                                                                                            /* Q26 */
    1099        3773 :         IF( GT_32( inpp, 1677721600 ) )                                                                                                                                     // 25 in Q26
    1100             :         {
    1101          79 :             set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
    1102          79 :             hStereoTCA->delay_0_mem_exp = temp;
    1103          79 :             move16();
    1104             :         }
    1105             :         ELSE
    1106             :         {
    1107        3694 :             IF( GT_16( temp, hStereoTCA->delay_0_mem_exp ) )
    1108             :             {
    1109         160 :                 scale_sig32( hStereoTCA->delay_0_mem_fx, MAX_DELAYREGLEN - 1, sub( hStereoTCA->delay_0_mem_exp, temp ) ); /* Q31-hStereoTCA->delay_0_mem_exp */
    1110         160 :                 hStereoTCA->delay_0_mem_exp = temp;
    1111         160 :                 move16();
    1112             :             }
    1113             :             ELSE
    1114             :             {
    1115        3534 :                 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        3534 :                 move32();
    1117             :             }
    1118             :         }
    1119             :     }
    1120             :     ELSE
    1121             :     {
    1122          54 :         hStereoTCA->smooth_dist_reg_prv_corr_fx = 0;
    1123          54 :         move32();
    1124          54 :         hStereoTCA->smooth_dist_reg_prv_corr_exp = 0;
    1125          54 :         move16();
    1126             :     }
    1127        3827 :     test();
    1128        3827 :     IF( vad_flag1 == 0 || vad_flag2 == 0 )
    1129             :     {
    1130          54 :         Word32 tmp_delay = L_shr( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 1 );
    1131          54 :         Word16 tmp_delay_e = add( hStereoTCA->delay_0_mem_exp, 1 );
    1132          54 :         corrLagStats[0] = TRUNC_FX( tmp_delay, tmp_delay_e ); /* Q0 */
    1133          54 :         move32();
    1134             :     }
    1135             : 
    1136             :     /* second iteration of xcorr update @ inputFs with interp*/
    1137        3827 :     tempRK_fx = hStereoTCA->corrEstLT_fx + add( -lagSearchRange[0], corrLagStats[0] );
    1138        3827 :     set32_fx( rInterp_fx, 0, MAX_INTERPOLATE );
    1139        3827 :     set16_fx( rInterp_exp, 0, MAX_INTERPOLATE );
    1140             : 
    1141             :     /* select the Rk interp sinc window */
    1142        3827 :     winInterp_fx = ica_sincInterp4_fx + SINC_ORDER1;
    1143             : 
    1144        3827 :     IF( EQ_16( dsFactor, 2 ) )
    1145             :     {
    1146         814 :         winInterp_fx = ica_sincInterp2_fx + SINC_ORDER1;
    1147             :     }
    1148        3013 :     ELSE IF( EQ_16( dsFactor, 6 ) )
    1149             :     {
    1150         985 :         winInterp_fx = ica_sincInterp6_fx + SINC_ORDER1;
    1151             :     }
    1152             : 
    1153        3827 :     corrLagStats[1] = i_mult( corrLagStats[0], dsFactor ); /* Q0 */
    1154        3827 :     move16();
    1155        3827 :     interpMin = s_max( -sub( dsFactor, 1 ), -add( corrLagStats[1], i_mult( L_NCSHIFT_DS, dsFactor ) ) );
    1156        3827 :     interpMax = s_min( sub( dsFactor, 1 ), sub( i_mult( L_NCSHIFT_DS, dsFactor ), corrLagStats[1] ) );
    1157        3827 :     interpLen = add( sub( interpMax, interpMin ), 1 );
    1158             : 
    1159       31300 :     for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
    1160             :     {
    1161       27473 :         rInterp_fx[k] = 0;
    1162       27473 :         move32();
    1163      370586 :         FOR( j = -( SINC_ORDER1 / dsFactor ); j <= ( SINC_ORDER1 / dsFactor ); j++ )
    1164             :         {
    1165      343113 :             m = i_mult( j, dsFactor ); /* Q0 */
    1166      343113 :             test();
    1167      343113 :             IF( GE_16( sub( m, i ), -SINC_ORDER1 ) && LE_16( sub( m, i ), SINC_ORDER1 ) )
    1168             :             {
    1169      319467 :                 IF( GT_16( j, sub( lagSearchRange[1], corrLagStats[0] ) ) )
    1170             :                 {
    1171          67 :                     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          67 :                     move32();
    1173          67 :                     rInterp_exp[k] = temp;
    1174          67 :                     move16();
    1175             :                 }
    1176      319400 :                 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      319224 :                     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      319224 :                     move32();
    1187      319224 :                     rInterp_exp[k] = temp;
    1188      319224 :                     move16();
    1189             :                 }
    1190             :             }
    1191             :         }
    1192             :     }
    1193        3827 :     temp = rInterp_exp[0];
    1194        3827 :     move16();
    1195       45924 :     FOR( i = 0; i < MAX_INTERPOLATE; i++ )
    1196             :     {
    1197       42097 :         temp = s_max( temp, rInterp_exp[i] );
    1198             :     }
    1199             : 
    1200       45924 :     FOR( i = 0; i < MAX_INTERPOLATE; i++ )
    1201             :     {
    1202       42097 :         rInterp_fx[i] = L_shl( rInterp_fx[i], sub( rInterp_exp[i], temp ) ); /* Q31-rInterp_exp[i] */
    1203       42097 :         move32();
    1204             :     }
    1205             : 
    1206        3827 :     corrLagStats[1] = add( corrLagStats[1], add( maximum_32_fx( rInterp_fx, interpLen, &tempF_fx ), interpMin ) ); /* Q0 */
    1207        3827 :     move16();
    1208             : 
    1209             :     /* save corr lag stats for the current frame */
    1210        3827 :     Copy( corrLagStats, hStereoTCA->corrLagStats, 3 ); /* Q0 */
    1211             : 
    1212        3827 :     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       63440 :         i1 = 0;
    1248       63440 :         move16();
    1249       63440 :         i2 = ncShift; /* Q0 */
    1250       63440 :         move16();
    1251             :     }
    1252             :     ELSE
    1253             :     {
    1254          30 :         i1 = ncShift; /* Q0 */
    1255          30 :         move16();
    1256          30 :         i2 = 0;
    1257          30 :         move16();
    1258             :     }
    1259             : 
    1260             :     /* abs sample sum estimation */
    1261       63470 :     tempN = 0;
    1262       63470 :     move32();
    1263       63470 :     tempD = 0;
    1264       63470 :     move32();
    1265    43752829 :     FOR( i = 0; i < length; i++ )
    1266             :     {
    1267    43689359 :         tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); /* q_chan */
    1268    43689359 :         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        3827 :         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        3827 :         tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp );                          /* Q31-exp */
    1317        3827 :         unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); /* Q31-exp */
    1318        3827 :         exp = add( sub( exp_chan, exp ), exp_div );
    1319        3827 :         if ( unclr_instTargetGain == 0 )
    1320             :         {
    1321           0 :             exp = 0;
    1322           0 :             move16();
    1323             :         }
    1324        3827 :         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        3827 :         hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); /* Q15 */
    1327        3827 :         move32();
    1328             :     }
    1329             : 
    1330       63470 :     test();
    1331       63470 :     IF( EQ_16( tdm_LRTD_flag, 1 ) )
    1332             :     {
    1333        3698 :         currentGain = 0;
    1334        3698 :         move32();
    1335             :     }
    1336       59772 :     ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
    1337             :     {
    1338         219 :         currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, &exp );
    1339         219 :         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        3827 : 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        3827 :     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        3827 :         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        3827 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio_fx; /* Q31 */
    1407        3827 :             move32();
    1408        3827 :             One_m_Ratio = L_sub( MAX_32, ratio_L );
    1409             :         }
    1410             : 
    1411        3827 :         ptr1 = sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[0]->q_inp32 */
    1412        3827 :         ptr2 = sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[1]->q_inp32 */
    1413             : 
    1414        3827 :         IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
    1415             :         {
    1416        3765 :             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      895633 :                 FOR( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
    1429             :                 {
    1430      891960 :                     ptr1[i] = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
    1431      891960 :                     move32();
    1432      891960 :                     ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1433      891960 :                     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          62 :             set32_fx( sts[1]->input32_fx - input_frame, 0, input_frame );
    1444             : 
    1445          62 :             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        3974 :                 FOR( i = 0; i < lMemRecalc_SCh; i++ )
    1480             :                 {
    1481        3920 :                     ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1482        3920 :                     move32();
    1483             :                 }
    1484             : 
    1485             :                 /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
    1486          54 :                 fac = div_s( 1, lMemRecalc ); // Q15
    1487          54 :                 incr = fac;                   // Q15
    1488          54 :                 move16();
    1489       13494 :                 FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
    1490             :                 {
    1491       13440 :                     tmp1 = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
    1492       13440 :                     tmp2 = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
    1493             : 
    1494       13440 :                     ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */
    1495       13440 :                     move32();
    1496             :                     /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
    1497       13440 :                     ptr2[i] = tmp2;                                    /* q_com */
    1498       13440 :                     move32();
    1499             : 
    1500       13440 :                     fac = add_sat( fac, incr );
    1501             :                 }
    1502             :             }
    1503             :         }
    1504             :     }
    1505             : 
    1506        3827 :     IF( hCPE->hStereoICBWE != NULL )
    1507             :     {
    1508             :         assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
    1509         129 :         i = NS2SA_FX2( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
    1510         129 :         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         129 :         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         129 :         hCPE->hStereoICBWE->q_dataChan_fx = sub( q_com, Q16 );
    1513         129 :         move16();
    1514             :     }
    1515             : 
    1516        3827 :     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       59426 :         hStereoTCA->LRTD_G_ATT_cnt = 1;
    1618       59426 :         move16();
    1619             :     }
    1620        4044 :     ELSE IF( hCPE->hStereoTD != NULL )
    1621             :     {
    1622        3827 :         IF( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
    1623             :         {
    1624         129 :             hStereoTCA->LRTD_G_ATT_cnt = add( hStereoTCA->LRTD_G_ATT_cnt, 1 );
    1625         129 :             move16();
    1626         129 :             hStereoTCA->LRTD_G_ATT_cnt = s_min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
    1627         129 :             move16();
    1628             :         }
    1629             :     }
    1630             : 
    1631       63470 :     IF( NE_16( hCPE->element_mode, IVAS_CPE_TD ) )
    1632             :     {
    1633       59643 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1634       59643 :         move16();
    1635       59643 :         hStereoTCA->corrStatsSmoothFac_fx = 22938 /*0.7 in Q15 */;
    1636       59643 :         move16();
    1637       59643 :         estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, NULL, 0 );
    1638       59643 :         hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx;
    1639       59643 :         move16();
    1640             : 
    1641             :         /* back up the L/R missing target */
    1642       59643 :         Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
    1643       59643 :         Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
    1644       59643 :         hStereoTCA->memChan_q = q_com;
    1645       59643 :         move16();
    1646       59643 :         hStereoTCA->lMemRecalc = 0;
    1647       59643 :         move16();
    1648       59643 :         hStereoTCA->lMemRecalc_12k8 = 0;
    1649       59643 :         move16();
    1650       59643 :         hStereoTCA->lMemRecalc_16k = 0;
    1651       59643 :         move16();
    1652             : 
    1653       59643 :         return;
    1654             :     }
    1655        3827 :     ELSE IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
    1656             :     {
    1657          62 :         tempF_fx = hStereoTCA->targetGain_fx; // Q29
    1658          62 :         move32();
    1659          62 :         tempF1_fx = hStereoTCA->prevTargetGain_fx; // Q29
    1660          62 :         move32();
    1661          62 :         tempS = hStereoTCA->prevRefChanIndx;
    1662          62 :         move16();
    1663             : 
    1664          62 :         Copy( hStereoTCA->prevCorrLagStats, tempS_buff, 3 ); /* Q0 */
    1665             : 
    1666          62 :         stereo_tca_init_enc_fx( hStereoTCA, input_Fs );
    1667             : 
    1668          62 :         hStereoTCA->targetGain_fx = tempF_fx; // Q29
    1669          62 :         move32();
    1670          62 :         hStereoTCA->prevTargetGain_fx = tempF1_fx; // Q29
    1671          62 :         move32();
    1672             : 
    1673          62 :         IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
    1674             :         {
    1675          62 :             hStereoTCA->targetGain_fx = L_min( hStereoTCA->targetGain_fx, ONE_IN_Q29 ); // Q29
    1676          62 :             move32();
    1677          62 :             hStereoTCA->prevTargetGain_fx = L_min( hStereoTCA->prevTargetGain_fx, ONE_IN_Q29 ); // Q29
    1678          62 :             move32();
    1679             : 
    1680          62 :             hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
    1681          62 :             move32();
    1682             :         }
    1683             : 
    1684          62 :         hStereoTCA->prevRefChanIndx = tempS;
    1685          62 :         move16();
    1686          62 :         Copy( tempS_buff, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
    1687             : 
    1688             :         /* populate memory */
    1689          62 :         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        3827 :     Copy32( hStereoTCA->memChanL_DS_fx, bufChanL_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
    1698        3827 :     Copy32( hStereoTCA->memChanR_DS_fx, bufChanR_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
    1699             : 
    1700        3827 :     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        3827 :     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        3827 :     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        3827 :     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        3827 :     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        3827 :     bufChan_q = s_min( hStereoTCA->memChan_DS_q, bufChan_q );
    1708        3827 :     q_com = bufChan_q;
    1709        3827 :     move16();
    1710        3827 :     hStereoTCA->memChan_DS_q = bufChan_q;
    1711        3827 :     move16();
    1712             : 
    1713             :     /* pointers to the current frame of DS */
    1714             : 
    1715        3827 :     ptrChanL_DS_fx = bufChanL_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
    1716        3827 :     ptrChanR_DS_fx = bufChanR_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
    1717             : 
    1718             :     /* resample factor */
    1719        3827 :     dsFactor = extract_l( Mpy_32_32( input_Fs, 268436 /* 1/CORR_INTER_FS in Q31*/ ) ); // Q0
    1720             : 
    1721             :     /* resample the stereo channels */
    1722        3827 :     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        3827 :     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        3827 :     prev_ICA_flag = 0;
    1733        3827 :     move16();
    1734        3827 :     test();
    1735        3827 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 )
    1736             :     {
    1737          37 :         prev_ICA_flag = 1;
    1738          37 :         move16();
    1739             :     }
    1740             : 
    1741        3827 :     test();
    1742        3827 :     IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
    1743         220 :     {
    1744             :         /* initialize the refinement search for NC-shift */
    1745         220 :         hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
    1746         220 :         move16();
    1747         220 :         maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
    1748         220 :         move16();
    1749         220 :         IF( LE_16( hStereoTCA->corrStatsSmoothFac_fx, 22938 /*0.7f*/ ) )
    1750             :         {
    1751           0 :             maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
    1752           0 :             move16();
    1753             :         }
    1754             : 
    1755         220 :         IF( LT_32( input_Fs, 32000 ) )
    1756             :         {
    1757          56 :             maxCorrStatsDev = extract_l( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0
    1758             :         }
    1759             : 
    1760         220 :         musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
    1761         220 :         move16();
    1762             : 
    1763         220 :         IF( musicMode )
    1764             :         {
    1765          45 :             maxCorrStatsDev = 1;
    1766          45 :             move16();
    1767          45 :             set16_fx( hStereoTCA->corrLagStats + 1, 0, 2 );
    1768             :         }
    1769             : 
    1770         220 :         tempS = sub( hStereoTCA->corrLagStats[1], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1771             : 
    1772         220 :         IF( GT_16( abs_s( tempS ), maxCorrStatsDev ) )
    1773             :         {
    1774          80 :             IF( tempS > 0 )
    1775             :             {
    1776          20 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], maxCorrStatsDev ); /* Q0 */
    1777             :             }
    1778             :             ELSE
    1779             :             {
    1780          60 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], -maxCorrStatsDev ); /* Q0 */
    1781             :             }
    1782          80 :             move16();
    1783             :         }
    1784             : 
    1785         220 :         neighborLimit = maxCorrStatsDev;
    1786         220 :         move16();
    1787             :         /* refine and search based on the corrlag stats */
    1788         220 :         test();
    1789         220 :         test();
    1790         220 :         IF( tempS != 0 && NE_16( dsFactor, 1 ) && prev_ICA_flag == 0 )
    1791             :         {
    1792         144 :             tempF_fx = 0;
    1793         144 :             move32();
    1794         144 :             corrEstStage2_exp = 0;
    1795         144 :             move16();
    1796         144 :             IF( !musicMode )
    1797             :             {
    1798         130 :                 tempLag[0] = s_min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1799         130 :                 move16();
    1800         130 :                 tempLag[1] = s_max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1801         130 :                 move16();
    1802             : 
    1803         130 :                 neighborLimit = s_min( 3, maxCorrStatsDev );
    1804             : 
    1805         130 :                 IF( LT_16( hStereoTCA->prevCorrLagStats[2], hStereoTCA->corrLagStats[2] ) )
    1806             :                 {
    1807          92 :                     tempLag[1] = s_min( tempLag[1], add( tempLag[0], neighborLimit ) ); /* Q0 */
    1808             :                 }
    1809             :                 ELSE
    1810             :                 {
    1811          38 :                     tempLag[0] = s_max( tempLag[0], sub( tempLag[1], neighborLimit ) ); /* Q0 */
    1812             :                 }
    1813         130 :                 move16();
    1814         130 :                 utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, corrEstStage2_fx, &corrEstStage2_exp, tempLag, input_frame, 0 );
    1815             : 
    1816         130 :                 hStereoTCA->corrLagStats[2] = maximum_l( corrEstStage2_fx, add( sub( tempLag[1], tempLag[0] ), 1 ), &tempF_fx );
    1817         130 :                 move16();
    1818         130 :                 hStereoTCA->corrLagStats[2] = add( hStereoTCA->corrLagStats[2], tempLag[0] );
    1819         130 :                 move16();
    1820             :             }
    1821             : 
    1822         144 :             IF( GT_16( abs_s( tempS ), neighborLimit ) )
    1823             :             {
    1824         113 :                 tempLag[0] = hStereoTCA->corrLagStats[1]; /* Q0 */
    1825         113 :                 move16();
    1826         113 :                 tempLag[1] = hStereoTCA->corrLagStats[1]; /* Q0 */
    1827         113 :                 move16();
    1828         113 :                 utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, &tempF1_fx, &tempF1_exp, tempLag, input_frame, 0 );
    1829             : 
    1830         113 :                 test();
    1831         113 :                 IF( ( BASOP_Util_Cmp_Mant32Exp( tempF1_fx, tempF1_exp, tempF_fx, corrEstStage2_exp ) > 0 ) || musicMode )
    1832             :                 {
    1833          29 :                     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          21 :                         hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_max( -abs_s( tempS ), -maxCorrStatsDev ) ); /* Q0 */
    1840             :                     }
    1841          29 :                     move16();
    1842             :                 }
    1843             :             }
    1844             : 
    1845             :             /* restrict the reference channel for +/- variation */
    1846         144 :             test();
    1847         144 :             test();
    1848         144 :             test();
    1849         144 :             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         220 :         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          37 :             hStereoTCA->corrLagStats[2] = 0;
    1859          37 :             move16();
    1860             : 
    1861          37 :             test();
    1862          37 :             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         220 :         prevNCShift = abs_s( hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
    1874         220 :         currentNCShift = abs_s( hStereoTCA->corrLagStats[2] );  /* Q0 */
    1875             : 
    1876         220 :         IF( EQ_16( hStereoTCA->prevRefChanIndx, L_CH_INDX ) )
    1877             :         {
    1878         192 :             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         192 :             Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                                                           // bufChan_q - 2
    1880         192 :             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         192 :             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          28 :             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          28 :             Copy32( ptrChanL_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                   // bufChan_q -2
    1887          28 :             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          28 :             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         220 :         bufChan_q = sub( bufChan_q, 2 );
    1891         220 :         q_com = bufChan_q;
    1892         220 :         move16();
    1893         220 :         input_mem_loc_q = bufChan_q;
    1894         220 :         move16();
    1895         220 :         target_fx = ptrChanR_fx; /* bufChan_q -2 */
    1896         220 :         target_idx = R_CH_INDX;  /* Q0 */
    1897         220 :         move16();
    1898             :         /* identify target signal to correct for shift variations */
    1899         220 :         test();
    1900         220 :         test();
    1901         220 :         IF( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || EQ_16( hStereoTCA->prevRefChanIndx, R_CH_INDX ) )
    1902             :         {
    1903          49 :             target_fx = ptrChanL_fx; /* bufChan_q - 2 */
    1904          49 :             target_idx = L_CH_INDX;
    1905          49 :             move16();
    1906             :         }
    1907             : 
    1908             :         /* target signal adjustment for temporal shift variations */
    1909         220 :         IF( sub( prevNCShift, currentNCShift ) != 0 )
    1910             :         {
    1911         106 :             L_shift_adapt = L_SHIFT_ADAPT_16k;
    1912         106 :             move16();
    1913         106 :             if ( GT_32( input_Fs, INT_FS_16k ) )
    1914             :             {
    1915          82 :                 L_shift_adapt = L_SHIFT_ADAPT_MAX;
    1916          82 :                 move16();
    1917             :             }
    1918             : 
    1919             :             /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */
    1920         106 :             tempS = shr( currentNCShift, 1 ); /* Q0 */
    1921             : 
    1922         106 :             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          87 :                 adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
    1925             :             }
    1926             :             ELSE
    1927             :             {
    1928          19 :                 tempS = s_min( s_max( tempS, add( sub( prevNCShift, currentNCShift ), sub( L_shift_adapt, input_frame ) ) ), add( sub( prevNCShift, currentNCShift ), lMemRecalc ) ); /* Q0 */
    1929             : 
    1930          19 :                 adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
    1931             :             }
    1932             : 
    1933         106 :             IF( target_idx == L_CH_INDX )
    1934             :             {
    1935          40 :                 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          66 :                 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          66 :                 scale_sig32( input_mem_loc_fx[target_idx], sub( sub( add( lMemRecalc, lMemRecalc_SCh ), tempS ), currentNCShift ), -2 );
    1941          66 :                 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          66 :                 scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), -2 );
    1943          66 :                 input_mem_loc_q = sub( bufChan_q, 2 );
    1944             :             }
    1945             :         }
    1946             : 
    1947             :         /* reference channel index */
    1948         220 :         IF( hStereoTCA->corrLagStats[2] >= 0 )
    1949             :         {
    1950         190 :             hStereoTCA->refChanIndx = L_CH_INDX;
    1951             :         }
    1952             :         ELSE
    1953             :         {
    1954          30 :             hStereoTCA->refChanIndx = R_CH_INDX;
    1955             :         }
    1956         220 :         move16();
    1957             : 
    1958             :         /* Estimate and quantize the gain for scaling */
    1959             : 
    1960         220 :         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         220 :         Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */
    1966             : 
    1967         220 :         scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) );                                                                          /*Q10*/
    1968         220 :         hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */
    1969             : 
    1970         220 :         tempF_fx = tempF_16fx;
    1971         220 :         move32();
    1972             :     }
    1973             :     ELSE
    1974             :     {
    1975        3607 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1976        3607 :         move16();
    1977        3607 :         hStereoTCA->corrLagStats[2] = 0;
    1978        3607 :         move16();
    1979        3607 :         hStereoTCA->prevCorrLagStats[2] = 0;
    1980        3607 :         move16();
    1981        3607 :         hStereoTCA->indx_ica_NCShift = 0;
    1982        3607 :         move16();
    1983             : 
    1984        3607 :         currentNCShift = 0; /* only to avoid compilation warning */
    1985        3607 :         move16();
    1986        3607 :         target_fx = ptrChanL_fx; /* only to avoid compilation warning bufChan_q*/
    1987        3607 :         move16();
    1988        3607 :         target_idx = L_CH_INDX; /* only to avoid compilation warning */
    1989        3607 :         move16();
    1990             : 
    1991        3607 :         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        3607 :         Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) );                                       // bufChan_q -2
    1994        3607 :         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        3607 :         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        3607 :         bufChan_q = sub( bufChan_q, 2 );
    1998        3607 :         q_com = bufChan_q;
    1999        3607 :         move16();
    2000        3607 :         input_mem_loc_q = bufChan_q;
    2001        3607 :         move16();
    2002             :         /* Estimate and quantize the gain for scaling */
    2003             : 
    2004        3607 :         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        3827 :     Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
    2013        3827 :     Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
    2014        3827 :     hStereoTCA->memChan_q = bufChan_q;
    2015             : 
    2016        3827 :     IF( currentNCShift != 0 )
    2017             :     {
    2018             :         /* Temporal channel adjustment of the LA samples based on the NC shift */
    2019          96 :         tcaTargetCh_LA_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, &q_com, currentNCShift, input_frame );
    2020             : 
    2021          96 :         scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) );                                                                                                                                                                                                       // s_min( q_com, bufChan_q )
    2022          96 :         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          96 :         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          96 :         scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) );                                                                                                                                                                                                       // s_min( q_com, bufChan_q )
    2027          96 :         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          96 :         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          96 :         bufChan_q = s_min( q_com, bufChan_q );
    2030          96 :         q_com = bufChan_q;
    2031             :     }
    2032             : 
    2033             :     /* Update of changed samples corresponding to the memory */
    2034             :     /* Scaling to common Q*/
    2035        3827 :     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        3827 :     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        3827 :     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        3827 :     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        3827 :     input_mem_loc_q = s_min( input_mem_loc_q, sts[0]->q_inp32 ); /* sts[0]->q_inp32 */
    2041        3827 :     sts[0]->q_inp32 = input_mem_loc_q;
    2042        3827 :     move16();
    2043        3827 :     sts[1]->q_inp32 = input_mem_loc_q;
    2044        3827 :     move16();
    2045             : 
    2046        3827 :     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        3827 :     test();
    2050        3827 :     IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
    2051             :     {
    2052         220 :         Word16 shift = sub( q_com, sts[target_idx]->q_inp32 );
    2053      135580 :         FOR( Word16 idx = 0; idx < input_frame; idx++ )
    2054             :         {
    2055      135360 :             sts[target_idx]->input32_fx[idx] = L_shr( target_fx[currentNCShift + idx], shift );
    2056      135360 :             move32();
    2057             :         }
    2058             :     }
    2059             : 
    2060        3827 :     IF( NE_16( hCPE->element_mode, IVAS_CPE_DFT ) )
    2061             :     {
    2062             :         /* Scale the Right channel with the gain */
    2063             :         Word16 j;
    2064        3827 :         Word16 l_ica_ovl = NS2SA_FX2( input_Fs, STEREO_L_TCA_OVLP_NS );
    2065             : 
    2066        3827 :         Word16 winSlope = div_s( 1, l_ica_ovl ); // Q15
    2067             : 
    2068        3827 :         tempF1_fx = hStereoTCA->targetGain_fx; // Q29
    2069        3827 :         move32();
    2070        3827 :         tempF_fx = hStereoTCA->prevTargetGain_fx; // Q29
    2071        3827 :         move32();
    2072             : 
    2073      629827 :         FOR( ( i = 0, j = 0 ); i < l_ica_ovl; ( i++, j++ ) )
    2074             :         {
    2075      626000 :             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      626000 :             move32();
    2077             :         }
    2078             : 
    2079     1881827 :         FOR( ; i < input_frame; i++ )
    2080             :         {
    2081     1878000 :             sts[1]->input32_fx[i] = Mpy_32_32( sts[1]->input32_fx[i], tempF1_fx ); // inpq-2
    2082     1878000 :             move32();
    2083             :         }
    2084             : 
    2085        3827 :         scale_sig32( sts[1]->input_buff32_fx, (Word16) Mpy_32_32( input_Fs, 42949673 ) /* 1/50 in Q31*/, -2 );      // inpq-2
    2086        3827 :         scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), -2 ); // inpq-2
    2087        3827 :         sts[0]->q_inp32 = sub( sts[0]->q_inp32, 2 );
    2088        3827 :         move16();
    2089        3827 :         sts[1]->q_inp32 = sub( sts[1]->q_inp32, 2 );
    2090        3827 :         move16();
    2091             :     }
    2092             : 
    2093             :     /* update L/R DS memories */
    2094        3827 :     Copy32( bufChanL_DS_fx + L_FRAME_DS, hStereoTCA->memChanL_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
    2095        3827 :     Copy32( bufChanR_DS_fx + L_FRAME_DS, hStereoTCA->memChanR_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
    2096             : 
    2097             :     /* save the reference channel index for next frame */
    2098        3827 :     hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; /* Q0 */
    2099        3827 :     move16();
    2100             :     /* save the corr lag stats for next frame */
    2101        3827 :     Copy( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
    2102             : 
    2103             :     /* save the target gain for next frame */
    2104        3827 :     hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx; // Q29
    2105        3827 :     move32();
    2106        3827 :     return;
    2107             : }
    2108             : /*-------------------------------------------------------------------*
    2109             :  * stereo_tca_init_enc()
    2110             :  *
    2111             :  * Stereo temporal inter-channel adjustment (ICA) encoder initialization
    2112             :  *-------------------------------------------------------------------*/
    2113         893 : void stereo_tca_init_enc_fx(
    2114             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle           */
    2115             :     const Word32 input_Fs             /* i  : input sampling frequency    Q0*/
    2116             : )
    2117             : {
    2118             :     Word16 div1;
    2119             :     Word16 div_e;
    2120         893 :     hStereoTCA->lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS );
    2121         893 :     move16();
    2122         893 :     div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_12k8 ), input_Fs, &div_e ); /* Q15-div_e */
    2123         893 :     hStereoTCA->lMemRecalc_12k8 = shr( div1, 1 + sub( 15, div_e ) );
    2124         893 :     move16();
    2125             : 
    2126         893 :     div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_16k ), input_Fs, &div_e ); /* Q15-div_e */
    2127         893 :     hStereoTCA->lMemRecalc_16k = shr( div1, 1 + sub( 15, div_e ) );
    2128         893 :     move16();
    2129             : 
    2130         893 :     hStereoTCA->refChanIndx = L_CH_INDX;
    2131         893 :     hStereoTCA->prevRefChanIndx = L_CH_INDX;
    2132         893 :     move16();
    2133         893 :     move16();
    2134             : 
    2135         893 :     hStereoTCA->targetGain_fx = ONE_IN_Q29;     // Q29
    2136         893 :     hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
    2137         893 :     hStereoTCA->instTargetGain_fx = ONE_IN_Q29; // Q29
    2138         893 :     move32();
    2139         893 :     move32();
    2140         893 :     move32();
    2141         893 :     hStereoTCA->corrStatsSmoothFac_fx = 22938; // Q15
    2142         893 :     move16();
    2143             : 
    2144         893 :     set16_fx( hStereoTCA->corrLagStats, 0, 3 );
    2145         893 :     set16_fx( hStereoTCA->prevCorrLagStats, 0, 3 );
    2146             : 
    2147         893 :     set32_fx( hStereoTCA->memChanL_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
    2148         893 :     set32_fx( hStereoTCA->memChanR_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
    2149         893 :     hStereoTCA->memChan_q = 31;
    2150         893 :     move16();
    2151         893 :     set32_fx( hStereoTCA->memChanL_DS_fx, 0, ADDED_MEM_DS );
    2152         893 :     set32_fx( hStereoTCA->memChanR_DS_fx, 0, ADDED_MEM_DS );
    2153         893 :     hStereoTCA->memChan_DS_q = Q31;
    2154         893 :     move16();
    2155         893 :     hStereoTCA->mem_tempF_fx = 0;
    2156         893 :     move32();
    2157         893 :     hStereoTCA->mem_tempF_exp = 0;
    2158         893 :     move16();
    2159         893 :     set32_fx( hStereoTCA->corrEstPrev_fx[0], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2160         893 :     set32_fx( hStereoTCA->corrEstPrev_fx[1], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2161         893 :     set32_fx( hStereoTCA->corrEstPrev_fx[2], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2162         893 :     hStereoTCA->corrEstPrev_exp = 0;
    2163         893 :     move16();
    2164         893 :     set32_fx( hStereoTCA->corrEstLT_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2165         893 :     hStereoTCA->corrEstLT_exp = 0;
    2166         893 :     move16();
    2167         893 :     set32_fx( hStereoTCA->memdecim_fx, 0, 12 );
    2168         893 :     hStereoTCA->ica_envVarLT_fx = 2097152000; // 2000 in Q20
    2169         893 :     move32();
    2170         893 :     hStereoTCA->ica_envVarLT_exp = 11; // 2000 in Q20
    2171         893 :     move16();
    2172             : 
    2173         893 :     set32_fx( hStereoTCA->C_mem_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2174         893 :     set16_fx( hStereoTCA->C_mem_exp, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
    2175         893 :     hStereoTCA->E1_mem_fx = 0;
    2176         893 :     move32();
    2177         893 :     hStereoTCA->E2_mem_fx = 0;
    2178         893 :     move32();
    2179         893 :     hStereoTCA->E1_mem_exp = 0;
    2180         893 :     move16();
    2181         893 :     hStereoTCA->E2_mem_exp = 0;
    2182         893 :     move16();
    2183         893 :     set32_fx( hStereoTCA->delay_0_mem_fx, 0, MAX_DELAYREGLEN );
    2184         893 :     hStereoTCA->delay_0_mem_exp = 0;
    2185         893 :     move16();
    2186         893 :     hStereoTCA->smooth_dist_reg_prv_corr_fx = MAX_32; // Q15
    2187         893 :     hStereoTCA->smooth_dist_reg_prv_corr_exp = 0;     // Q15
    2188         893 :     hStereoTCA->LRTD_G_ATT_cnt = 1;
    2189         893 :     move16();
    2190         893 :     move16();
    2191             : 
    2192         893 :     return;
    2193             : }
    2194             : /*-------------------------------------------------------------------*
    2195             :  * Function unclr_calc_corr_features()
    2196             :  *
    2197             :  *-------------------------------------------------------------------*/
    2198        3827 : static void unclr_calc_corr_features_fx(
    2199             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle                             */
    2200             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: ICA Stereo Encoder handle                            */
    2201             :     Word32 buf1[],                        /* i  : left channel                                     q_com*/
    2202             :     Word32 buf2[],                        /* i  : right channel                                    q_com*/
    2203             :     Word16 q_com,
    2204             :     const Word16 length, /* i  : length of input signal buffers                       Q0*/
    2205             :     Word32 corrEst[],    /* i  : buffer containing inter-channel correlation values   corrEst_exp*/
    2206             :     Word16 corrEst_exp,
    2207             :     const Word16 lagSearchRange[], /* i  : minimum and maximum lags for corrEst[]               Q0*/
    2208             :     Word32 *corrEst_ncorr,         /* o  : norm. x-correlation btw. current and previous correlation buffers corrEst_ncorr_exp*/
    2209             :     Word16 *corrEst_ncorr_exp )
    2210             : {
    2211             :     Word16 i, corrLagMax, d_corrLagMax, tempLen, k;
    2212             :     Word32 num, den;
    2213             :     Word32 corrL, corrR, ener, ener_side, mono_i, side_i, ic_Lm, ic_Rm, tdm_es_em, m_corrL_corrR, d_corrL_corrR;
    2214             :     Word32 sum_prod, corrEstMax;
    2215             :     Word16 corrL_exp, corrR_exp, ener_exp, ener_side_exp, sum_prod_exp, exp, exp1, exp2, num_exp, den_exp;
    2216             : 
    2217        3827 :     corrL = ONE_IN_Q31;
    2218        3827 :     move32();
    2219        3827 :     corrL_exp = 0;
    2220        3827 :     move16();
    2221        3827 :     corrR = ONE_IN_Q31;
    2222        3827 :     move32();
    2223        3827 :     corrR_exp = 0;
    2224        3827 :     move16();
    2225        3827 :     ener = ONE_IN_Q31;
    2226        3827 :     move32();
    2227        3827 :     ener_exp = 0;
    2228        3827 :     move16();
    2229        3827 :     ener_side = ONE_IN_Q31;
    2230        3827 :     move32();
    2231        3827 :     ener_side_exp = 0;
    2232        3827 :     move16();
    2233        3827 :     sum_prod = 0;
    2234        3827 :     move32();
    2235        3827 :     sum_prod_exp = 0;
    2236        3827 :     move16();
    2237             : 
    2238      616147 :     FOR( i = 0; i < length; i++ )
    2239             :     {
    2240      612320 :         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 */
    2241      612320 :         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 */
    2242      612320 :         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 */
    2243      612320 :         ener = BASOP_Util_Add_Mant32Exp( ener, ener_exp, Mpy_32_32( mono_i, mono_i ), shl( exp, 1 ), &ener_exp );
    2244             : 
    2245      612320 :         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 */
    2246      612320 :         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 */
    2247             : 
    2248             :         Word16 n1, n2, prod_i_exp;
    2249             :         Word32 x, y, prod_i;
    2250      612320 :         n1 = norm_l( buf1[i] );
    2251      612320 :         n2 = norm_l( buf2[i] );
    2252      612320 :         x = L_shl( buf1[i], n1 );   // q: q_com + n1
    2253      612320 :         y = L_shl( buf2[i], n2 );   // q: q_com + n2
    2254      612320 :         prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31
    2255      612320 :         prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) );
    2256      612320 :         sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */
    2257             :     }
    2258             : 
    2259             :     /* average energy of L and R channels */
    2260        3827 :     hStereoClassif->ave_ener_L_fx = Mpy_32_32( hStereoTCA->E1_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_L_fx_e */
    2261        3827 :     move32();
    2262        3827 :     hStereoClassif->ave_ener_L_fx_e = hStereoTCA->E1_mem_exp;
    2263        3827 :     move16();
    2264        3827 :     hStereoClassif->ave_ener_R_fx = Mpy_32_32( hStereoTCA->E2_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_R_fx_e */
    2265        3827 :     move32();
    2266        3827 :     hStereoClassif->ave_ener_R_fx_e = hStereoTCA->E2_mem_exp;
    2267        3827 :     move16();
    2268             : 
    2269             :     /* unnormalized L/R correlation */
    2270        3827 :     IF( sum_prod )
    2271             :     {
    2272        3827 :         sum_prod = BASOP_Util_Log10( L_abs( sum_prod ), sum_prod_exp ); /* Q31-sum_prod_exp */
    2273        3827 :         sum_prod_exp = 6;
    2274        3827 :         move16();
    2275             :     }
    2276             :     ELSE
    2277             :     {
    2278           0 :         sum_prod = 0;
    2279           0 :         move32();
    2280           0 :         sum_prod_exp = 0;
    2281           0 :         move16();
    2282             :     }
    2283             : 
    2284        3827 :     hStereoClassif->unclr_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
    2285        3827 :     move32();
    2286        3827 :     hStereoClassif->xtalk_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
    2287        3827 :     move32();
    2288             :     /* S/M energy ratio */
    2289        3827 :     Word32 inp1 = Sqrt32( Mpy_32_32( ener_side, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_side_exp ); /* Q31-ener_side_exp */
    2290        3827 :     inp1 = BASOP_Util_Log10( inp1, ener_side_exp );                                                    /* Q31-ener_side_exp */
    2291        3827 :     Word16 temp = ener_exp;
    2292        3827 :     move16();
    2293        3827 :     Word32 inp2 = Sqrt32( Mpy_32_32( ener, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_exp ); /* Q31-ener_exp */
    2294        3827 :     inp2 = BASOP_Util_Log10( inp2, ener_exp );                                               /* Q31-ener_exp */
    2295        3827 :     ener_exp = temp;
    2296        3827 :     move16();
    2297             : 
    2298        3827 :     tdm_es_em = L_abs( Mpy_32_32( L_sub( inp1, inp2 ), 1342177280 ) ); /* Q25 + Q27 - Q31 = 21*/
    2299             : 
    2300        3827 :     hStereoClassif->unclr_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
    2301        3827 :     move32();
    2302        3827 :     hStereoClassif->xtalk_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
    2303        3827 :     move32();
    2304             : 
    2305             :     /* L/R correlation values (zero lag, maximum) */
    2306        3827 :     corrLagMax = maximum_l( corrEst, sub( lagSearchRange[1], add( lagSearchRange[0], 1 ) ), &corrEstMax );
    2307        3827 :     d_corrLagMax = sub( corrLagMax, hStereoClassif->unclr_corrLagMax_prev );
    2308             : 
    2309        3827 :     hStereoClassif->unclr_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
    2310        3827 :     move32();
    2311        3827 :     hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
    2312        3827 :     move32();
    2313        3827 :     hStereoClassif->xtalk_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
    2314        3827 :     move32();
    2315             : 
    2316        3827 :     if ( corrEstMax < 0 )
    2317             :     {
    2318           0 :         corrEstMax = 0;
    2319           0 :         move32();
    2320             :     }
    2321             : 
    2322        3827 :     hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
    2323        3827 :     move32();
    2324        3827 :     hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
    2325        3827 :     move32();
    2326        3827 :     hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */
    2327        3827 :     move32();
    2328        3827 :     hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
    2329        3827 :     move32();
    2330        3827 :     hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
    2331        3827 :     move32();
    2332        3827 :     hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */
    2333        3827 :     move32();
    2334             : 
    2335             :     /* L/M and R/M correlation */
    2336        3827 :     if ( corrL < 0 )
    2337             :     {
    2338         113 :         corrL = 0;
    2339         113 :         move32();
    2340             :     }
    2341             : 
    2342        3827 :     if ( corrR < 0 )
    2343             :     {
    2344          58 :         corrR = 0;
    2345          58 :         move32();
    2346             :     }
    2347             : 
    2348        3827 :     ic_Lm = BASOP_Util_Divide3232_Scale_newton( corrL, ener, &exp1 ); /* Q31-exp1 */
    2349        3827 :     exp1 = add( exp1, sub( corrL_exp, ener_exp ) );
    2350        3827 :     ic_Rm = BASOP_Util_Divide3232_Scale_newton( corrR, ener, &exp2 ); /* Q31-exp2 */
    2351        3827 :     exp2 = add( exp2, sub( corrR_exp, ener_exp ) );
    2352             : 
    2353        3827 :     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)
    2354             : 
    2355        3827 :     inp1 = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, L_negate( corrR ), corrR_exp, &exp ); /* Q31-exp */
    2356        3827 :     IF( inp1 )
    2357             :     {
    2358        3827 :         d_corrL_corrR = BASOP_Util_Log10( L_abs( inp1 ), exp ); // Q25
    2359             :     }
    2360             :     ELSE
    2361             :     {
    2362           0 :         d_corrL_corrR = 0;
    2363           0 :         move32();
    2364             :     }
    2365             : 
    2366        3827 :     hStereoClassif->unclr_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
    2367        3827 :     move32();
    2368        3827 :     hStereoClassif->unclr_fv_fx[E_d_corrL_corrR] = L_shr( d_corrL_corrR, 10 ); // Q15
    2369        3827 :     move32();
    2370        3827 :     hStereoClassif->xtalk_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
    2371        3827 :     move32();
    2372             : 
    2373             :     /* norm. x-correlation btw. current and previous correlation buffers */
    2374        3827 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
    2375        3827 :     move16();
    2376             : 
    2377        3827 :     Word64 L64_sum = 0;
    2378        3827 :     move64();
    2379      313814 :     FOR( k = 0; k < tempLen; k++ )
    2380             :     {
    2381      309987 :         L64_sum = W_mac_32_32( L64_sum, corrEst[k], hStereoTCA->corrEstPrev_fx[2][k] ); /* 2*(Q31-corrEst_exp)+1 */
    2382             :     }
    2383        3827 :     k = W_norm( L64_sum );
    2384        3827 :     L64_sum = W_shl( L64_sum, k ); /* 2*(Q31-corrEst_exp)+1+k */
    2385        3827 :     num = W_extract_h( L64_sum );  // ener_side_q
    2386        3827 :     num_exp = sub( 31, sub( add( add( add( sub( 31, corrEst_exp ), sub( 31, hStereoTCA->corrEstPrev_exp ) ), 1 ), k ), 32 ) );
    2387             : 
    2388        3827 :     exp1 = corrEst_exp;
    2389        3827 :     move16();
    2390        3827 :     inp1 = sum2_32_exp_fx( corrEst, tempLen, &exp1, 3 );
    2391             : 
    2392        3827 :     exp2 = hStereoTCA->corrEstPrev_exp;
    2393        3827 :     move16();
    2394        3827 :     inp2 = sum2_32_exp_fx( hStereoTCA->corrEstPrev_fx[2], tempLen, &exp2, 3 );
    2395             : 
    2396        3827 :     den_exp = add( exp1, exp2 );
    2397        3827 :     den = Sqrt32( Mpy_32_32( inp1, inp2 ), &den_exp ); /* Q31-den_exp */
    2398             : 
    2399        3827 :     IF( den == 0 )
    2400             :     {
    2401          62 :         *corrEst_ncorr = 0;
    2402          62 :         move32();
    2403          62 :         *corrEst_ncorr_exp = 0;
    2404          62 :         move16();
    2405             :     }
    2406             :     ELSE
    2407             :     {
    2408        3765 :         *corrEst_ncorr = BASOP_Util_Divide3232_Scale_newton( num, den, &exp ); /* Q31-corrEst_ncorr_exp */
    2409        3765 :         *corrEst_ncorr_exp = add( exp, sub( num_exp, den_exp ) );
    2410        3765 :         move32();
    2411        3765 :         move16();
    2412             :     }
    2413             : 
    2414        3827 :     hStereoClassif->unclr_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
    2415        3827 :     move32();
    2416        3827 :     hStereoClassif->xtalk_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
    2417        3827 :     move32();
    2418             : 
    2419        3827 :     return;
    2420             : }

Generated by: LCOV version 1.14