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

Generated by: LCOV version 1.14