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

Generated by: LCOV version 1.14