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 @ 9ddacaa85e9af3c6e72d1664bd6065cbc5f14284 Lines: 529 546 96.9 %
Date: 2025-10-18 06:44:27 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          81 : 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          81 :     if ( hStereoTCA->refChanIndx == L_CH_INDX )
      96             :     {
      97          43 :         ref = ptrChanL;
      98          43 :         target = ptrChanR;
      99             :     }
     100             :     else
     101             :     {
     102          38 :         ref = ptrChanR;
     103          38 :         target = ptrChanL;
     104             :     }
     105             : 
     106          81 :     tempS = NS2SA( input_frame * FRAMES_PER_SEC, L_SAMPLES_LA_NS );
     107          81 :     tempF1 = 0.0f;
     108          81 :     tempF2 = 0.0f;
     109       53761 :     for ( i = 0; i < ( input_frame - currentNCShift ); i++ )
     110             :     {
     111       53680 :         tempF1 += fabsf( ref[i] );
     112       53680 :         tempF2 += fabsf( target[i + currentNCShift] );
     113             :     }
     114          81 :     gAdj = ( tempF1 == 0 ) ? 1.0f : tempF2 / max( tempF1, 0.00001f );
     115             : 
     116          81 :     tempF1 = EVS_PI / ( 2.0f * (float) tempS );
     117        1851 :     for ( i = 0; i < tempS; i++ )
     118             :     {
     119        1770 :         win[i] = sinf( tempF1 * ( 0.5f + (float) i ) );
     120             :     }
     121             : 
     122          81 :     j = 0;
     123        1851 :     for ( i = ( input_frame - currentNCShift - tempS ); i < input_frame - currentNCShift; i++, j++ )
     124             :     {
     125        1770 :         target[i + currentNCShift] = ( win[j] * gAdj ) * ref[i] + ( 1.0f - win[j] ) * target[i + currentNCShift];
     126             :     }
     127        3041 :     for ( ; i < input_frame; i++, j++ )
     128             :     {
     129        2960 :         target[i + currentNCShift] = gAdj * ref[i];
     130             :     }
     131             : 
     132          81 :     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        8352 : 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        8352 :     y1 = mem[0];
     153        8352 :     y2 = mem[1];
     154        8352 :     x0 = mem[2];
     155        8352 :     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        8352 :     if ( coeff_set == 0 )
     164             :     {
     165        8236 :         a1 = 0.747789178258504f;
     166        8236 :         a2 = -0.272214937925007f;
     167        8236 :         b0 = 0.505001029045878f;
     168        8236 :         b1 = -1.01000205809176f;
     169        8236 :         b2 = 0.505001029045878f;
     170             :     }
     171             :     else
     172             :     {
     173         116 :         a1 = -0.13456126833218354f;
     174         116 :         a2 = -0.38813694706072926f;
     175         116 :         b0 = 1.0f;
     176         116 :         b1 = -1.9980666374183167f;
     177         116 :         b2 = 1.0f;
     178             :     }
     179             : 
     180     1412512 :     for ( i = 0; i < lg; i++ )
     181             :     {
     182     1404160 :         x2 = x1;
     183     1404160 :         x1 = x0;
     184     1404160 :         x0 = signal[i];
     185     1404160 :         y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b0 ) + ( x1 * b1 ) + ( x2 * b2 );
     186     1404160 :         signal[i] = y0;
     187     1404160 :         y2 = y1;
     188     1404160 :         y1 = y0;
     189             :     }
     190             : 
     191        8352 :     mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0;
     192        8352 :     mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0;
     193        8352 :     mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0;
     194        8352 :     mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0;
     195             : 
     196        8352 :     return;
     197             : }
     198             : 
     199             : 
     200             : /*---------------------------------------------------------------
     201             :  * deEmphResample()
     202             :  *
     203             :  * De-emphasize and resample the L and R channels.
     204             :  * ---------------------------------------------------------------*/
     205             : 
     206        4118 : 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        4118 :     dsFac1 = ( dsFactor >> 1 );
     222        4118 :     dsFac2 = dsFactor / dsFac1;
     223             : 
     224             :     /* convert stereo data to two distinct channels, e.g., L, R */
     225        4118 :     mvr2r( tempChan1, buf1, input_frame );
     226        4118 :     mvr2r( tempChan2, buf2, input_frame );
     227             : 
     228             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
     229        4118 :     deemph( buf1, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[0] );
     230        4118 :     deemph( buf2, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[1] );
     231             : 
     232     1321878 :     for ( i = 0; i < ( input_frame / dsFac1 ); i++ )
     233             :     {
     234     1317760 :         tempBuf1[i] = buf1[i * dsFac1];
     235     1317760 :         tempBuf2[i] = buf2[i * dsFac1];
     236             :     }
     237             : 
     238             :     /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
     239        4118 :     deemph( tempBuf1, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[2] );
     240        4118 :     deemph( tempBuf2, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[3] );
     241             : 
     242      662998 :     for ( i = 0; i < ( input_frame / dsFactor ); i++ )
     243             :     {
     244      658880 :         chan1[i] = tempBuf1[i * dsFac2];
     245      658880 :         chan2[i] = tempBuf2[i * dsFac2];
     246             :     }
     247             : 
     248        4118 :     spectral_balancer( chan1, &hStereoTCA->memdecim[4], input_frame / dsFactor, 0 ); /*4 mem */
     249        4118 :     spectral_balancer( chan2, &hStereoTCA->memdecim[8], input_frame / dsFactor, 0 ); /*4 mem */
     250             : 
     251        4118 :     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        4118 : 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        4118 :     E1 = sum2_f( buf1, len );
     274        4118 :     E2 = sum2_f( buf2, len );
     275             : 
     276        4118 :     Inv_Tot_E = 1.0f / ( ( 2.0f * (float) len ) * sqrtf( ( E1 + hStereoTCA->E1_mem ) * ( E2 + hStereoTCA->E2_mem ) + 0.000000001f ) );
     277             : 
     278        4118 :     hStereoTCA->E1_mem = E1;
     279        4118 :     hStereoTCA->E2_mem = E2;
     280             : 
     281      172956 :     for ( i = lagSearchRange[0], j = 0; i <= 0; i++, j++ )
     282             :     {
     283      168838 :         C = dotp( buf1, buf2 + i, len );
     284      168838 :         corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
     285      168838 :         hStereoTCA->C_mem[j] = C;
     286             :     }
     287             : 
     288      168838 :     for ( ; i <= lagSearchRange[1]; i++, j++ )
     289             :     {
     290      164720 :         C = dotp( buf1 - i, buf2, len );
     291      164720 :         corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
     292      164720 :         hStereoTCA->C_mem[j] = C;
     293             :     }
     294             : 
     295        4118 :     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         196 : 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         196 :     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         196 :         mvr2r( buf1, tempBuf1, len );
     343         196 :         mvr2r( buf2, tempBuf2, len );
     344             :     }
     345             : 
     346         196 :     temp = sum2_f( tempBuf1, len );
     347         196 :     temp *= sum2_f( tempBuf2, len );
     348         196 :     scale = ( temp == 0 ) ? 1.0f : inv_sqrt( temp );
     349             : 
     350             :     /* starting point of lag search range should be less than the ending point */
     351         196 :     assert( lagSearchRange[0] <= lagSearchRange[1] );
     352             : 
     353             :     /* first part of noncausal corr est. */
     354         378 :     for ( i = lagSearchRange[0], j = 0; i <= min( 0, lagSearchRange[1] ); i++, j++ )
     355             :     {
     356         182 :         temp = dotp( tempBuf1 - i, tempBuf2, ( len + i ) );
     357         182 :         corrEst[j] = temp / ( len + i );
     358             :     }
     359             : 
     360             :     /* second part of noncausal corr est. */
     361         475 :     for ( ; i <= lagSearchRange[1]; i++, j++ )
     362             :     {
     363         279 :         temp = dotp( tempBuf1, tempBuf2 + i, ( len - i ) );
     364         279 :         corrEst[j] = temp / ( len - i );
     365             :     }
     366         196 :     v_multc( corrEst, scale, corrEst, j );
     367             : 
     368         196 :     return;
     369             : }
     370             : 
     371             : /*---------------------------------------------------------------
     372             :  *  corrStatsEst()
     373             :  *
     374             :  *  Non-causal shift estimation to encode future samples.
     375             :  * ---------------------------------------------------------------*/
     376             : 
     377        4118 : 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        4118 :     X_hat = 0;
     408        4118 :     X_SQR_hat = 0;
     409        4118 :     XY_hat = 0;
     410             : 
     411             :     /* Initializations */
     412        4118 :     alpha = 0.7f;
     413        4118 :     lagSearchRange[0] = -L_NCSHIFT_DS;
     414        4118 :     lagSearchRange[1] = L_NCSHIFT_DS;
     415        4118 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
     416             : 
     417        4118 :     set_s( corrLagStats, 0, 3 );
     418             : 
     419             :     /* First iteration of xcorr estimation */
     420        4118 :     utilCrossCorr_mod( hStereoTCA, buf1, buf2, corrEst, lagSearchRange, bufLenDS - L_XCORRMEM_DS );
     421             : 
     422             :     /* calculate features for the UNCLR classifier */
     423        4118 :     unclr_calc_corr_features( hStereoClassif, hStereoTCA, buf1, buf2, bufLenDS - L_XCORRMEM_DS, corrEst, lagSearchRange, &corrEst_ncorr );
     424             : 
     425       12354 :     for ( i = 1; i < 3; i++ )
     426             :     {
     427        8236 :         v_add( hStereoTCA->corrEstPrev[i], hStereoTCA->corrEstPrev[0], hStereoTCA->corrEstPrev[0], tempLen );
     428             :     }
     429             : 
     430             :     /* back up the corrEst */
     431       12354 :     for ( i = 0; i < 2; i++ )
     432             :     {
     433        8236 :         mvr2r( hStereoTCA->corrEstPrev[i + 1], hStereoTCA->corrEstPrev[i], tempLen );
     434             :     }
     435        4118 :     mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
     436             : 
     437        4118 :     temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
     438        4118 :     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        4118 :     tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
     440        4118 :     hStereoTCA->mem_tempF = temp_B;
     441             : 
     442        4118 :     alpha = 0.93f;
     443        4118 :     if ( tempF > 4.0f * hStereoTCA->ica_envVarLT )
     444             :     {
     445         142 :         alpha = 0.83f;
     446             :     }
     447        3976 :     else if ( tempF > 2.0f * hStereoTCA->ica_envVarLT )
     448             :     {
     449         348 :         alpha = 0.85f;
     450             :     }
     451        3628 :     else if ( tempF > hStereoTCA->ica_envVarLT )
     452             :     {
     453        1165 :         alpha = 0.90f;
     454             :     }
     455             : 
     456        4118 :     hStereoTCA->corrStatsSmoothFac = alpha;
     457             : 
     458             :     /* long term corr Stats estimation */
     459        4118 :     v_multc( hStereoTCA->corrEstLT, alpha, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
     460        4118 :     v_multc( corrEst, 1.0f - alpha, corrEst, 2 * L_NCSHIFT_DS + 1 );
     461        4118 :     v_add( hStereoTCA->corrEstLT, corrEst, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
     462             : 
     463        4118 :     hStereoTCA->ica_envVarLT = SMOOTH_ENV_FACTOR * hStereoTCA->ica_envVarLT + ( 1 - SMOOTH_ENV_FACTOR ) * tempF;
     464             : 
     465        4118 :     mvr2r( hStereoTCA->corrEstLT, corrEst, 2 * L_NCSHIFT_DS + 1 );
     466        4118 :     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       49416 :     for ( i = 1; i < MAX_DELAYREGLEN; i++ )
     469             :     {
     470       45298 :         X_hat += (float) i;
     471       45298 :         Y_hat += hStereoTCA->delay_0_mem[i];
     472       45298 :         XY_hat += i * hStereoTCA->delay_0_mem[i];
     473       45298 :         X_SQR_hat += (float) ( i * i );
     474             :     }
     475        4118 :     X_hat *= INV_MAX_DELAYREGLEN;
     476        4118 :     Y_hat *= INV_MAX_DELAYREGLEN;
     477        4118 :     XY_hat *= INV_MAX_DELAYREGLEN;
     478        4118 :     X_SQR_hat *= INV_MAX_DELAYREGLEN;
     479             : 
     480        4118 :     beta_reg = 0;
     481        4118 :     tempF = X_SQR_hat - ( X_hat * X_hat );
     482        4118 :     if ( tempF != 0 )
     483             :     {
     484        4118 :         beta_reg = ( XY_hat - X_hat * Y_hat ) / tempF;
     485             :     }
     486        4118 :     alpha_reg = ( Y_hat - beta_reg * X_hat );
     487        4118 :     reg_prv_corr = beta_reg * MAX_DELAYREGLEN + alpha_reg;
     488             : 
     489        4118 :     if ( TRUNC( reg_prv_corr ) <= -L_NCSHIFT_DS )
     490             :     {
     491           0 :         reg_prv_corr = -L_NCSHIFT_DS + 1;
     492             :     }
     493             : 
     494        4118 :     if ( TRUNC( reg_prv_corr ) >= L_NCSHIFT_DS )
     495             :     {
     496           0 :         reg_prv_corr = L_NCSHIFT_DS - 1;
     497             :     }
     498             : 
     499        4118 :     bias_par = A_BIAS * hStereoTCA->smooth_dist_reg_prv_corr + B_BIAS;
     500        4118 :     bias_par = min( bias_par, XH_BIAS );
     501        4118 :     bias_par = max( bias_par, XL_BIAS );
     502             : 
     503        4118 :     width_par = A_WIDTH * hStereoTCA->smooth_dist_reg_prv_corr + B_WIDTH;
     504        4118 :     width_par = min( width_par, XH_WIDTH );
     505        4118 :     width_par = max( width_par, XL_WIDTH );
     506             : 
     507        4118 :     win_width = (int16_t) ( width_par * ( 4 * L_NCSHIFT_DS + 1 ) );
     508        4118 :     win_bias = bias_par;
     509        4118 :     k1 = 0.5f * ( 1.0f + win_bias );
     510        4118 :     k2 = 0.5f * ( 1.0f - win_bias );
     511             : 
     512      172890 :     for ( i = 0; i < ( 2 * L_NCSHIFT_DS - 2 * win_width ); i++ )
     513             :     {
     514      168772 :         loc_weight_win[i] = win_bias;
     515             :     }
     516             : 
     517      329572 :     for ( i = ( 2 * L_NCSHIFT_DS - 2 * win_width ); i <= ( 2 * L_NCSHIFT_DS + 2 * win_width ); i++ )
     518             :     {
     519      325454 :         loc_weight_win[i] = k1 + k2 * cosf( EVS_PI * ( ( i - 2 * L_NCSHIFT_DS ) / ( 2.0f * win_width ) ) );
     520             :     }
     521             : 
     522      177008 :     for ( i = ( 2 * L_NCSHIFT_DS + 2 * win_width ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
     523             :     {
     524      172890 :         loc_weight_win[i] = win_bias;
     525             :     }
     526             : 
     527      337676 :     for ( i = 0, j = L_NCSHIFT_DS - TRUNC( reg_prv_corr ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
     528             :     {
     529      333558 :         corrEst[i] *= loc_weight_win[j];
     530             :     }
     531             : 
     532        4118 :     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        4118 :     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        4118 :     if ( corrEst_ncorr > 0.8f && vad_flag1 )
     546             :     {
     547        1639 :         i = max( 0, hStereoTCA->prevCorrLagStats[0] - 1 + L_NCSHIFT_DS );
     548        1639 :         j = min( 2 * L_NCSHIFT_DS, hStereoTCA->prevCorrLagStats[0] + 1 + L_NCSHIFT_DS );
     549        1639 :         k = j - i + 1;
     550        1639 :         v_multc( corrEst + i, 1.2f, corrEst + i, k );
     551             :     }
     552             : 
     553             :     /* Initial corr lag estimate */
     554        4118 :     corrLagStats[0] = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &tempF );
     555        4118 :     corrLagStats[0] += lagSearchRange[0];
     556             : 
     557        4118 :     stmp = corrLagStats[0] * dsFactor;
     558        4118 :     hStereoClassif->unclr_fv[E_corrLagStats0] = (float) stmp;
     559        4118 :     hStereoClassif->xtalk_fv[E_corrLagStats0] = (float) stmp;
     560        4118 :     hStereoClassif->xtalk_fv[E_ica_corr_value0] = tempF;
     561             : 
     562        4118 :     if ( vad_flag1 == 0 && alpha > 0.7f )
     563             :     {
     564          33 :         corrLagStats[0] = 0;
     565             :     }
     566             : 
     567        4118 :     dist_reg_prv_corr = fabsf( reg_prv_corr - corrLagStats[0] );
     568             : 
     569        4118 :     if ( vad_flag1 == 1 && vad_flag2 == 1 )
     570             :     {
     571        4037 :         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        4037 :         mvr2r( &( hStereoTCA->delay_0_mem[1] ), &( hStereoTCA->delay_0_mem[0] ), MAX_DELAYREGLEN - 1 );
     574             : 
     575        4037 :         hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] = 0.2f * hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] + 0.8f * corrLagStats[0];
     576             : 
     577        4037 :         if ( fabsf( reg_prv_corr - hStereoTCA->delay_0_mem[0] ) > 25 )
     578             :         {
     579          90 :             set_f( &( hStereoTCA->delay_0_mem[0] ), hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
     580             :         }
     581             :     }
     582             :     else
     583             :     {
     584          81 :         hStereoTCA->smooth_dist_reg_prv_corr = 0.;
     585             :     }
     586             : 
     587        4118 :     if ( vad_flag1 == 0 || vad_flag2 == 0 )
     588             :     {
     589          81 :         corrLagStats[0] = TRUNC( hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] );
     590             :     }
     591             : 
     592             :     /* second iteration of xcorr update @ inputFs with interp*/
     593        4118 :     tempRK = hStereoTCA->corrEstLT - lagSearchRange[0] + corrLagStats[0];
     594        4118 :     set_f( rInterp, 0, MAX_INTERPOLATE );
     595             : 
     596             :     /* select the Rk interp sinc window */
     597        4118 :     winInterp = ica_sincInterp4 + SINC_ORDER1;
     598        4118 :     if ( dsFactor == 2 )
     599             :     {
     600         777 :         winInterp = ica_sincInterp2 + SINC_ORDER1;
     601             :     }
     602        3341 :     else if ( dsFactor == 6 )
     603             :     {
     604        1284 :         winInterp = ica_sincInterp6 + SINC_ORDER1;
     605             :     }
     606             : 
     607        4118 :     corrLagStats[1] = corrLagStats[0] * dsFactor;
     608             : 
     609        4118 :     interpMin = max( -( dsFactor - 1 ), -corrLagStats[1] - L_NCSHIFT_DS * dsFactor );
     610        4118 :     interpMax = min( ( dsFactor - 1 ), L_NCSHIFT_DS * dsFactor - corrLagStats[1] );
     611        4118 :     interpLen = interpMax - interpMin + 1;
     612             : 
     613       34972 :     for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
     614             :     {
     615       30854 :         rInterp[k] = 0.0f;
     616      403432 :         for ( j = -SINC_ORDER1 / dsFactor; j <= SINC_ORDER1 / dsFactor; j++ )
     617             :         {
     618      372578 :             m = j * dsFactor;
     619      372578 :             if ( ( m - i >= -SINC_ORDER1 ) && ( m - i <= SINC_ORDER1 ) )
     620             :             {
     621      345842 :                 if ( j > lagSearchRange[1] - corrLagStats[0] )
     622             :                 {
     623          59 :                     rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[1] - corrLagStats[0]];
     624             :                 }
     625      345783 :                 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      345607 :                     rInterp[k] += winInterp[m - i] * tempRK[j];
     632             :                 }
     633             :             }
     634             :         }
     635             :     }
     636        4118 :     corrLagStats[1] += ( maximum( rInterp, interpLen, &tempF ) + interpMin );
     637             : 
     638             :     /* save corr lag stats for the current frame */
     639        4118 :     mvs2s( corrLagStats, hStereoTCA->corrLagStats, 3 );
     640             : 
     641        4118 :     return;
     642             : }
     643             : 
     644             : 
     645             : /*---------------------------------------------------------------
     646             :  *  Function estDownmixGain()
     647             :  *
     648             :  *  Down mix gain estimation module; convert L/R to M/S.
     649             :  * ---------------------------------------------------------------*/
     650             : 
     651      113680 : 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      113680 :     if ( hStereoTCA->refChanIndx == L_CH_INDX )
     668             :     {
     669      113642 :         i1 = 0;
     670      113642 :         i2 = ncShift;
     671             :     }
     672             :     else
     673             :     {
     674          38 :         i1 = ncShift;
     675          38 :         i2 = 0;
     676             :     }
     677             : 
     678             :     /* abs sample sum estimation */
     679      113680 :     tempN = 0;
     680      113680 :     tempD = 0;
     681    88750720 :     for ( i = 0, tempN = 0.0f, tempD = 0.0f; i < length; i++ )
     682             :     {
     683    88637040 :         tempN += fabsf( chan1[i1 + i] );
     684    88637040 :         tempD += fabsf( chan2[i2 + i] );
     685             :     }
     686             : 
     687      113680 :     alpha = hStereoTCA->corrStatsSmoothFac;
     688      113680 :     currentGain = ( tempD == 0 ) ? ( hStereoTCA->prevTargetGain ) : ( tempN / tempD );
     689      113680 :     currentGain = max( 1e-5f, currentGain );
     690      113680 :     hStereoTCA->instTargetGain = currentGain;
     691      113680 :     currentGain = (alpha) *log10f( hStereoTCA->prevTargetGain ) + ( 1.0f - alpha ) * log10f( currentGain );
     692             : 
     693      113680 :     if ( element_mode == IVAS_CPE_TD && hStereoClassif != NULL )
     694             :     {
     695        4118 :         tempD = powf( 10, currentGain );
     696        4118 :         unclr_instTargetGain = log10f( tempN / ( tempD + 1e-5f ) + 1.0f );
     697        4118 :         hStereoClassif->unclr_fv[E_ica_instTargetGain] = unclr_instTargetGain;
     698             :     }
     699             : 
     700      113680 :     if ( tdm_LRTD_flag == 1 )
     701             :     {
     702        3955 :         currentGain = 0.0f;
     703             :     }
     704      109725 :     else if ( hStereoTCA->LRTD_G_ATT_cnt > 1 ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
     705             :     {
     706         258 :         currentGain /= ( (float) hStereoTCA->LRTD_G_ATT_cnt );
     707             :     }
     708             : 
     709             :     /* quantize the target gain */
     710      113680 :     hStereoTCA->indx_ica_gD = (int16_t) usquant( currentGain, &tempD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP, 1 << STEREO_BITS_TCA_GD );
     711      113680 :     hStereoTCA->targetGain = powf( 10, tempD );
     712             : 
     713      113680 :     return;
     714             : }
     715             : 
     716             : /*---------------------------------------------------------------
     717             :  *  Function icaMemUpdate()
     718             :  *
     719             :  *  Recalculates the memories corresponding to the previous frame.
     720             :  * ---------------------------------------------------------------*/
     721             : 
     722        4118 : 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        4118 :     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        4118 :         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        4106 :             ratio_L = hCPE->hStereoTD->tdm_last_ratio;
     751        4106 :             One_m_Ratio = 1.0f - ratio_L;
     752             :         }
     753             : 
     754        4118 :         ptr1 = sts[0]->input - lMemRecalc - lMemRecalc_SCh;
     755        4118 :         ptr2 = sts[1]->input - lMemRecalc - lMemRecalc_SCh;
     756             : 
     757        4118 :         if ( hCPE->last_element_mode == IVAS_CPE_TD )
     758             :         {
     759        4049 :             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     1003797 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     770             :                 {
     771      999840 :                     ptr1[i] = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
     772      999840 :                     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          69 :             set_f( sts[1]->input - input_frame, 0, input_frame );
     782             : 
     783          69 :             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        4646 :                 for ( i = 0; i < lMemRecalc_SCh; i++ )
     811             :                 {
     812        4585 :                     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          61 :                 fac = 1.0f / (float) lMemRecalc;
     817          61 :                 incr = fac;
     818             : 
     819       15781 :                 for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
     820             :                 {
     821       15720 :                     tmp1 = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
     822       15720 :                     tmp2 = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
     823             : 
     824       15720 :                     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       15720 :                     ptr2[i] = tmp2;
     827             : 
     828       15720 :                     fac += incr;
     829             :                 }
     830             :             }
     831             :         }
     832             :     }
     833             : 
     834        4118 :     if ( hCPE->hStereoICBWE != NULL )
     835             :     {
     836             :         assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
     837         163 :         i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
     838         163 :         mvr2r( bufChanL + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[0], i );
     839         163 :         mvr2r( bufChanR + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[1], i );
     840             :     }
     841             : 
     842        4118 :     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     1188495 : 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     1188495 :     int16_t musicMode = 0, neighborLimit;
     885             :     int32_t input_Fs;
     886             :     int16_t prev_ICA_flag;
     887             : 
     888             :     /* initialization */
     889     1188495 :     sts = hCPE->hCoreCoder;
     890     1188495 :     hStereoTCA = hCPE->hStereoTCA;
     891             : 
     892     1188495 :     input_Fs = sts[0]->input_Fs;
     893             : 
     894     1188495 :     lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
     895     1188495 :     lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS );
     896             : 
     897     1188495 :     if ( hCPE->element_mode == IVAS_CPE_MDCT )
     898             :     {
     899     1074815 :         return;
     900             :     }
     901             : 
     902             :     /* populate L/R memories into current buffers */
     903      113680 :     mvr2r( hStereoTCA->memChanL, bufChanL, lMemRecalc + lMemRecalc_SCh );
     904      113680 :     mvr2r( hStereoTCA->memChanR, bufChanR, lMemRecalc + lMemRecalc_SCh );
     905             : 
     906             :     /* pointers to the current frame */
     907      113680 :     ptrChanL = bufChanL + lMemRecalc + lMemRecalc_SCh;
     908      113680 :     ptrChanR = bufChanR + lMemRecalc + lMemRecalc_SCh;
     909             : 
     910             :     /* copy interleaved stereo data to two channels, e.g., L, R */
     911      113680 :     mvr2r( sts[0]->input, ptrChanL, input_frame );
     912      113680 :     mvr2r( sts[1]->input, ptrChanR, input_frame );
     913             : 
     914             :     /* UNCLR classifier update */
     915      113680 :     if ( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
     916             :     {
     917      109331 :         hStereoTCA->LRTD_G_ATT_cnt = 1;
     918             :     }
     919        4349 :     else if ( hCPE->hStereoTD != NULL )
     920             :     {
     921        4118 :         if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
     922             :         {
     923         163 :             hStereoTCA->LRTD_G_ATT_cnt++;
     924         163 :             hStereoTCA->LRTD_G_ATT_cnt = min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
     925             :         }
     926             :     }
     927             : 
     928      113680 :     if ( hCPE->element_mode != IVAS_CPE_TD )
     929             :     {
     930      109562 :         hStereoTCA->refChanIndx = L_CH_INDX;
     931      109562 :         hStereoTCA->corrStatsSmoothFac = 0.7f;
     932      109562 :         estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 );
     933      109562 :         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      109562 :         mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
     940      109562 :         mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
     941             : 
     942      109562 :         hStereoTCA->lMemRecalc = 0;
     943      109562 :         hStereoTCA->lMemRecalc_12k8 = 0;
     944      109562 :         hStereoTCA->lMemRecalc_16k = 0;
     945             : 
     946      109562 :         return;
     947             :     }
     948        4118 :     else if ( hCPE->last_element_mode != IVAS_CPE_TD )
     949             :     {
     950          69 :         tempF = hStereoTCA->targetGain;
     951          69 :         tempF1 = hStereoTCA->prevTargetGain;
     952          69 :         tempS = hStereoTCA->prevRefChanIndx;
     953          69 :         mvs2s( hStereoTCA->prevCorrLagStats, tempS_buff, 3 );
     954          69 :         stereo_tca_init_enc( hStereoTCA, input_Fs );
     955          69 :         hStereoTCA->targetGain = tempF;
     956          69 :         hStereoTCA->prevTargetGain = tempF1;
     957             : 
     958          69 :         if ( hCPE->hStereoClassif->lrtd_mode == 1 )
     959             :         {
     960          69 :             hStereoTCA->targetGain = min( hStereoTCA->targetGain, 1.0f );
     961          69 :             hStereoTCA->prevTargetGain = min( hStereoTCA->prevTargetGain, 1.0f );
     962             : 
     963          69 :             hStereoTCA->prevTargetGain = 1;
     964             :         }
     965             : 
     966          69 :         hStereoTCA->prevRefChanIndx = tempS;
     967          69 :         mvs2s( tempS_buff, hStereoTCA->prevCorrLagStats, 3 );
     968             : 
     969             :         /* populate memory */
     970          69 :         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        4118 :     mvr2r( hStereoTCA->memChanL_DS, bufChanL_DS, ADDED_MEM_DS );
     979        4118 :     mvr2r( hStereoTCA->memChanR_DS, bufChanR_DS, ADDED_MEM_DS );
     980             : 
     981             :     /* pointers to the current frame of DS */
     982        4118 :     ptrChanL_DS = bufChanL_DS + ADDED_MEM_DS;
     983        4118 :     ptrChanR_DS = bufChanR_DS + ADDED_MEM_DS;
     984             : 
     985             :     /* resample factor */
     986        4118 :     dsFactor = (int16_t) ( input_Fs / CORR_INTER_FS );
     987             : 
     988             :     /* resample the stereo channels */
     989        4118 :     deEmphResample( hStereoTCA, ptrChanL, ptrChanR, ptrChanL_DS, ptrChanR_DS, input_frame, dsFactor );
     990             : 
     991             : 
     992             :     /* inter-channel corrStats estimation */
     993        4118 :     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        4118 :     prev_ICA_flag = 0;
    1000        4118 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 )
    1001             :     {
    1002          39 :         prev_ICA_flag = 1;
    1003             :     }
    1004             : 
    1005        4118 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
    1006             :     {
    1007             :         /* initialize the refinement search for NC-shift */
    1008         263 :         hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
    1009             : 
    1010         263 :         maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
    1011         263 :         if ( hStereoTCA->corrStatsSmoothFac <= 0.7f )
    1012             :         {
    1013           0 :             maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
    1014             :         }
    1015             : 
    1016         263 :         if ( input_Fs < 32000 )
    1017             :         {
    1018          45 :             maxCorrStatsDev = (int16_t) ( maxCorrStatsDev * input_Fs / 32000.0f );
    1019             :         }
    1020             : 
    1021         263 :         musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
    1022         263 :         if ( musicMode )
    1023             :         {
    1024         118 :             maxCorrStatsDev = 1;
    1025         118 :             set_s( hStereoTCA->corrLagStats + 1, 0, 2 );
    1026             :         }
    1027             : 
    1028         263 :         tempS = ( hStereoTCA->corrLagStats[1] - hStereoTCA->prevCorrLagStats[2] );
    1029         263 :         if ( abs( tempS ) > maxCorrStatsDev )
    1030             :         {
    1031          78 :             hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? maxCorrStatsDev : -maxCorrStatsDev );
    1032             :         }
    1033             : 
    1034         263 :         neighborLimit = maxCorrStatsDev;
    1035             : 
    1036             :         /* refine and search based on the corrlag stats */
    1037         263 :         if ( tempS != 0 && dsFactor != 1 && prev_ICA_flag == 0 )
    1038             :         {
    1039         130 :             tempF = 0;
    1040         130 :             if ( !musicMode )
    1041             :             {
    1042         104 :                 tempLag[0] = min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
    1043         104 :                 tempLag[1] = max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
    1044             : 
    1045         104 :                 neighborLimit = min( 3, maxCorrStatsDev );
    1046         104 :                 if ( hStereoTCA->prevCorrLagStats[2] < hStereoTCA->corrLagStats[2] )
    1047             :                 {
    1048          74 :                     tempLag[1] = min( tempLag[1], tempLag[0] + neighborLimit );
    1049             :                 }
    1050             :                 else
    1051             :                 {
    1052          30 :                     tempLag[0] = max( tempLag[0], tempLag[1] - neighborLimit );
    1053             :                 }
    1054             : 
    1055         104 :                 utilCrossCorr( ptrChanL, ptrChanR, NULL, corrEstStage2, tempLag, input_frame, 0 );
    1056             : 
    1057         104 :                 hStereoTCA->corrLagStats[2] = maximum( corrEstStage2, ( tempLag[1] - tempLag[0] + 1 ), &tempF );
    1058         104 :                 hStereoTCA->corrLagStats[2] += tempLag[0];
    1059             :             }
    1060             : 
    1061         130 :             if ( abs( tempS ) > neighborLimit )
    1062             :             {
    1063          92 :                 tempLag[0] = hStereoTCA->corrLagStats[1];
    1064          92 :                 tempLag[1] = hStereoTCA->corrLagStats[1];
    1065          92 :                 utilCrossCorr( ptrChanL, ptrChanR, NULL, &tempF1, tempLag, input_frame, 0 );
    1066             : 
    1067          92 :                 if ( tempF1 > tempF || musicMode )
    1068             :                 {
    1069          27 :                     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         130 :             if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
    1075             :             {
    1076           3 :                 hStereoTCA->corrLagStats[2] = 0;
    1077             :             }
    1078             :         }
    1079             : 
    1080         263 :         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          39 :             hStereoTCA->corrLagStats[2] = 0;
    1083             : 
    1084          39 :             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         263 :         prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats[2] );
    1095         263 :         currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats[2] );
    1096             : 
    1097         263 :         if ( hStereoTCA->prevRefChanIndx == L_CH_INDX )
    1098             :         {
    1099         222 :             mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1100         222 :             v_multc( ptrChanR + prevNCShift - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
    1101             :         }
    1102             :         else
    1103             :         {
    1104          41 :             mvr2r( ptrChanL + prevNCShift - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1105          41 :             v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
    1106             :         }
    1107             : 
    1108         263 :         target = ptrChanR;
    1109         263 :         target_idx = R_CH_INDX;
    1110             :         /* identify target signal to correct for shift variations */
    1111         263 :         if ( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
    1112             :         {
    1113          63 :             target = ptrChanL;
    1114          63 :             target_idx = L_CH_INDX;
    1115             :         }
    1116             : 
    1117             :         /* target signal adjustment for temporal shift variations */
    1118         263 :         if ( ( prevNCShift - currentNCShift ) != 0 )
    1119             :         {
    1120         110 :             L_shift_adapt = L_SHIFT_ADAPT_16k;
    1121         110 :             if ( input_Fs > INT_FS_16k )
    1122             :             {
    1123          87 :                 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         110 :             tempS = ( currentNCShift >> 1 );
    1128         110 :             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          92 :                 adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
    1138             :             }
    1139             :             else
    1140             :             {
    1141          18 :                 tempS = min( max( tempS, prevNCShift - currentNCShift + L_shift_adapt - input_frame ), prevNCShift - currentNCShift + lMemRecalc );
    1142          18 :                 adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
    1143             :             }
    1144             : 
    1145         110 :             if ( target_idx == L_CH_INDX )
    1146             :             {
    1147          50 :                 mvr2r( target - tempS, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
    1148             :             }
    1149             :             else
    1150             :             {
    1151          60 :                 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         263 :         if ( hStereoTCA->corrLagStats[2] >= 0 )
    1157             :         {
    1158         225 :             hStereoTCA->refChanIndx = L_CH_INDX;
    1159             :         }
    1160             :         else
    1161             :         {
    1162          38 :             hStereoTCA->refChanIndx = R_CH_INDX;
    1163             :         }
    1164             : 
    1165             :         /* Estimate and quantize the gain for scaling */
    1166         263 :         estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
    1167             : 
    1168             :         /* quantize the corrStats */
    1169         263 :         hStereoTCA->indx_ica_NCShift = (int16_t) usquant( ( (float) currentNCShift ) / dsFactor, &tempF, 0, 1.0f, 1 << STEREO_BITS_TCA_CORRSTATS );
    1170             :     }
    1171             :     else
    1172             :     {
    1173        3855 :         hStereoTCA->refChanIndx = L_CH_INDX;
    1174        3855 :         hStereoTCA->corrLagStats[2] = 0;
    1175        3855 :         hStereoTCA->prevCorrLagStats[2] = 0;
    1176        3855 :         hStereoTCA->indx_ica_NCShift = 0;
    1177             : 
    1178        3855 :         currentNCShift = 0;     /* only to avoid compilation warning */
    1179        3855 :         target = ptrChanL;      /* only to avoid compilation warning */
    1180        3855 :         target_idx = L_CH_INDX; /* only to avoid compilation warning */
    1181             : 
    1182        3855 :         mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
    1183        3855 :         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        3855 :         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        4118 :     mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
    1195        4118 :     mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
    1196             : 
    1197        4118 :     if ( currentNCShift != 0 )
    1198             :     {
    1199             :         /* Temporal channel adjustment of the LA samples based on the NC shift */
    1200          81 :         tcaTargetCh_LA( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, input_frame );
    1201             :     }
    1202             : 
    1203             :     /* Update of changed samples corresponding to the memory */
    1204        4118 :     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        4118 :     if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
    1208             :     {
    1209         263 :         mvr2r( target + currentNCShift, sts[target_idx]->input, input_frame );
    1210             :     }
    1211             : 
    1212        4118 :     if ( hCPE->element_mode != IVAS_CPE_DFT )
    1213             :     {
    1214             :         /* Scale the Right channel with the gain */
    1215             :         int16_t j;
    1216        4118 :         int16_t l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS );
    1217        4118 :         float winSlope = 1.0f / (float) l_ica_ovl;
    1218             : 
    1219        4118 :         tempF1 = hStereoTCA->targetGain;
    1220        4118 :         tempF = hStereoTCA->prevTargetGain;
    1221             : 
    1222      703558 :         for ( i = 0, j = 0; i < l_ica_ovl; i++, j++ )
    1223             :         {
    1224      699440 :             sts[1]->input[i] = ( 1.0f - j * winSlope ) * tempF * sts[1]->input[i] + ( j * winSlope ) * tempF1 * sts[1]->input[i];
    1225             :         }
    1226     2102438 :         for ( ; i < input_frame; i++ )
    1227             :         {
    1228     2098320 :             sts[1]->input[i] *= tempF1;
    1229             :         }
    1230             :     }
    1231             : 
    1232             :     /* update L/R DS memories */
    1233        4118 :     mvr2r( bufChanL_DS + L_FRAME_DS, hStereoTCA->memChanL_DS, ADDED_MEM_DS );
    1234        4118 :     mvr2r( bufChanR_DS + L_FRAME_DS, hStereoTCA->memChanR_DS, ADDED_MEM_DS );
    1235             : 
    1236             :     /* save the reference channel index for next frame */
    1237        4118 :     hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
    1238             : 
    1239             :     /* save the corr lag stats for next frame */
    1240        4118 :     mvs2s( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 );
    1241             : 
    1242             :     /* save the target gain for next frame */
    1243        4118 :     hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
    1244             : 
    1245        4118 :     return;
    1246             : }
    1247             : 
    1248             : /*-------------------------------------------------------------------*
    1249             :  * stereo_tca_init_enc()
    1250             :  *
    1251             :  * Stereo temporal inter-channel adjustment (ICA) encoder initialization
    1252             :  *-------------------------------------------------------------------*/
    1253             : 
    1254        1502 : 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        1502 :     hStereoTCA->lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
    1260        1502 :     hStereoTCA->lMemRecalc_12k8 = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_12k8 ) / input_Fs );
    1261        1502 :     hStereoTCA->lMemRecalc_16k = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_16k ) / input_Fs );
    1262             : 
    1263        1502 :     hStereoTCA->refChanIndx = L_CH_INDX;
    1264        1502 :     hStereoTCA->prevRefChanIndx = L_CH_INDX;
    1265             : 
    1266        1502 :     hStereoTCA->targetGain = 1.0f;
    1267        1502 :     hStereoTCA->prevTargetGain = 1.0f;
    1268        1502 :     hStereoTCA->instTargetGain = 1.0f;
    1269        1502 :     hStereoTCA->corrStatsSmoothFac = 0.7f;
    1270             : 
    1271        1502 :     set_s( hStereoTCA->corrLagStats, 0, 3 );
    1272        1502 :     set_s( hStereoTCA->prevCorrLagStats, 0, 3 );
    1273             : 
    1274        1502 :     set_f( hStereoTCA->memChanL, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
    1275        1502 :     set_f( hStereoTCA->memChanR, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
    1276        1502 :     set_f( hStereoTCA->memChanL_DS, 0.0f, ADDED_MEM_DS );
    1277        1502 :     set_f( hStereoTCA->memChanR_DS, 0.0f, ADDED_MEM_DS );
    1278        1502 :     hStereoTCA->mem_tempF = 0.;
    1279        1502 :     set_f( hStereoTCA->corrEstPrev[0], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1280        1502 :     set_f( hStereoTCA->corrEstPrev[1], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1281        1502 :     set_f( hStereoTCA->corrEstPrev[2], 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1282             : 
    1283        1502 :     set_f( hStereoTCA->corrEstLT, 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1284        1502 :     set_f( hStereoTCA->memdecim, 0.0f, 12 );
    1285        1502 :     hStereoTCA->ica_envVarLT = 2000.0f;
    1286             : 
    1287        1502 :     set_f( hStereoTCA->C_mem, 0.0f, 2 * L_NCSHIFT_DS + 1 );
    1288        1502 :     hStereoTCA->E1_mem = 0.0f;
    1289        1502 :     hStereoTCA->E2_mem = 0.0f;
    1290        1502 :     set_f( hStereoTCA->delay_0_mem, 0.0f, MAX_DELAYREGLEN );
    1291        1502 :     hStereoTCA->smooth_dist_reg_prv_corr = 1.0f;
    1292        1502 :     hStereoTCA->LRTD_G_ATT_cnt = 1;
    1293             : 
    1294        1502 :     return;
    1295             : }
    1296             : 
    1297             : 
    1298             : /*-------------------------------------------------------------------*
    1299             :  * Function unclr_calc_corr_features()
    1300             :  *
    1301             :  *-------------------------------------------------------------------*/
    1302             : 
    1303        4118 : 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        4118 :     corrL = 1.0f;
    1320        4118 :     corrR = 1.0f;
    1321        4118 :     ener = 1.0f;
    1322        4118 :     ener_side = 1.0f;
    1323        4118 :     sum_prod = 0.0f;
    1324             : 
    1325      662998 :     for ( i = 0; i < length; i++ )
    1326             :     {
    1327      658880 :         mono_i = ( buf1[i] + buf2[i] ) / 2.0f;
    1328      658880 :         corrL += buf1[i] * mono_i;
    1329      658880 :         corrR += buf2[i] * mono_i;
    1330      658880 :         ener += mono_i * mono_i;
    1331      658880 :         side_i = ( buf1[i] - buf2[i] ) / 2.0f;
    1332      658880 :         ener_side += side_i * side_i;
    1333      658880 :         prod_i = buf1[i] * buf2[i];
    1334      658880 :         sum_prod += prod_i;
    1335             :     }
    1336             : 
    1337             :     /* average energy of L and R channels */
    1338        4118 :     hStereoClassif->ave_ener_L = hStereoTCA->E1_mem / length;
    1339        4118 :     hStereoClassif->ave_ener_R = hStereoTCA->E2_mem / length;
    1340             : 
    1341             :     /* unnormalized L/R correlation */
    1342        4118 :     sum_prod = log10f( fabsf( sum_prod ) + 1.0f );
    1343        4118 :     hStereoClassif->unclr_fv[E_sum_prod] = sum_prod;
    1344        4118 :     hStereoClassif->xtalk_fv[E_sum_prod] = sum_prod;
    1345             : 
    1346             :     /* S/M energy ratio */
    1347        4118 :     tdm_es_em = fabsf( 10.0f * ( log10f( sqrtf( ener_side / L_FRAME_DS ) ) - log10f( sqrtf( ener / L_FRAME_DS ) ) ) );
    1348        4118 :     hStereoClassif->unclr_fv[E_tdm_es_em] = tdm_es_em;
    1349        4118 :     hStereoClassif->xtalk_fv[E_tdm_es_em] = tdm_es_em;
    1350             : 
    1351             :     /* L/R correlation values (zero lag, maximum) */
    1352        4118 :     corrLagMax = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &corrEstMax );
    1353        4118 :     d_corrLagMax = corrLagMax - hStereoClassif->unclr_corrLagMax_prev;
    1354        4118 :     hStereoClassif->unclr_fv[E_d_corrLagMax] = (float) d_corrLagMax;
    1355        4118 :     hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
    1356        4118 :     hStereoClassif->xtalk_fv[E_d_corrLagMax] = (float) d_corrLagMax;
    1357             : 
    1358        4118 :     if ( corrEstMax < 0 )
    1359             :     {
    1360           0 :         corrEstMax = 0;
    1361             :     }
    1362             : 
    1363        4118 :     hStereoClassif->unclr_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
    1364        4118 :     hStereoClassif->unclr_fv[E_corrEstMax] = corrEstMax;
    1365        4118 :     hStereoClassif->unclr_fv[E_corrLagMax] = corrLagMax;
    1366        4118 :     hStereoClassif->xtalk_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
    1367        4118 :     hStereoClassif->xtalk_fv[E_corrEstMax] = corrEstMax;
    1368        4118 :     hStereoClassif->xtalk_fv[E_corrLagMax] = corrLagMax;
    1369             : 
    1370             :     /* L/M and R/M correlation */
    1371        4118 :     if ( corrL < 0 )
    1372             :     {
    1373         109 :         corrL = 0;
    1374             :     }
    1375             : 
    1376        4118 :     if ( corrR < 0 )
    1377             :     {
    1378          65 :         corrR = 0;
    1379             :     }
    1380             : 
    1381        4118 :     ic_Lm = corrL / ener;
    1382        4118 :     ic_Rm = corrR / ener;
    1383        4118 :     m_corrL_corrR = max( fabsf( ic_Lm ), fabsf( ic_Rm ) ) - min( fabsf( ic_Lm ), fabsf( ic_Rm ) );
    1384        4118 :     d_corrL_corrR = log10f( fabsf( corrL - corrR ) + 1.0f );
    1385             : 
    1386        4118 :     hStereoClassif->unclr_fv[E_m_corrL_corrR] = m_corrL_corrR;
    1387        4118 :     hStereoClassif->unclr_fv[E_d_corrL_corrR] = d_corrL_corrR;
    1388        4118 :     hStereoClassif->xtalk_fv[E_m_corrL_corrR] = m_corrL_corrR;
    1389             : 
    1390             :     /* norm. x-correlation btw. current and previous correlation buffers */
    1391        4118 :     tempLen = ( 2 * L_NCSHIFT_DS + 1 );
    1392        4118 :     num = dotp( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
    1393        4118 :     den = sqrtf( sum2_f( corrEst, tempLen ) * sum2_f( hStereoTCA->corrEstPrev[2], tempLen ) );
    1394             : 
    1395        4118 :     *corrEst_ncorr = ( den == 0 ) ? 0.0f : ( num / den );
    1396        4118 :     hStereoClassif->unclr_fv[E_corrEst_ncorr] = *corrEst_ncorr;
    1397        4118 :     hStereoClassif->xtalk_fv[E_corrEst_ncorr] = *corrEst_ncorr;
    1398             : 
    1399        4118 :     return;
    1400             : }

Generated by: LCOV version 1.14