LCOV - code coverage report
Current view: top level - lib_enc - tcx_ltp_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 43b7b28dcb1471ff5d355252c4b8f37ee7ecc268 Lines: 619 648 95.5 %
Date: 2025-11-02 02:02:47 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <assert.h>
       6             : #include "options.h"
       7             : //#include "prot_fx.h"
       8             : #include "stl.h"
       9             : #include "cnst.h"
      10             : #include "basop_util.h"
      11             : #include "rom_com.h"
      12             : #include "prot_fx.h"     /* Function prototypes                    */
      13             : #include "prot_fx_enc.h" /* Function prototypes                    */
      14             : 
      15             : 
      16    27129804 : static Word32 dot(
      17             :     const Word16 *X,
      18             :     const Word16 *Y,
      19             :     Word16 n )
      20             : {
      21             :     Word32 acc;
      22             :     Word16 i;
      23             : 
      24             :     Word64 acc_64;
      25    27129804 :     acc_64 = 0;
      26    27129804 :     move64();
      27  7814126860 :     FOR( i = 0; i < n; i++ )
      28             :     {
      29  7786997056 :         acc_64 = W_mac0_16_16( acc_64, X[i], Y[i] );
      30             :     }
      31    27129804 :     acc = W_sat_l( acc_64 );
      32             : 
      33    27129804 :     return acc;
      34             : }
      35             : 
      36             : 
      37             : /* o  : interpolated value   */
      38     5367969 : static Word32 interpolate_corr(
      39             :     const Word32 *x,      /* i  : input vector         */
      40             :     const Word16 frac,    /* i  : fraction of lag      */
      41             :     const Word16 frac_max /* i  : max fraction         */
      42             : )
      43             : {
      44             :     Word32 s;
      45             :     const Word16 *c, *win;
      46             : 
      47     5367969 :     win = E_ROM_inter4_1_fx;
      48     5367969 :     if ( EQ_16( frac_max, 6 ) )
      49             :     {
      50      287726 :         win = E_ROM_inter6_1_fx;
      51             :     }
      52             : 
      53     5367969 :     s = L_deposit_l( 0 );
      54             : 
      55     5367969 :     c = &win[frac];
      56     5367969 :     s = L_add( s, Mpy_32_16_1( x[0], *c ) );
      57     5367969 :     c += frac_max;
      58     5367969 :     s = L_add( s, Mpy_32_16_1( x[-1], *c ) );
      59     5367969 :     c += frac_max;
      60     5367969 :     s = L_add( s, Mpy_32_16_1( x[-2], *c ) );
      61     5367969 :     c += frac_max;
      62     5367969 :     s = L_add( s, Mpy_32_16_1( x[-3], *c ) );
      63             : 
      64     5367969 :     c = &win[frac_max - frac];
      65     5367969 :     s = L_add( s, Mpy_32_16_1( x[1], *c ) );
      66     5367969 :     c += frac_max;
      67     5367969 :     s = L_add( s, Mpy_32_16_1( x[2], *c ) );
      68     5367969 :     c += frac_max;
      69     5367969 :     s = L_add( s, Mpy_32_16_1( x[3], *c ) );
      70     5367969 :     c += frac_max;
      71     5367969 :     s = L_add( s, Mpy_32_16_1( x[4], *c ) );
      72             : 
      73             : 
      74     5367969 :     return s;
      75             : }
      76             : 
      77        1312 : static void tcx_ltp_pitch_search(
      78             :     Word16 pitch_ol,
      79             :     Word16 *pitch_int,
      80             :     Word16 *pitch_fr,
      81             :     Word16 *index,
      82             :     Word16 *norm_corr,
      83             :     const Word16 len,
      84             :     Word16 *wsp,
      85             :     Word16 pitmin,
      86             :     Word16 pitfr1,
      87             :     Word16 pitfr2,
      88             :     Word16 pitmax,
      89             :     Word16 pitres )
      90             : {
      91             :     Word16 i, t, t0, t1, step, fraction, t0_min, t0_max, t_min, t_max, delta, temp_m, temp_e, s, s_wsp;
      92             :     Word32 cor_max, cor[256], *pt_cor, temp;
      93             :     Word16 wsp2[L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1];
      94             : 
      95        1312 :     delta = 16;
      96        1312 :     move16();
      97        1312 :     if ( EQ_16( pitres, 6 ) )
      98             :     {
      99        1050 :         delta = 8;
     100        1050 :         move16();
     101             :     }
     102             : 
     103        1312 :     t0_min = sub( pitch_ol, shr( delta, 1 ) );
     104        1312 :     t0_max = sub( add( t0_min, delta ), 1 );
     105             : 
     106        1312 :     IF( LT_16( t0_min, pitmin ) )
     107             :     {
     108          40 :         t0_min = pitmin;
     109          40 :         move16();
     110          40 :         t0_max = sub( add( t0_min, delta ), 1 );
     111             :     }
     112             : 
     113        1312 :     IF( GT_16( t0_max, pitmax ) )
     114             :     {
     115          18 :         t0_max = pitmax;
     116          18 :         move16();
     117          18 :         t0_min = add( sub( t0_max, delta ), 1 );
     118             :     }
     119             : 
     120        1312 :     t_min = sub( t0_min, L_INTERPOL1 );
     121        1312 :     t_max = add( t0_max, L_INTERPOL1 );
     122             : 
     123             :     /* normalize wsp */
     124        1312 :     assert( len + t_max <= L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1 );
     125        1312 :     s_wsp = getScaleFactor16( wsp - t_max, add( len, t_max ) );
     126        1312 :     s_wsp = sub( s_wsp, 4 );
     127      541679 :     FOR( t = negate( t_max ); t < len; t++ )
     128             :     {
     129      540367 :         wsp2[t + t_max] = shl( wsp[t], s_wsp );
     130      540367 :         move16();
     131             :     }
     132        1312 :     wsp = wsp2 + t_max;
     133        1312 :     move16();
     134             : 
     135        1312 :     pt_cor = cor;
     136        1312 :     move32();
     137             : 
     138       24400 :     FOR( t = t_min; t <= t_max; t++ )
     139             :     {
     140       23088 :         *pt_cor = dot( wsp, wsp - t, len );
     141       23088 :         move32();
     142       23088 :         pt_cor++;
     143             :     }
     144             : 
     145        1312 :     pt_cor = cor + L_INTERPOL1;
     146        1312 :     cor_max = L_add( *pt_cor++, 0 );
     147        1312 :     t1 = t0_min;
     148        1312 :     move16();
     149        1312 :     move32();
     150             : 
     151       12592 :     FOR( t = t0_min + 1; t <= t0_max; t++ )
     152             :     {
     153       11280 :         IF( GT_32( *pt_cor, cor_max ) )
     154             :         {
     155        4954 :             cor_max = *pt_cor;
     156        4954 :             move32();
     157        4954 :             t1 = t;
     158        4954 :             move16();
     159             :         }
     160       11280 :         pt_cor++;
     161             :     }
     162             : 
     163        1312 :     temp = dot( wsp, wsp, len );
     164        1312 :     s = norm_l( temp );
     165        1312 :     temp_m = extract_h( L_shl( temp, s ) );
     166        1312 :     temp_e = negate( s );
     167             : 
     168        1312 :     temp = dot( wsp - t1, wsp - t1, len );
     169        1312 :     s = norm_l( temp );
     170        1312 :     temp_m = mult( temp_m, extract_h( L_shl( temp, s ) ) );
     171        1312 :     temp_e = sub( temp_e, s );
     172             : 
     173        1312 :     temp_m = Sqrt16( temp_m, &temp_e );
     174             : 
     175        1312 :     if ( temp_m == 0 )
     176             :     {
     177           0 :         temp_m = 1;
     178           0 :         move16();
     179             :     }
     180        1312 :     s = sub( norm_l( cor_max ), 1 );
     181        1312 :     temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m );
     182        1312 :     temp_e = sub( negate( s ), temp_e );
     183             : 
     184        1312 :     *norm_corr = shl_sat( temp_m, temp_e );
     185             : 
     186        1312 :     IF( GE_16( t1, pitfr1 ) )
     187             :     {
     188         188 :         *pitch_int = t1;
     189         188 :         move16();
     190         188 :         *pitch_fr = 0;
     191         188 :         move16();
     192             : 
     193         188 :         *index = add( sub( t1, pitfr1 ), extract_l( L_mac0( L_mult0( sub( pitfr2, pitmin ), pitres ),
     194         188 :                                                             sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ) ) );
     195         188 :         move16();
     196             : 
     197         188 :         return;
     198             :     }
     199             : 
     200             :     /*------------------------------------------------------------------*
     201             :      * Search fractional pitch with 1/4 subsample resolution.
     202             :      * search the fractions around t0 and choose the one which maximizes
     203             :      * the interpolated normalized correlation.
     204             :      *-----------------------------------------------------------------*/
     205             : 
     206        1124 :     pt_cor = cor + sub( L_INTERPOL1, t0_min );
     207        1124 :     t0 = t1;
     208        1124 :     move16();
     209             : 
     210        1124 :     step = 1;
     211        1124 :     move16();
     212        1124 :     if ( GE_16( t0, pitfr2 ) )
     213             :     {
     214         896 :         step = 2;
     215         896 :         move16();
     216             :     }
     217        1124 :     fraction = step;
     218        1124 :     move16();
     219             : 
     220        1124 :     IF( EQ_16( t0, t0_min ) ) /* Limit case */
     221             :     {
     222         127 :         fraction = 0;
     223         127 :         move16();
     224         127 :         cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
     225             :     }
     226             :     ELSE /* Process negative fractions */
     227             :     {
     228         997 :         t0 = sub( t0, 1 );
     229         997 :         cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
     230             : 
     231        2192 :         FOR( i = fraction + step; i < pitres; i += step )
     232             :         {
     233        1195 :             temp = interpolate_corr( &pt_cor[t0], i, pitres );
     234             : 
     235        1195 :             IF( GT_32( temp, cor_max ) )
     236             :             {
     237        1165 :                 cor_max = L_add( temp, 0 );
     238        1165 :                 fraction = i;
     239        1165 :                 move16();
     240             :             }
     241             :         }
     242             :     }
     243             : 
     244        1124 :     i = 0;
     245        1124 :     move16();
     246        4711 :     FOR( i = 0; i < pitres; i += step ) /* Process positive fractions */
     247             :     {
     248        3587 :         temp = interpolate_corr( &pt_cor[t1], i, pitres );
     249             : 
     250        3587 :         IF( GT_32( temp, cor_max ) )
     251             :         {
     252        1100 :             cor_max = L_add( temp, 0 );
     253        1100 :             fraction = i;
     254        1100 :             move16();
     255        1100 :             t0 = t1;
     256        1100 :             move16();
     257             :         }
     258             :     }
     259             : 
     260        1124 :     *pitch_int = t0;
     261        1124 :     move16();
     262        1124 :     *pitch_fr = fraction;
     263        1124 :     move16();
     264             : 
     265        1124 :     IF( GE_16( t0, pitfr2 ) )
     266             :     {
     267         896 :         *index = add( extract_l( L_mac0( L_mult0( sub( t0, pitfr2 ), shr( pitres, 1 ) ),
     268         896 :                                          sub( pitfr2, pitmin ), pitres ) ),
     269         896 :                       shr( fraction, 1 ) );
     270         896 :         move16();
     271             :     }
     272             :     ELSE
     273             :     {
     274         228 :         *index = add( imult1616( sub( t0, pitmin ), pitres ), fraction );
     275         228 :         move16();
     276             :     }
     277             : }
     278             : 
     279     1083424 : static void tcx_ltp_pitch_search_ivas_fx(
     280             :     const Word16 pitch_ol,
     281             :     Word16 *pitch_int,
     282             :     Word16 *pitch_fr,
     283             :     Word16 *index,
     284             :     Word16 *norm_corr,
     285             :     const Word16 len,
     286             :     const Word16 *wsp, // Qx
     287             :     const Word16 pitmin,
     288             :     const Word16 pitfr1,
     289             :     const Word16 pitfr2,
     290             :     const Word16 pitmax,
     291             :     const Word16 pitres,
     292             :     const Word16 check_border_case,
     293             :     Word16 *border_case )
     294             : {
     295             :     Word16 i, t, t0, t1, step, fraction, t0_min, t0_max, t_min, t_max, delta, temp_m, temp_e, s, s_wsp;
     296             :     Word32 cor_max, cor[256], *pt_cor, temp;
     297             :     Word16 wsp2[L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1];
     298             : 
     299     1083424 :     delta = 16;
     300     1083424 :     move16();
     301     1083424 :     if ( EQ_16( pitres, 6 ) )
     302             :     {
     303      174580 :         delta = 8;
     304      174580 :         move16();
     305             :     }
     306             : 
     307     1083424 :     t0_min = sub( pitch_ol, shr( delta, 1 ) );
     308     1083424 :     t0_max = sub( add( t0_min, delta ), 1 );
     309             : 
     310     1083424 :     IF( LT_16( t0_min, pitmin ) )
     311             :     {
     312       87031 :         t0_min = pitmin;
     313       87031 :         move16();
     314       87031 :         t0_max = sub( add( t0_min, delta ), 1 );
     315             :     }
     316             : 
     317     1083424 :     IF( GT_16( t0_max, pitmax ) )
     318             :     {
     319       21975 :         t0_max = pitmax;
     320       21975 :         move16();
     321       21975 :         t0_min = add( sub( t0_max, delta ), 1 );
     322             :     }
     323             : 
     324     1083424 :     t_min = sub( t0_min, L_INTERPOL1 );
     325     1083424 :     t_max = add( t0_max, L_INTERPOL1 );
     326             : 
     327             :     /* normalize wsp */
     328     1083424 :     s_wsp = getScaleFactor16( wsp - t_max, add( len, t_max ) );
     329     1083424 :     s_wsp = sub( s_wsp, 4 );
     330   444257573 :     FOR( t = negate( t_max ); t < len; t++ )
     331             :     {
     332   443174149 :         wsp2[t + t_max] = shl( wsp[t], s_wsp ); // Q(x + s_wsp)
     333   443174149 :         move16();
     334             :     }
     335     1083424 :     wsp = wsp2 + t_max;
     336             : 
     337     1083424 :     pt_cor = cor;
     338             : 
     339    25688960 :     FOR( t = t_min; t <= t_max; t++ )
     340             :     {
     341    24605536 :         *pt_cor = dot( wsp, wsp - t, len ); // 2*(x + s_wsp)
     342    24605536 :         move32();
     343    24605536 :         pt_cor++;
     344             :     }
     345             : 
     346     1083424 :     pt_cor = cor + L_INTERPOL1;
     347     1083424 :     cor_max = L_add( *pt_cor++, 0 );
     348     1083424 :     t1 = t0_min;
     349     1083424 :     move16();
     350             : 
     351    15938144 :     FOR( t = t0_min + 1; t <= t0_max; t++ )
     352             :     {
     353    14854720 :         IF( GT_32( *pt_cor, cor_max ) )
     354             :         {
     355     5705553 :             cor_max = *pt_cor;
     356     5705553 :             move32();
     357     5705553 :             t1 = t;
     358     5705553 :             move16();
     359             :         }
     360    14854720 :         pt_cor++;
     361             :     }
     362             : 
     363     1083424 :     temp = dot( wsp, wsp, len ); // 2*(x + s_wsp)
     364     1083424 :     s = norm_l( temp );
     365     1083424 :     temp_e = negate( s );
     366     1083424 :     temp_m = extract_h( L_shl( temp, s ) ); // Q(2*(x + s_wsp) - temp_e - 16)
     367             : 
     368     1083424 :     temp = dot( wsp - t1, wsp - t1, len ); //  2*(x + s_wsp)
     369     1083424 :     s = norm_l( temp );
     370     1083424 :     temp_m = mult( temp_m, extract_h( L_shl( temp, s ) ) ); // //Q = 4*(x + s_wsp) + s - temp_e - 47
     371     1083424 :     temp_e = sub( temp_e, s );
     372             : 
     373     1083424 :     temp_m = Sqrt16( temp_m, &temp_e );
     374             : 
     375     1083424 :     if ( temp_m == 0 )
     376             :     {
     377       14285 :         temp_m = 1;
     378       14285 :         move16();
     379             :     }
     380     1083424 :     s = sub( norm_l( cor_max ), 1 );
     381     1083424 :     temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m );
     382     1083424 :     temp_e = sub( negate( s ), temp_e );
     383             : 
     384     1083424 :     *norm_corr = shl_sat( temp_m, temp_e );
     385             : 
     386     1083424 :     test();
     387     1083424 :     IF( check_border_case && EQ_16( t1, t0_min ) )
     388             :     {
     389             :         Word32 tmpCor;
     390      383916 :         FOR( t = t1 - L_INTERPOL1; t < t1; t++ )
     391             :         {
     392      331708 :             tmpCor = dot( wsp, wsp - t, len );
     393      331708 :             IF( GT_32( tmpCor, cor_max ) )
     394             :             {
     395       86740 :                 *border_case = 1;
     396       86740 :                 move16();
     397       86740 :                 break;
     398             :             }
     399             :         }
     400             :     }
     401             : 
     402     1083424 :     IF( GE_16( t1, pitfr1 ) )
     403             :     {
     404      232891 :         *pitch_int = t1;
     405      232891 :         move16();
     406      232891 :         *pitch_fr = 0;
     407      232891 :         move16();
     408             : 
     409      232891 :         *index = add( sub( t1, pitfr1 ), extract_l( L_mac0( L_mult0( sub( pitfr2, pitmin ), pitres ),
     410      232891 :                                                             sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ) ) );
     411      232891 :         move16();
     412             : 
     413      232891 :         return;
     414             :     }
     415             : 
     416             :     /*------------------------------------------------------------------*
     417             :      * Search fractional pitch with 1/4 subsample resolution.
     418             :      * search the fractions around t0 and choose the one which maximizes
     419             :      * the interpolated normalized correlation.
     420             :      *-----------------------------------------------------------------*/
     421             : 
     422      850533 :     pt_cor = cor + sub( L_INTERPOL1, t0_min );
     423      850533 :     t0 = t1;
     424      850533 :     move16();
     425             : 
     426      850533 :     step = 1;
     427      850533 :     move16();
     428      850533 :     if ( GE_16( t0, pitfr2 ) )
     429             :     {
     430      128800 :         step = 2;
     431      128800 :         move16();
     432             :     }
     433      850533 :     fraction = step;
     434      850533 :     move16();
     435             : 
     436      850533 :     IF( EQ_16( t0, t0_min ) ) /* Limit case */
     437             :     {
     438      111956 :         fraction = 0;
     439      111956 :         move16();
     440      111956 :         cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
     441             :     }
     442             :     ELSE /* Process negative fractions */
     443             :     {
     444      738577 :         t0 = sub( t0, 1 );
     445      738577 :         cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
     446             : 
     447     2045428 :         FOR( i = fraction + step; i < pitres; i += step )
     448             :         {
     449     1306851 :             temp = interpolate_corr( &pt_cor[t0], i, pitres );
     450             : 
     451     1306851 :             IF( GT_32( temp, cor_max ) )
     452             :             {
     453     1223268 :                 cor_max = L_add( temp, 0 );
     454     1223268 :                 fraction = i;
     455     1223268 :                 move16();
     456             :             }
     457             :         }
     458             :     }
     459             : 
     460     4055212 :     FOR( i = 0; i < pitres; i += step ) /* Process positive fractions */
     461             :     {
     462     3204679 :         temp = interpolate_corr( &pt_cor[t1], i, pitres );
     463             : 
     464     3204679 :         IF( GT_32( temp, cor_max ) )
     465             :         {
     466      912655 :             cor_max = L_add( temp, 0 );
     467      912655 :             fraction = i;
     468      912655 :             move16();
     469      912655 :             t0 = t1;
     470      912655 :             move16();
     471             :         }
     472             :     }
     473             : 
     474      850533 :     *pitch_int = t0;
     475      850533 :     move16();
     476      850533 :     *pitch_fr = fraction;
     477      850533 :     move16();
     478             : 
     479      850533 :     IF( GE_16( t0, pitfr2 ) )
     480             :     {
     481      127958 :         *index = add( extract_l( L_mac0( L_mult0( sub( t0, pitfr2 ), shr( pitres, 1 ) ),
     482      127958 :                                          sub( pitfr2, pitmin ), pitres ) ),
     483      127958 :                       shr( fraction, 1 ) );
     484      127958 :         move16();
     485             :     }
     486             :     ELSE
     487             :     {
     488      722575 :         *index = add( imult1616( sub( t0, pitmin ), pitres ), fraction );
     489      722575 :         move16();
     490             :     }
     491             : }
     492             : 
     493             : 
     494         943 : static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_frame, Word16 *gain, Word16 *gain_index )
     495             : {
     496             :     Word32 corr, ener;
     497             :     Word16 i, g, s1, s2, tmp;
     498             : 
     499         943 :     s1 = sub( getScaleFactor16( speech, L_frame ), 4 );
     500         943 :     s2 = sub( getScaleFactor16( pred_speech, L_frame ), 4 );
     501             : 
     502             :     /* Find gain */
     503         943 :     corr = L_deposit_l( 0 );
     504         943 :     ener = L_deposit_l( 1 );
     505             : 
     506      289711 :     FOR( i = 0; i < L_frame; i++ )
     507             :     {
     508      288768 :         tmp = shl_sat( pred_speech[i], s2 );
     509      288768 :         corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp );
     510      288768 :         ener = L_mac0_sat( ener, tmp, tmp );
     511             :     }
     512             : 
     513         943 :     s1 = sub( 1, add( s1, s2 ) );
     514         943 :     s2 = sub( 1, shl( s2, 1 ) );
     515             : 
     516         943 :     tmp = sub( norm_l( corr ), 1 );
     517         943 :     corr = L_shl( corr, tmp );
     518         943 :     s1 = sub( s1, tmp );
     519             : 
     520         943 :     tmp = norm_l( ener );
     521         943 :     ener = L_shl( ener, tmp );
     522         943 :     s2 = sub( s2, tmp );
     523             : 
     524         943 :     g = divide1616( round_fx_sat( corr ), round_fx_sat( ener ) );
     525             :     BASOP_SATURATE_WARNING_OFF_EVS
     526         943 :     g = shl_sat( g, sub( s1, s2 ) );
     527             :     BASOP_SATURATE_WARNING_ON_EVS
     528             : 
     529             :     /* Quantize gain */
     530         943 :     g = shr( sub_sat( g, 0x1000 ), 13 );
     531         943 :     g = s_max( g, -1 );
     532             : 
     533         943 :     *gain_index = g;
     534         943 :     move16();
     535             : 
     536             :     /* Dequantize gain */
     537         943 :     *gain = imult1616( add( g, 1 ), 0x1400 );
     538         943 :     move16();
     539         943 : }
     540             : 
     541      888815 : static void tcx_ltp_find_gain_ivas_fx( Word16 *speech /*Qx*/, Word16 *pred_speech /*Qx*/, Word16 L_frame, Word16 *gain, Word16 *gain_index )
     542             : {
     543             :     Word32 corr, ener;
     544             :     Word16 i, g, s1, s2, tmp;
     545             : 
     546      888815 :     s1 = sub( getScaleFactor16( speech, L_frame ), 4 );
     547      888815 :     s2 = sub( getScaleFactor16( pred_speech, L_frame ), 4 );
     548             : 
     549             :     /* Find gain */
     550      888815 :     corr = L_deposit_l( 0 );
     551      888815 :     ener = L_deposit_l( 1 );
     552             : 
     553   273176751 :     FOR( i = 0; i < L_frame; i++ )
     554             :     {
     555   272287936 :         tmp = shl_sat( pred_speech[i], s2 );                  // Qx + s2
     556   272287936 :         corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp ); // 2*Qx + s1 + s2
     557   272287936 :         ener = L_mac0_sat( ener, tmp, tmp );                  // 2*(Qx+s2)
     558             :     }
     559             : 
     560      888815 :     s1 = sub( 1, add( s1, s2 ) );
     561      888815 :     s2 = sub( 1, shl( s2, 1 ) );
     562             : 
     563      888815 :     tmp = sub( norm_l( corr ), 1 );
     564      888815 :     corr = L_shl( corr, tmp );
     565      888815 :     s1 = sub( s1, tmp );
     566             : 
     567      888815 :     tmp = norm_l( ener );
     568      888815 :     ener = L_shl( ener, tmp );
     569      888815 :     s2 = sub( s2, tmp );
     570             : 
     571      888815 :     g = divide1616( round_fx_sat( corr ), round_fx_sat( ener ) );
     572             :     BASOP_SATURATE_WARNING_OFF_EVS
     573      888815 :     g = shl_sat( g, sub( s1, s2 ) ); /*Q15*/
     574             :     BASOP_SATURATE_WARNING_ON_EVS
     575             : 
     576             :     /* Quantize gain */
     577      888815 :     g = shr_sat( sub_sat( g /*Q15*/, 0x1000 ), 13 ); // Q0
     578      888815 :     g = s_max( g, -1 );
     579             : 
     580      888815 :     *gain_index = g;
     581      888815 :     move16();
     582             : 
     583             :     /* Dequantize gain */
     584      888815 :     *gain = imult1616( add( g, 1 ), 0x1400 ); /*Q15*/
     585      888815 :     move16();
     586             : 
     587      888815 :     return;
     588             : }
     589             : 
     590        1312 : void tcx_ltp_encode_fx(
     591             :     Word16 tcxltp_on,
     592             :     Word8 tcxOnly,
     593             :     Word16 tcxMode,
     594             :     Word16 L_frame,
     595             :     Word16 L_subfr,
     596             :     Word16 *speech,
     597             :     Word16 *speech_ltp,
     598             :     Word16 *wsp,
     599             :     Word16 Top,
     600             :     Word16 *ltp_param,
     601             :     Word16 *ltp_bits,
     602             :     Word16 *pitch_int,
     603             :     Word16 *pitch_fr,
     604             :     Word16 *gain,
     605             :     Word16 *pitch_int_past,
     606             :     Word16 *pitch_fr_past,
     607             :     Word16 *gain_past,
     608             :     Word16 *norm_corr_past,
     609             :     Word16 last_core,
     610             :     Word16 pitmin,
     611             :     Word16 pitfr1,
     612             :     Word16 pitfr2,
     613             :     Word16 pitmax,
     614             :     Word16 pitres,
     615             :     TRAN_DET_HANDLE hTranDet,
     616             :     Word8 SideInfoOnly,
     617             :     Word16 *A,
     618             :     Word16 lpcorder )
     619             : {
     620             :     Word16 n;
     621             :     Word16 norm_corr;
     622             :     Word16 pred_speech[L_FRAME32k];
     623             :     Word16 tempFlatness;
     624             :     Word16 maxEnergyChange;
     625             :     Word16 buf_zir[M + L_SUBFR], *zir;
     626             :     Word16 Aest[M + 1];
     627             :     Word16 alpha, step;
     628             : 
     629        1312 :     norm_corr = 0;
     630        1312 :     move16();
     631             : 
     632             :     /* Reset memory if past frame is acelp */
     633        1312 :     IF( last_core == ACELP_CORE )
     634             :     {
     635         627 :         *pitch_int_past = L_frame;
     636         627 :         move16();
     637         627 :         *pitch_fr_past = 0;
     638         627 :         move16();
     639         627 :         *gain_past = 0;
     640         627 :         move16();
     641             :     }
     642             : 
     643             :     /* By default, LTP is off */
     644        1312 :     ltp_param[0] = 0;
     645        1312 :     move16();
     646             : 
     647        1312 :     test();
     648        1312 :     IF( tcxltp_on != 0 || SideInfoOnly != 0 )
     649             :     {
     650             :         Word16 nPrevSubblocks;
     651        1312 :         Word8 isTCX10 = 0;
     652             : 
     653        1312 :         if ( EQ_16( tcxMode, TCX_10 ) )
     654             :         {
     655           0 :             isTCX10 = 1;
     656           0 :             move16();
     657             :         }
     658             : 
     659             :         /* Find pitch lag */
     660        1312 :         tcx_ltp_pitch_search( Top, pitch_int, pitch_fr, &ltp_param[1], &norm_corr, L_frame, wsp, pitmin, pitfr1, pitfr2, pitmax, pitres );
     661             : 
     662        1312 :         nPrevSubblocks = extract_h( L_mac( 0x17fff, NSUBBLOCKS, div_s( *pitch_int, L_frame ) ) );
     663        1312 :         nPrevSubblocks = add( s_min( nPrevSubblocks, NSUBBLOCKS ), 1 );
     664             : 
     665        1312 :         tempFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( hTranDet, NSUBBLOCKS, nPrevSubblocks );
     666             : 
     667        1312 :         maxEnergyChange = GetTCXMaxenergyChange_fx( hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks );
     668             : 
     669             :         /* Switch LTP on */
     670        1312 :         test();
     671        1312 :         test();
     672        1312 :         test();
     673        1312 :         test();
     674        1312 :         test();
     675        1312 :         test();
     676        1312 :         test();
     677        1312 :         test();
     678        1312 :         test();
     679        1312 :         test();
     680        1312 :         test();
     681        1312 :         test();
     682        1312 :         test();
     683        1312 :         test();
     684        1312 :         test();
     685        1312 :         test();
     686             :         BASOP_SATURATE_WARNING_OFF_EVS;
     687        1312 :         if ( (
     688        1312 :                  tcxOnly == 0 &&
     689        2624 :                  EQ_16( tcxMode, TCX_20 ) &&
     690        2327 :                  GT_16( mult( norm_corr, *norm_corr_past ), 0x2000 ) &&
     691        1384 :                  LT_16( tempFlatness, 448 /*3.5f Q7*/ ) ) ||
     692           0 :              ( tcxOnly != 0 &&
     693           0 :                EQ_16( tcxMode, TCX_10 ) &&
     694           0 :                GT_16( s_max( norm_corr, *norm_corr_past ), 0x4000 ) &&
     695         369 :                LT_16( maxEnergyChange, 448 /*3.5f Q7*/ ) ) ||
     696             :              ( /* Use LTP for lower correlation when pitch lag is big, L_frame*(1.2f-norm_corr) < pitch_int <=> norm_corr > 1.2f-pitch_int/L_frame */
     697           0 :                tcxOnly != 0 &&
     698           0 :                GT_16( norm_corr, 14418 /*0.44f Q15*/ ) &&
     699           0 :                L_msu( L_mult( L_frame, sub( 19661 /*1.2f Q14*/, shr( norm_corr, 1 ) ) ), *pitch_int, 1 << 14 ) < 0 /* L_frame*(1.2f-norm_corr) < pitch_int */
     700         369 :                ) ||
     701           0 :              ( tcxOnly != 0 &&
     702           0 :                EQ_16( tcxMode, TCX_20 ) &&
     703           0 :                GT_16( norm_corr, 14418 /*0.44f Q15*/ ) &&
     704           0 :                ( LT_16( tempFlatness, 768 /*6.0f Q7*/ ) ||
     705           0 :                  ( LT_16( tempFlatness, 896 /*7.0f Q7*/ ) &&
     706           0 :                    LT_16( maxEnergyChange, 2816 /*22.0f Q7*/ ) ) ) ) )
     707             :         {
     708         943 :             ltp_param[0] = 1;
     709         943 :             move16();
     710             :         }
     711             :         BASOP_SATURATE_WARNING_ON_EVS;
     712             :     }
     713             : 
     714        1312 :     IF( ltp_param[0] != 0 )
     715             :     {
     716             :         /* Find predicted signal */
     717         943 :         predict_signal( speech, pred_speech, *pitch_int, *pitch_fr, pitres, L_frame );
     718             : 
     719             :         /* Find gain */
     720         943 :         tcx_ltp_find_gain( speech, pred_speech, L_frame, gain, &ltp_param[2] );
     721             : 
     722             :         /* Total number of bits for LTP */
     723         943 :         IF( NE_16( ltp_param[2], -1 ) ) /* gain > 0 */
     724             :         {
     725         943 :             *ltp_bits = 12;
     726         943 :             move16();
     727             :         }
     728             :         ELSE /* gain <= 0 -> turn off LTP */
     729             :         {
     730           0 :             ltp_param[0] = 0;
     731           0 :             move16();
     732             :         }
     733             :     }
     734             : 
     735        1312 :     IF( ltp_param[0] == 0 )
     736             :     {
     737             :         /* No LTP -> set everything to zero */
     738         369 :         *pitch_int = L_frame;
     739         369 :         move16();
     740         369 :         *pitch_fr = 0;
     741         369 :         move16();
     742         369 :         ltp_param[1] = 0;
     743         369 :         move16();
     744         369 :         set16_fx( pred_speech, 0, L_frame );
     745         369 :         *gain = 0;
     746         369 :         move16();
     747         369 :         ltp_param[2] = 0;
     748         369 :         move16();
     749             : 
     750         369 :         *ltp_bits = 0;
     751         369 :         move16();
     752         369 :         test();
     753         369 :         IF( tcxltp_on != 0 || SideInfoOnly != 0 )
     754             :         {
     755         369 :             *ltp_bits = 1;
     756         369 :             move16();
     757             :         }
     758             :     }
     759             : 
     760        1312 :     IF( SideInfoOnly != 0 )
     761             :     {
     762           0 :         *gain = 0;
     763           0 :         move16();
     764             :     }
     765             : 
     766        1312 :     test();
     767        1312 :     IF( *gain_past == 0 && *gain == 0 )
     768             :     {
     769         301 :         Copy( speech, speech_ltp, L_subfr );
     770             :     }
     771        1011 :     ELSE IF( *gain_past == 0 )
     772             :     {
     773         532 :         alpha = 0;
     774         532 :         move16();
     775             : 
     776             :         /* step = 1.f/(float)(L_subfr); */
     777         532 :         step = shl( 2, norm_s( L_subfr ) );
     778         532 :         IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
     779             :         {
     780           0 :             step = mult_r( step, 26214 /*64.f/80.f Q15*/ );
     781             :         }
     782             : 
     783       34580 :         FOR( n = 0; n < L_subfr; n++ )
     784             :         {
     785       34048 :             speech_ltp[n] = sub_sat( speech[n], mult_r_sat( *gain, mult_r_sat( alpha, pred_speech[n] ) ) );
     786       34048 :             move16();
     787             :             BASOP_SATURATE_WARNING_OFF_EVS;
     788       34048 :             alpha = add_sat( alpha, step );
     789             :             BASOP_SATURATE_WARNING_ON_EVS;
     790             :         }
     791             :     }
     792             :     ELSE
     793             :     {
     794         479 :         IF( A == NULL )
     795             :         {
     796           0 :             tcx_ltp_get_lpc( speech - L_frame, L_frame, Aest, lpcorder );
     797           0 :             A = Aest;
     798             :         }
     799             : 
     800         479 :         IF( *gain > 0 )
     801             :         {
     802         411 :             predict_signal( speech - lpcorder, buf_zir, *pitch_int, *pitch_fr, pitres, lpcorder );
     803             :         }
     804             :         ELSE
     805             :         {
     806          68 :             set16_fx( buf_zir, 0, lpcorder );
     807             :         }
     808             : 
     809        8143 :         FOR( n = 0; n < lpcorder; n++ )
     810             :         {
     811        7664 :             buf_zir[n] = add_sat( sub_sat( speech_ltp[n - lpcorder], speech[n - lpcorder] ), mult_r( *gain, buf_zir[n] ) );
     812        7664 :             move16();
     813             :         }
     814             : 
     815         479 :         zir = buf_zir + lpcorder;
     816             : 
     817         479 :         set16_fx( zir, 0, L_subfr );
     818             : 
     819         479 :         E_UTIL_synthesis( 0, A, zir, zir, L_subfr, buf_zir, 0, lpcorder );
     820             : 
     821         479 :         alpha = 0x7FFF;
     822         479 :         move16();
     823             :         /* step = 1.f/(float)(L_subfr/2); */
     824         479 :         step = shl( 4, norm_s( L_subfr ) );
     825         479 :         IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
     826             :         {
     827           0 :             step = mult_r( step, 26214 /*64.f/80.f Q15*/ );
     828             :         }
     829             : 
     830       15807 :         FOR( n = ( L_subfr >> 1 ); n < L_subfr; n++ )
     831             :         {
     832       15328 :             zir[n] = mult_r( zir[n], alpha );
     833       15328 :             move16();
     834       15328 :             alpha = sub( alpha, step );
     835             :         }
     836             : 
     837       31135 :         FOR( n = 0; n < L_subfr; n++ )
     838             :         {
     839       30656 :             speech_ltp[n] = add_sat( sub_sat( speech[n], mult_r_sat( *gain, pred_speech[n] ) ), zir[n] );
     840       30656 :             move16();
     841             :         }
     842             :     }
     843             : 
     844        1312 :     test();
     845        1312 :     IF( SideInfoOnly || *gain == 0 )
     846             :     {
     847       91057 :         FOR( n = L_subfr; n < L_frame; n++ )
     848             :         {
     849       90688 :             speech_ltp[n] = speech[n];
     850       90688 :             move16();
     851             :         }
     852             :     }
     853             :     ELSE
     854             :     {
     855      229359 :         FOR( n = L_subfr; n < L_frame; n++ )
     856             :         {
     857      228416 :             speech_ltp[n] = sub_sat( speech[n], mult( *gain, pred_speech[n] ) );
     858      228416 :             move16();
     859             :         }
     860             :     }
     861             : 
     862             :     /* Update */
     863        1312 :     *pitch_int_past = *pitch_int;
     864        1312 :     move16();
     865        1312 :     *pitch_fr_past = *pitch_fr;
     866        1312 :     move16();
     867        1312 :     *gain_past = *gain;
     868        1312 :     move16();
     869        1312 :     *norm_corr_past = norm_corr;
     870        1312 :     move16();
     871             : 
     872        1312 :     return;
     873             : }
     874             : 
     875             : 
     876      888815 : void tcx_ltp_encode_ivas_fx(
     877             :     Encoder_State *st,
     878             :     const Word16 tcxMode,
     879             :     const Word16 L_frame,
     880             :     Word16 *speech_fx,
     881             :     Word16 *speech_ltp_fx,
     882             :     const Word16 *wsp_fx,
     883             :     const Word16 Top[],
     884             :     Word16 *ltp_param,
     885             :     Word16 *ltp_bits,
     886             :     Word16 *A_fx,
     887             :     const Word16 disable_ltp,
     888             :     const Word16 element_mode )
     889             : {
     890             :     Word16 i, n;
     891             :     Word16 ltp_on, tcxOnly, L_subfr, SideInfoOnly, delta;
     892             :     Word16 si_gain_fx;        // Q15
     893             :     Word16 alpha_fx, step_fx; // Q15
     894             :     Word16 norm_corr_fx;      // Q15
     895             :     Word16 border_case;
     896             :     Word16 tempFlatness_fx;                           // Q7
     897             :     Word16 maxEnergyChange_fx;                        // Q3
     898             :     Word16 pred_speech_fx[L_FRAME_PLUS];              // Qspeech
     899             :     Word16 buf_zir_fx[M + L_FRAME_PLUS / 4], *zir_fx; // Qspeech
     900             :     Word16 Aest_fx[M + 1];
     901             :     Word16 exponent;
     902             :     Word16 sqr;
     903      888815 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     904             : 
     905      888815 :     tcxOnly = st->tcxonly;
     906      888815 :     move16();
     907      888815 :     L_subfr = L_SUBFR;
     908      888815 :     move16();
     909      888815 :     SideInfoOnly = extract_l( GT_32( st->sr_core, 25600 ) );
     910      888815 :     move16();
     911             : 
     912             :     /* Reset memory if past frame is acelp */
     913      888815 :     IF( st->last_core == ACELP_CORE )
     914             :     {
     915        9260 :         hTcxEnc->tcxltp_pitch_int_past = L_frame;
     916        9260 :         move16();
     917        9260 :         hTcxEnc->tcxltp_pitch_fr_past = 0;
     918        9260 :         move16();
     919        9260 :         hTcxEnc->tcxltp_gain_past = 0;
     920        9260 :         move16();
     921             :     }
     922             : 
     923             :     /* By default, LTP is off */
     924      888815 :     ltp_param[0] = 0;
     925      888815 :     move16();
     926      888815 :     norm_corr_fx = 0;
     927      888815 :     move16();
     928      888815 :     border_case = 0;
     929      888815 :     move16();
     930             : 
     931      888815 :     test();
     932      888815 :     IF( hTcxEnc->tcxltp || SideInfoOnly )
     933             :     {
     934             :         Word16 nPrevSubblocks;
     935      888815 :         Word8 isTCX10 = 0;
     936      888815 :         move16();
     937             : 
     938             :         /* Find pitch lag */
     939      888815 :         IF( EQ_16( st->pit_res_max, 6 ) )
     940             :         {
     941      174580 :             delta = 8;
     942      174580 :             move16();
     943             :         }
     944             :         ELSE
     945             :         {
     946      714235 :             delta = 16;
     947      714235 :             move16();
     948             :         }
     949             : 
     950      888815 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
     951             :         {
     952      652353 :             IF( LT_16( abs_s( sub( Top[0], Top[1] ) ), shr( delta, 1 ) ) )
     953             :             {
     954             :                 /* estimates are close enough and stable, take the artihmetic mean as estimate */
     955      457744 :                 tcx_ltp_pitch_search_ivas_fx( shr( add( Top[0], Top[1] ), 1 ), &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &ltp_param[1], &norm_corr_fx, L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
     956             :             }
     957             :             ELSE
     958             :             {
     959             :                 /* pitch jumps between half frames, calc ltp for both estimates, choose the better one */
     960             :                 Word16 pitch_int_2[2];
     961             :                 Word16 pitch_fr_2[2];
     962             :                 Word16 norm_corr_2_fx[2];
     963             :                 Word16 pit_param_2[2];
     964             : 
     965      583827 :                 FOR( i = 0; i < 2; i++ )
     966             :                 {
     967      389218 :                     tcx_ltp_pitch_search_ivas_fx( Top[i], &pitch_int_2[i], &pitch_fr_2[i], &pit_param_2[i], &norm_corr_2_fx[i], L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
     968             :                 }
     969             : 
     970      194609 :                 IF( GT_16( norm_corr_2_fx[1], norm_corr_2_fx[0] ) )
     971             :                 {
     972      125128 :                     i = 1;
     973             :                 }
     974             :                 ELSE
     975             :                 {
     976       69481 :                     i = 0;
     977             :                 }
     978      194609 :                 move16();
     979             : 
     980      194609 :                 hTcxEnc->tcxltp_pitch_int = pitch_int_2[i];
     981      194609 :                 move16();
     982      194609 :                 hTcxEnc->tcxltp_pitch_fr = pitch_fr_2[i];
     983      194609 :                 move16();
     984      194609 :                 ltp_param[1] = pit_param_2[i];
     985      194609 :                 move16();
     986      194609 :                 norm_corr_fx = norm_corr_2_fx[i];
     987      194609 :                 move16();
     988             :             }
     989             :         }
     990             :         ELSE
     991             :         {
     992             :             Word16 tmp;
     993      236462 :             IF( GT_16( element_mode, EVS_MONO ) )
     994             :             {
     995      236462 :                 tmp = 1;
     996             :             }
     997             :             ELSE
     998             :             {
     999           0 :                 tmp = 0;
    1000             :             }
    1001      236462 :             move16();
    1002      236462 :             tcx_ltp_pitch_search_ivas_fx( Top[1], &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &ltp_param[1], &norm_corr_fx, L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, tmp, &border_case );
    1003             :         }
    1004             : 
    1005      888815 :         if ( border_case )
    1006             :         {
    1007       82639 :             norm_corr_fx = 0;
    1008       82639 :             move16();
    1009             :         }
    1010             : 
    1011             :         // nPrevSubblocks = ( 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
    1012      888815 :         nPrevSubblocks = extract_h( L_add( L_mac( 32768, NSUBBLOCKS, div_s( hTcxEnc->tcxltp_pitch_int, L_frame ) ), 65535 ) ); // 0.5f Q16 //65535( 1.Q16 - 1) added to get the ceil
    1013      888815 :         nPrevSubblocks = add( s_min( nPrevSubblocks, NSUBBLOCKS ), 1 );
    1014             : 
    1015      888815 :         IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
    1016             :         {
    1017       14333 :             tempFlatness_fx = extract_l( L_shr( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14 ) ); // Q7
    1018       14333 :             maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) );            // Q3
    1019             :         }
    1020             :         ELSE
    1021             :         {
    1022      874482 :             tempFlatness_fx = extract_l( L_shr( ( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS, nPrevSubblocks ) ), 14 ) ); // Q7
    1023      874482 :             maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks );                // Q3
    1024             :         }
    1025             : 
    1026             :         /* Switch LTP on */
    1027      888815 :         test();
    1028      888815 :         test();
    1029      888815 :         test();
    1030      888815 :         test();
    1031      888815 :         test();
    1032      888815 :         test();
    1033      888815 :         test();
    1034      888815 :         test();
    1035      888815 :         test();
    1036      888815 :         test();
    1037      888815 :         test();
    1038      888815 :         test();
    1039      888815 :         test();
    1040      888815 :         test();
    1041      888815 :         test();
    1042      888815 :         test();
    1043      888815 :         IF( (
    1044             :                 ( tcxOnly == 0 ) &&
    1045             :                 EQ_16( tcxMode, TCX_20 ) &&
    1046             :                 GT_16( mult( norm_corr_fx, hTcxEnc->tcxltp_norm_corr_past ), 0x2000 ) && /*mult returns Q15*/
    1047             :                 LT_16( tempFlatness_fx, 448 /*3.5f Q7*/ ) ) ||
    1048             :             ( EQ_16( tcxOnly, 1 ) &&
    1049             :               EQ_16( tcxMode, TCX_10 ) &&
    1050             :               GT_16( s_max( norm_corr_fx, hTcxEnc->tcxltp_norm_corr_past ), 0x4000 ) &&
    1051             :               LT_16( maxEnergyChange_fx, 28 /*3.5f Q3*/ ) ) ||
    1052             :             ( /* Use LTP for lower correlation when pitch lag is big, L_frame*(1.2f-norm_corr) < pitch_int <=> norm_corr > 1.2f-pitch_int/L_frame */
    1053             :               EQ_16( tcxOnly, 1 ) &&
    1054             :               GT_16( norm_corr_fx, 14418 /*0.44f Q15*/ ) &&
    1055             :               L_msu( L_mult( L_frame, sub( 19661 /*1.2f Q14*/, shr( norm_corr_fx, 1 ) ) ), hTcxEnc->tcxltp_pitch_int, 1 << 14 ) < 0 /* L_frame*(1.2f-norm_corr) < pitch_int */
    1056             :               ) ||
    1057             :             ( EQ_16( tcxOnly, 1 ) &&
    1058             :               EQ_16( tcxMode, TCX_20 ) &&
    1059             :               GT_16( norm_corr_fx, 14418 /*0.44f Q15*/ ) &&
    1060             :               ( LT_16( tempFlatness_fx, 768 /*6.0f Q7*/ ) ||
    1061             :                 ( LT_16( tempFlatness_fx, 896 /*7.0f Q7*/ ) &&
    1062             :                   LT_16( maxEnergyChange_fx, 176 /*22.0f Q3*/ ) ) ) ) )
    1063             :         {
    1064      543009 :             IF( disable_ltp == 0 )
    1065             :             {
    1066      542953 :                 ltp_param[0] = 1;
    1067      542953 :                 move16();
    1068             :             }
    1069             :         }
    1070             : 
    1071             :         /* hysteresis for stable ltp prediction */
    1072      888815 :         ltp_on = 0;
    1073      888815 :         move16();
    1074             : 
    1075      888815 :         test();
    1076      888815 :         test();
    1077      888815 :         test();
    1078      888815 :         test();
    1079      888815 :         test();
    1080             : 
    1081      888815 :         exponent = 15;
    1082      888815 :         move16();
    1083      888815 :         sqr = Sqrt16( hTcxEnc->tcxltp_on_mem, &exponent );
    1084      888815 :         move16();
    1085      888815 :         IF( ( EQ_16( tcxOnly, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( GT_16( ( mult( sqr, mult( ( norm_corr_fx ), 29492 ) ) ), shr( 14419, exponent ) ) && ( LT_16( tempFlatness_fx, 768 ) || ( LT_16( tempFlatness_fx, 896 ) && LT_16( maxEnergyChange_fx, 176 ) ) ) ) ) ) // 0.9f Q15, 6.0f Q7, 7.0f Q7, 22.0f Q3
    1086             :         {
    1087      421193 :             ltp_on = 1;
    1088      421193 :             move16();
    1089             :         }
    1090             : 
    1091      888815 :         test();
    1092      888815 :         IF( EQ_16( tcxOnly, 1 ) && EQ_16( ltp_param[0], 1 ) )
    1093             :         {
    1094             :             /* increase ltp counter */
    1095      481798 :             hTcxEnc->tcxltp_on_mem = s_min( 5, add( hTcxEnc->tcxltp_on_mem, 1 ) );
    1096      481798 :             move16();
    1097             :         }
    1098      407017 :         ELSE IF( EQ_16( ltp_on, 1 ) )
    1099             :         {
    1100             :             /* hysteresis takes effect, decrease counter */
    1101       46339 :             hTcxEnc->tcxltp_on_mem = s_max( 0, sub( hTcxEnc->tcxltp_on_mem, 1 ) );
    1102       46339 :             move16();
    1103       46339 :             ltp_param[0] = ltp_on;
    1104       46339 :             move16();
    1105             :         }
    1106             :         ELSE
    1107             :         {
    1108             :             /* no ltp in this frame, reset counter */
    1109      360678 :             hTcxEnc->tcxltp_on_mem = 0;
    1110      360678 :             move16();
    1111             :         }
    1112             :     }
    1113             : 
    1114             :     /* Find predicted signal */
    1115      888815 :     predict_signal( speech_fx, pred_speech_fx, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame );
    1116             : 
    1117             :     /* Find gain */
    1118      888815 :     tcx_ltp_find_gain_ivas_fx( speech_fx, pred_speech_fx, L_frame, &hTcxEnc->tcxltp_gain, &ltp_param[2] );
    1119             : 
    1120      888815 :     IF( ltp_param[0] )
    1121             :     {
    1122             :         /* Total number of bits for LTP */
    1123      589292 :         IF( add( ltp_param[2], 1 ) ) /* hTcxEnc->tcxltp_gain > 0 */
    1124             :         {
    1125      589220 :             *ltp_bits = 12;
    1126      589220 :             move16();
    1127             :         }
    1128             :         ELSE /* hTcxEnc->tcxltp_gain <= 0 -> turn off LTP */
    1129             :         {
    1130          72 :             ltp_param[0] = 0;
    1131          72 :             move16();
    1132             :         }
    1133             :     }
    1134             : 
    1135      888815 :     IF( !ltp_param[0] )
    1136             :     {
    1137             :         /* No LTP -> set everything to zero */
    1138      299595 :         hTcxEnc->tcxltp_pitch_int = L_frame;
    1139      299595 :         move16();
    1140      299595 :         hTcxEnc->tcxltp_pitch_fr = 0;
    1141      299595 :         move16();
    1142      299595 :         ltp_param[1] = 0;
    1143      299595 :         move16();
    1144      299595 :         set16_fx( pred_speech_fx, 0, L_frame );
    1145      299595 :         hTcxEnc->tcxltp_gain = 0;
    1146      299595 :         move16();
    1147      299595 :         ltp_param[2] = 0;
    1148      299595 :         move16();
    1149             : 
    1150      299595 :         test();
    1151      299595 :         IF( hTcxEnc->tcxltp || SideInfoOnly )
    1152             :         {
    1153      299595 :             *ltp_bits = 1;
    1154      299595 :             move16();
    1155             :         }
    1156             :         ELSE
    1157             :         {
    1158           0 :             *ltp_bits = 0;
    1159           0 :             move16();
    1160             :         }
    1161             :     }
    1162             : 
    1163      888815 :     si_gain_fx = 0;
    1164      888815 :     move16();
    1165             : 
    1166      888815 :     IF( SideInfoOnly )
    1167             :     {
    1168      426181 :         si_gain_fx = hTcxEnc->tcxltp_gain;
    1169      426181 :         move16();
    1170      426181 :         hTcxEnc->tcxltp_gain = 0;
    1171      426181 :         move16();
    1172             :     }
    1173             : 
    1174      888815 :     IF( speech_ltp_fx != NULL )
    1175             :     {
    1176      222129 :         test();
    1177      222129 :         IF( hTcxEnc->tcxltp_gain_past == 0 && hTcxEnc->tcxltp_gain == 0 )
    1178             :         {
    1179      150844 :             Copy( speech_fx, speech_ltp_fx, L_subfr );
    1180             :         }
    1181       71285 :         ELSE IF( hTcxEnc->tcxltp_gain_past == 0 )
    1182             :         {
    1183       11609 :             alpha_fx = 0;
    1184       11609 :             move16();
    1185             : 
    1186       11609 :             step_fx = shl( 2, norm_s( L_subfr ) );
    1187       11609 :             IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
    1188             :             {
    1189           0 :                 step_fx = mult_r( step_fx, 26214 /*64.f/80.f Q15*/ );
    1190             :             }
    1191             : 
    1192      754585 :             FOR( n = 0; n < L_subfr; n++ )
    1193             :             {
    1194      742976 :                 speech_ltp_fx[n] = sub_sat( speech_fx[n], mult_r_sat( hTcxEnc->tcxltp_gain, mult_r_sat( alpha_fx, pred_speech_fx[n] ) ) );
    1195      742976 :                 move16();
    1196      742976 :                 alpha_fx = add_sat( alpha_fx, step_fx );
    1197             :             }
    1198             :         }
    1199             :         ELSE
    1200             :         {
    1201       59676 :             IF( A_fx == NULL )
    1202             :             {
    1203       59676 :                 tcx_ltp_get_lpc( speech_fx - L_frame, L_frame, Aest_fx, M );
    1204       59676 :                 A_fx = Aest_fx;
    1205             :             }
    1206             : 
    1207       59676 :             IF( hTcxEnc->tcxltp_gain > 0 )
    1208             :             {
    1209       50666 :                 predict_signal( speech_fx - M, buf_zir_fx, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M );
    1210             :             }
    1211             :             ELSE
    1212             :             {
    1213        9010 :                 set16_fx( buf_zir_fx, 0, M );
    1214             :             }
    1215             : 
    1216     1014492 :             FOR( n = 0; n < M; n++ )
    1217             :             {
    1218      954816 :                 buf_zir_fx[n] = add_sat( sub_sat( speech_ltp_fx[n - M], speech_fx[n - M] ), mult_r( hTcxEnc->tcxltp_gain, buf_zir_fx[n] ) );
    1219      954816 :                 move16();
    1220             :             }
    1221             : 
    1222       59676 :             zir_fx = buf_zir_fx + M;
    1223       59676 :             set16_fx( zir_fx, 0, L_subfr );
    1224             : 
    1225       59676 :             Syn_filt_s( 0, A_fx, M, zir_fx, zir_fx, L_subfr, buf_zir_fx, 0 );
    1226             : 
    1227       59676 :             alpha_fx = 0x7FFF; // 1.f Q15
    1228       59676 :             move16();
    1229       59676 :             step_fx = shl( 4, norm_s( L_subfr ) );
    1230       59676 :             IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
    1231             :             {
    1232           0 :                 step_fx = mult_r( step_fx, 26214 /*64.f/80.f Q15*/ );
    1233             :             }
    1234             : 
    1235     1969308 :             FOR( n = L_subfr >> 1; n < L_subfr; n++ )
    1236             :             {
    1237     1909632 :                 zir_fx[n] = mult_r( zir_fx[n], alpha_fx );
    1238     1909632 :                 move16();
    1239     1909632 :                 alpha_fx = sub( alpha_fx, step_fx );
    1240             :             }
    1241             : 
    1242     3878940 :             FOR( n = 0; n < L_subfr; n++ )
    1243             :             {
    1244     3819264 :                 speech_ltp_fx[n] = add_sat( sub_sat( speech_fx[n], mult_r_sat( hTcxEnc->tcxltp_gain, pred_speech_fx[n] ) ), zir_fx[n] );
    1245     3819264 :                 move16();
    1246             :             }
    1247             :         }
    1248             : 
    1249      222129 :         test();
    1250      222129 :         IF( SideInfoOnly || hTcxEnc->tcxltp_gain == 0 )
    1251             :         {
    1252    71975214 :             FOR( n = L_subfr; n < L_frame; n++ )
    1253             :             {
    1254    71815360 :                 speech_ltp_fx[n] = speech_fx[n];
    1255    71815360 :                 move16();
    1256             :             }
    1257             :         }
    1258             :         ELSE
    1259             :         {
    1260    15033027 :             FOR( n = L_subfr; n < L_frame; n++ )
    1261             :             {
    1262    14970752 :                 speech_ltp_fx[n] = sub_sat( speech_fx[n], mult( hTcxEnc->tcxltp_gain, pred_speech_fx[n] ) );
    1263    14970752 :                 move16();
    1264             :             }
    1265             :         }
    1266             :     }
    1267             : 
    1268             :     /* Update */
    1269      888815 :     hTcxEnc->tcxltp_pitch_int_past = hTcxEnc->tcxltp_pitch_int;
    1270      888815 :     move16();
    1271      888815 :     hTcxEnc->tcxltp_pitch_fr_past = hTcxEnc->tcxltp_pitch_fr;
    1272      888815 :     move16();
    1273      888815 :     hTcxEnc->tcxltp_gain_past = hTcxEnc->tcxltp_gain;
    1274      888815 :     move16();
    1275             : 
    1276      888815 :     IF( SideInfoOnly )
    1277             :     {
    1278      426181 :         hTcxEnc->tcxltp_gain = si_gain_fx;
    1279      426181 :         move16();
    1280             :     }
    1281             : 
    1282      888815 :     hTcxEnc->tcxltp_norm_corr_past = norm_corr_fx;
    1283      888815 :     move16();
    1284             : 
    1285      888815 :     return;
    1286             : }

Generated by: LCOV version 1.14