LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_ica_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 529 546 96.9 %
Date: 2025-05-23 08:37:30 Functions: 11 11 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.h"
      40             : #include "ivas_prot.h"
      41             : #ifdef DEBUGGING
      42             : #include "debug.h"
      43             : #endif
      44             : #include "wmc_auto.h"
      45             : #include "rom_com.h"
      46             : #include "ivas_rom_com.h"
      47             : 
      48             : 
      49             : /*---------------------------------------------------------------
      50             :  * Local function prototypes
      51             :  * ---------------------------------------------------------------*/
      52             : 
      53             : static void unclr_calc_corr_features( STEREO_CLASSIF_HANDLE hStereoClassif, STEREO_TCA_ENC_HANDLE hStereoTCA, const float buf1[], const float buf2[], const int16_t length, const float corrEst[], const int16_t lagSearchRange[], float *corrEst_ncorr );
      54             : 
      55             : 
      56             : /*-------------------------------------------------------------------*
      57             :  * Local constants
      58             :  *-------------------------------------------------------------------*/
      59             : 
      60             : #define XL_BIAS            0.20f
      61             : #define XH_BIAS            0.40f
      62             : #define XL_WIDTH           0.12f
      63             : #define XH_WIDTH           0.15f /* 0.25 is MAX */
      64             : #define YL_DIST            7.0f
      65             : #define YH_DIST            9.0f
      66             : #define SMOOTH_DIST_FACTOR 0.4f
      67             : #define SMOOTH_ENV_FACTOR  0.6f
      68             : 
      69             : #define A_BIAS  ( ( XH_BIAS - XL_BIAS ) / ( YH_DIST - YL_DIST ) )
      70             : #define B_BIAS  ( XH_BIAS - ( A_BIAS * YH_DIST ) )
      71             : #define A_WIDTH ( ( XH_WIDTH - XL_WIDTH ) / ( YH_DIST - YL_DIST ) )
      72             : #define B_WIDTH ( XH_WIDTH - ( A_WIDTH * YH_DIST ) )
      73             : 
      74             : 
      75             : /*---------------------------------------------------------------
      76             :  * tcaTargetCh_LA()
      77             :  *
      78             :  * Temporal channel adjustment of LA samples in target channel
      79             :  * ---------------------------------------------------------------*/
      80             : 
      81          49 : static void tcaTargetCh_LA(
      82             :     STEREO_TCA_ENC_HANDLE hStereoTCA,
      83             :     float *ptrChanL,
      84             :     float *ptrChanR,
      85             :     const int16_t currentNCShift,
      86             :     const int16_t input_frame )
      87             : {
      88             :     int16_t i, j;
      89             :     int16_t tempS;
      90             :     float tempF1, tempF2, gAdj;
      91             : 
      92             :     float *ref, *target;
      93             :     float win[240]; /* 5 ms at 48 kHz */
      94             : 
      95          49 :     if ( hStereoTCA->refChanIndx == L_CH_INDX )
      96             :     {
      97          32 :         ref = ptrChanL;
      98          32 :         target = ptrChanR;
      99             :     }
     100             :     else
     101             :     {
     102          17 :         ref = ptrChanR;
     103          17 :         target = ptrChanL;
     104             :     }
     105             : 
     106          49 :     tempS = NS2SA( input_frame * FRAMES_PER_SEC, L_SAMPLES_LA_NS );
     107          49 :     tempF1 = 0.0f;
     108          49 :     tempF2 = 0.0f;
     109       29353 :     for ( i = 0; i < ( input_frame - currentNCShift ); i++ )
     110             :     {
     111       29304 :         tempF1 += fabsf( ref[i] );
     112       29304 :         tempF2 += fabsf( target[i + currentNCShift] );
     113             :     }
     114          49 :     gAdj = ( tempF1 == 0 ) ? 1.0f : tempF2 / max( tempF1, 0.00001f );
     115             : 
     116          49 :     tempF1 = EVS_PI / ( 2.0f * (float) tempS );
     117        1049 :     for ( i = 0; i < tempS; i++ )
     118             :     {
     119        1000 :         win[i] = sinf( tempF1 * ( 0.5f + (float) i ) );
     120             :     }
     121             : 
     122          49 :     j = 0;
     123        1049 :     for ( i = ( input_frame - currentNCShift - tempS ); i < input_frame - currentNCShift; i++, j++ )
     124             :     {
     125        1000 :         target[i + currentNCShift] = ( win[j] * gAdj ) * ref[i] + ( 1.0f - win[j] ) * target[i + currentNCShift];
     126             :     }
     127        2745 :     for ( ; i < input_frame; i++, j++ )
     128             :     {
     129        2696 :         target[i + currentNCShift] = gAdj * ref[i];
     130             :     }
     131             : 
     132          49 :     return;
     133             : }
     134             : 
     135             : /*---------------------------------------------------------------
     136             :  * spectral_balancer()
     137             :  *
     138             :  * Spectral-balancer to take care of the low-freq rumble and
     139             :  * compensate for the pre-emphasis.
     140             :  * ---------------------------------------------------------------*/
     141             : 
     142        7650 : void spectral_balancer(
     143             :     float *signal,
     144             :     float *mem,
     145             :     const int16_t lg,
     146             :     const int16_t coeff_set )
     147             : {
     148             :     int16_t i;
     149             :     float x0, x1, x2, y0, y1, y2;
     150             :     float a1, a2, b0, b1, b2;
     151             : 
     152        7650 :     y1 = mem[0];
     153        7650 :     y2 = mem[1];
     154        7650 :     x0 = mem[2];
     155        7650 :     x1 = mem[3];
     156             : 
     157             :     /* hp filter 60Hz at 3dB for 8000KHz sampling rate
     158             :         1. [b,a] = butter(1, 60.0/8000.0, 'high');
     159             :         2. spectral_balancing_filter
     160             :         <<gain = 0.97697627795388164   -> maybe not needed>>
     161             :         b =[1, -1] [1, -0.6]
     162             :         a =[1, -0.95395255590776329] [1, 0.5] */
     163        7650 :     if ( coeff_set == 0 )
     164             :     {
     165        7582 :         a1 = 0.747789178258504f;
     166        7582 :         a2 = -0.272214937925007f;
     167        7582 :         b0 = 0.505001029045878f;
     168        7582 :         b1 = -1.01000205809176f;
     169        7582 :         b2 = 0.505001029045878f;
     170             :     }
     171             :     else
     172             :     {
     173          68 :         a1 = -0.13456126833218354f;
     174          68 :         a2 = -0.38813694706072926f;
     175          68 :         b0 = 1.0f;
     176          68 :         b1 = -1.9980666374183167f;
     177          68 :         b2 = 1.0f;
     178             :     }
     179             : 
     180     1266850 :     for ( i = 0; i < lg; i++ )
     181             :     {
     182     1259200 :         x2 = x1;
     183     1259200 :         x1 = x0;
     184     1259200 :         x0 = signal[i];
     185     1259200 :         y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b0 ) + ( x1 * b1 ) + ( x2 * b2 );
     186     1259200 :         signal[i] = y0;
     187     1259200 :         y2 = y1;
     188     1259200 :         y1 = y0;
     189             :     }
     190             : 
     191        7650 :     mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0;
     192        7650 :     mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0;
     193        7650 :     mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0;
     194        7650 :     mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0;
     195             : 
     196        7650 :     return;
     197             : }
     198             : 
     199             : 
     200             : /*---------------------------------------------------------------
     201             :  * deEmphResample()
     202             :  *
     203             :  * De-emphasize and resample the L and R channels.
     204             :  * ---------------------------------------------------------------*/
     205             : 
     206        3791 : static void deEmphResample(
     207             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle   */
     208             :     const float *tempChan1,           /* i  : Stereo data                 */
     209             :     const float *tempChan2,           /* i  : Stereo data                 */
     210             :     float *chan1,
     211             :     float *chan2,
     212             :     const int16_t input_frame,
     213             :     const int16_t dsFactor )
     214             : {
     215             :     float buf1[L_FRAME48k], buf2[L_FRAME48k];
     216             :     float tempBuf1[2 * L_FRAME_DS], tempBuf2[2 * L_FRAME_DS];
     217             :     int16_t i;
     218             :     int16_t dsFac1, dsFac2;
     219             : 
     220             :     /* Estimate first and second stage downsample factors */
     221        3791 :     dsFac1 = ( dsFactor >> 1 );
     222        3791 :     dsFac2 = dsFactor / dsFac1;
     223             : 
     224             :     /* convert stereo data to two distinct channels, e.g., L, R */
     225        3791 :     mvr2r( tempChan1, buf1, input_frame );
     226        3791 :     mvr2r( tempChan2, buf2, input_frame );
     227             : 
     228             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
     229        3791 :     deemph( buf1, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[0] );
     230        3791 :     deemph( buf2, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[1] );
     231             : 
     232     1216911 :     for ( i = 0; i < ( input_frame / dsFac1 ); i++ )
     233             :     {
     234     1213120 :         tempBuf1[i] = buf1[i * dsFac1];
     235     1213120 :         tempBuf2[i] = buf2[i * dsFac1];
     236             :     }
     237             : 
     238             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
     239        3791 :     deemph( tempBuf1, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[2] );
     240        3791 :     deemph( tempBuf2, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[3] );
     241             : 
     242      610351 :     for ( i = 0; i < ( input_frame / dsFactor ); i++ )
     243             :     {
     244      606560 :         chan1[i] = tempBuf1[i * dsFac2];
     245      606560 :         chan2[i] = tempBuf2[i * dsFac2];
     246             :     }
     247             : 
     248        3791 :     spectral_balancer( chan1, &hStereoTCA->memdecim[4], input_frame / dsFactor, 0 ); /*4 mem */
     249        3791 :     spectral_balancer( chan2, &hStereoTCA->memdecim[8], input_frame / dsFactor, 0 ); /*4 mem */
     250             : 
     251        3791 :     return;
     252             : }
     253             : 
     254             : /*---------------------------------------------------------------
     255             :  * utilCrossCorr_mod()
     256             :  *
     257             :  * Biased crossCorr estimation between buf1, buf2 over the
     258             :  * lag range of (lagSearchRange[0], lagSearchRange[1]).
     259             :  * ---------------------------------------------------------------*/
     260             : 
     261        3791 : static void utilCrossCorr_mod(
     262             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle   */
     263             :     const float *buf1,
     264             :     const float *buf2,
     265             :     float *corrEst, /* o  : correlation estimate          */
     266             :     const int16_t *lagSearchRange,
     267             :     const int16_t len )
     268             : {
     269             :     float C, E1, E2;
     270             :     int16_t i, j;
     271             :     float Inv_Tot_E;
     272             : 
     273        3791 :     E1 = sum2_f( buf1, len );
     274        3791 :     E2 = sum2_f( buf2, len );
     275             : 
     276        3791 :     Inv_Tot_E = 1.0f / ( ( 2.0f * (float) len ) * sqrtf( ( E1 + hStereoTCA->E1_mem ) * ( E2 + hStereoTCA->E2_mem ) + 0.000000001f ) );
     277             : 
     278        3791 :     hStereoTCA->E1_mem = E1;
     279        3791 :     hStereoTCA->E2_mem = E2;
     280             : 
     281      159222 :     for ( i = lagSearchRange[0], j = 0; i <= 0; i++, j++ )
     282             :     {
     283      155431 :         C = dotp( buf1, buf2 + i, len );
     284      155431 :         corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
     285      155431 :         hStereoTCA->C_mem[j] = C;
     286             :     }
     287             : 
     288      155431 :     for ( ; i <= lagSearchRange[1]; i++, j++ )
     289             :     {
     290      151640 :         C = dotp( buf1 - i, buf2, len );
     291      151640 :         corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
     292      151640 :         hStereoTCA->C_mem[j] = C;
     293             :     }
     294             : 
     295        3791 :     return;
     296             : }
     297             : 
     298             : 
     299             : /*---------------------------------------------------------------
     300             :  * utilCrossCorr()
     301             :  *
     302             :  * crossCorr estimation between buf1, buf2 over the
     303             :  * lag range of (lagSearchRange[0], lagSearchRange[1]).
     304             :  * ---------------------------------------------------------------*/
     305             : 
     306         161 : static void utilCrossCorr(
     307             :     const float *buf1,
     308             :     const float *buf2,
     309             :     const float *win,
     310             :     float *corrEst, /* o  : correlation estimate      */
     311             :     const int16_t *lagSearchRange,
     312             :     const int16_t len,
     313             :     const int16_t winSymmFlag )
     314             : {
     315             :     float tempBuf1[L_FRAME48k];
     316             :     float tempBuf2[L_FRAME48k];
     317             :     float temp, scale;
     318             :     int16_t i, j;
     319             : 
     320             :     /* Apply windowing */
     321         161 :     if ( win != NULL )
     322             :     {
     323           0 :         if ( winSymmFlag == 0 )
     324             :         {
     325           0 :             v_mult( buf1, win, tempBuf1, len );
     326           0 :             v_mult( buf2, win, tempBuf2, len );
     327             :         }
     328             :         else
     329             :         {
     330           0 :             v_mult( buf1, win, tempBuf1, ( len >> 1 ) );
     331           0 :             v_mult( buf2, win, tempBuf2, ( len >> 1 ) );
     332             : 
     333           0 :             for ( i = ( len >> 1 ); i < len; i++ )
     334             :             {
     335           0 :                 tempBuf1[i] = win[len - 1 - i] * buf1[i];
     336           0 :                 tempBuf2[i] = win[len - 1 - i] * buf2[i];
     337             :             }
     338             :         }
     339             :     }
     340             :     else
     341             :     {
     342         161 :         mvr2r( buf1, tempBuf1, len );
     343         161 :         mvr2r( buf2, tempBuf2, len );
     344             :     }
     345             : 
     346         161 :     temp = sum2_f( tempBuf1, len );
     347         161 :     temp *= sum2_f( tempBuf2, len );
     348         161 :     scale = ( temp == 0 ) ? 1.0f : inv_sqrt( temp );
     349             : 
     350             :     /* starting point of lag search range should be less than the ending point */
     351         161 :     assert( lagSearchRange[0] <= lagSearchRange[1] );
     352             : 
     353             :     /* first part of noncausal corr est. */
     354         311 :     for ( i = lagSearchRange[0], j = 0; i <= min( 0, lagSearchRange[1] ); i++, j++ )
     355             :     {
     356         150 :         temp = dotp( tempBuf1 - i, tempBuf2, ( len + i ) );
     357         150 :         corrEst[j] = temp / ( len + i );
     358             :     }
     359             : 
     360             :     /* second part of noncausal corr est. */
     361         391 :     for ( ; i <= lagSearchRange[1]; i++, j++ )
     362             :     {
     363         230 :         temp = dotp( tempBuf1, tempBuf2 + i, ( len - i ) );
     364         230 :         corrEst[j] = temp / ( len - i );
     365             :     }
     366         161 :     v_multc( corrEst, scale, corrEst, j );
     367             : 
     368         161 :     return;
     369             : }
     370             : 
     371             : /*---------------------------------------------------------------
     372             :  *  corrStatsEst()
     373             :  *
     374             :  *  Non-causal shift estimation to encode future samples.
     375             :  * ---------------------------------------------------------------*/
     376             : 
     377        3791 : static void corrStatsEst(
     378             :     STEREO_TCA_ENC_HANDLE hStereoTCA,    /* i/o: Stereo TCA Encoder handle   */
     379             :     const float *buf1,                   /* i  : channel 1                   */
     380             :     const float *buf2,                   /* i  : channel 2                   */
     381             :     const int16_t bufLenDS,              /* i  : buffer length               */
     382             :     const int16_t dsFactor,              /* i  : buffer length               */
     383             :     const int16_t vad_flag1,             /* i  : VAD flag channel 1          */
     384             :     const int16_t vad_flag2,             /* i  : VAD flag channel 2          */
     385             :     STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle    */
     386             : )
     387             : {
     388             :     int16_t lagSearchRange[2];
     389             :     float corrEst[2 * L_NCSHIFT_DS + 1];
     390             :     int16_t corrLagStats[3];
     391             :     float *tempRK;
     392             :     const float *winInterp;
     393             :     float rInterp[MAX_INTERPOLATE];
     394             :     int16_t interpMin, interpMax, interpLen;
     395             :     int16_t i, j, k, m;
     396             :     float tempF, alpha;
     397             :     float win_bias;
     398             :     int16_t tempLen, win_width;
     399             :     float loc_weight_win[4 * L_NCSHIFT_DS + 1];
     400             :     float X_hat, Y_hat, XY_hat, X_SQR_hat;
     401             :     float alpha_reg, beta_reg, reg_prv_corr, dist_reg_prv_corr, bias_par, width_par;
     402             :     float k1, k2, temp_A, temp_B;
     403             :     int16_t stmp;
     404             :     float corrEst_ncorr;
     405             : 
     406             :     /* init of regression parameters*/
     407        3791 :     X_hat = 0;
     408        3791 :     X_SQR_hat = 0;
     409        3791 :     XY_hat = 0;
     410             : 
     411             :     /* Initializations */
     412        3791 :     alpha = 0.7f;
     413        3791 :     lagSearchRange[0] = -L_NCSHIFT_DS;
     414        3791 :     lagSearchRange[1] = L_NCSHIFT_DS;
     415        3791 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
     416             : 
     417        3791 :     set_s( corrLagStats, 0, 3 );
     418             : 
     419             :     /* First iteration of xcorr estimation */
     420        3791 :     utilCrossCorr_mod( hStereoTCA, buf1, buf2, corrEst, lagSearchRange, bufLenDS - L_XCORRMEM_DS );
     421             : 
     422             :     /* calculate features for the UNCLR classifier */
     423        3791 :     unclr_calc_corr_features( hStereoClassif, hStereoTCA, buf1, buf2, bufLenDS - L_XCORRMEM_DS, corrEst, lagSearchRange, &corrEst_ncorr );
     424             : 
     425       11373 :     for ( i = 1; i < 3; i++ )
     426             :     {
     427        7582 :         v_add( hStereoTCA->corrEstPrev[i], hStereoTCA->corrEstPrev[0], hStereoTCA->corrEstPrev[0], tempLen );
     428             :     }
     429             : 
     430             :     /* back up the corrEst */
     431       11373 :     for ( i = 0; i < 2; i++ )
     432             :     {
     433        7582 :         mvr2r( hStereoTCA->corrEstPrev[i + 1], hStereoTCA->corrEstPrev[i], tempLen );
     434             :     }
     435        3791 :     mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
     436             : 
     437        3791 :     temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
     438        3791 :     temp_B = sumAbs( buf1 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) + sumAbs( buf2 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS );
     439        3791 :     tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
     440        3791 :     hStereoTCA->mem_tempF = temp_B;
     441             : 
     442        3791 :     alpha = 0.93f;
     443        3791 :     if ( tempF > 4.0f * hStereoTCA->ica_envVarLT )
     444             :     {
     445         122 :         alpha = 0.83f;
     446             :     }
     447        3669 :     else if ( tempF > 2.0f * hStereoTCA->ica_envVarLT )
     448             :     {
     449         313 :         alpha = 0.85f;
     450             :     }
     451        3356 :     else if ( tempF > hStereoTCA->ica_envVarLT )
     452             :     {
     453        1055 :         alpha = 0.90f;
     454             :     }
     455             : 
     456        3791 :     hStereoTCA->corrStatsSmoothFac = alpha;
     457             : 
     458             :     /* long term corr Stats estimation */
     459        3791 :     v_multc( hStereoTCA->corrEstLT, alpha, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
     460        3791 :     v_multc( corrEst, 1.0f - alpha, corrEst, 2 * L_NCSHIFT_DS + 1 );
     461        3791 :     v_add( hStereoTCA->corrEstLT, corrEst, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
     462             : 
     463        3791 :     hStereoTCA->ica_envVarLT = SMOOTH_ENV_FACTOR * hStereoTCA->ica_envVarLT + ( 1 - SMOOTH_ENV_FACTOR ) * tempF;
     464             : 
     465        3791 :     mvr2r( hStereoTCA->corrEstLT, corrEst, 2 * L_NCSHIFT_DS + 1 );
     466        3791 :     Y_hat = hStereoTCA->delay_0_mem[0];
     467             :     /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
     468       45492 :     for ( i = 1; i < MAX_DELAYREGLEN; i++ )
     469             :     {
     470       41701 :         X_hat += (float) i;
     471       41701 :         Y_hat += hStereoTCA->delay_0_mem[i];
     472       41701 :         XY_hat += i * hStereoTCA->delay_0_mem[i];
     473       41701 :         X_SQR_hat += (float) ( i * i );
     474             :     }
     475        3791 :     X_hat *= INV_MAX_DELAYREGLEN;
     476        3791 :     Y_hat *= INV_MAX_DELAYREGLEN;
     477        3791 :     XY_hat *= INV_MAX_DELAYREGLEN;
     478        3791 :     X_SQR_hat *= INV_MAX_DELAYREGLEN;
     479             : 
     480        3791 :     beta_reg = 0;
     481        3791 :     tempF = X_SQR_hat - ( X_hat * X_hat );
     482        3791 :     if ( tempF != 0 )
     483             :     {
     484        3791 :         beta_reg = ( XY_hat - X_hat * Y_hat ) / tempF;
     485             :     }
     486        3791 :     alpha_reg = ( Y_hat - beta_reg * X_hat );
     487        3791 :     reg_prv_corr = beta_reg * MAX_DELAYREGLEN + alpha_reg;
     488             : 
     489        3791 :     if ( TRUNC( reg_prv_corr ) <= -L_NCSHIFT_DS )
     490             :     {
     491           0 :         reg_prv_corr = -L_NCSHIFT_DS + 1;
     492             :     }
     493             : 
     494        3791 :     if ( TRUNC( reg_prv_corr ) >= L_NCSHIFT_DS )
     495             :     {
     496           0 :         reg_prv_corr = L_NCSHIFT_DS - 1;
     497             :     }
     498             : 
     499        3791 :     bias_par = A_BIAS * hStereoTCA->smooth_dist_reg_prv_corr + B_BIAS;
     500        3791 :     bias_par = min( bias_par, XH_BIAS );
     501        3791 :     bias_par = max( bias_par, XL_BIAS );
     502             : 
     503        3791 :     width_par = A_WIDTH * hStereoTCA->smooth_dist_reg_prv_corr + B_WIDTH;
     504        3791 :     width_par = min( width_par, XH_WIDTH );
     505        3791 :     width_par = max( width_par, XL_WIDTH );
     506             : 
     507        3791 :     win_width = (int16_t) ( width_par * ( 4 * L_NCSHIFT_DS + 1 ) );
     508        3791 :     win_bias = bias_par;
     509        3791 :     k1 = 0.5f * ( 1.0f + win_bias );
     510        3791 :     k2 = 0.5f * ( 1.0f - win_bias );
     511             : 
     512      159085 :     for ( i = 0; i < ( 2 * L_NCSHIFT_DS - 2 * win_width ); i++ )
     513             :     {
     514      155294 :         loc_weight_win[i] = win_bias;
     515             :     }
     516             : 
     517      303554 :     for ( i = ( 2 * L_NCSHIFT_DS - 2 * win_width ); i <= ( 2 * L_NCSHIFT_DS + 2 * win_width ); i++ )
     518             :     {
     519      299763 :         loc_weight_win[i] = k1 + k2 * cosf( EVS_PI * ( ( i - 2 * L_NCSHIFT_DS ) / ( 2.0f * win_width ) ) );
     520             :     }
     521             : 
     522      162876 :     for ( i = ( 2 * L_NCSHIFT_DS + 2 * win_width ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
     523             :     {
     524      159085 :         loc_weight_win[i] = win_bias;
     525             :     }
     526             : 
     527      310862 :     for ( i = 0, j = L_NCSHIFT_DS - TRUNC( reg_prv_corr ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
     528             :     {
     529      307071 :         corrEst[i] *= loc_weight_win[j];
     530             :     }
     531             : 
     532        3791 :     if ( hStereoTCA->prevTargetGain < 0.8f && vad_flag1 )
     533             :     {
     534             :         /* ch 2 is prev reference channel */
     535           0 :         v_multc( corrEst, 1.2f, corrEst, L_NCSHIFT_DS + 1 );
     536           0 :         v_multc( corrEst + L_NCSHIFT_DS + 1, 0.833f, corrEst + L_NCSHIFT_DS + 1, L_NCSHIFT_DS );
     537             :     }
     538        3791 :     else if ( hStereoTCA->prevTargetGain > 1.2f && vad_flag1 )
     539             :     {
     540             :         /* ch 1 is prev reference channel */
     541           0 :         v_multc( corrEst, 0.833f, corrEst, L_NCSHIFT_DS );
     542           0 :         v_multc( corrEst + L_NCSHIFT_DS, 1.2f, corrEst + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 );
     543             :     }
     544             : 
     545        3791 :     if ( corrEst_ncorr > 0.8f && vad_flag1 )
     546             :     {
     547        1544 :         i = max( 0, hStereoTCA->prevCorrLagStats[0] - 1 + L_NCSHIFT_DS );
     548        1544 :         j = min( 2 * L_NCSHIFT_DS, hStereoTCA->prevCorrLagStats[0] + 1 + L_NCSHIFT_DS );
     549        1544 :         k = j - i + 1;
     550        1544 :         v_multc( corrEst + i, 1.2f, corrEst + i, k );
     551             :     }
     552             : 
     553             :     /* Initial corr lag estimate */
     554        3791 :     corrLagStats[0] = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &tempF );
     555        3791 :     corrLagStats[0] += lagSearchRange[0];
     556             : 
     557        3791 :     stmp = corrLagStats[0] * dsFactor;
     558        3791 :     hStereoClassif->unclr_fv[E_corrLagStats0] = (float) stmp;
     559        3791 :     hStereoClassif->xtalk_fv[E_corrLagStats0] = (float) stmp;
     560        3791 :     hStereoClassif->xtalk_fv[E_ica_corr_value0] = tempF;
     561             : 
     562        3791 :     if ( vad_flag1 == 0 && alpha > 0.7f )
     563             :     {
     564          15 :         corrLagStats[0] = 0;
     565             :     }
     566             : 
     567        3791 :     dist_reg_prv_corr = fabsf( reg_prv_corr - corrLagStats[0] );
     568             : 
     569        3791 :     if ( vad_flag1 == 1 && vad_flag2 == 1 )
     570             :     {
     571        3740 :         hStereoTCA->smooth_dist_reg_prv_corr = SMOOTH_DIST_FACTOR * hStereoTCA->smooth_dist_reg_prv_corr + ( 1.0f - SMOOTH_DIST_FACTOR ) * dist_reg_prv_corr;
     572             : 
     573        3740 :         mvr2r( &( hStereoTCA->delay_0_mem[1] ), &( hStereoTCA->delay_0_mem[0] ), MAX_DELAYREGLEN - 1 );
     574             : 
     575        3740 :         hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] = 0.2f * hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] + 0.8f * corrLagStats[0];
     576             : 
     577        3740 :         if ( fabsf( reg_prv_corr - hStereoTCA->delay_0_mem[0] ) > 25 )
     578             :         {
     579          85 :             set_f( &( hStereoTCA->delay_0_mem[0] ), hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
     580             :         }
     581             :     }
     582             :     else
     583             :     {
     584          51 :         hStereoTCA->smooth_dist_reg_prv_corr = 0.;
     585             :     }
     586             : 
     587        3791 :     if ( vad_flag1 == 0 || vad_flag2 == 0 )
     588             :     {
     589          51 :         corrLagStats[0] = TRUNC( hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] );
     590             :     }
     591             : 
     592             :     /* second iteration of xcorr update @ inputFs with interp*/
     593        3791 :     tempRK = hStereoTCA->corrEstLT - lagSearchRange[0] + corrLagStats[0];
     594        3791 :     set_f( rInterp, 0, MAX_INTERPOLATE );
     595             : 
     596             :     /* select the Rk interp sinc window */
     597        3791 :     winInterp = ica_sincInterp4 + SINC_ORDER1;
     598        3791 :     if ( dsFactor == 2 )
     599             :     {
     600         745 :         winInterp = ica_sincInterp2 + SINC_ORDER1;
     601             :     }
     602        3046 :     else if ( dsFactor == 6 )
     603             :     {
     604        1028 :         winInterp = ica_sincInterp6 + SINC_ORDER1;
     605             :     }
     606             : 
     607        3791 :     corrLagStats[1] = corrLagStats[0] * dsFactor;
     608             : 
     609        3791 :     interpMin = max( -( dsFactor - 1 ), -corrLagStats[1] - L_NCSHIFT_DS * dsFactor );
     610        3791 :     interpMax = min( ( dsFactor - 1 ), L_NCSHIFT_DS * dsFactor - corrLagStats[1] );
     611        3791 :     interpLen = interpMax - interpMin + 1;
     612             : 
     613       31460 :     for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
     614             :     {
     615       27669 :         rInterp[k] = 0.0f;
     616      368954 :         for ( j = -SINC_ORDER1 / dsFactor; j <= SINC_ORDER1 / dsFactor; j++ )
     617             :         {
     618      341285 :             m = j * dsFactor;
     619      341285 :             if ( ( m - i >= -SINC_ORDER1 ) && ( m - i <= SINC_ORDER1 ) )
     620             :             {
     621      317407 :                 if ( j > lagSearchRange[1] - corrLagStats[0] )
     622             :                 {
     623           8 :                     rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[1] - corrLagStats[0]];
     624             :                 }
     625      317399 :                 else if ( j < lagSearchRange[0] - corrLagStats[0] )
     626             :                 {
     627         176 :                     rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[0] - corrLagStats[0]];
     628             :                 }
     629             :                 else
     630             :                 {
     631      317223 :                     rInterp[k] += winInterp[m - i] * tempRK[j];
     632             :                 }
     633             :             }
     634             :         }
     635             :     }
     636        3791 :     corrLagStats[1] += ( maximum( rInterp, interpLen, &tempF ) + interpMin );
     637             : 
     638             :     /* save corr lag stats for the current frame */
     639        3791 :     mvs2s( corrLagStats, hStereoTCA->corrLagStats, 3 );
     640             : 
     641        3791 :     return;
     642             : }
     643             : 
     644             : 
     645             : /*---------------------------------------------------------------
     646             :  *  Function estDownmixGain()
     647             :  *
     648             :  *  Down mix gain estimation module; convert L/R to M/S.
     649             :  * ---------------------------------------------------------------*/
     650             : 
     651       63470 : static void estDownmixGain(
     652             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: Stereo TCA Encoder handle   */
     653             :     const float *chan1,                   /* i  : reference signal            */
     654             :     const float *chan2,                   /* i/o: target signal to be scaled  */
     655             :     const int16_t ncShift,                /* i  : shift                       */
     656             :     const int16_t length,                 /* i  : input frame length          */
     657             :     const int16_t element_mode,           /* i  : element mode                */
     658             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle    */
     659             :     const int16_t tdm_LRTD_flag           /* i  : LRTD stereo mode flag       */
     660             : )
     661             : {
     662             :     int16_t i, i1, i2;
     663             :     float tempN, tempD;
     664             :     float alpha, currentGain;
     665             :     float unclr_instTargetGain;
     666             : 
     667       63470 :     if ( hStereoTCA->refChanIndx == L_CH_INDX )
     668             :     {
     669       63453 :         i1 = 0;
     670       63453 :         i2 = ncShift;
     671             :     }
     672             :     else
     673             :     {
     674          17 :         i1 = ncShift;
     675          17 :         i2 = 0;
     676             :     }
     677             : 
     678             :     /* abs sample sum estimation */
     679       63470 :     tempN = 0;
     680       63470 :     tempD = 0;
     681    43756774 :     for ( i = 0, tempN = 0.0f, tempD = 0.0f; i < length; i++ )
     682             :     {
     683    43693304 :         tempN += fabsf( chan1[i1 + i] );
     684    43693304 :         tempD += fabsf( chan2[i2 + i] );
     685             :     }
     686             : 
     687       63470 :     alpha = hStereoTCA->corrStatsSmoothFac;
     688       63470 :     currentGain = ( tempD == 0 ) ? ( hStereoTCA->prevTargetGain ) : ( tempN / tempD );
     689       63470 :     currentGain = max( 1e-5f, currentGain );
     690       63470 :     hStereoTCA->instTargetGain = currentGain;
     691       63470 :     currentGain = (alpha) *log10f( hStereoTCA->prevTargetGain ) + ( 1.0f - alpha ) * log10f( currentGain );
     692             : 
     693       63470 :     if ( element_mode == IVAS_CPE_TD && hStereoClassif != NULL )
     694             :     {
     695        3791 :         tempD = powf( 10, currentGain );
     696        3791 :         unclr_instTargetGain = log10f( tempN / ( tempD + 1e-5f ) + 1.0f );
     697        3791 :         hStereoClassif->unclr_fv[E_ica_instTargetGain] = unclr_instTargetGain;
     698             :     }
     699             : 
     700       63470 :     if ( tdm_LRTD_flag == 1 )
     701             :     {
     702        3665 :         currentGain = 0.0f;
     703             :     }
     704       59805 :     else if ( hStereoTCA->LRTD_G_ATT_cnt > 1 ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
     705             :     {
     706         216 :         currentGain /= ( (float) hStereoTCA->LRTD_G_ATT_cnt );
     707             :     }
     708             : 
     709             :     /* quantize the target gain */
     710       63470 :     hStereoTCA->indx_ica_gD = (int16_t) usquant( currentGain, &tempD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP, 1 << STEREO_BITS_TCA_GD );
     711       63470 :     hStereoTCA->targetGain = powf( 10, tempD );
     712             : 
     713       63470 :     return;
     714             : }
     715             : 
     716             : /*---------------------------------------------------------------
     717             :  *  Function icaMemUpdate()
     718             :  *
     719             :  *  Recalculates the memories corresponding to the previous frame.
     720             :  * ---------------------------------------------------------------*/
     721             : 
     722        3791 : static void icaMemUpdate(
     723             :     Encoder_State **sts,          /* i/o: encoder state structure                 */
     724             :     CPE_ENC_HANDLE hCPE,          /* i  : CPE encoder structure                   */
     725             :     float *bufChanL,              /* i/o: L signal correction from previous frame */
     726             :     float *bufChanR,              /* i/o: R signal correction from previous frame */
     727             :     const int16_t lMemRecalc,     /* i  : memory length at input Sampling Rate    */
     728             :     const int16_t lMemRecalc_SCh, /* i  : SCh memory length at input Sampling Rate*/
     729             :     const int16_t input_frame     /* i  : frame length                            */
     730             : )
     731             : {
     732             :     float *ptr1, *ptr2;
     733             :     int16_t i;
     734             :     float ratio_L, One_m_Ratio;
     735             : 
     736        3791 :     if ( hCPE->element_mode == IVAS_CPE_TD )
     737             :     {
     738             :         /* Recalc of the memories - Downmix @ inputFs */
     739             :         /*----------------------------------------------------------------*
     740             :          * Create first part of the mixture using the old ratios
     741             :          *----------------------------------------------------------------*/
     742             : 
     743        3791 :         if ( hCPE->hStereoTD->tdm_last_SM_flag )
     744             :         {
     745          12 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM;
     746          12 :             One_m_Ratio = ratio_L - 1.0f;
     747             :         }
     748             :         else
     749             :         {
     750        3779 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio;
     751        3779 :             One_m_Ratio = 1.0f - ratio_L;
     752             :         }
     753             : 
     754        3791 :         ptr1 = sts[0]->input - lMemRecalc - lMemRecalc_SCh;
     755        3791 :         ptr2 = sts[1]->input - lMemRecalc - lMemRecalc_SCh;
     756             : 
     757        3791 :         if ( hCPE->last_element_mode == IVAS_CPE_TD )
     758             :         {
     759        3732 :             if ( hCPE->hStereoTD->flag_skip_DMX )
     760             :             {
     761       30932 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     762             :                 {
     763       30840 :                     ptr1[i] = bufChanL[i];
     764       30840 :                     ptr2[i] = bufChanR[i];
     765             :                 }
     766             :             }
     767             :             else
     768             :             {
     769      901000 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     770             :                 {
     771      897360 :                     ptr1[i] = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
     772      897360 :                     ptr2[i] = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
     773             :                 }
     774             :             }
     775             :         }
     776             :         else
     777             :         {
     778             :             float fac, incr, tmp1, tmp2;
     779             : 
     780             :             /* reset the past input signal (the signal is used in SWB BWE) */
     781          59 :             set_f( sts[1]->input - input_frame, 0, input_frame );
     782             : 
     783          59 :             if ( hCPE->hStereoTD->flag_skip_DMX )
     784             :             {
     785             :                 /* reconstruction of the Secondary channel past segment */
     786         813 :                 for ( i = 0; i < lMemRecalc_SCh; i++ )
     787             :                 {
     788         805 :                     ptr2[i] = bufChanL[i] * One_m_Ratio + bufChanR[i] * ratio_L;
     789             :                 }
     790             : 
     791             :                 /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
     792           8 :                 fac = 1.0f / (float) lMemRecalc;
     793           8 :                 incr = fac;
     794             : 
     795        2768 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     796             :                 {
     797        2760 :                     tmp1 = bufChanL[i];
     798        2760 :                     tmp2 = bufChanR[i];
     799             : 
     800        2760 :                     ptr1[i] = ( 1.0f - fac ) * ptr1[i] + fac * tmp1;
     801             :                     /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
     802        2760 :                     ptr2[i] = tmp2;
     803             : 
     804        2760 :                     fac += incr;
     805             :                 }
     806             :             }
     807             :             else
     808             :             {
     809             :                 /* reconstruction of the Secondary channel past segment */
     810        3796 :                 for ( i = 0; i < lMemRecalc_SCh; i++ )
     811             :                 {
     812        3745 :                     ptr2[i] = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
     813             :                 }
     814             : 
     815             :                 /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
     816          51 :                 fac = 1.0f / (float) lMemRecalc;
     817          51 :                 incr = fac;
     818             : 
     819       12891 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     820             :                 {
     821       12840 :                     tmp1 = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
     822       12840 :                     tmp2 = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
     823             : 
     824       12840 :                     ptr1[i] = ( 1.0f - fac ) * ptr1[i] + fac * tmp1;
     825             :                     /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
     826       12840 :                     ptr2[i] = tmp2;
     827             : 
     828       12840 :                     fac += incr;
     829             :                 }
     830             :             }
     831             :         }
     832             :     }
     833             : 
     834        3791 :     if ( hCPE->hStereoICBWE != NULL )
     835             :     {
     836             :         assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
     837         126 :         i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
     838         126 :         mvr2r( bufChanL + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[0], i );
     839         126 :         mvr2r( bufChanR + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[1], i );
     840             :     }
     841             : 
     842        3791 :     return;
     843             : }
     844             : 
     845             : /*---------------------------------------------------------------
     846             :  *  stereo_tca_enc()
     847             :  *
     848             :  *     Stereo temporal inter-channel adjustment/allocation processing module;
     849             :  *     Downmix, convert L/R to M/S.
     850             :  * ---------------------------------------------------------------*/
     851             : 
     852      420855 : void stereo_tca_enc(
     853             :     CPE_ENC_HANDLE hCPE,      /* i  : CPE encoder structure           */
     854             :     const int16_t input_frame /* i  : length of a frame per channel   */
     855             : )
     856             : {
     857             :     /* temp variables */
     858             :     int16_t i, dsFactor, lMemRecalc;
     859             :     Encoder_State **sts;
     860             :     STEREO_TCA_ENC_HANDLE hStereoTCA;
     861             : 
     862             :     /* Buffers, input Left and right channels  @ input_Fs*/
     863             :     int16_t lMemRecalc_SCh;
     864             :     float bufChanL[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
     865             :     float bufChanR[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
     866             :     float input_mem_loc[2][NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS )];
     867             :     float *ptrChanL, *ptrChanR;
     868             : 
     869             :     /* Buffers at internal sampling rate, i.e., CORR_INTER_FS */
     870             :     float bufChanL_DS[L_FRAME_DS + ADDED_MEM_DS];
     871             :     float bufChanR_DS[L_FRAME_DS + ADDED_MEM_DS];
     872             :     float *ptrChanL_DS, *ptrChanR_DS;
     873             :     float *target;
     874             :     int16_t target_idx;
     875             : 
     876             :     int16_t prevNCShift, currentNCShift;
     877             :     int16_t tempLag[2];
     878             :     float corrEstStage2[N_MAX_SHIFT_CHANGE + 1];
     879             : 
     880             :     /* temp variables */
     881             :     float tempF, tempF1;
     882             :     int16_t tempS, tempS_buff[3];
     883             :     int16_t maxCorrStatsDev, L_shift_adapt;
     884      420855 :     int16_t musicMode = 0, neighborLimit;
     885             :     int32_t input_Fs;
     886             :     int16_t prev_ICA_flag;
     887             : 
     888             :     /* initialization */
     889      420855 :     sts = hCPE->hCoreCoder;
     890      420855 :     hStereoTCA = hCPE->hStereoTCA;
     891             : 
     892      420855 :     input_Fs = sts[0]->input_Fs;
     893             : 
     894      420855 :     lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
     895      420855 :     lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS );
     896             : 
     897      420855 :     if ( hCPE->element_mode == IVAS_CPE_MDCT )
     898             :     {
     899      357385 :         return;
     900             :     }
     901             : 
     902             :     /* populate L/R memories into current buffers */
     903       63470 :     mvr2r( hStereoTCA->memChanL, bufChanL, lMemRecalc + lMemRecalc_SCh );
     904       63470 :     mvr2r( hStereoTCA->memChanR, bufChanR, lMemRecalc + lMemRecalc_SCh );
     905             : 
     906             :     /* pointers to the current frame */
     907       63470 :     ptrChanL = bufChanL + lMemRecalc + lMemRecalc_SCh;
     908       63470 :     ptrChanR = bufChanR + lMemRecalc + lMemRecalc_SCh;
     909             : 
     910             :     /* copy interleaved stereo data to two channels, e.g., L, R */
     911       63470 :     mvr2r( sts[0]->input, ptrChanL, input_frame );
     912       63470 :     mvr2r( sts[1]->input, ptrChanR, input_frame );
     913             : 
     914             :     /* UNCLR classifier update */
     915       63470 :     if ( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
     916             :     {
     917       59461 :         hStereoTCA->LRTD_G_ATT_cnt = 1;
     918             :     }
     919        4009 :     else if ( hCPE->hStereoTD != NULL )
     920             :     {
     921        3791 :         if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
     922             :         {
     923         126 :             hStereoTCA->LRTD_G_ATT_cnt++;
     924         126 :             hStereoTCA->LRTD_G_ATT_cnt = min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
     925             :         }
     926             :     }
     927             : 
     928       63470 :     if ( hCPE->element_mode != IVAS_CPE_TD )
     929             :     {
     930       59679 :         hStereoTCA->refChanIndx = L_CH_INDX;
     931       59679 :         hStereoTCA->corrStatsSmoothFac = 0.7f;
     932       59679 :         estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 );
     933       59679 :         hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
     934             : #ifdef DEBUG_MODE_INFO
     935             :         hStereoTCA->indx_ica_NCShift = 0;
     936             : #endif
     937             : 
     938             :         /* back up the L/R missing target */
     939       59679 :         mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
     940       59679 :         mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
     941             : 
     942       59679 :         hStereoTCA->lMemRecalc = 0;
     943       59679 :         hStereoTCA->lMemRecalc_12k8 = 0;
     944       59679 :         hStereoTCA->lMemRecalc_16k = 0;
     945             : 
     946       59679 :         return;
     947             :     }
     948        3791 :     else if ( hCPE->last_element_mode != IVAS_CPE_TD )
     949             :     {
     950          59 :         tempF = hStereoTCA->targetGain;
     951          59 :         tempF1 = hStereoTCA->prevTargetGain;
     952          59 :         tempS = hStereoTCA->prevRefChanIndx;
     953          59 :         mvs2s( hStereoTCA->prevCorrLagStats, tempS_buff, 3 );
     954          59 :         stereo_tca_init_enc( hStereoTCA, input_Fs );
     955          59 :         hStereoTCA->targetGain = tempF;
     956          59 :         hStereoTCA->prevTargetGain = tempF1;
     957             : 
     958          59 :         if ( hCPE->hStereoClassif->lrtd_mode == 1 )
     959             :         {
     960          59 :             hStereoTCA->targetGain = min( hStereoTCA->targetGain, 1.0f );
     961          59 :             hStereoTCA->prevTargetGain = min( hStereoTCA->prevTargetGain, 1.0f );
     962             : 
     963          59 :             hStereoTCA->prevTargetGain = 1;
     964             :         }
     965             : 
     966          59 :         hStereoTCA->prevRefChanIndx = tempS;
     967          59 :         mvs2s( tempS_buff, hStereoTCA->prevCorrLagStats, 3 );
     968             : 
     969             :         /* populate memory */
     970          59 :         if ( hCPE->last_element_mode == IVAS_CPE_MDCT )
     971             :         {
     972           8 :             mvr2r( sts[0]->input - lMemRecalc - lMemRecalc_SCh, bufChanL, lMemRecalc + lMemRecalc_SCh );
     973           8 :             mvr2r( sts[1]->input - lMemRecalc - lMemRecalc_SCh, bufChanR, lMemRecalc + lMemRecalc_SCh );
     974             :         }
     975             :     }
     976             : 
     977             :     /* populate L/R DS memories into current buffers */
     978        3791 :     mvr2r( hStereoTCA->memChanL_DS, bufChanL_DS, ADDED_MEM_DS );
     979        3791 :     mvr2r( hStereoTCA->memChanR_DS, bufChanR_DS, ADDED_MEM_DS );
     980             : 
     981             :     /* pointers to the current frame of DS */
     982        3791 :     ptrChanL_DS = bufChanL_DS + ADDED_MEM_DS;
     983        3791 :     ptrChanR_DS = bufChanR_DS + ADDED_MEM_DS;
     984             : 
     985             :     /* resample factor */
     986        3791 :     dsFactor = (int16_t) ( input_Fs / CORR_INTER_FS );
     987             : 
     988             :     /* resample the stereo channels */
     989        3791 :     deEmphResample( hStereoTCA, ptrChanL, ptrChanR, ptrChanL_DS, ptrChanR_DS, input_frame, dsFactor );
     990             : 
     991             : 
     992             :     /* inter-channel corrStats estimation */
     993        3791 :     corrStatsEst( hStereoTCA, bufChanL_DS + ADDED_MEM_DS, bufChanR_DS + ADDED_MEM_DS, ( L_FRAME_DS + L_XCORRMEM_DS ), dsFactor, hCPE->hCoreCoder[0]->vad_flag, hCPE->hCoreCoder[1]->vad_flag, hCPE->hStereoClassif );
     994             : 
     995             :     /*-----------------------------------------------------------------*
     996             :      * refine the ICA stats
     997             :      *-----------------------------------------------------------------*/
     998             : 
     999        3791 :     prev_ICA_flag = 0;
    1000        3791 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 )
    1001             :     {
    1002          33 :         prev_ICA_flag = 1;
    1003             :     }
    1004             : 
    1005        3791 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
    1006             :     {
    1007             :         /* initialize the refinement search for NC-shift */
    1008         210 :         hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
    1009             : 
    1010         210 :         maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
    1011         210 :         if ( hStereoTCA->corrStatsSmoothFac <= 0.7f )
    1012             :         {
    1013           0 :             maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
    1014             :         }
    1015             : 
    1016         210 :         if ( input_Fs < 32000 )
    1017             :         {
    1018          35 :             maxCorrStatsDev = (int16_t) ( maxCorrStatsDev * input_Fs / 32000.0f );
    1019             :         }
    1020             : 
    1021         210 :         musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
    1022         210 :         if ( musicMode )
    1023             :         {
    1024         104 :             maxCorrStatsDev = 1;
    1025         104 :             set_s( hStereoTCA->corrLagStats + 1, 0, 2 );
    1026             :         }
    1027             : 
    1028         210 :         tempS = ( hStereoTCA->corrLagStats[1] - hStereoTCA->prevCorrLagStats[2] );
    1029         210 :         if ( abs( tempS ) > maxCorrStatsDev )
    1030             :         {
    1031          66 :             hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? maxCorrStatsDev : -maxCorrStatsDev );
    1032             :         }
    1033             : 
    1034         210 :         neighborLimit = maxCorrStatsDev;
    1035             : 
    1036             :         /* refine and search based on the corrlag stats */
    1037         210 :         if ( tempS != 0 && dsFactor != 1 && prev_ICA_flag == 0 )
    1038             :         {
    1039         103 :             tempF = 0;
    1040         103 :             if ( !musicMode )
    1041             :             {
    1042          83 :                 tempLag[0] = min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
    1043          83 :                 tempLag[1] = max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
    1044             : 
    1045          83 :                 neighborLimit = min( 3, maxCorrStatsDev );
    1046          83 :                 if ( hStereoTCA->prevCorrLagStats[2] < hStereoTCA->corrLagStats[2] )
    1047             :                 {
    1048          61 :                     tempLag[1] = min( tempLag[1], tempLag[0] + neighborLimit );
    1049             :                 }
    1050             :                 else
    1051             :                 {
    1052          22 :                     tempLag[0] = max( tempLag[0], tempLag[1] - neighborLimit );
    1053             :                 }
    1054             : 
    1055          83 :                 utilCrossCorr( ptrChanL, ptrChanR, NULL, corrEstStage2, tempLag, input_frame, 0 );
    1056             : 
    1057          83 :                 hStereoTCA->corrLagStats[2] = maximum( corrEstStage2, ( tempLag[1] - tempLag[0] + 1 ), &tempF );
    1058          83 :                 hStereoTCA->corrLagStats[2] += tempLag[0];
    1059             :             }
    1060             : 
    1061         103 :             if ( abs( tempS ) > neighborLimit )
    1062             :             {
    1063          78 :                 tempLag[0] = hStereoTCA->corrLagStats[1];
    1064          78 :                 tempLag[1] = hStereoTCA->corrLagStats[1];
    1065          78 :                 utilCrossCorr( ptrChanL, ptrChanR, NULL, &tempF1, tempLag, input_frame, 0 );
    1066             : 
    1067          78 :                 if ( tempF1 > tempF || musicMode )
    1068             :                 {
    1069          20 :                     hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? min( (int16_t) abs( tempS ), maxCorrStatsDev ) : max( (int16_t) -abs( tempS ), -maxCorrStatsDev ) );
    1070             :                 }
    1071             :             }
    1072             : 
    1073             :             /* restrict the reference channel for +/- variation */
    1074         103 :             if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
    1075             :             {
    1076           1 :                 hStereoTCA->corrLagStats[2] = 0;
    1077             :             }
    1078             :         }
    1079             : 
    1080         210 :         if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec /*hCPE->hStereoClassif->lrtd_mode*/ == 1 ) /* Content is considered as uncorrelated -> ICA shift is turned off  */
    1081             :         {
    1082          33 :             hStereoTCA->corrLagStats[2] = 0;
    1083             : 
    1084          33 :             if ( hCPE->hStereoTD->tdm_LRTD_flag == 1 && prev_ICA_flag == 0 )
    1085             :             {
    1086           0 :                 hStereoTCA->prevCorrLagStats[2] = 0;
    1087             :             }
    1088             :         }
    1089             : 
    1090             :         /* Perform the following:
    1091             :            1. adjust samples,
    1092             :            2. interp shift variation,
    1093             :            3. gain estimation */
    1094         210 :         prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats[2] );
    1095         210 :         currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats[2] );
    1096             : 
    1097         210 :         if ( hStereoTCA->prevRefChanIndx == L_CH_INDX )
    1098             :         {
    1099         193 :             mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1100         193 :             v_multc( ptrChanR + prevNCShift - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
    1101             :         }
    1102             :         else
    1103             :         {
    1104          17 :             mvr2r( ptrChanL + prevNCShift - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1105          17 :             v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
    1106             :         }
    1107             : 
    1108         210 :         target = ptrChanR;
    1109         210 :         target_idx = R_CH_INDX;
    1110             :         /* identify target signal to correct for shift variations */
    1111         210 :         if ( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
    1112             :         {
    1113          33 :             target = ptrChanL;
    1114          33 :             target_idx = L_CH_INDX;
    1115             :         }
    1116             : 
    1117             :         /* target signal adjustment for temporal shift variations */
    1118         210 :         if ( ( prevNCShift - currentNCShift ) != 0 )
    1119             :         {
    1120          79 :             L_shift_adapt = L_SHIFT_ADAPT_16k;
    1121          79 :             if ( input_Fs > INT_FS_16k )
    1122             :             {
    1123          62 :                 L_shift_adapt = L_SHIFT_ADAPT_MAX;
    1124             :             }
    1125             : 
    1126             :             /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */
    1127          79 :             tempS = ( currentNCShift >> 1 );
    1128          79 :             if ( abs( currentNCShift - prevNCShift ) <= min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * input_Fs / 32000.0f ) )
    1129             :             {
    1130             : #ifdef DEBUGGING
    1131             :                 /* Max sample looked in INTERP1 should lie within the bounds of input_frame and memory populated */
    1132             :                 assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 ) + L_shift_adapt - tempS < input_frame );
    1133             :                 assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 + tempS ) < L_NCSHIFTMAX );
    1134             :                 assert( tempS + currentNCShift <= lMemRecalc );
    1135             :                 assert( input_frame - ( min( N_MAX_SHIFT_CHANGE, ( N_MAX_SHIFT_CHANGE * input_Fs ) / 32000 ) + 1 + SINC_ORDER1 / INTERP_FACTOR1 ) - ( prevNCShift >> 1 ) >= L_shift_adapt - tempS );
    1136             : #endif
    1137          62 :                 adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
    1138             :             }
    1139             :             else
    1140             :             {
    1141          17 :                 tempS = min( max( tempS, prevNCShift - currentNCShift + L_shift_adapt - input_frame ), prevNCShift - currentNCShift + lMemRecalc );
    1142          17 :                 adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
    1143             :             }
    1144             : 
    1145          79 :             if ( target_idx == L_CH_INDX )
    1146             :             {
    1147          32 :                 mvr2r( target - tempS, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
    1148             :             }
    1149             :             else
    1150             :             {
    1151          47 :                 v_multc( target - tempS, hStereoTCA->prevTargetGain, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
    1152             :             }
    1153             :         }
    1154             : 
    1155             :         /* reference channel index */
    1156         210 :         if ( hStereoTCA->corrLagStats[2] >= 0 )
    1157             :         {
    1158         193 :             hStereoTCA->refChanIndx = L_CH_INDX;
    1159             :         }
    1160             :         else
    1161             :         {
    1162          17 :             hStereoTCA->refChanIndx = R_CH_INDX;
    1163             :         }
    1164             : 
    1165             :         /* Estimate and quantize the gain for scaling */
    1166         210 :         estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
    1167             : 
    1168             :         /* quantize the corrStats */
    1169         210 :         hStereoTCA->indx_ica_NCShift = (int16_t) usquant( ( (float) currentNCShift ) / dsFactor, &tempF, 0, 1.0f, 1 << STEREO_BITS_TCA_CORRSTATS );
    1170             :     }
    1171             :     else
    1172             :     {
    1173        3581 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1174        3581 :         hStereoTCA->corrLagStats[2] = 0;
    1175        3581 :         hStereoTCA->prevCorrLagStats[2] = 0;
    1176        3581 :         hStereoTCA->indx_ica_NCShift = 0;
    1177             : 
    1178        3581 :         currentNCShift = 0;     /* only to avoid compilation warning */
    1179        3581 :         target = ptrChanL;      /* only to avoid compilation warning */
    1180        3581 :         target_idx = L_CH_INDX; /* only to avoid compilation warning */
    1181             : 
    1182        3581 :         mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1183        3581 :         v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
    1184             : 
    1185             :         /* Estimate and quantize the gain for scaling */
    1186        3581 :         estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
    1187             :     }
    1188             : 
    1189             :     /*-----------------------------------------------------------------*
    1190             :      * updates and memory backups
    1191             :      *-----------------------------------------------------------------*/
    1192             : 
    1193             :     /* back up the L/R missing target */
    1194        3791 :     mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
    1195        3791 :     mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
    1196             : 
    1197        3791 :     if ( currentNCShift != 0 )
    1198             :     {
    1199             :         /* Temporal channel adjustment of the LA samples based on the NC shift */
    1200          49 :         tcaTargetCh_LA( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, input_frame );
    1201             :     }
    1202             : 
    1203             :     /* Update of changed samples corresponding to the memory */
    1204        3791 :     icaMemUpdate( sts, hCPE, input_mem_loc[0], input_mem_loc[1], lMemRecalc, lMemRecalc_SCh, input_frame );
    1205             : 
    1206             :     /* populate the st->input target buffer */
    1207        3791 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
    1208             :     {
    1209         210 :         mvr2r( target + currentNCShift, sts[target_idx]->input, input_frame );
    1210             :     }
    1211             : 
    1212        3791 :     if ( hCPE->element_mode != IVAS_CPE_DFT )
    1213             :     {
    1214             :         /* Scale the Right channel with the gain */
    1215             :         int16_t j;
    1216        3791 :         int16_t l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS );
    1217        3791 :         float winSlope = 1.0f / (float) l_ica_ovl;
    1218             : 
    1219        3791 :         tempF1 = hStereoTCA->targetGain;
    1220        3791 :         tempF = hStereoTCA->prevTargetGain;
    1221             : 
    1222      632991 :         for ( i = 0, j = 0; i < l_ica_ovl; i++, j++ )
    1223             :         {
    1224      629200 :             sts[1]->input[i] = ( 1.0f - j * winSlope ) * tempF * sts[1]->input[i] + ( j * winSlope ) * tempF1 * sts[1]->input[i];
    1225             :         }
    1226     1891391 :         for ( ; i < input_frame; i++ )
    1227             :         {
    1228     1887600 :             sts[1]->input[i] *= tempF1;
    1229             :         }
    1230             :     }
    1231             : 
    1232             :     /* update L/R DS memories */
    1233        3791 :     mvr2r( bufChanL_DS + L_FRAME_DS, hStereoTCA->memChanL_DS, ADDED_MEM_DS );
    1234        3791 :     mvr2r( bufChanR_DS + L_FRAME_DS, hStereoTCA->memChanR_DS, ADDED_MEM_DS );
    1235             : 
    1236             :     /* save the reference channel index for next frame */
    1237        3791 :     hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
    1238             : 
    1239             :     /* save the corr lag stats for next frame */
    1240        3791 :     mvs2s( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 );
    1241             : 
    1242             :     /* save the target gain for next frame */
    1243        3791 :     hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
    1244             : 
    1245        3791 :     return;
    1246             : }
    1247             : 
    1248             : /*-------------------------------------------------------------------*
    1249             :  * stereo_tca_init_enc()
    1250             :  *
    1251             :  * Stereo temporal inter-channel adjustment (ICA) encoder initialization
    1252             :  *-------------------------------------------------------------------*/
    1253             : 
    1254         890 : void stereo_tca_init_enc(
    1255             :     STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle           */
    1256             :     const int32_t input_Fs            /* i  : input sampling frequency    */
    1257             : )
    1258             : {
    1259         890 :     hStereoTCA->lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
    1260         890 :     hStereoTCA->lMemRecalc_12k8 = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_12k8 ) / input_Fs );
    1261         890 :     hStereoTCA->lMemRecalc_16k = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_16k ) / input_Fs );
    1262             : 
    1263         890 :     hStereoTCA->refChanIndx = L_CH_INDX;
    1264         890 :     hStereoTCA->prevRefChanIndx = L_CH_INDX;
    1265             : 
    1266         890 :     hStereoTCA->targetGain = 1.0f;
    1267         890 :     hStereoTCA->prevTargetGain = 1.0f;
    1268         890 :     hStereoTCA->instTargetGain = 1.0f;
    1269         890 :     hStereoTCA->corrStatsSmoothFac = 0.7f;
    1270             : 
    1271         890 :     set_s( hStereoTCA->corrLagStats, 0, 3 );
    1272         890 :     set_s( hStereoTCA->prevCorrLagStats, 0, 3 );
    1273             : 
    1274         890 :     set_f( hStereoTCA->memChanL, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
    1275         890 :     set_f( hStereoTCA->memChanR, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
    1276         890 :     set_f( hStereoTCA->memChanL_DS, 0.0f, ADDED_MEM_DS );
    1277         890 :     set_f( hStereoTCA->memChanR_DS, 0.0f, ADDED_MEM_DS );
    1278         890 :     hStereoTCA->mem_tempF = 0.;
    1279         890 :     set_f( hStereoTCA->corrEstPrev[0], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1280         890 :     set_f( hStereoTCA->corrEstPrev[1], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1281         890 :     set_f( hStereoTCA->corrEstPrev[2], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1282             : 
    1283         890 :     set_f( hStereoTCA->corrEstLT, 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1284         890 :     set_f( hStereoTCA->memdecim, 0.0f, 12 );
    1285         890 :     hStereoTCA->ica_envVarLT = 2000.0f;
    1286             : 
    1287         890 :     set_f( hStereoTCA->C_mem, 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1288         890 :     hStereoTCA->E1_mem = 0.0f;
    1289         890 :     hStereoTCA->E2_mem = 0.0f;
    1290         890 :     set_f( hStereoTCA->delay_0_mem, 0.0f, MAX_DELAYREGLEN );
    1291         890 :     hStereoTCA->smooth_dist_reg_prv_corr = 1.0f;
    1292         890 :     hStereoTCA->LRTD_G_ATT_cnt = 1;
    1293             : 
    1294         890 :     return;
    1295             : }
    1296             : 
    1297             : 
    1298             : /*-------------------------------------------------------------------*
    1299             :  * Function unclr_calc_corr_features()
    1300             :  *
    1301             :  *-------------------------------------------------------------------*/
    1302             : 
    1303        3791 : static void unclr_calc_corr_features(
    1304             :     STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle                             */
    1305             :     STEREO_TCA_ENC_HANDLE hStereoTCA,     /* i/o: ICA Stereo Encoder handle                            */
    1306             :     const float buf1[],                   /* i  : left channel                                         */
    1307             :     const float buf2[],                   /* i  : right channel                                        */
    1308             :     const int16_t length,                 /* i  : length of input signal buffers                       */
    1309             :     const float corrEst[],                /* i  : buffer containing inter-channel correlation values   */
    1310             :     const int16_t lagSearchRange[],       /* i  : minimum and maximum lags for corrEst[]               */
    1311             :     float *corrEst_ncorr                  /* o  : norm. x-correlation btw. current and previous correlation buffers */
    1312             : )
    1313             : {
    1314             :     int16_t i, corrLagMax, d_corrLagMax, tempLen;
    1315             :     float num, den;
    1316             :     float corrL, corrR, ener, ener_side, mono_i, side_i, ic_Lm, ic_Rm, tdm_es_em, m_corrL_corrR, d_corrL_corrR;
    1317             :     float prod_i, sum_prod, corrEstMax;
    1318             : 
    1319        3791 :     corrL = 1.0f;
    1320        3791 :     corrR = 1.0f;
    1321        3791 :     ener = 1.0f;
    1322        3791 :     ener_side = 1.0f;
    1323        3791 :     sum_prod = 0.0f;
    1324             : 
    1325      610351 :     for ( i = 0; i < length; i++ )
    1326             :     {
    1327      606560 :         mono_i = ( buf1[i] + buf2[i] ) / 2.0f;
    1328      606560 :         corrL += buf1[i] * mono_i;
    1329      606560 :         corrR += buf2[i] * mono_i;
    1330      606560 :         ener += mono_i * mono_i;
    1331      606560 :         side_i = ( buf1[i] - buf2[i] ) / 2.0f;
    1332      606560 :         ener_side += side_i * side_i;
    1333      606560 :         prod_i = buf1[i] * buf2[i];
    1334      606560 :         sum_prod += prod_i;
    1335             :     }
    1336             : 
    1337             :     /* average energy of L and R channels */
    1338        3791 :     hStereoClassif->ave_ener_L = hStereoTCA->E1_mem / length;
    1339        3791 :     hStereoClassif->ave_ener_R = hStereoTCA->E2_mem / length;
    1340             : 
    1341             :     /* unnormalized L/R correlation */
    1342        3791 :     sum_prod = log10f( fabsf( sum_prod ) + 1.0f );
    1343        3791 :     hStereoClassif->unclr_fv[E_sum_prod] = sum_prod;
    1344        3791 :     hStereoClassif->xtalk_fv[E_sum_prod] = sum_prod;
    1345             : 
    1346             :     /* S/M energy ratio */
    1347        3791 :     tdm_es_em = fabsf( 10.0f * ( log10f( sqrtf( ener_side / L_FRAME_DS ) ) - log10f( sqrtf( ener / L_FRAME_DS ) ) ) );
    1348        3791 :     hStereoClassif->unclr_fv[E_tdm_es_em] = tdm_es_em;
    1349        3791 :     hStereoClassif->xtalk_fv[E_tdm_es_em] = tdm_es_em;
    1350             : 
    1351             :     /* L/R correlation values (zero lag, maximum) */
    1352        3791 :     corrLagMax = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &corrEstMax );
    1353        3791 :     d_corrLagMax = corrLagMax - hStereoClassif->unclr_corrLagMax_prev;
    1354        3791 :     hStereoClassif->unclr_fv[E_d_corrLagMax] = (float) d_corrLagMax;
    1355        3791 :     hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
    1356        3791 :     hStereoClassif->xtalk_fv[E_d_corrLagMax] = (float) d_corrLagMax;
    1357             : 
    1358        3791 :     if ( corrEstMax < 0 )
    1359             :     {
    1360           0 :         corrEstMax = 0;
    1361             :     }
    1362             : 
    1363        3791 :     hStereoClassif->unclr_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
    1364        3791 :     hStereoClassif->unclr_fv[E_corrEstMax] = corrEstMax;
    1365        3791 :     hStereoClassif->unclr_fv[E_corrLagMax] = corrLagMax;
    1366        3791 :     hStereoClassif->xtalk_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
    1367        3791 :     hStereoClassif->xtalk_fv[E_corrEstMax] = corrEstMax;
    1368        3791 :     hStereoClassif->xtalk_fv[E_corrLagMax] = corrLagMax;
    1369             : 
    1370             :     /* L/M and R/M correlation */
    1371        3791 :     if ( corrL < 0 )
    1372             :     {
    1373          97 :         corrL = 0;
    1374             :     }
    1375             : 
    1376        3791 :     if ( corrR < 0 )
    1377             :     {
    1378          57 :         corrR = 0;
    1379             :     }
    1380             : 
    1381        3791 :     ic_Lm = corrL / ener;
    1382        3791 :     ic_Rm = corrR / ener;
    1383        3791 :     m_corrL_corrR = max( fabsf( ic_Lm ), fabsf( ic_Rm ) ) - min( fabsf( ic_Lm ), fabsf( ic_Rm ) );
    1384        3791 :     d_corrL_corrR = log10f( fabsf( corrL - corrR ) + 1.0f );
    1385             : 
    1386        3791 :     hStereoClassif->unclr_fv[E_m_corrL_corrR] = m_corrL_corrR;
    1387        3791 :     hStereoClassif->unclr_fv[E_d_corrL_corrR] = d_corrL_corrR;
    1388        3791 :     hStereoClassif->xtalk_fv[E_m_corrL_corrR] = m_corrL_corrR;
    1389             : 
    1390             :     /* norm. x-correlation btw. current and previous correlation buffers */
    1391        3791 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
    1392        3791 :     num = dotp( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
    1393        3791 :     den = sqrtf( sum2_f( corrEst, tempLen ) * sum2_f( hStereoTCA->corrEstPrev[2], tempLen ) );
    1394             : 
    1395        3791 :     *corrEst_ncorr = ( den == 0 ) ? 0.0f : ( num / den );
    1396        3791 :     hStereoClassif->unclr_fv[E_corrEst_ncorr] = *corrEst_ncorr;
    1397        3791 :     hStereoClassif->xtalk_fv[E_corrEst_ncorr] = *corrEst_ncorr;
    1398             : 
    1399        3791 :     return;
    1400             : }

Generated by: LCOV version 1.14