LCOV - code coverage report
Current view: top level - lib_com - tcx_ltp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 707 1156 61.2 %
Date: 2025-10-13 22:24:20 Functions: 11 16 68.8 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"
       6             : #include "prot_fx.h"
       7             : #include "cnst.h"
       8             : #include "basop_util.h"
       9             : #include "rom_com.h"
      10             : 
      11             : /*-------------------------------------------------------------------
      12             :  * Local constants
      13             :  *-------------------------------------------------------------------*/
      14             : 
      15             : #define ALPHA                  27853 /*0.85f Q15*/
      16             : #define MAX_TCX_LTP_FILTER_LEN 8
      17             : #define MAX_TRANSITION_LEN     240 /* L_FRAME_48K / 4 */
      18             : 
      19       59921 : void tcx_ltp_get_lpc(
      20             :     Word16 *x,         /* Qx */
      21             :     const Word16 L,    /* Q0 */
      22             :     Word16 *A,         /* Qx */
      23             :     const Word16 order /* Q0 */
      24             : )
      25             : {
      26             :     Word16 i, j, s, s2, tmp;
      27             :     Word32 r, L_tmp;
      28             : 
      29       59921 :     Word16 tmpbuf[L_FRAME_MAX], *p = x;
      30             :     Word16 r_l[TCXLTP_LTP_ORDER + 1], r_h[TCXLTP_LTP_ORDER + 1];
      31             : 
      32             : 
      33       59921 :     assert( L <= L_FRAME_MAX );
      34             : 
      35             :     /* calc r[0], determine shift */
      36       59921 :     s = 0;
      37       59921 :     move16();
      38       59921 :     r = L_deposit_l( 0 );
      39    18458705 :     FOR( j = 0; j < L; j++ )
      40             :     {
      41    18398784 :         L_tmp = L_sub( r, 0x40000000 /* 1 in Q30 */ ); /* Q30 */
      42    18398784 :         if ( L_tmp > 0 )
      43        5199 :             s = sub( s, 1 );
      44    18398784 :         if ( L_tmp > 0 )
      45        5199 :             r = L_shr( r, 2 );
      46             : 
      47    18398784 :         tmp = shl( x[j], s );          /* Qx + s */
      48    18398784 :         r = L_mac0_sat( r, tmp, tmp ); /* Q30 */
      49             :     }
      50       59921 :     r = L_max( r, L_shl( 100, shl( s, 1 ) ) );   /* Q30 */
      51       59921 :     r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
      52       59921 :     s2 = norm_l( r );
      53       59921 :     r = L_shl( r, s2 );
      54       59921 :     s2 = sub( s2, 1 );
      55       59921 :     r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
      56       59921 :     move16();
      57       59921 :     move16();
      58             : 
      59       59921 :     IF( s < 0 )
      60             :     {
      61             :         /* shift buffer by s, recompute r[0] to reduce risk of instable LPC */
      62        4364 :         r = L_deposit_l( 0 );
      63        4364 :         tmp = lshl( (Word16) 0x8000, s ); /* factor corresponding to right shift by -s */
      64             : 
      65             :         {
      66        4364 :             Word64 r64 = 0;
      67        4364 :             move64();
      68     1519116 :             FOR( j = 0; j < L; j++ )
      69             :             {
      70     1514752 :                 tmpbuf[j] = mult_r( x[j], tmp ); /* Qx */
      71     1514752 :                 move16();
      72     1514752 :                 r64 = W_mac0_16_16( r64, tmpbuf[j], tmpbuf[j] ); /* Q30 */
      73             :             }
      74        4364 :             r = W_sat_l( r64 ); /* Q30 */
      75             :         }
      76        4364 :         r = L_max( r, L_shl( 100, shl( s, 1 ) ) );   /* Q30 */
      77        4364 :         r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
      78        4364 :         s2 = norm_l( r );
      79        4364 :         r = L_shl( r, s2 );
      80        4364 :         s2 = sub( s2, 1 );
      81        4364 :         r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
      82        4364 :         move16();
      83        4364 :         move16();
      84             : 
      85        4364 :         p = tmpbuf;
      86             :     }
      87             : 
      88             :     /* calc r[1...] */
      89     1020617 :     FOR( i = 1; i <= order; i++ )
      90             :     {
      91      960696 :         r = L_deposit_l( 0 );
      92             : 
      93      960696 :         tmp = sub( L, i );
      94             :         {
      95      960696 :             Word64 r64 = 0;
      96      960696 :             move64();
      97   288795324 :             FOR( j = 0; j < tmp; j++ )
      98             :             {
      99   287834628 :                 r64 = W_mac0_16_16( r64, p[j], p[j + i] ); /* Q30 */
     100             :             }
     101      960696 :             r = W_sat_l( r64 );
     102             :         }
     103      960696 :         r = L_shl( r, s2 );
     104      960696 :         r_l[i] = L_Extract_lc( r, &r_h[i] ); /* Q14 */
     105      960696 :         move16();
     106      960696 :         move16();
     107             :     }
     108             : 
     109       59921 :     E_LPC_lev_dur( r_h, r_l, A, NULL, order, NULL );
     110       59921 : }
     111             : 
     112           0 : void tcx_ltp_get_lpc_fx(
     113             :     Word32 *x,         /* Qx */
     114             :     const Word16 L,    /* Q0 */
     115             :     Word32 *A,         /* Qx */
     116             :     const Word16 order /* Q0 */
     117             : )
     118             : {
     119             :     Word16 i, j, s, s2;
     120             :     Word32 r, tmp, L_tmp;
     121             : 
     122           0 :     Word32 tmpbuf[L_FRAME_MAX], *p = x;
     123             :     Word16 r_l[TCXLTP_LTP_ORDER + 1], r_h[TCXLTP_LTP_ORDER + 1];
     124             : 
     125             : 
     126           0 :     assert( L <= L_FRAME_MAX );
     127             : 
     128             :     /* calc r[0], determine shift */
     129           0 :     s = 0;
     130           0 :     move16();
     131           0 :     r = L_deposit_l( 0 );
     132           0 :     FOR( j = 0; j < L; j++ )
     133             :     {
     134           0 :         L_tmp = L_sub( r, 0x40000000 /* 1 in Q30 */ ); /* Q30 */
     135           0 :         if ( L_tmp > 0 )
     136           0 :             s = sub( s, 1 );
     137           0 :         if ( L_tmp > 0 )
     138           0 :             r = L_shr( r, 2 );
     139             : 
     140           0 :         tmp = L_shl( x[j], s ); /* Qx + s */
     141           0 :         r = Madd_32_32( r, tmp, tmp );
     142             :     }
     143           0 :     r = L_max( r, L_shl( 100, shl( s, 1 ) ) );   /* Q30 */
     144           0 :     r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
     145           0 :     s2 = norm_l( r );
     146           0 :     r = L_shl( r, s2 );
     147           0 :     s2 = sub( s2, 1 );
     148           0 :     r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
     149           0 :     move16();
     150           0 :     move16();
     151             : 
     152           0 :     IF( s < 0 )
     153             :     {
     154             :         /* shift buffer by s, recompute r[0] to reduce risk of instable LPC */
     155           0 :         r = L_deposit_l( 0 );
     156           0 :         tmp = lshl( (Word16) 0x8000, s ); /* factor corresponding to right shift by -s */
     157             : 
     158             :         {
     159           0 :             Word64 r64 = 0;
     160           0 :             move64();
     161           0 :             FOR( j = 0; j < L; j++ )
     162             :             {
     163           0 :                 tmpbuf[j] = Mpy_32_32( x[j], tmp );
     164           0 :                 move32();
     165           0 :                 r64 = W_add( r64, W_mult0_32_32( tmpbuf[j], tmpbuf[j] ) );
     166             :             }
     167           0 :             r = W_sat_l( r64 );
     168             :         }
     169           0 :         r = L_max( r, L_shl( 100, shl( s, 1 ) ) );   /* Q30 */
     170           0 :         r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
     171           0 :         s2 = norm_l( r );
     172           0 :         r = L_shl( r, s2 );
     173           0 :         s2 = sub( s2, 1 );
     174           0 :         r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
     175           0 :         move16();
     176           0 :         move16();
     177             : 
     178           0 :         p = tmpbuf;
     179             :     }
     180             : 
     181             :     /* calc r[1...] */
     182           0 :     FOR( i = 1; i <= order; i++ )
     183             :     {
     184           0 :         r = L_deposit_l( 0 );
     185             : 
     186           0 :         tmp = sub( L, i );
     187             :         {
     188           0 :             Word64 r64 = 0;
     189           0 :             move64();
     190           0 :             FOR( j = 0; j < tmp; j++ )
     191             :             {
     192           0 :                 r64 = W_add( r64, Mpy_32_32( p[j], p[j + i] ) ); /* Q30 */
     193             :             }
     194           0 :             r = W_sat_l( r64 );
     195             :         }
     196           0 :         r = L_shl( r, s2 );
     197           0 :         r_l[i] = L_Extract_lc( r, &r_h[i] ); /* Q14 */
     198           0 :         move16();
     199           0 :         move16();
     200             :     }
     201             : 
     202           0 :     E_LPC_lev_dur_fx( r_h, r_l, A, NULL, order, NULL );
     203           0 : }
     204             : 
     205         245 : static void tcx_ltp_get_zir(
     206             :     Word16 *zir,            /* Qx */
     207             :     const Word16 length,    /* Q0 */
     208             :     Word16 *synth_ltp,      /* Qx */
     209             :     Word16 *synth,          /* Qx */
     210             :     Word16 *A,              /* Qx */
     211             :     const Word16 lpcorder,  /* Q0 */
     212             :     const Word16 gain,      /* Q15 */
     213             :     const Word16 pitch_int, /* Q0 */
     214             :     const Word16 pitch_fr,  /* Q0 */
     215             :     const Word16 pitres,    /* Q0 */
     216             :     const Word16 filtIdx    /* Q0 */
     217             : )
     218             : {
     219             :     Word16 buf[TCXLTP_LTP_ORDER], alpha, step;
     220             :     Word16 *x0, *x1;
     221             :     Word16 *y0, *y1;
     222             :     Word32 s, s2;
     223             :     const Word16 *w0, *w1, *v0, *v1;
     224             :     Word16 i, j, k, L;
     225             : 
     226         245 :     x0 = &synth_ltp[-pitch_int]; /* Qx */
     227         245 :     x1 = x0 - 1;
     228         245 :     y0 = synth; /* Qx */
     229         245 :     y1 = y0 - 1;
     230             : 
     231         245 :     assert( filtIdx >= 0 );
     232             : 
     233         245 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];          /* Q15 */
     234         245 :     w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr]; /* Q15 */
     235         245 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                 /* Q15 */
     236         245 :     v1 = &tcxLtpFilters[filtIdx].filt[pitres];            /* Q15 */
     237         245 :     L = tcxLtpFilters[filtIdx].length;                    /* Q0 */
     238         245 :     move16();
     239             : 
     240        6125 :     FOR( j = 0; j < lpcorder; j++ )
     241             :     {
     242        5880 :         s = L_deposit_l( 0 );
     243        5880 :         s2 = L_deposit_l( 0 );
     244        5880 :         k = 0;
     245        5880 :         move16();
     246       38928 :         FOR( i = 0; i < L; i++ )
     247             :         {
     248       33048 :             s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     249       33048 :             s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     250       33048 :             k = k + pitres;
     251             :         }
     252             : 
     253             :         /* s2 *= ALPHA;
     254             :            buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */
     255        5880 :         i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) );
     256        5880 :         buf[j] = add_sat( sub_sat( synth[j], synth_ltp[j] ), mult_r_sat( gain, i ) ); /* Qx */
     257        5880 :         move16();
     258             : 
     259        5880 :         x0++;
     260        5880 :         x1++;
     261        5880 :         y0++;
     262        5880 :         y1++;
     263             :     }
     264             : 
     265         245 :     set16_fx( zir, 0, length );
     266             : 
     267         245 :     E_UTIL_synthesis( 0, A, zir, zir, length, buf, 0, lpcorder );
     268             : 
     269         245 :     alpha = 0x7FFF; /* 1 in Q15 */
     270         245 :     move16();
     271             :     /* step = 1.f/(float)(length/2); */
     272         245 :     step = shl( 4, norm_s( length ) );
     273         245 :     if ( s_and( length, sub( length, 1 ) ) != 0 )
     274             :     {
     275         245 :         step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
     276             :     }
     277         245 :     if ( EQ_16( length, 240 ) )
     278             :     {
     279         152 :         step = 273 /*1.f/120.f Q15*/;
     280         152 :         move16();
     281             :     }
     282             : 
     283       25925 :     FOR( j = length / 2; j < length; j++ )
     284             :     {
     285       25680 :         zir[j] = mult_r( zir[j], alpha ); /* Qx */
     286       25680 :         move16();
     287       25680 :         alpha = sub( alpha, step );
     288             :     }
     289         245 : }
     290             : 
     291           0 : static void tcx_ltp_get_zir_fx(
     292             :     Word32 *zir,            /* Qx */
     293             :     const Word16 length,    /* Q0 */
     294             :     Word32 *synth_ltp,      /* Qx */
     295             :     Word32 *synth,          /* Qx */
     296             :     Word32 *A,              /* Qx */
     297             :     const Word16 lpcorder,  /* Q0 */
     298             :     const Word16 gain,      /* Q15 */
     299             :     const Word16 pitch_int, /* Q0 */
     300             :     const Word16 pitch_fr,  /* Q0 */
     301             :     const Word16 pitres,    /* Q0 */
     302             :     const Word16 filtIdx    /* Q0 */
     303             : )
     304             : {
     305             :     Word32 buf[TCXLTP_LTP_ORDER];
     306             :     Word16 alpha, step;
     307             :     Word32 *x0, *x1;
     308             :     Word32 *y0, *y1;
     309             :     Word32 s, s2;
     310             :     const Word16 *w0, *w1, *v0, *v1;
     311             :     Word32 i;
     312             :     Word16 j, k, L;
     313             : 
     314           0 :     x0 = &synth_ltp[-pitch_int]; /* Qx */
     315           0 :     x1 = x0 - 1;
     316           0 :     y0 = synth; /* Qx */
     317           0 :     y1 = y0 - 1;
     318             : 
     319           0 :     assert( filtIdx >= 0 );
     320             : 
     321           0 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];          /* Q15 */
     322           0 :     w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr]; /* Q15 */
     323           0 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                 /* Q15 */
     324           0 :     v1 = &tcxLtpFilters[filtIdx].filt[pitres];            /* Q15 */
     325           0 :     L = tcxLtpFilters[filtIdx].length;                    /* Q0 */
     326           0 :     move16();
     327             : 
     328           0 :     FOR( j = 0; j < lpcorder; j++ )
     329             :     {
     330           0 :         s = L_deposit_l( 0 );
     331           0 :         s2 = L_deposit_l( 0 );
     332           0 :         k = 0;
     333           0 :         move16();
     334           0 :         FOR( i = 0; i < L; i++ )
     335             :         {
     336           0 :             s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     337           0 :             s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     338           0 :             k = k + pitres;
     339             :         }
     340             : 
     341             :         /* s2 *= ALPHA;
     342             :            buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */
     343           0 :         i = L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) );                                      /* Qx */
     344           0 :         buf[j] = L_add_sat( L_sub_sat( synth[j], synth_ltp[j] ), Mpy_32_16_1( i, gain ) ); /* Qx */
     345             : 
     346           0 :         move16();
     347             : 
     348           0 :         x0++;
     349           0 :         x1++;
     350           0 :         y0++;
     351           0 :         y1++;
     352             :     }
     353             : 
     354           0 :     set32_fx( zir, 0, length );
     355             : 
     356           0 :     E_UTIL_synthesis_fx( 0, A, zir, zir, length, buf, 0, lpcorder );
     357             : 
     358           0 :     alpha = 0x7FFF; /* 1 in Q15 */
     359           0 :     move16();
     360             :     /* step = 1.f/(float)(length/2); */
     361           0 :     step = shl( 4, norm_s( length ) );
     362           0 :     if ( s_and( length, sub( length, 1 ) ) != 0 )
     363             :     {
     364           0 :         step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
     365             :     }
     366           0 :     if ( EQ_16( length, 240 ) )
     367             :     {
     368           0 :         step = 273 /*1.f/120.f Q15*/;
     369           0 :         move16();
     370             :     }
     371             : 
     372           0 :     FOR( j = shr( length, 1 ); j < length; j++ )
     373             :     {
     374           0 :         zir[j] = Mpy_32_16_r( zir[j], alpha ); /* Qx */
     375           0 :         move32();
     376           0 :         alpha = sub( alpha, step );
     377             :     }
     378           0 : }
     379             : 
     380      940835 : void predict_signal(
     381             :     const Word16 excI[],   /* i  : input excitation buffer  Qx*/
     382             :     Word16 excO[],         /* o  : output excitation buffer Qx*/
     383             :     const Word16 T0,       /* i  : integer pitch lag        Q0*/
     384             :     Word16 frac,           /* i  : fraction of lag          Q0*/
     385             :     const Word16 frac_max, /* i  : max fraction             Q0*/
     386             :     const Word16 L_subfr   /* i  : subframe size            Q0*/
     387             : )
     388             : {
     389             :     Word16 j;
     390             :     Word32 s;
     391             :     const Word16 *x0, *win;
     392             : #ifndef ISSUE_1836_replace_overflow_libcom
     393             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     394             :     Flag Overflow = 0;
     395             :     move32();
     396             : #endif
     397             : #endif
     398      940835 :     x0 = &excI[-T0 - 1];
     399      940835 :     frac = negate( frac );
     400             : 
     401      940835 :     IF( frac < 0 )
     402             :     {
     403      464636 :         frac = add( frac, frac_max );
     404      464636 :         x0--;
     405             :     }
     406             : 
     407      940835 :     win = &inter4_2tcx2[frac][0]; /* Q15 */
     408      940835 :     if ( EQ_16( frac_max, 6 ) )
     409      201657 :         win = &inter6_2tcx2[frac][0]; /* Q15 */
     410             : 
     411   274334771 :     FOR( j = 0; j < L_subfr; j++ )
     412             :     {
     413             : #ifdef ISSUE_1836_replace_overflow_libcom
     414   273393936 :         s = L_mult_sat( win[0], x0[0] );         /* Qx + 16 */
     415   273393936 :         s = L_mac_sat( s, win[1], x0[1] );       /* Qx + 16 */
     416   273393936 :         s = L_mac_sat( s, win[2], x0[2] );       /* Qx + 16 */
     417   273393936 :         excO[j] = mac_r_sat( s, win[3], x0[3] ); /* Qx + 16 */
     418             : #else
     419             :         s = L_mult_o( win[0], x0[0], &Overflow );        /* Qx + 16 */
     420             :         s = L_mac_o( s, win[1], x0[1], &Overflow );      /* Qx + 16 */
     421             :         s = L_mac_o( s, win[2], x0[2], &Overflow );      /* Qx + 16 */
     422             :         excO[j] = mac_ro( s, win[3], x0[3], &Overflow ); /* Qx + 16 */
     423             : #endif
     424   273393936 :         move16();
     425             : 
     426   273393936 :         x0++;
     427             :     }
     428      940835 : }
     429             : 
     430        6736 : static void tcx_ltp_synth_filter(
     431             :     Word16 *synth_ltp, /* Qx */
     432             :     Word16 *synth,     /* Qx */
     433             :     Word16 length,     /* Q0 */
     434             :     Word16 pitch_int,  /* Q0 */
     435             :     Word16 pitch_fr,   /* Q0 */
     436             :     Word16 gain,       /* Q15 */
     437             :     Word16 pitch_res,  /* Q0 */
     438             :     Word16 *zir,       /* can be NULL */
     439             :     Word16 fade,       /* 0=normal, +1=fade-in, -1=fade-out     Q0*/
     440             :     Word16 filtIdx     /* Q0 */
     441             : )
     442             : {
     443             :     Word16 *x0, *x1;
     444             :     Word16 *y0, *y1;
     445             :     Word32 s, s2;
     446             :     const Word16 *v0, *v1;
     447             :     const Word16 *w0, *w1;
     448        6736 :     Word16 alpha, step = 0; /* initialize just to avoid compiler warning */
     449        6736 :     move16();
     450             :     Word16 i, j, k, L;
     451             : 
     452        6736 :     IF( gain > 0 )
     453             :     {
     454        1440 :         x0 = &synth_ltp[-pitch_int]; /* Qx */
     455        1440 :         x1 = x0 - 1;
     456        1440 :         y0 = synth; /* Qx */
     457        1440 :         y1 = y0 - 1;
     458             : 
     459        1440 :         assert( filtIdx >= 0 );
     460             : 
     461        1440 :         w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
     462        1440 :         w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
     463        1440 :         v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
     464        1440 :         v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
     465             : 
     466        1440 :         L = tcxLtpFilters[filtIdx].length; /* Q0 */
     467        1440 :         move16();
     468             : 
     469        1440 :         alpha = 0;
     470        1440 :         move16();
     471        1440 :         IF( fade != 0 )
     472             :         {
     473         168 :             if ( fade < 0 )
     474             :             {
     475          84 :                 alpha = 0x7FFF; /* 1 in Q15 */
     476          84 :                 move16();
     477             :             }
     478             : 
     479             :             /* step = 1.f/(float)(length); */
     480         168 :             step = shl( 2, norm_s( length ) );
     481         168 :             if ( s_and( length, sub( length, 1 ) ) != 0 )
     482             :             {
     483         168 :                 step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
     484             :             }
     485         168 :             if ( EQ_16( length, 240 ) )
     486             :             {
     487          94 :                 step = 137 /*1.f/240.f Q15*/;
     488          94 :                 move16();
     489             :             }
     490             : 
     491         168 :             if ( fade < 0 )
     492          84 :                 step = negate( step );
     493             :         }
     494             : 
     495             : #ifdef OPT_TCXLTP_FILTER_LOOP
     496        1440 :         IF( zir != NULL )
     497             :         {
     498         245 :             IF( fade != 0 )
     499             :             {
     500           0 :                 FOR( j = 0; j < length; j++ )
     501             :                 {
     502           0 :                     s = L_deposit_l( 0 );
     503           0 :                     s2 = L_deposit_l( 0 );
     504           0 :                     k = 0;
     505           0 :                     move16();
     506           0 :                     FOR( i = 0; i < L; i++ )
     507             :                     {
     508           0 :                         s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     509           0 :                         s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     510           0 :                         k = k + pitch_res;
     511             :                     }
     512             : 
     513             :                     /* s2 *= ALPHA;
     514             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     515             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     516             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     517           0 :                     i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
     518           0 :                     k = mult_r( gain, i );                                                     /* Qx */
     519           0 :                     k = mult_r( k, alpha );                                                    /* Qx */
     520           0 :                     k = add_sat( synth[j], k );                                                /* Qx */
     521           0 :                     k = sub_sat( k, zir[j] );                                                  /* Qx */
     522             : 
     523           0 :                     synth_ltp[j] = k; /* Qx */
     524           0 :                     move16();
     525             : 
     526             :                     BASOP_SATURATE_WARNING_OFF_EVS;
     527           0 :                     alpha = add_sat( alpha, step );
     528             :                     BASOP_SATURATE_WARNING_ON_EVS;
     529             : 
     530           0 :                     x0++;
     531           0 :                     x1++;
     532           0 :                     y0++;
     533           0 :                     y1++;
     534             :                 }
     535             :             }
     536             :             ELSE
     537             :             {
     538       51605 :                 FOR( j = 0; j < length; j++ )
     539             :                 {
     540       51360 :                     s = L_deposit_l( 0 );
     541       51360 :                     s2 = L_deposit_l( 0 );
     542       51360 :                     k = 0;
     543       51360 :                     move16();
     544      344640 :                     FOR( i = 0; i < L; i++ )
     545             :                     {
     546      293280 :                         s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     547      293280 :                         s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     548      293280 :                         k = k + pitch_res;
     549             :                     }
     550             : 
     551             :                     /* s2 *= ALPHA;
     552             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     553             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     554             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     555       51360 :                     i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
     556       51360 :                     k = mult_r( gain, i );                                                     /* Qx */
     557       51360 :                     k = add_sat( synth[j], k );                                                /* Qx */
     558       51360 :                     k = sub_sat( k, zir[j] );                                                  /* Qx */
     559             : 
     560       51360 :                     synth_ltp[j] = k; /* Qx */
     561       51360 :                     move16();
     562             : 
     563       51360 :                     x0++;
     564       51360 :                     x1++;
     565       51360 :                     y0++;
     566       51360 :                     y1++;
     567             :                 }
     568             :             }
     569             :         }
     570             :         ELSE
     571             :         {
     572        1195 :             IF( fade != 0 )
     573             :             {
     574       34568 :                 FOR( j = 0; j < length; j++ )
     575             :                 {
     576       34400 :                     s = L_deposit_l( 0 );
     577       34400 :                     s2 = L_deposit_l( 0 );
     578       34400 :                     k = 0;
     579       34400 :                     move16();
     580      228960 :                     FOR( i = 0; i < L; i++ )
     581             :                     {
     582      194560 :                         s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     583      194560 :                         s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     584      194560 :                         k = k + pitch_res;
     585             :                     }
     586             : 
     587             :                     /* s2 *= ALPHA;
     588             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     589             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     590             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     591       34400 :                     i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
     592       34400 :                     k = mult_r( gain, i );                                                     /* Qx */
     593       34400 :                     k = mult_r( k, alpha );
     594       34400 :                     k = add_sat( synth[j], k ); /* Qx */
     595             : 
     596       34400 :                     synth_ltp[j] = k; /* Qx */
     597       34400 :                     move16();
     598             : 
     599             :                     BASOP_SATURATE_WARNING_OFF_EVS;
     600       34400 :                     alpha = add_sat( alpha, step );
     601             :                     BASOP_SATURATE_WARNING_ON_EVS;
     602             : 
     603       34400 :                     x0++;
     604       34400 :                     x1++;
     605       34400 :                     y0++;
     606       34400 :                     y1++;
     607             :                 }
     608             :             }
     609             :             ELSE
     610             :             {
     611      294701 :                 FOR( j = 0; j < length; j++ )
     612             :                 {
     613      293674 :                     s = L_deposit_l( 0 );
     614      293674 :                     s2 = L_deposit_l( 0 );
     615      293674 :                     k = 0;
     616      293674 :                     move16();
     617     1952262 :                     FOR( i = 0; i < L; i++ )
     618             :                     {
     619     1658588 :                         s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     620     1658588 :                         s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     621     1658588 :                         k = k + pitch_res;
     622             :                     }
     623             : 
     624             :                     /* s2 *= ALPHA;
     625             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     626             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     627             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     628      293674 :                     i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
     629      293674 :                     k = mult_r( gain, i );                                                     /* Qx */
     630      293674 :                     k = add_sat( synth[j], k );                                                /* Qx */
     631             : 
     632      293674 :                     synth_ltp[j] = k; /* Qx */
     633      293674 :                     move16();
     634             : 
     635             : 
     636      293674 :                     x0++;
     637      293674 :                     x1++;
     638      293674 :                     y0++;
     639      293674 :                     y1++;
     640             :                 }
     641             :             }
     642             :         }
     643             : #else
     644             :         FOR( j = 0; j < length; j++ )
     645             :         {
     646             :             s = L_deposit_l( 0 );
     647             :             s2 = L_deposit_l( 0 );
     648             :             k = 0;
     649             :             move16();
     650             :             FOR( i = 0; i < L; i++ )
     651             :             {
     652             :                 s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
     653             :                 s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
     654             :                 k = k + pitch_res;
     655             :             }
     656             : 
     657             :             /* s2 *= ALPHA;
     658             :                normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     659             :                zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     660             :                fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     661             :             i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
     662             :             k = mult_r( gain, i );                                                     /* Qx */
     663             :             if ( fade != 0 )
     664             :                 k = mult_r( k, alpha ); /* Qx */
     665             :             k = add_sat( synth[j], k ); /* Qx */
     666             :             if ( zir != NULL )
     667             :             {
     668             :                 k = sub_sat( k, zir[j] ); /* Qx */
     669             :             }
     670             : 
     671             :             synth_ltp[j] = k; /* Qx */
     672             :             move16();
     673             : 
     674             :             BASOP_SATURATE_WARNING_OFF_EVS;
     675             :             if ( fade != 0 )
     676             :             {
     677             :                 alpha = add_sat( alpha, step );
     678             :             }
     679             :             BASOP_SATURATE_WARNING_ON_EVS;
     680             : 
     681             :             x0++;
     682             :             x1++;
     683             :             y0++;
     684             :             y1++;
     685             :         }
     686             : #endif
     687             :     }
     688             :     ELSE
     689             :     {
     690        5296 :         Copy( synth, synth_ltp, length ); /* Qx */
     691             :     }
     692        6736 : }
     693             : 
     694     2270942 : static void tcx_ltp_synth_filter32(
     695             :     Word32 *synth_ltp, /* Qx */
     696             :     Word32 *synth,     /* Qx */
     697             :     Word16 length,     /* Q0 */
     698             :     Word16 pitch_int,  /* Q0 */
     699             :     Word16 pitch_fr,   /* Q0 */
     700             :     Word16 gain,       /* Q15 */
     701             :     Word16 pitch_res,  /* Q0 */
     702             :     Word32 *zir,       /* can be NULL   Qx*/
     703             :     Word16 fade,       /* 0=normal, +1=fade-in, -1=fade-out     Q0*/
     704             :     Word16 filtIdx     /* Q0 */
     705             : )
     706             : {
     707             :     Word32 *x0, *x1;
     708             :     Word32 *y0, *y1;
     709             :     Word32 s, s2;
     710             :     const Word16 *v0, *v1;
     711             :     const Word16 *w0, *w1;
     712     2270942 :     Word16 alpha, step = 0; /* initialize just to avoid compiler warning */
     713             :     Word16 i, j, k, L;
     714             :     Word32 L_tmp, L_tmp2;
     715             : 
     716     2270942 :     IF( gain > 0 )
     717             :     {
     718      364994 :         x0 = &synth_ltp[-pitch_int]; /* Qx */
     719      364994 :         x1 = x0 - 1;
     720      364994 :         y0 = synth; /* Qx */
     721      364994 :         y1 = y0 - 1;
     722             : 
     723      364994 :         assert( filtIdx >= 0 );
     724             : 
     725      364994 :         w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
     726      364994 :         w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
     727      364994 :         v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
     728      364994 :         v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
     729             : 
     730      364994 :         L = tcxLtpFilters[filtIdx].length; /* Q0 */
     731      364994 :         move16();
     732      364994 :         alpha = 0;
     733      364994 :         move16();
     734      364994 :         IF( fade != 0 )
     735             :         {
     736           0 :             if ( fade < 0 )
     737             :             {
     738           0 :                 alpha = 0x7FFF; /* 1 in Q15 */
     739           0 :                 move16();
     740             :             }
     741             : 
     742             :             /* step = 1.f/(float)(length); */
     743           0 :             step = shl( 2, norm_s( length ) );
     744           0 :             if ( s_and( length, sub( length, 1 ) ) != 0 )
     745             :             {
     746           0 :                 step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
     747             :             }
     748           0 :             if ( EQ_16( length, 240 ) )
     749             :             {
     750           0 :                 step = 137 /*1.f/240.f Q15*/;
     751           0 :                 move16();
     752             :             }
     753             : 
     754           0 :             if ( fade < 0 )
     755           0 :                 step = negate( step );
     756             :         }
     757             : 
     758             : #ifdef OPT_TCXLTP_FILTER_LOOP
     759      364994 :         IF( fade != 0 )
     760             :         {
     761           0 :             IF( zir != NULL )
     762             :             {
     763           0 :                 FOR( j = 0; j < length; j++ )
     764             :                 {
     765           0 :                     s = L_deposit_l( 0 );
     766           0 :                     s2 = L_deposit_l( 0 );
     767           0 :                     k = 0;
     768           0 :                     move16();
     769           0 :                     FOR( i = 0; i < L; i++ )
     770             :                     {
     771           0 :                         s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     772           0 :                         s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     773           0 :                         k = k + pitch_res;
     774             :                     }
     775             : 
     776             :                     /* s2 *= ALPHA;
     777             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     778             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     779             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     780           0 :                     L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
     781           0 :                     L_tmp2 = Mpy_32_16_r( L_tmp, gain );              /* Qx */
     782           0 :                     L_tmp2 = Mpy_32_16_r( L_tmp2, alpha );            /* Qx */
     783           0 :                     L_tmp2 = L_sub_sat( L_tmp2, zir[j] );             /* Qx */
     784           0 :                     L_tmp2 = L_add_sat( synth[j], L_tmp2 );           /* Qx */
     785             : 
     786           0 :                     synth_ltp[j] = L_tmp2; /* Qx */
     787           0 :                     move16();
     788             : 
     789             :                     BASOP_SATURATE_WARNING_OFF_EVS;
     790           0 :                     alpha = add_sat( alpha, step );
     791             :                     BASOP_SATURATE_WARNING_ON_EVS;
     792             : 
     793           0 :                     x0++;
     794           0 :                     x1++;
     795           0 :                     y0++;
     796           0 :                     y1++;
     797             :                 }
     798             :             }
     799             :             ELSE
     800             :             {
     801           0 :                 FOR( j = 0; j < length; j++ )
     802             :                 {
     803           0 :                     s = L_deposit_l( 0 );
     804           0 :                     s2 = L_deposit_l( 0 );
     805           0 :                     k = 0;
     806           0 :                     move16();
     807           0 :                     FOR( i = 0; i < L; i++ )
     808             :                     {
     809           0 :                         s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     810           0 :                         s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     811           0 :                         k = k + pitch_res;
     812             :                     }
     813             : 
     814             :                     /* s2 *= ALPHA;
     815             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     816             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     817             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     818           0 :                     L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
     819           0 :                     L_tmp2 = Mpy_32_16_r( L_tmp, gain );              /* Qx */
     820           0 :                     L_tmp2 = Mpy_32_16_r( L_tmp2, alpha );            /* Qx */
     821           0 :                     L_tmp2 = L_add_sat( synth[j], L_tmp2 );           /* Qx */
     822             : 
     823           0 :                     synth_ltp[j] = L_tmp2; /* Qx */
     824           0 :                     move16();
     825             : 
     826             :                     BASOP_SATURATE_WARNING_OFF_EVS;
     827           0 :                     alpha = add_sat( alpha, step );
     828             :                     BASOP_SATURATE_WARNING_ON_EVS;
     829             : 
     830           0 :                     x0++;
     831           0 :                     x1++;
     832           0 :                     y0++;
     833           0 :                     y1++;
     834             :                 }
     835             :             }
     836             :         }
     837             :         ELSE
     838             :         {
     839      364994 :             IF( zir != NULL )
     840             :             {
     841           0 :                 FOR( j = 0; j < length; j++ )
     842             :                 {
     843           0 :                     s = L_deposit_l( 0 );
     844           0 :                     s2 = L_deposit_l( 0 );
     845           0 :                     k = 0;
     846           0 :                     move16();
     847           0 :                     FOR( i = 0; i < L; i++ )
     848             :                     {
     849           0 :                         s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     850           0 :                         s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     851           0 :                         k = k + pitch_res;
     852             :                     }
     853             : 
     854             :                     /* s2 *= ALPHA;
     855             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     856             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     857             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     858           0 :                     L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
     859           0 :                     L_tmp2 = Mpy_32_16_r( L_tmp, gain );              /* Qx */
     860           0 :                     L_tmp2 = L_sub_sat( L_tmp2, zir[j] );             /* Qx */
     861           0 :                     L_tmp2 = L_add_sat( synth[j], L_tmp2 );           /* Qx */
     862             : 
     863           0 :                     synth_ltp[j] = L_tmp2; /* Qx */
     864           0 :                     move16();
     865             : 
     866           0 :                     x0++;
     867           0 :                     x1++;
     868           0 :                     y0++;
     869           0 :                     y1++;
     870             :                 }
     871             :             }
     872             :             ELSE
     873             :             {
     874   108260784 :                 FOR( j = 0; j < length; j++ )
     875             :                 {
     876   107895790 :                     s = L_deposit_l( 0 );
     877   107895790 :                     s2 = L_deposit_l( 0 );
     878   107895790 :                     k = 0;
     879   107895790 :                     move16();
     880   837594220 :                     FOR( i = 0; i < L; i++ )
     881             :                     {
     882   729698430 :                         s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     883   729698430 :                         s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     884   729698430 :                         k = k + pitch_res;
     885             :                     }
     886             : 
     887             :                     /* s2 *= ALPHA;
     888             :                        normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     889             :                        zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     890             :                        fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     891   107895790 :                     L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
     892   107895790 :                     L_tmp2 = Mpy_32_16_r( L_tmp, gain );              /* Qx */
     893   107895790 :                     L_tmp2 = L_add_sat( synth[j], L_tmp2 );           /* Qx */
     894             : 
     895   107895790 :                     synth_ltp[j] = L_tmp2; /* Qx */
     896   107895790 :                     move16();
     897             : 
     898   107895790 :                     x0++;
     899   107895790 :                     x1++;
     900   107895790 :                     y0++;
     901   107895790 :                     y1++;
     902             :                 }
     903             :             }
     904             :         }
     905             : #else
     906             :         FOR( j = 0; j < length; j++ )
     907             :         {
     908             :             s = L_deposit_l( 0 );
     909             :             s2 = L_deposit_l( 0 );
     910             :             k = 0;
     911             :             move16();
     912             :             FOR( i = 0; i < L; i++ )
     913             :             {
     914             :                 s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
     915             :                 s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
     916             :                 k = k + pitch_res;
     917             :             }
     918             : 
     919             :             /* s2 *= ALPHA;
     920             :                normal:      synth_ltp[j] = synth[j] - gain * s2 + gain * s;
     921             :                zir:         synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
     922             :                fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
     923             :             L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
     924             :             L_tmp2 = Mpy_32_16_r( L_tmp, gain );              /* Qx */
     925             :             IF( fade != 0 )
     926             :             L_tmp2 = Mpy_32_16_r( L_tmp2, alpha );  /* Qx */
     927             :             L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
     928             :             if ( zir != NULL )
     929             :             {
     930             :                 L_tmp2 = L_sub_sat( L_tmp2, zir[j] ); /* Qx */
     931             :             }
     932             : 
     933             :             synth_ltp[j] = L_tmp2; /* Qx */
     934             :             move16();
     935             : 
     936             :             BASOP_SATURATE_WARNING_OFF_EVS;
     937             :             if ( fade != 0 )
     938             :             {
     939             :                 alpha = add_sat( alpha, step );
     940             :             }
     941             :             BASOP_SATURATE_WARNING_ON_EVS;
     942             : 
     943             :             x0++;
     944             :             x1++;
     945             :             y0++;
     946             :             y1++;
     947             :         }
     948             : #endif
     949             :     }
     950             :     ELSE
     951             :     {
     952     1905948 :         Copy32( synth, synth_ltp, length ); /* Qx */
     953             :     }
     954     2270942 : }
     955             : 
     956           0 : static void tcx_ltp_synth_filter_10(
     957             :     Word16 *out,            /* Qx */
     958             :     Word16 *in,             /* Qx */
     959             :     const Word16 length,    /* Q0 */
     960             :     const Word16 pitch_int, /* Q0 */
     961             :     const Word16 pitch_fr,  /* Q0 */
     962             :     const Word16 gain,      /* Q15 */
     963             :     const Word16 pitch_res, /* Q0 */
     964             :     const Word16 filtIdx    /* Q0 */
     965             : )
     966             : {
     967             :     Word16 *x0, *x1;
     968             :     Word16 *y0, *y1;
     969             :     Word32 s, s2;
     970             :     const Word16 *v0, *v1;
     971             :     const Word16 *w0, *w1;
     972             :     Word16 i, j, k, L;
     973             :     Word16 curr_gain, gain_step;
     974             : 
     975           0 :     x0 = &out[-pitch_int]; /* Qx */
     976           0 :     x1 = x0 - 1;
     977           0 :     y0 = in; /* Qx */
     978           0 :     y1 = y0 - 1;
     979             : 
     980           0 :     assert( GE_16( filtIdx, 0 ) );
     981             : 
     982           0 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
     983           0 :     w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
     984           0 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
     985           0 :     v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
     986           0 :     L = tcxLtpFilters[filtIdx].length;                       /* Q0 */
     987             : 
     988           0 :     curr_gain = gain;
     989           0 :     move16();
     990             : 
     991           0 :     gain_step = div_s( negate( gain ), length ); /* Q15 */
     992             : 
     993           0 :     FOR( j = 0; j < length; j++ )
     994             :     {
     995           0 :         s = 0;
     996           0 :         s2 = 0;
     997           0 :         move32();
     998           0 :         move32();
     999           0 :         k = 0;
    1000           0 :         move16();
    1001           0 :         FOR( i = 0; i < L; i++ )
    1002             :         {
    1003           0 :             s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
    1004           0 :             s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
    1005           0 :             k = add( k, pitch_res );
    1006             :         }
    1007             : 
    1008           0 :         out[j] = add_sat( in[j], mult_r_sat( curr_gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
    1009             : 
    1010           0 :         x0++;
    1011           0 :         x1++;
    1012           0 :         y0++;
    1013           0 :         y1++;
    1014             : 
    1015           0 :         curr_gain = add( curr_gain, gain_step );
    1016             :     }
    1017             : 
    1018           0 :     return;
    1019             : }
    1020             : 
    1021       27633 : static void tcx_ltp_synth_filter_10_fx(
    1022             :     Word32 *out,            /* Qx */
    1023             :     Word32 *in,             /* Qx */
    1024             :     const Word16 length,    /* Q0 */
    1025             :     const Word16 pitch_int, /* Q0 */
    1026             :     const Word16 pitch_fr,  /* Q0 */
    1027             :     const Word16 gain,      /* Q15 */
    1028             :     const Word16 pitch_res, /* Q0 */
    1029             :     const Word16 filtIdx    /* Q0 */
    1030             : )
    1031             : {
    1032             :     Word32 *x0, *x1;
    1033             :     Word32 *y0, *y1;
    1034             :     Word32 s, s2;
    1035             :     const Word16 *v0, *v1;
    1036             :     const Word16 *w0, *w1;
    1037             :     Word16 i, j, k, L;
    1038             :     Word16 curr_gain, gain_step;
    1039             : 
    1040       27633 :     x0 = &out[-pitch_int]; /* Qx */
    1041       27633 :     x1 = x0 - 1;
    1042       27633 :     y0 = in; /* Qx */
    1043       27633 :     y1 = y0 - 1;
    1044             : 
    1045       27633 :     assert( filtIdx >= 0 );
    1046             : 
    1047       27633 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
    1048       27633 :     w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
    1049       27633 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
    1050       27633 :     v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
    1051       27633 :     L = tcxLtpFilters[filtIdx].length;                       /* Q0 */
    1052             : 
    1053       27633 :     curr_gain = gain;
    1054       27633 :     move16();
    1055       27633 :     gain_step = idiv1616( negate( gain ), length ); // TODO
    1056             : 
    1057     5646513 :     FOR( j = 0; j < length; j++ )
    1058             :     {
    1059     5618880 :         s = 0;
    1060     5618880 :         move16();
    1061     5618880 :         s2 = 0;
    1062     5618880 :         move16();
    1063     5618880 :         k = 0;
    1064     5618880 :         move16();
    1065    43352960 :         FOR( i = 0; i < L; i++ )
    1066             :         {
    1067    37734080 :             s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
    1068    37734080 :             s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
    1069    37734080 :             k = k + pitch_res;
    1070             :         }
    1071             : 
    1072     5618880 :         out[j] = L_add_sat( in[j], Mpy_32_16_1( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), curr_gain ) ); /* Qx */
    1073     5618880 :         move32();
    1074     5618880 :         x0++;
    1075     5618880 :         x1++;
    1076     5618880 :         y0++;
    1077     5618880 :         y1++;
    1078             : 
    1079     5618880 :         curr_gain = add( curr_gain, gain_step );
    1080             :     }
    1081             : 
    1082       27633 :     return;
    1083             : }
    1084             : 
    1085           0 : static void tcx_ltp_synth_filter_01(
    1086             :     Word16 *out,            /* Qx */
    1087             :     Word16 *in,             /* Qx */
    1088             :     const Word16 length,    /* Q0 */
    1089             :     const Word16 pitch_int, /* Q0 */
    1090             :     const Word16 pitch_fr,  /* Q0 */
    1091             :     const Word16 gain,      /* Q15 */
    1092             :     const Word16 pitch_res, /* Q0 */
    1093             :     const Word16 filtIdx    /* Q0 */
    1094             : )
    1095             : {
    1096             :     Word16 *x0, *x1;
    1097             :     Word16 *y0, *y1;
    1098             :     Word32 s, s2;
    1099             :     const Word16 *v0, *v1;
    1100             :     const Word16 *w0, *w1;
    1101             :     Word16 i, j, k, L;
    1102             :     Word16 curr_gain, gain_step;
    1103             : 
    1104           0 :     x0 = &out[-( pitch_int )]; /* Qx */
    1105           0 :     x1 = x0 - 1;
    1106           0 :     y0 = in; /* Qx */
    1107           0 :     y1 = y0 - 1;
    1108             : 
    1109           0 :     assert( filtIdx >= 0 );
    1110             : 
    1111           0 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
    1112           0 :     w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
    1113           0 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
    1114           0 :     v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
    1115           0 :     L = tcxLtpFilters[filtIdx].length;                       /* Q0 */
    1116             : 
    1117           0 :     curr_gain = 0;
    1118           0 :     move16();
    1119           0 :     gain_step = idiv1616( gain, length ); // TODO
    1120             : 
    1121           0 :     for ( j = 0; j < length; j++ )
    1122             :     {
    1123           0 :         s = 0;
    1124           0 :         move16();
    1125           0 :         s2 = 0;
    1126           0 :         move16();
    1127             : 
    1128           0 :         for ( i = 0, k = 0; i < L; i++, k = k + pitch_res )
    1129             :         {
    1130           0 :             s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
    1131           0 :             s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
    1132             :         }
    1133             : 
    1134           0 :         out[j] = add_sat( in[j], mult_r_sat( curr_gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
    1135           0 :         move32();
    1136             : 
    1137           0 :         x0++;
    1138           0 :         x1++;
    1139           0 :         y0++;
    1140           0 :         y1++;
    1141             : 
    1142           0 :         curr_gain = add( curr_gain, gain_step );
    1143             :     }
    1144             : 
    1145           0 :     return;
    1146             : }
    1147             : 
    1148       28847 : static void tcx_ltp_synth_filter_01_fx(
    1149             :     Word32 *out,            /* Qx */
    1150             :     Word32 *in,             /* Qx */
    1151             :     const Word16 length,    /* Q0 */
    1152             :     const Word16 pitch_int, /* Q0 */
    1153             :     const Word16 pitch_fr,  /* Q0 */
    1154             :     const Word16 gain,      /* Q15 */
    1155             :     const Word16 pitch_res, /* Q0 */
    1156             :     const Word16 filtIdx    /* Q0 */
    1157             : )
    1158             : {
    1159             :     Word32 *x0, *x1;
    1160             :     Word32 *y0, *y1;
    1161             :     Word32 s, s2;
    1162             :     const Word16 *v0, *v1;
    1163             :     const Word16 *w0, *w1;
    1164             :     Word16 i, j, k, L;
    1165             :     Word16 curr_gain, gain_step;
    1166             : 
    1167       28847 :     x0 = &out[-( pitch_int )]; /* Qx */
    1168       28847 :     x1 = x0 - 1;
    1169       28847 :     y0 = in; /* Qx */
    1170       28847 :     y1 = y0 - 1;
    1171             : 
    1172       28847 :     assert( filtIdx >= 0 );
    1173             : 
    1174       28847 :     w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];             /* Q15 */
    1175       28847 :     w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
    1176       28847 :     v0 = &tcxLtpFilters[filtIdx].filt[0];                    /* Q15 */
    1177       28847 :     v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];            /* Q15 */
    1178       28847 :     L = tcxLtpFilters[filtIdx].length;                       /* Q0 */
    1179             : 
    1180       28847 :     curr_gain = 0;
    1181       28847 :     move16();
    1182       28847 :     gain_step = idiv1616( gain, length );
    1183             : 
    1184     5907407 :     FOR( j = 0; j < length; j++ )
    1185             :     {
    1186     5878560 :         s = 0;
    1187     5878560 :         move16();
    1188     5878560 :         s2 = 0;
    1189     5878560 :         move16();
    1190     5878560 :         k = 0;
    1191     5878560 :         move16();
    1192    45426880 :         FOR( i = 0; i < L; i++ )
    1193             :         {
    1194    39548320 :             s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
    1195    39548320 :             s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
    1196    39548320 :             k = k + pitch_res;
    1197             :         }
    1198             : 
    1199     5878560 :         out[j] = L_add_sat( in[j], Mpy_32_16_r( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), curr_gain ) ); /* Qx */
    1200     5878560 :         move32();
    1201             : 
    1202     5878560 :         x0++;
    1203     5878560 :         x1++;
    1204     5878560 :         y0++;
    1205     5878560 :         y1++;
    1206             : 
    1207     5878560 :         curr_gain = add( curr_gain, gain_step );
    1208             :     }
    1209             : 
    1210       28847 :     return;
    1211             : }
    1212             : 
    1213             : /*-------------------------------------------------------------------
    1214             :  *tcx_ltp_synth_filter_11_unequal_pitch_flt()
    1215             :  *
    1216             :  * blend between two filters by means of OAO
    1217             :  * filter the input signal at the initial subinterval with
    1218             :  * the first filter unit according to parameters associated to
    1219             :  * the preceding update interval with scaling from non-zero gain towards 0
    1220             :  * followed by the second filter unit according to parameters associated to
    1221             :  * the current update interval with scaling from 0 towards non-zero gain
    1222             :  ---------------------------------------------------------------------*/
    1223             : 
    1224           0 : static void tcx_ltp_synth_filter_11_unequal_pitch(
    1225             :     Word16 *out,                 /* Qx */
    1226             :     Word16 *in,                  /* Qx */
    1227             :     const Word16 length,         /* Q0 */
    1228             :     const Word16 cur_pitch_int,  /* Q0 */
    1229             :     const Word16 cur_pitch_fr,   /* Q0 */
    1230             :     const Word16 cur_gain,       /* Q15 */
    1231             :     const Word16 pitch_res,      /* Q0 */
    1232             :     const Word16 filtIdx,        /* Q0 */
    1233             :     const Word16 prev_pitch_int, /* Q0 */
    1234             :     const Word16 prev_pitch_fr,  /* Q0 */
    1235             :     const Word16 prev_gain,      /* Q15 */
    1236             :     const Word16 prev_pitch_res, /* Q0 */
    1237             :     const Word16 prev_filtIdx    /* Q0 */
    1238             : )
    1239             : {
    1240             :     Word16 *x0, *x1;
    1241             :     Word16 *y0, *y1;
    1242             :     Word16 *l0, *l1;
    1243             :     Word16 *m0, *m1;
    1244             :     Word32 s, s2, s3, s4;
    1245             :     const Word16 *v0, *v1;
    1246             :     const Word16 *w0, *w1;
    1247             :     const Word16 *p0, *p1;
    1248             :     const Word16 *q0, *q1;
    1249             :     Word16 i, j, k, L;
    1250             :     Word16 prev_L;
    1251             :     Word16 temp_buf[MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN];
    1252             :     Word16 *temp_ptr;
    1253             :     Word16 gain, gain_step;
    1254             : 
    1255           0 :     x0 = &out[-( prev_pitch_int )];
    1256           0 :     x1 = x0 - 1;
    1257           0 :     y0 = in;
    1258           0 :     y1 = y0 - 1;
    1259             : 
    1260           0 :     assert( ( filtIdx >= 0 ) && ( prev_filtIdx >= 0 ) );
    1261             : 
    1262           0 :     w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr];                  /* Q15 */
    1263           0 :     w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; /* Q15 */
    1264           0 :     v0 = &tcxLtpFilters[prev_filtIdx].filt[0];                              /* Q15 */
    1265           0 :     v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res];                 /* Q15 */
    1266             : 
    1267           0 :     prev_L = tcxLtpFilters[prev_filtIdx].length; /* Q0 */
    1268           0 :     move16();
    1269             : 
    1270           0 :     p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr];             /* Q15 */
    1271           0 :     p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr]; /* Q15 */
    1272           0 :     q0 = &tcxLtpFilters[filtIdx].filt[0];                        /* Q15 */
    1273           0 :     q1 = &tcxLtpFilters[filtIdx].filt[pitch_res];                /* Q15 */
    1274             : 
    1275           0 :     L = tcxLtpFilters[filtIdx].length; /* Q0 */
    1276           0 :     move16();
    1277             : 
    1278             :     /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */
    1279           0 :     gain = prev_gain;
    1280           0 :     move16();
    1281           0 :     gain_step = idiv1616( negate( prev_gain ), length );
    1282             : 
    1283           0 :     FOR( j = 0; j < length; j++ )
    1284             :     {
    1285           0 :         s = 0;
    1286           0 :         move16();
    1287           0 :         s2 = 0;
    1288           0 :         move16();
    1289           0 :         k = 0;
    1290           0 :         move16();
    1291           0 :         FOR( i = 0; i < prev_L; i++ )
    1292             :         {
    1293           0 :             s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] );   /* Qx */
    1294           0 :             s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
    1295           0 :             k = k + prev_pitch_res;
    1296             :         }
    1297             : 
    1298           0 :         out[j] = add_sat( in[j], mult_r_sat( gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
    1299             : 
    1300           0 :         x0++;
    1301           0 :         x1++;
    1302           0 :         y0++;
    1303           0 :         y1++;
    1304             : 
    1305           0 :         gain = add( gain, gain_step );
    1306             :     }
    1307             : 
    1308           0 :     Copy( out - L, temp_buf, length + L );         /* Qx */
    1309           0 :     Copy( in + length, temp_buf + length + L, L ); /* Qx */
    1310           0 :     temp_ptr = &temp_buf[0] + L;
    1311             : 
    1312           0 :     m0 = temp_ptr;                 /* Qx */
    1313           0 :     m1 = temp_ptr - 1;             /* Qx */
    1314           0 :     l0 = &out[-( cur_pitch_int )]; /* Qx */
    1315           0 :     l1 = l0 - 1;
    1316             : 
    1317             :     /* 2. increasing gain filter. The second filter unit with the parameters associated to the current interval and scaling from 0 towards current gain */
    1318           0 :     gain = 0;
    1319           0 :     move16();
    1320           0 :     gain_step = idiv1616( cur_gain, length );
    1321             : 
    1322           0 :     FOR( j = 0; j < length; j++ )
    1323             :     {
    1324           0 :         s3 = 0;
    1325           0 :         move16();
    1326           0 :         s4 = 0;
    1327           0 :         move16();
    1328           0 :         k = 0;
    1329           0 :         move16();
    1330           0 :         FOR( i = 0; i < L; i++ )
    1331             :         {
    1332           0 :             s3 = L_mac_sat( L_mac_sat( s3, p0[k], l0[i] ), p1[k], l1[-i] ); /* Qx */
    1333           0 :             s4 = L_mac_sat( L_mac_sat( s4, q0[k], m0[i] ), q1[k], m1[-i] ); /* Qx */
    1334           0 :             k = k + pitch_res;
    1335             :         }
    1336             : 
    1337           0 :         out[j] = add_sat( *( temp_ptr + j ), mult_r_sat( gain, sub_sat( round_fx_sat( s3 ), mult_r_sat( round_fx_sat( s4 ), ALPHA ) ) ) ); /* Qx */
    1338           0 :         move32();
    1339             : 
    1340           0 :         l0++;
    1341           0 :         l1++;
    1342           0 :         m0++;
    1343           0 :         m1++;
    1344             : 
    1345           0 :         gain = add( gain, gain_step );
    1346             :     }
    1347             : 
    1348           0 :     return;
    1349             : }
    1350             : 
    1351      120624 : static void tcx_ltp_synth_filter_11_unequal_pitch_fx(
    1352             :     Word32 *out,                 /* Qx */
    1353             :     Word32 *in,                  /* Qx */
    1354             :     const Word16 length,         /* Q0 */
    1355             :     const Word16 cur_pitch_int,  /* Q0 */
    1356             :     const Word16 cur_pitch_fr,   /* Q0 */
    1357             :     const Word16 cur_gain,       /* Q15 */
    1358             :     const Word16 pitch_res,      /* Q0 */
    1359             :     const Word16 filtIdx,        /* Q0 */
    1360             :     const Word16 prev_pitch_int, /* Q0 */
    1361             :     const Word16 prev_pitch_fr,  /* Q0 */
    1362             :     const Word16 prev_gain,      /* Q15 */
    1363             :     const Word16 prev_pitch_res, /* Q0 */
    1364             :     const Word16 prev_filtIdx    /* Q0 */
    1365             : )
    1366             : {
    1367             :     Word32 *x0, *x1;
    1368             :     Word32 *y0, *y1;
    1369             :     Word32 *l0, *l1;
    1370             :     Word32 *m0, *m1;
    1371             :     Word32 s, s2, s3, s4;
    1372             :     const Word16 *v0, *v1;
    1373             :     const Word16 *w0, *w1;
    1374             :     const Word16 *p0, *p1;
    1375             :     const Word16 *q0, *q1;
    1376             :     Word16 i, j, k, L;
    1377             :     Word16 prev_L;
    1378             :     Word32 temp_buf[MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN];
    1379             :     Word32 *temp_ptr;
    1380             :     Word16 gain, gain_step;
    1381             : 
    1382      120624 :     x0 = &out[-( prev_pitch_int )]; /* Qx */
    1383      120624 :     x1 = x0 - 1;
    1384      120624 :     y0 = in; /* Qx */
    1385      120624 :     y1 = y0 - 1;
    1386             : 
    1387      120624 :     assert( GE_16( filtIdx, 0 ) && GE_16( prev_filtIdx, 0 ) );
    1388             : 
    1389      120624 :     w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr];                  /* Q15 */
    1390      120624 :     w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; /* Q15 */
    1391      120624 :     v0 = &tcxLtpFilters[prev_filtIdx].filt[0];                              /* Q15 */
    1392      120624 :     v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res];                 /* Q15 */
    1393             : 
    1394      120624 :     prev_L = tcxLtpFilters[prev_filtIdx].length; /* Q0 */
    1395      120624 :     move16();
    1396             : 
    1397      120624 :     p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr];             /* Q15 */
    1398      120624 :     p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr]; /* Q15 */
    1399      120624 :     q0 = &tcxLtpFilters[filtIdx].filt[0];                        /* Q15 */
    1400      120624 :     q1 = &tcxLtpFilters[filtIdx].filt[pitch_res];                /* Q15 */
    1401             : 
    1402      120624 :     L = tcxLtpFilters[filtIdx].length; /* Q0 */
    1403      120624 :     move16();
    1404             : 
    1405             :     /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */
    1406      120624 :     gain = prev_gain;
    1407      120624 :     move16();
    1408      120624 :     gain_step = idiv1616( negate( prev_gain ), length ); // TODOD
    1409             : 
    1410    24648944 :     FOR( j = 0; j < length; j++ )
    1411             :     {
    1412    24528320 :         s = 0;
    1413    24528320 :         move16();
    1414    24528320 :         s2 = 0;
    1415    24528320 :         move16();
    1416    24528320 :         k = 0;
    1417    24528320 :         move16();
    1418   191180800 :         FOR( i = 0; i < prev_L; i++ )
    1419             :         {
    1420   166652480 :             s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] );   /* Qx */
    1421   166652480 :             s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
    1422   166652480 :             k += prev_pitch_res;
    1423             :         }
    1424             : 
    1425    24528320 :         out[j] = L_add_sat( in[j], Mpy_32_16_r( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), gain ) ); /* Qx */
    1426    24528320 :         move32();
    1427    24528320 :         x0++;
    1428    24528320 :         x1++;
    1429    24528320 :         y0++;
    1430    24528320 :         y1++;
    1431             : 
    1432    24528320 :         gain = add( gain, gain_step );
    1433             :     }
    1434             : 
    1435      120624 :     Copy32( out - L, temp_buf, length + L );         /* Qx */
    1436      120624 :     Copy32( in + length, temp_buf + length + L, L ); /* Qx */
    1437      120624 :     temp_ptr = &temp_buf[0] + L;                     /* Qx */
    1438             : 
    1439      120624 :     m0 = temp_ptr; /* Qx */
    1440      120624 :     m1 = temp_ptr - 1;
    1441      120624 :     l0 = &out[-( cur_pitch_int )]; /* Qx */
    1442      120624 :     l1 = l0 - 1;
    1443             : 
    1444             :     /* 2. increasing gain filter. The second filter unit with the parameters associated to the current interval and scaling from 0 towards current gain */
    1445      120624 :     gain = 0;
    1446      120624 :     move16();
    1447      120624 :     gain_step = idiv1616( cur_gain, length );
    1448             : 
    1449    24648944 :     FOR( j = 0; j < length; j++ )
    1450             :     {
    1451    24528320 :         s3 = 0;
    1452    24528320 :         move16();
    1453    24528320 :         s4 = 0;
    1454    24528320 :         move16();
    1455    24528320 :         k = 0;
    1456   191180800 :         FOR( i = 0; i < L; i++ )
    1457             :         {
    1458   166652480 :             s3 = Madd_32_16_r( Madd_32_16_r( s3, l0[i], p0[k] ), l1[-i], p1[k] ); /* Qx */
    1459   166652480 :             s4 = Madd_32_16_r( Madd_32_16_r( s4, m0[i], q0[k] ), m1[-i], q1[k] ); /* Qx */
    1460   166652480 :             k = add( k, pitch_res );
    1461             :         }
    1462             : 
    1463    24528320 :         out[j] = L_add_sat( *( temp_ptr + j ), Mpy_32_16_r( L_sub_sat( s3, Mpy_32_16_1( s4, ALPHA ) ), gain ) ); /* Qx */
    1464    24528320 :         move32();
    1465             : 
    1466    24528320 :         l0++;
    1467    24528320 :         l1++;
    1468    24528320 :         m0++;
    1469    24528320 :         m1++;
    1470             : 
    1471    24528320 :         gain = add( gain, gain_step );
    1472             :     }
    1473             : 
    1474      120624 :     return;
    1475             : }
    1476             : 
    1477      832050 : Word16 tcx_ltp_decode_params(
    1478             :     Word16 *ltp_param,   /* Q0 */
    1479             :     Word16 *pitch_int,   /* Q0 */
    1480             :     Word16 *pitch_fr,    /* Q0 */
    1481             :     Word16 *gain,        /* Q13 */
    1482             :     const Word16 pitmin, /* Q0 */
    1483             :     const Word16 pitfr1, /* Q0 */
    1484             :     const Word16 pitfr2, /* Q0 */
    1485             :     const Word16 pitmax, /* Q0 */
    1486             :     const Word16 pitres  /* Q0 */
    1487             : )
    1488             : {
    1489             :     Word16 tmp, tmp2;
    1490             : 
    1491             : 
    1492             :     /* Decode Pitch and Gain */
    1493      832050 :     test();
    1494      832050 :     IF( ltp_param != 0 && ltp_param[0] != 0 )
    1495             :     {
    1496      557525 :         tmp = imult1616( sub( pitfr2, pitmin ), pitres ); /* Q0 */
    1497             : 
    1498      557525 :         IF( LT_16( ltp_param[1], tmp ) )
    1499             :         {
    1500      376748 :             tmp2 = idiv1616U( ltp_param[1], pitres );
    1501             : 
    1502      376748 :             *pitch_int = add( pitmin, tmp2 ); /* Q0 */
    1503      376748 :             move16();
    1504      376748 :             tmp2 = sub( *pitch_int, pitmin );                           /* Q0 */
    1505      376748 :             *pitch_fr = sub( ltp_param[1], imult1616( tmp2, pitres ) ); /* Q0 */
    1506      376748 :             move16();
    1507             :         }
    1508             :         ELSE
    1509             :         {
    1510      180777 :             tmp2 = imult1616( sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ); /* Q0 */
    1511             : 
    1512      180777 :             IF( LT_16( ltp_param[1], add( tmp, tmp2 ) ) )
    1513             :             {
    1514       54381 :                 tmp2 = idiv1616U( sub( ltp_param[1], tmp ), shr( pitres, 1 ) ); /* Q0 */
    1515             : 
    1516       54381 :                 *pitch_int = add( pitfr2, tmp2 ); /* Q0 */
    1517       54381 :                 move16();
    1518       54381 :                 *pitch_fr = shl( sub( sub( ltp_param[1], tmp ), imult1616( tmp2, shr( pitres, 1 ) ) ), 1 ); /* Q0 */
    1519       54381 :                 move16();
    1520             :             }
    1521             :             ELSE
    1522             :             {
    1523      126396 :                 *pitch_int = sub( add( ltp_param[1], pitfr1 ), add( tmp, tmp2 ) ); /* Q0 */
    1524      126396 :                 move16();
    1525      126396 :                 *pitch_fr = 0;
    1526      126396 :                 move16();
    1527             :             }
    1528             :         }
    1529             : 
    1530      557525 :         *gain = imult1616( add( ltp_param[2], 1 ), 0x1400 /* 0.625 in Q13 */ ); /* Q13 */
    1531      557525 :         move16();
    1532             : 
    1533      557525 :         IF( LT_16( *pitch_int, PIT_MIN_SHORTER ) )
    1534             :         {
    1535             :             /*pitch out of range due to bit error */
    1536           0 :             *pitch_int = PIT_MIN_SHORTER; /* Q0 */
    1537           0 :             move16();
    1538           0 :             return 1;
    1539             :         }
    1540             : 
    1541      557525 :         IF( GT_16( *pitch_int, PIT_MAX_MAX ) )
    1542             :         {
    1543             :             /*pitch out of range due to bit error */
    1544           0 :             *pitch_int = PIT_MAX_MAX; /* Q0 */
    1545           0 :             move16();
    1546           0 :             return 1;
    1547             :         }
    1548             :     }
    1549             :     ELSE
    1550             :     {
    1551      274525 :         *pitch_int = pitmax; /* Q0 */
    1552      274525 :         move16();
    1553      274525 :         *pitch_fr = 0;
    1554      274525 :         move16();
    1555      274525 :         *gain = 0;
    1556      274525 :         move16();
    1557             :     }
    1558             : 
    1559      832050 :     return 0;
    1560             : }
    1561             : 
    1562        3100 : void tcx_ltp_post_fx(
    1563             :     Decoder_State *st,
    1564             :     TCX_LTP_DEC_HANDLE hTcxLtpDec,
    1565             :     Word16 core,         /* Q0 */
    1566             :     Word16 output_frame, /* Q0 */
    1567             :     Word16 delay,        /* Q0 */
    1568             :     Word16 *sig,         /* Qx */
    1569             :     Word16 *tcx_buf      /* Qx */
    1570             : )
    1571             : {
    1572             :     Word16 tmp, L_transition, lpcorder, filtIdx;
    1573             :     Word16 gain, gain2;
    1574             :     Word32 tmp32;
    1575             :     Word16 zir[L_FRAME_PLUS / 4], A[TCXLTP_LTP_ORDER + 1];
    1576             :     Word16 buf_in[TCXLTP_MAX_DELAY + L_FRAME48k + TCXLTP_MAX_DELAY], buf_out[2 * L_FRAME48k];
    1577             :     Word16 *sig_in, *sig_out;
    1578             :     Word16 pitch_int, pitch_fr;
    1579             :     Word16 tcx_buf_len, bfi, L_frame_core, SideInfoOnly;
    1580             :     Word32 total_brate;
    1581             : 
    1582        3100 :     total_brate = st->total_brate; /* Q0 */
    1583        3100 :     move32();
    1584        3100 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    1585             :     {
    1586           0 :         total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); /* Q0 */
    1587           0 :         move32();
    1588             :     }
    1589             : 
    1590        3100 :     filtIdx = 0; /* just to avoid comilation warnings */
    1591        3100 :     move16();
    1592        3100 :     tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
    1593        3100 :     SideInfoOnly = 0;
    1594        3100 :     move16();
    1595        3100 :     if ( GE_32( total_brate, HQ_96k ) )
    1596             :     {
    1597           0 :         SideInfoOnly = 1;
    1598           0 :         move16();
    1599             :     }
    1600             : 
    1601        3100 :     L_frame_core = st->L_frame; /* Q0 */
    1602        3100 :     move16();
    1603             : 
    1604        3100 :     if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    1605             :     {
    1606           0 :         L_frame_core = L_FRAME; /* Q0 */
    1607           0 :         move16();
    1608             :     }
    1609             : 
    1610        3100 :     IF( EQ_16( core, ACELP_CORE ) )
    1611             :     {
    1612        2466 :         bfi = 0;
    1613        2466 :         move16();
    1614        2466 :         pitch_int = 0;
    1615        2466 :         move16();
    1616        2466 :         pitch_fr = 0;
    1617        2466 :         move16();
    1618        2466 :         gain = 0;
    1619        2466 :         move16();
    1620        2466 :         L_frame_core = st->L_frame_past; /* Q0 */
    1621        2466 :         move16();
    1622             :     }
    1623             :     ELSE
    1624             :     {
    1625         634 :         bfi = st->bfi;                            /* Q0 */
    1626         634 :         pitch_int = hTcxLtpDec->tcxltp_pitch_int; /* Q0 */
    1627         634 :         pitch_fr = hTcxLtpDec->tcxltp_pitch_fr;   /* Q0 */
    1628         634 :         gain = hTcxLtpDec->tcxltp_gain;           /* Q15 */
    1629         634 :         move16();
    1630         634 :         move16();
    1631         634 :         move16();
    1632         634 :         move16();
    1633             :     }
    1634             :     /******** Init ********/
    1635             : 
    1636             : 
    1637             :     /* Parameters */
    1638        3100 :     L_transition = shr( output_frame, 2 ); /* Q0 */
    1639        3100 :     lpcorder = TCXLTP_LTP_ORDER;
    1640        3100 :     move16();
    1641             : 
    1642             :     /* Input buffer */
    1643        3100 :     sig_in = buf_in + tcx_buf_len;
    1644        3100 :     Copy( hTcxLtpDec->tcxltp_mem_in, buf_in, tcx_buf_len ); /* exp(exp_tcxltp_mem_in) */
    1645        3100 :     Copy( sig, buf_in + tcx_buf_len, output_frame );        /* Qx */
    1646        3100 :     IF( GT_16( core, ACELP_CORE ) )
    1647             :     {
    1648         634 :         Copy( tcx_buf, sig_in + output_frame, tcx_buf_len ); /* Qx */
    1649             :     }
    1650        3100 :     Copy( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in, tcx_buf_len ); /* Qx */
    1651             : 
    1652             :     /* Output buffer */
    1653        3100 :     sig_out = buf_out + output_frame;
    1654        3100 :     Copy( hTcxLtpDec->tcxltp_mem_out, buf_out, output_frame ); /* exp(exp_tcxltp_mem_out) */
    1655             : 
    1656             :     /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
    1657        3100 :     test();
    1658        3100 :     test();
    1659        3100 :     IF( !( SideInfoOnly != 0 || hTcxLtpDec->tcxltp != 0 ) || EQ_16( core, ACELP_CORE ) )
    1660             :     {
    1661             :         /* No LTP */
    1662        2466 :         pitch_int = 0;
    1663        2466 :         move16();
    1664        2466 :         pitch_fr = 0;
    1665        2466 :         move16();
    1666        2466 :         gain = 0;
    1667        2466 :         move16();
    1668             :     }
    1669         634 :     ELSE IF( bfi == 0 )
    1670             :     {
    1671             :         /* LTP and good frame */
    1672         634 :         test();
    1673         634 :         IF( EQ_16( st->element_mode, EVS_MONO ) ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
    1674             :         {
    1675         634 :             IF( NE_16( output_frame, L_frame_core ) )
    1676             :             {
    1677         634 :                 tmp = div_s( output_frame, shl( L_frame_core, 2 ) );                              /* Q13 */
    1678         634 :                 tmp32 = L_mult0( add( imult1616( pitch_int, st->pit_res_max ), pitch_fr ), tmp ); /* Q13 */
    1679         634 :                 tmp = round_fx( L_shl( tmp32, 3 ) );                                              /* Q0 */
    1680         634 :                 pitch_int = idiv1616U( tmp, st->pit_res_max );
    1681         634 :                 pitch_fr = sub( tmp, imult1616( pitch_int, st->pit_res_max ) ); /* Q0 */
    1682             :             }
    1683         634 :             test();
    1684         634 :             test();
    1685         634 :             IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, L_FRAME16k ) )
    1686             :             {
    1687           0 :                 gain = mult_r( gain, 10486 /*0.32f Q15*/ ); /* Q15 */
    1688             :             }
    1689         634 :             ELSE IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, 512 ) )
    1690             :             {
    1691           0 :                 gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
    1692             :             }
    1693             :             ELSE
    1694             :             {
    1695         634 :                 gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
    1696             :             }
    1697             :         }
    1698           0 :         ELSE IF( GT_16( st->element_mode, IVAS_SCE ) && GE_32( total_brate, IVAS_96k ) )
    1699             :         {
    1700           0 :             gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
    1701             :         }
    1702             :         ELSE
    1703             :         {
    1704           0 :             gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
    1705             :         }
    1706             :     }
    1707             :     ELSE
    1708             :     {
    1709             :         /* PLC: [TCX: Fade-out]
    1710             :          * PLC: LTP and bad frame (concealment) */
    1711           0 :         IF( EQ_16( st->pit_res_max, st->pit_res_max_past ) ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
    1712             :         {
    1713           0 :             pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev;
    1714           0 :             move16();
    1715           0 :             pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev;
    1716           0 :             move16();
    1717           0 :             gain = shl( mult_r( hTcxLtpDec->tcxltp_gain_post_prev, st->hTcxDec->damping ), 1 );
    1718             :         }
    1719             :         ELSE
    1720             :         {
    1721           0 :             gain = 0;
    1722           0 :             move16();
    1723             :         }
    1724             :     }
    1725             : 
    1726             : 
    1727        3100 :     IF( SideInfoOnly != 0 )
    1728             :     {
    1729           0 :         gain = 0;
    1730           0 :         move16();
    1731           0 :         if ( bfi != 0 )
    1732             :         {
    1733           0 :             hTcxLtpDec->tcxltp_gain_post_prev = 0;
    1734           0 :             move16();
    1735             :         }
    1736             :     }
    1737        3100 :     gain2 = gain;
    1738        3100 :     move16();
    1739             : 
    1740        3100 :     IF( EQ_16( L_frame_core, L_FRAME ) )
    1741             :     {
    1742        2046 :         SWITCH( output_frame )
    1743             :         {
    1744           0 :             case L_FRAME8k:
    1745           0 :                 filtIdx = 0;
    1746           0 :                 move16();
    1747           0 :                 BREAK;
    1748           0 :             case L_FRAME16k:
    1749           0 :                 filtIdx = 1;
    1750           0 :                 move16();
    1751           0 :                 BREAK;
    1752        1046 :             case L_FRAME32k:
    1753        1046 :                 filtIdx = 2;
    1754        1046 :                 move16();
    1755        1046 :                 BREAK;
    1756        1000 :             case L_FRAME48k:
    1757        1000 :                 filtIdx = 3;
    1758        1000 :                 move16();
    1759        1000 :                 BREAK;
    1760           0 :             default:
    1761           0 :                 assert( 0 );
    1762             :         }
    1763             :     }
    1764        1054 :     ELSE IF( EQ_16( L_frame_core, L_FRAME16k ) )
    1765             :     {
    1766        1037 :         SWITCH( output_frame )
    1767             :         {
    1768           0 :             case L_FRAME8k:
    1769           0 :                 filtIdx = 4;
    1770           0 :                 move16();
    1771           0 :                 BREAK;
    1772           0 :             case L_FRAME16k:
    1773           0 :                 filtIdx = 5;
    1774           0 :                 move16();
    1775           0 :                 BREAK;
    1776           4 :             case L_FRAME32k:
    1777           4 :                 filtIdx = 6;
    1778           4 :                 move16();
    1779           4 :                 BREAK;
    1780        1033 :             case L_FRAME48k:
    1781        1033 :                 filtIdx = 7;
    1782        1033 :                 move16();
    1783        1033 :                 BREAK;
    1784           0 :             default:
    1785           0 :                 assert( 0 );
    1786             :         }
    1787             :     }
    1788          17 :     ELSE IF( EQ_16( L_frame_core, 512 ) )
    1789             :     {
    1790           0 :         SWITCH( output_frame )
    1791             :         {
    1792           0 :             case L_FRAME8k:
    1793           0 :                 filtIdx = 8;
    1794           0 :                 move16();
    1795           0 :                 BREAK;
    1796           0 :             case L_FRAME16k:
    1797           0 :                 filtIdx = 9;
    1798           0 :                 move16();
    1799           0 :                 BREAK;
    1800           0 :             case L_FRAME32k:
    1801           0 :                 filtIdx = 10;
    1802           0 :                 move16();
    1803           0 :                 BREAK;
    1804           0 :             case L_FRAME48k:
    1805           0 :                 filtIdx = 11;
    1806           0 :                 move16();
    1807           0 :                 BREAK;
    1808           0 :             default:
    1809           0 :                 assert( 0 );
    1810             :         }
    1811             :     }
    1812             :     ELSE
    1813             :     {
    1814          17 :         filtIdx = -1;
    1815          17 :         move16();
    1816             :     }
    1817             : 
    1818             : 
    1819             :     /******** Previous-frame part ********/
    1820             : 
    1821        3100 :     tcx_ltp_synth_filter( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev,
    1822        3100 :                           st->pit_res_max_past, NULL, 0, hTcxLtpDec->tcxltp_filt_idx_prev );
    1823             : 
    1824             :     /******** Transition part ********/
    1825             : 
    1826        3100 :     test();
    1827        3100 :     test();
    1828        3100 :     test();
    1829             :     // #ifdef IVAS_CODE_TCX_LTP
    1830        3100 :     IF( NE_16( st->element_mode, EVS_MONO ) )
    1831             :     {
    1832           0 :         test();
    1833           0 :         test();
    1834           0 :         test();
    1835           0 :         test();
    1836           0 :         test();
    1837           0 :         test();
    1838           0 :         test();
    1839           0 :         IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    1840             :         {
    1841             :             /* The filtering is deactivated, just copy input to the output */
    1842           0 :             Copy( sig_in + delay, sig_out + delay, L_transition ); /* Qx */
    1843             :         }
    1844           0 :         ELSE IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev != 0 )
    1845             :         {
    1846             :             /* Filtering with the first filter unit */
    1847           0 :             tcx_ltp_synth_filter_10( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
    1848             :         }
    1849           0 :         ELSE IF( gain != 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    1850             :         {
    1851             :             /* Filtering with the second filter unit */
    1852           0 :             tcx_ltp_synth_filter_01( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
    1853             :         }
    1854           0 :         ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) && EQ_16( st->pit_res_max, st->pit_res_max_past ) && EQ_16( filtIdx, hTcxLtpDec->tcxltp_filt_idx_prev ) )
    1855             :         {
    1856           0 :             tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    1857             :         }
    1858             :         ELSE
    1859             :         {
    1860             :             /* Filtering with the first filter unit, followed by the filtering with the second filter unit */
    1861           0 :             tcx_ltp_synth_filter_11_unequal_pitch( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx,
    1862           0 :                                                    hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
    1863             :         }
    1864             :     }
    1865             :     ELSE
    1866             :     {
    1867        3100 :         test();
    1868        3100 :         test();
    1869        3100 :         test();
    1870        3100 :         test();
    1871        3100 :         IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    1872             :         {
    1873        2564 :             Copy( sig_in + delay, sig_out + delay, L_transition ); /* Qx */
    1874             :         }
    1875         536 :         ELSE IF( hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    1876             :         {
    1877          84 :             tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int,
    1878          84 :                                   pitch_fr, gain, st->pit_res_max, NULL, 1, filtIdx );
    1879             :         }
    1880         452 :         ELSE IF( gain == 0 )
    1881             :         {
    1882          84 :             tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev,
    1883          84 :                                   hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, NULL, -1, hTcxLtpDec->tcxltp_filt_idx_prev );
    1884             :         }
    1885         368 :         ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) )
    1886             :         {
    1887         123 :             tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    1888             :         }
    1889             :         ELSE
    1890             :         {
    1891         245 :             tcx_ltp_get_lpc( sig_out + delay - output_frame, output_frame, A, lpcorder );
    1892             : 
    1893         245 :             tcx_ltp_get_zir( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx );
    1894             : 
    1895         245 :             tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, 0, filtIdx );
    1896             :         }
    1897             :     }
    1898             : 
    1899             :     /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/
    1900             : 
    1901        3100 :     tcx_ltp_synth_filter( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    1902             : 
    1903             : 
    1904             :     /******** Output ********/
    1905             : 
    1906             : 
    1907             :     /* copy to output */
    1908             : 
    1909        3100 :     Copy( sig_out, sig, output_frame ); /* Qx */
    1910             : 
    1911             :     /* Update */
    1912        3100 :     hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
    1913        3100 :     move16();
    1914        3100 :     hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
    1915        3100 :     move16();
    1916        3100 :     hTcxLtpDec->tcxltp_gain_post_prev = gain2;
    1917        3100 :     move16();
    1918        3100 :     hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
    1919        3100 :     move16();
    1920        3100 :     st->pit_res_max_past = st->pit_res_max;
    1921        3100 :     move16();
    1922        3100 :     Copy( sig_out, hTcxLtpDec->tcxltp_mem_out, output_frame ); /* Qx */
    1923        3100 : }
    1924             : 
    1925             : 
    1926             : /* IVAS 32-bit variant */
    1927     1124260 : void tcx_ltp_post_fx32(
    1928             :     Decoder_State *st,
    1929             :     TCX_LTP_DEC_HANDLE hTcxLtpDec,
    1930             :     Word16 core,         /* Q0 */
    1931             :     Word16 output_frame, /* Q0 */
    1932             :     Word16 delay,        /* Q0 */
    1933             :     Word32 *sig,         /* sig_q */
    1934             :     Word32 *tcx_buf,     /* sig_q */
    1935             :     Word16 sig_q )
    1936             : {
    1937             :     Word16 tmp, L_transition, lpcorder, filtIdx;
    1938             :     Word16 gain, gain2;
    1939             :     Word32 tmp32;
    1940             :     Word32 zir[L_FRAME_PLUS / 4], A[TCXLTP_LTP_ORDER + 1];
    1941             :     Word32 buf_in[TCXLTP_MAX_DELAY + L_FRAME48k + TCXLTP_MAX_DELAY], buf_out[2 * L_FRAME48k];
    1942             :     Word32 *sig_in, *sig_out;
    1943             :     Word16 pitch_int, pitch_fr;
    1944             :     Word16 tcx_buf_len, bfi, L_frame_core, SideInfoOnly;
    1945             :     Word32 total_brate;
    1946             : 
    1947     1124260 :     total_brate = st->total_brate;
    1948     1124260 :     move32();
    1949     1124260 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    1950             :     {
    1951      698688 :         total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); // TDO
    1952      698688 :         move32();
    1953             :     }
    1954             : 
    1955     1124260 :     filtIdx = 0; /* just to avoid comilation warnings */
    1956     1124260 :     move16();
    1957     1124260 :     tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
    1958     1124260 :     move16();
    1959     1124260 :     SideInfoOnly = 0;
    1960     1124260 :     move16();
    1961     1124260 :     if ( GE_32( total_brate, HQ_96k ) )
    1962             :     {
    1963      400596 :         SideInfoOnly = 1;
    1964      400596 :         move16();
    1965             :     }
    1966             : 
    1967     1124260 :     L_frame_core = st->L_frame; /* Q0 */
    1968     1124260 :     move16();
    1969             : 
    1970     1124260 :     if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    1971             :     {
    1972      698688 :         L_frame_core = L_FRAME;
    1973      698688 :         move16();
    1974             :     }
    1975             : 
    1976     1124260 :     IF( EQ_16( core, ACELP_CORE ) )
    1977             :     {
    1978      204274 :         bfi = 0;
    1979      204274 :         pitch_int = 0;
    1980      204274 :         pitch_fr = 0;
    1981      204274 :         gain = 0;
    1982      204274 :         L_frame_core = st->L_frame_past; /* Q0 */
    1983      204274 :         move16();
    1984      204274 :         move16();
    1985      204274 :         move16();
    1986      204274 :         move16();
    1987             :     }
    1988             :     ELSE
    1989             :     {
    1990      919986 :         bfi = st->bfi;                            /* Q0 */
    1991      919986 :         pitch_int = hTcxLtpDec->tcxltp_pitch_int; /* Q0 */
    1992      919986 :         pitch_fr = hTcxLtpDec->tcxltp_pitch_fr;   /* Q0 */
    1993      919986 :         gain = hTcxLtpDec->tcxltp_gain;           /* Q15 */
    1994      919986 :         move16();
    1995      919986 :         move16();
    1996      919986 :         move16();
    1997      919986 :         move16();
    1998             :     }
    1999             :     /******** Init ********/
    2000             : 
    2001             : 
    2002             :     /* Parameters */
    2003     1124260 :     L_transition = shr( output_frame, 2 ); /* Q0 */
    2004     1124260 :     lpcorder = TCXLTP_LTP_ORDER;
    2005     1124260 :     move16();
    2006             : 
    2007             :     /* Input buffer */
    2008     1124260 :     sig_in = buf_in + tcx_buf_len;
    2009     1124260 :     Copy32( hTcxLtpDec->tcxltp_mem_in_32, buf_in, tcx_buf_len ); /* exp(exp_tcxltp_mem_in)*/
    2010     1124260 :     scale_sig32( buf_in, tcx_buf_len, sub( hTcxLtpDec->exp_tcxltp_mem_in, sub( 31, sig_q ) ) );
    2011     1124260 :     Copy32( sig, buf_in + tcx_buf_len, output_frame ); /* sig_q */
    2012     1124260 :     IF( core > ACELP_CORE )
    2013             :     {
    2014      919986 :         Copy32( tcx_buf, sig_in + output_frame, tcx_buf_len ); /* sig_q */
    2015             :     }
    2016     1124260 :     Copy32( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in_32, tcx_buf_len ); /* sig_q */
    2017     1124260 :     hTcxLtpDec->exp_tcxltp_mem_in = sub( 31, sig_q );
    2018     1124260 :     move16();
    2019             :     /* Output buffer */
    2020     1124260 :     sig_out = buf_out + output_frame;
    2021     1124260 :     Copy32( hTcxLtpDec->tcxltp_mem_out_32, buf_out, output_frame ); /* exp(exp_tcxltp_mem_out) */
    2022     1124260 :     scale_sig32( buf_out, output_frame, sub( hTcxLtpDec->exp_tcxltp_mem_out, sub( 31, sig_q ) ) );
    2023             : 
    2024             :     /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
    2025     1124260 :     test();
    2026     1124260 :     test();
    2027     1124260 :     IF( !( SideInfoOnly != 0 || hTcxLtpDec->tcxltp != 0 ) || EQ_16( core, ACELP_CORE ) )
    2028             :     {
    2029             :         /* No LTP */
    2030      500717 :         pitch_int = 0;
    2031      500717 :         move16();
    2032      500717 :         pitch_fr = 0;
    2033      500717 :         move16();
    2034      500717 :         gain = 0;
    2035      500717 :         move16();
    2036             :     }
    2037      623543 :     ELSE IF( bfi == 0 )
    2038             :     {
    2039             :         /* LTP and good frame */
    2040      619131 :         IF( NE_16( output_frame, L_frame_core ) )
    2041             :         {
    2042      610356 :             tmp = div_s( output_frame, shl( L_frame_core, 2 ) );                              /* Q13 */
    2043      610356 :             tmp32 = L_mult0( add( imult1616( pitch_int, st->pit_res_max ), pitch_fr ), tmp ); /* Q13 */
    2044      610356 :             tmp = round_fx( L_shl( tmp32, 3 ) );                                              /* Q0 */
    2045      610356 :             pitch_int = idiv1616U( tmp, st->pit_res_max );
    2046      610356 :             pitch_fr = sub( tmp, imult1616( pitch_int, st->pit_res_max ) ); /* Q0 */
    2047             :         }
    2048      619131 :         IF( st->element_mode == EVS_MONO ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
    2049             :         {
    2050           0 :             test();
    2051           0 :             test();
    2052           0 :             IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, L_FRAME16k ) )
    2053             :             {
    2054           0 :                 gain = mult_r( gain, 10486 /*0.32f Q15*/ ); /* Q15 */
    2055             :             }
    2056           0 :             ELSE IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, 512 ) )
    2057             :             {
    2058           0 :                 gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
    2059             :             }
    2060             :             ELSE
    2061             :             {
    2062           0 :                 gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
    2063             :             }
    2064             :         }
    2065      619131 :         ELSE IF( GT_16( st->element_mode, IVAS_SCE ) && GE_32( total_brate, IVAS_96k ) )
    2066             :         {
    2067      382830 :             gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
    2068             :         }
    2069             :         ELSE
    2070             :         {
    2071      236301 :             gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
    2072             :         }
    2073             :     }
    2074             :     ELSE
    2075             :     {
    2076             :         /* PLC: [TCX: Fade-out]
    2077             :          * PLC: LTP and bad frame (concealment) */
    2078        4412 :         IF( st->pit_res_max == st->pit_res_max_past ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
    2079             :         {
    2080        4412 :             pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev; /* Q0 */
    2081        4412 :             move16();
    2082        4412 :             pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev; /* Q0 */
    2083        4412 :             move16();
    2084        4412 :             gain = shl( mult_r( hTcxLtpDec->tcxltp_gain_post_prev, st->hTcxDec->damping ), 1 ); /* Q15 */
    2085             :         }
    2086             :         ELSE
    2087             :         {
    2088           0 :             gain = 0;
    2089           0 :             move16();
    2090             :         }
    2091             :     }
    2092             : 
    2093             : 
    2094     1124260 :     IF( SideInfoOnly != 0 )
    2095             :     {
    2096      400596 :         gain = 0;
    2097      400596 :         move16();
    2098      400596 :         if ( bfi != 0 )
    2099             :         {
    2100        2839 :             hTcxLtpDec->tcxltp_gain_post_prev = 0;
    2101        2839 :             move16();
    2102             :         }
    2103             :     }
    2104     1124260 :     gain2 = gain;
    2105     1124260 :     move16();
    2106             : 
    2107     1124260 :     IF( EQ_16( L_frame_core, L_FRAME ) )
    2108             :     {
    2109      811781 :         SWITCH( output_frame )
    2110             :         {
    2111           0 :             case L_FRAME8k:
    2112           0 :                 filtIdx = 0;
    2113           0 :                 move16();
    2114           0 :                 BREAK;
    2115       80253 :             case L_FRAME16k:
    2116       80253 :                 filtIdx = 1;
    2117       80253 :                 move16();
    2118       80253 :                 BREAK;
    2119      186039 :             case L_FRAME32k:
    2120      186039 :                 filtIdx = 2;
    2121      186039 :                 move16();
    2122      186039 :                 BREAK;
    2123      545489 :             case L_FRAME48k:
    2124      545489 :                 filtIdx = 3;
    2125      545489 :                 move16();
    2126      545489 :                 BREAK;
    2127           0 :             default:
    2128           0 :                 assert( 0 );
    2129             :         }
    2130             :     }
    2131      312479 :     ELSE IF( EQ_16( L_frame_core, L_FRAME16k ) )
    2132             :     {
    2133      180898 :         SWITCH( output_frame )
    2134             :         {
    2135           0 :             case L_FRAME8k:
    2136           0 :                 filtIdx = 4;
    2137           0 :                 move16();
    2138           0 :                 BREAK;
    2139       19031 :             case L_FRAME16k:
    2140       19031 :                 filtIdx = 5;
    2141       19031 :                 move16();
    2142       19031 :                 BREAK;
    2143       46738 :             case L_FRAME32k:
    2144       46738 :                 filtIdx = 6;
    2145       46738 :                 move16();
    2146       46738 :                 BREAK;
    2147      115129 :             case L_FRAME48k:
    2148      115129 :                 filtIdx = 7;
    2149      115129 :                 move16();
    2150      115129 :                 BREAK;
    2151           0 :             default:
    2152           0 :                 assert( 0 );
    2153             :         }
    2154             :     }
    2155      131581 :     ELSE IF( EQ_16( L_frame_core, 512 ) )
    2156             :     {
    2157       13935 :         SWITCH( output_frame )
    2158             :         {
    2159           0 :             case L_FRAME8k:
    2160           0 :                 filtIdx = 8;
    2161           0 :                 move16();
    2162           0 :                 BREAK;
    2163         133 :             case L_FRAME16k:
    2164         133 :                 filtIdx = 9;
    2165         133 :                 move16();
    2166         133 :                 BREAK;
    2167        2685 :             case L_FRAME32k:
    2168        2685 :                 filtIdx = 10;
    2169        2685 :                 move16();
    2170        2685 :                 BREAK;
    2171       11117 :             case L_FRAME48k:
    2172       11117 :                 filtIdx = 11;
    2173       11117 :                 move16();
    2174       11117 :                 BREAK;
    2175           0 :             default:
    2176           0 :                 assert( 0 );
    2177             :         }
    2178             :     }
    2179             :     ELSE
    2180             :     {
    2181      117646 :         filtIdx = -1;
    2182      117646 :         move16();
    2183             :     }
    2184             : 
    2185             : 
    2186             :     /******** Previous-frame part ********/
    2187             : 
    2188     1124260 :     tcx_ltp_synth_filter32( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev,
    2189     1124260 :                             st->pit_res_max_past, NULL, 0, hTcxLtpDec->tcxltp_filt_idx_prev );
    2190             : 
    2191             :     /******** Transition part ********/
    2192     1124260 :     IF( NE_16( st->element_mode, EVS_MONO ) )
    2193             :     {
    2194     1124260 :         test();
    2195     1124260 :         test();
    2196     1124260 :         test();
    2197     1124260 :         test();
    2198     1124260 :         test();
    2199     1124260 :         test();
    2200     1124260 :         test();
    2201     1124260 :         test();
    2202     1124260 :         IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    2203             :         {
    2204             :             /* The filtering is deactivated, just copy input to the output */
    2205      924734 :             Copy32( sig_in + delay, sig_out + delay, L_transition ); /* sig_q */
    2206             :         }
    2207      199526 :         ELSE IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev != 0 )
    2208             :         {
    2209             :             /* Filtering with the first filter unit */
    2210       27633 :             tcx_ltp_synth_filter_10_fx( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
    2211             :         }
    2212      171893 :         ELSE IF( gain != 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    2213             :         {
    2214             :             /* Filtering with the second filter unit */
    2215       28847 :             tcx_ltp_synth_filter_01_fx( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
    2216             :         }
    2217      143046 :         ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) && EQ_16( st->pit_res_max, st->pit_res_max_past ) && EQ_16( filtIdx, hTcxLtpDec->tcxltp_filt_idx_prev ) )
    2218             :         {
    2219       22422 :             tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    2220             :         }
    2221             :         ELSE
    2222             :         {
    2223             :             /* Filtering with the first filter unit, followed by the filtering with the second filter unit */
    2224      120624 :             tcx_ltp_synth_filter_11_unequal_pitch_fx( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx,
    2225      120624 :                                                       hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
    2226             :         }
    2227             :     }
    2228             :     ELSE
    2229             :     {
    2230           0 :         test();
    2231           0 :         test();
    2232           0 :         test();
    2233           0 :         IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    2234             :         {
    2235           0 :             Copy32( sig_in + delay, sig_out + delay, L_transition ); /* sig_q */
    2236             :         }
    2237           0 :         ELSE IF( hTcxLtpDec->tcxltp_gain_post_prev == 0 )
    2238             :         {
    2239           0 :             tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int,
    2240           0 :                                     pitch_fr, gain, st->pit_res_max, NULL, 1, filtIdx );
    2241             :         }
    2242           0 :         ELSE IF( gain == 0 )
    2243             :         {
    2244           0 :             tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev,
    2245           0 :                                     hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, NULL, -1, hTcxLtpDec->tcxltp_filt_idx_prev );
    2246             :         }
    2247           0 :         ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) )
    2248             :         {
    2249           0 :             tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    2250             :         }
    2251             :         ELSE
    2252             :         {
    2253           0 :             tcx_ltp_get_lpc_fx( sig_out + delay - output_frame, output_frame, A, lpcorder );
    2254             : 
    2255           0 :             tcx_ltp_get_zir_fx( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx );
    2256             : 
    2257           0 :             tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, 0, filtIdx );
    2258             :         }
    2259             :     }
    2260             : 
    2261             :     /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/
    2262             : 
    2263     1124260 :     tcx_ltp_synth_filter32( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
    2264             : 
    2265             : 
    2266             :     /******** Output ********/
    2267             : 
    2268             : 
    2269             :     /* copy to output */
    2270             : 
    2271     1124260 :     Copy32( sig_out, sig, output_frame ); /* sig_q */
    2272             : 
    2273             :     /* Update */
    2274     1124260 :     hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
    2275     1124260 :     move16();
    2276     1124260 :     hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
    2277     1124260 :     move16();
    2278     1124260 :     hTcxLtpDec->tcxltp_gain_post_prev = gain2;
    2279     1124260 :     move16();
    2280     1124260 :     hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
    2281     1124260 :     move16();
    2282     1124260 :     st->pit_res_max_past = st->pit_res_max;
    2283     1124260 :     Copy32( sig_out, hTcxLtpDec->tcxltp_mem_out_32, output_frame ); /* sig_q */
    2284     1124260 :     hTcxLtpDec->exp_tcxltp_mem_out = sub( 31, sig_q );
    2285     1124260 :     move16();
    2286     1124260 : }

Generated by: LCOV version 1.14