LCOV - code coverage report
Current view: top level - lib_enc - enc_acelp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1053 1138 92.5 %
Date: 2025-05-03 01:55:50 Functions: 23 24 95.8 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <assert.h>
       5             : #include "typedef.h"
       6             : #include <stdint.h>
       7             : #include <string.h>
       8             : #include "options.h"
       9             : #include "cnst.h"
      10             : //#include "prot_fx.h"
      11             : #include "basop_util.h"
      12             : #include "rom_com_fx.h"
      13             : #include "rom_com.h"
      14             : #include "rom_enc.h"
      15             : #include "prot_fx.h"     /* Function prototypes                    */
      16             : #include "prot_fx_enc.h" /* Function prototypes                    */
      17             : 
      18             : 
      19             : #define _2_   0x4000 /*Q12*/
      20             : #define _1_   0x2000 /*Q12*/
      21             : #define _1_Q9 0x200
      22             : 
      23             : static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ );
      24             : 
      25             : void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ );
      26             : 
      27             : void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ );
      28             : 
      29             : Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn );
      30             : 
      31             : void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ );
      32             : 
      33             : void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ );
      34             : 
      35             : void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ );
      36             : 
      37             : /*
      38             :  * E_ACELP_h_vec_corrx
      39             :  *
      40             :  * Parameters:
      41             :  *    h              I: scaled impulse response
      42             :  *    vec            I: vector to correlate with h[]
      43             :  *    track          I: track to use
      44             :  *    sign           I: sign vector
      45             :  *    rrixix         I: correlation of h[x] with h[x]
      46             :  *    cor            O: result of correlation (16 elements)
      47             :  *
      48             :  * Function:
      49             :  *    Calculate the correlations of h[] with vec[] for the specified track
      50             :  *
      51             :  * Returns:
      52             :  *    void
      53             :  */
      54     1758199 : void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ )
      55             : {
      56             :     Word16 i, j;
      57             :     Word16 dn, corr;
      58             :     Word16 *dn2;
      59             :     Word16 *p0, *p1, *p2;
      60             :     Word32 L_sum;
      61             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      62     1758199 :     Flag Overflow = 0;
      63     1758199 :     move32();
      64             : #endif
      65             : 
      66     1758199 :     dn2 = &dn2_pos[( track * 8 )]; /*Q0*/
      67     1758199 :     p0 = rrixix[track];            /*Q9*/
      68             : 
      69    13338987 :     FOR( i = 0; i < nb_pulse; i++ )
      70             :     {
      71    11580788 :         dn = dn2[i]; /*Q0*/
      72    11580788 :         move16();
      73    11580788 :         L_sum = L_deposit_l( 0 );
      74    11580788 :         p1 = h;        /*Qx*/
      75    11580788 :         p2 = &vec[dn]; /*Qx*/
      76   404359364 :         FOR( j = dn; j < L_SUBFR - 1; j++ )
      77             :         {
      78   392778576 :             L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /*2*Qx+1*/
      79             :         }
      80             : 
      81    11580788 :         corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/
      82             : 
      83             :         /*cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];*/
      84    11580788 :         j = shr( dn, 2 );
      85    11580788 :         if ( sign[dn] > 0 )
      86             :         {
      87     5709194 :             corr = add_o( p0[j], corr, &Overflow ); /*Q9*/
      88             :         }
      89    11580788 :         if ( sign[dn] < 0 )
      90             :         {
      91     5871594 :             corr = sub_o( p0[j], corr, &Overflow ); /*Q9*/
      92             :         }
      93             : 
      94    11580788 :         cor[j] = corr; /*Q9*/
      95    11580788 :         move16();
      96             :     }
      97     1758199 :     return;
      98             : }
      99             : 
     100     2561331 : void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ )
     101             : {
     102             :     Word16 i, j, pos, corr;
     103             :     Word16 *p0, *p1, *p2;
     104             :     Word32 L_sum;
     105             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     106     2561331 :     Flag Overflow = 0;
     107     2561331 :     move32();
     108             : #endif
     109             : 
     110     2561331 :     p0 = rrixix[track]; /*Q9*/
     111             : 
     112     2561331 :     pos = track; /*Q0*/
     113     2561331 :     move16();
     114    43542627 :     FOR( i = 0; i < 16; i++ )
     115             :     {
     116    40981296 :         L_sum = L_deposit_l( 0 );
     117    40981296 :         p1 = h;         /*Qx*/
     118    40981296 :         p2 = &vec[pos]; /*Qx*/
     119  1333853776 :         FOR( j = pos; j < L_SUBFR - 1; j++ )
     120             :         {
     121  1292872480 :             L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /* 2*Qx+1 */
     122             :         }
     123    40981296 :         corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/
     124             : 
     125             :         /*cor[i] = s * sign[track] + p0[i];*/
     126             : 
     127    40981296 :         if ( sign[pos] > 0 )
     128             :         {
     129    20253888 :             corr = add_o( *p0++, corr, &Overflow ); /*Q9*/
     130             :         }
     131    40981296 :         if ( sign[pos] < 0 )
     132             :         {
     133    20727408 :             corr = sub_o( *p0++, corr, &Overflow ); /*Q9*/
     134             :         }
     135    40981296 :         cor[i] = corr; /*Q9*/
     136    40981296 :         move16();
     137             : 
     138    40981296 :         pos = add( pos, 4 );
     139             :     }
     140     2561331 :     return;
     141             : }
     142             : 
     143             : 
     144             : /*
     145             :  * E_ACELP_2pulse_search
     146             :  *
     147             :  * Parameters:
     148             :  *    nb_pos_ix      I: nb of pos for pulse 1 (1..8)
     149             :  *    track_x        I: track of pulse 1
     150             :  *    track_y        I: track of pulse 2
     151             :  *    ps           I/O: correlation of all fixed pulses
     152             :  *    alp          I/O: energy of all fixed pulses
     153             :  *    ix             O: position of pulse 1
     154             :  *    iy             O: position of pulse 2
     155             :  *    dn             I: corr. between target and h[]
     156             :  *    dn2            I: vector of selected positions
     157             :  *    cor_x          I: corr. of pulse 1 with fixed pulses
     158             :  *    cor_y          I: corr. of pulse 2 with fixed pulses
     159             :  *    rrixiy         I: corr. of pulse 1 with pulse 2
     160             :  *
     161             :  * Function:
     162             :  *    Find the best positions of 2 pulses in a subframe
     163             :  *
     164             :  * Returns:
     165             :  *    void
     166             :  */
     167     1758199 : static void E_ACELP_2pulse_search( Word16 nb_pos_ix /*Q0*/, UWord8 track_x /*Q0*/, UWord8 track_y /*Q0*/, Word16 *ps /*Qdn*/, Word16 *alp /*Qx*/, Word16 *ix /*Q0*/, Word16 *iy /*Q0*/, Word16 dn[] /*Qdn*/, Word16 *dn2 /*Q0*/, Word16 cor_x[] /*Qx*/, Word16 cor_y[] /*Qx*/, Word16 ( *rrixiy )[256] /*Q9*/ )
     168             : {
     169             :     Word16 x, x2, y, i, *pos_x;
     170             :     Word16 ps0, ps1, alp2_16, ps2, sq;
     171             :     Word32 alp0, alp1, alp2, s;
     172             :     Word16 *p1, *p2;
     173             :     Word16 sqk[2], alpk[2], ik;
     174             :     Word32 xy_save;
     175     1758199 :     Word16 check = 0; /* debug code not instrumented */
     176             : 
     177             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     178     1758199 :     Flag Overflow = 0;
     179     1758199 :     move32();
     180             : #endif
     181             : 
     182             : 
     183             :     /* eight dn2 max positions per track */
     184             :     /*pos_x = &dn2[track_x << 3];                      SHIFT(1); PTR_INIT(1);*/
     185     1758199 :     pos_x = &dn2[( track_x * 8 )]; /*Qdn*/
     186     1758199 :     move16();
     187             : 
     188             :     /* save these to limit memory searches */
     189     1758199 :     alp0 = L_deposit_h( *alp ); /*Qx-16*/
     190     1758199 :     ps0 = *ps;                  /*Qdn*/
     191     1758199 :     move16();
     192             : 
     193     1758199 :     alpk[0] = 1;
     194     1758199 :     move16();
     195     1758199 :     sqk[0] = -1;
     196     1758199 :     move16();
     197     1758199 :     x2 = shr( pos_x[0], 2 ); /*Qdn*/
     198     1758199 :     if ( mac_ro( L_mac_o( L_mac_o( alp0, cor_x[x2], _1_, &Overflow ), cor_y[0], _1_, &Overflow ), rrixiy[track_x][( x2 * 16 )], _1_, &Overflow ) < 0 )
     199             :     {
     200           0 :         sqk[0] = 1;
     201           0 :         move16();
     202             :     }
     203     1758199 :     ik = 0;
     204     1758199 :     move16();
     205     1758199 :     xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/
     206             : 
     207             :     /* loop track 1 */
     208    13338987 :     FOR( i = 0; i < nb_pos_ix; i++ )
     209             :     {
     210    11580788 :         x = pos_x[i]; /*Qdn*/
     211    11580788 :         move16();
     212    11580788 :         x2 = shr( x, 2 );
     213             :         /* dn[x] has only nb_pos_ix positions saved */
     214             :         /*ps1 = ps0 + dn[x];*/
     215    11580788 :         ps1 = add( ps0, dn[x] ); /*Qdn*/
     216             : 
     217             :         /*alp1 = alp0 + cor_x[x2];*/
     218    11580788 :         alp1 = L_mac_o( alp0, cor_x[x2], _1_, &Overflow ); /*Q22*/
     219             : 
     220    11580788 :         p1 = cor_y;                         /*Qx*/
     221    11580788 :         p2 = &rrixiy[track_x][( x2 * 16 )]; /*Q9*/
     222             : 
     223   196873396 :         FOR( y = track_y; y < L_SUBFR; y += 4 )
     224             :         {
     225             :             /*ps2 = ps1 + dn[y];*/
     226   185292608 :             ps2 = add( ps1, dn[y] ); /*Qdn*/
     227   185292608 :             move16();
     228             : 
     229             :             /*alp2 = alp1 + (*p1++) + (*p2++);*/
     230   185292608 :             alp2 = L_mac_o( alp1, *p1++, _1_, &Overflow );   /*Qx+12+1*/
     231   185292608 :             alp2_16 = mac_ro( alp2, *p2++, _1_, &Overflow ); /*Q6*/
     232   185292608 :             alpk[1 - ik] = alp2_16;                          /*Q6*/
     233   185292608 :             move16();
     234             : 
     235             :             /*sq = ps2 * ps2;*/
     236   185292608 :             sq = mult( ps2, ps2 ); /*2*Qdn+1*/
     237   185292608 :             sqk[1 - ik] = sq;      /*2*Qdn+1*/
     238   185292608 :             move16();
     239             : 
     240             :             /*s = (alpk[ik] * sq) - (sqk[0] * alp2);*/
     241   185292608 :             s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp2_16 ); /*Q16*/
     242             : 
     243   185292608 :             if ( s > 0 )
     244             :             {
     245     8573753 :                 ik = sub( 1, ik );
     246     8573753 :                 move16();
     247     8573753 :                 check = 1; /* debug code not instrumented */
     248     8573753 :                 move16();
     249             :             }
     250   185292608 :             if ( s > 0 )
     251             :             {
     252     8573753 :                 xy_save = L_mac0( y, x, L_SUBFR ); /*Qdn*/
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257     1758199 :     assert( check ); /* debug code not instrumented */
     258             : 
     259     1758199 :     ps2 = extract_l( xy_save );      /*Qdn*/
     260     1758199 :     *iy = s_and( ps2, L_SUBFR - 1 ); /*Q0*/
     261     1758199 :     move16();
     262     1758199 :     *ix = lshr( ps2, 6 ); /*Q0*/
     263     1758199 :     move16();
     264             : 
     265             :     /**ps = ps0 + dn[*ix] + dn[*iy];*/
     266     1758199 :     *ps = add( ps0, add( dn[*ix], dn[*iy] ) ); /*Qdn*/
     267     1758199 :     move16();
     268             : 
     269     1758199 :     *alp = alpk[ik]; /*Q6*/
     270     1758199 :     move16();
     271     1758199 :     return;
     272             : }
     273             : 
     274             : 
     275             : /*
     276             :  * E_ACELP_1pulse_search
     277             :  *
     278             :  * Parameters:
     279             :  *    track_x        I: track of pulse 1
     280             :  *    track_y        I: track of pulse 2
     281             :  *    ps           I/O: correlation of all fixed pulses
     282             :  *    alp          I/O: energy of all fixed pulses
     283             :  *    ix             O: position of pulse 1
     284             :  *    dn             I: corr. between target and h[]
     285             :  *    cor_x          I: corr. of pulse 1 with fixed pulses
     286             :  *    cor_y          I: corr. of pulse 2 with fixed pulses
     287             :  *
     288             :  * Function:
     289             :  *    Find the best positions of 1 pulse in a subframe
     290             :  *
     291             :  * Returns:
     292             :  *    void
     293             :  */
     294      401566 : static void E_ACELP_1pulse_search( UWord8 tracks[2],
     295             :                                    Word16 *ps,     /*Qdn*/
     296             :                                    Word16 *alp,    /*Qx*/
     297             :                                    Word16 *ix,     /*Q0*/
     298             :                                    Word16 dn[],    /*Qdn*/
     299             :                                    Word16 cor_x[], /*Q6*/
     300             :                                    Word16 cor_y[] /*Q6*/ )
     301             : {
     302      401566 :     Word16 x, x_save = 0;
     303             :     Word16 ps0;
     304             :     Word16 ps1, sq;
     305             :     Word16 alp1;
     306             :     Word32 s, alp0;
     307             :     Word16 sqk[2], alpk[2], ik;
     308             :     Word16 ntracks, t;
     309      401566 :     Word16 check = 0; /* debug code not instrumented */
     310             : 
     311             :     /* save these to limit memory searches */
     312      401566 :     alp0 = L_deposit_h( *alp );
     313      401566 :     ps0 = *ps; /*Qdn*/
     314      401566 :     move16();
     315             : 
     316      401566 :     alpk[0] = 1;
     317      401566 :     move16();
     318      401566 :     sqk[0] = -1;
     319      401566 :     move16();
     320      401566 :     if ( mac_r_sat( alp0, cor_x[( tracks[0] / 4 )], _1_ ) < 0 )
     321             :     {
     322           0 :         sqk[0] = 1;
     323           0 :         move16();
     324             :     }
     325      401566 :     ik = 0;
     326      401566 :     move16();
     327             : 
     328      401566 :     ntracks = 1;
     329      401566 :     move16();
     330      401566 :     if ( NE_16( tracks[1], tracks[0] ) )
     331             :     {
     332      241025 :         ntracks = 2;
     333      241025 :         move16();
     334             :     }
     335     1044157 :     FOR( t = 0; t < ntracks; ++t )
     336             :     {
     337      642591 :         if ( t != 0 )
     338             :         {
     339      241025 :             cor_x = cor_y;
     340      241025 :             move16();
     341             :         }
     342    10924047 :         FOR( x = tracks[t]; x < L_SUBFR; x += 4 )
     343             :         {
     344             :             /*ps1 = ps0 + dn[x];                             ADD(1);*/
     345    10281456 :             ps1 = add( ps0, dn[x] ); /*Qdn*/
     346             : 
     347             :             /*alp1 = alp0 + cor_x[x>>2];                     SHIFT(1);ADD(1);*/
     348    10281456 :             alp1 = mac_r_sat( alp0, cor_x[( x / 4 )], _1_ ); /*Q6*/
     349    10281456 :             alpk[1 - ik] = alp1;                             /*Q6*/
     350    10281456 :             move16();
     351             : 
     352             :             /*sq = ps1 * ps1;                                MULT(1);*/
     353    10281456 :             sq = mult( ps1, ps1 ); /*2*Qdn+1*/
     354    10281456 :             sqk[1 - ik] = sq;      /*2*Qdn+1*/
     355    10281456 :             move16();
     356             : 
     357             :             /*s = (alpk * sq) - (sqk * alp1);                MULT(1);MAC(1); */
     358    10281456 :             s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp1 ); /*Q16*/
     359             : 
     360    10281456 :             if ( s > 0 )
     361             :             {
     362     1684596 :                 ik = sub( 1, ik );
     363     1684596 :                 check = 1; /* debug code not instrumented */
     364             :             }
     365    10281456 :             if ( s > 0 )
     366             :             {
     367     1684596 :                 x_save = x;
     368     1684596 :                 move16();
     369             :             }
     370             :         }
     371             : 
     372      642591 :         assert( check ); /* debug code not instrumented */
     373             :     }
     374      401566 :     *ps = add( ps0, dn[x_save] ); /*2*Qdn+1*/
     375      401566 :     move16();
     376      401566 :     *alp = alpk[ik]; /*Q6*/
     377      401566 :     move16();
     378      401566 :     *ix = x_save; /*Q0*/
     379      401566 :     move16();
     380      401566 :     return;
     381             : }
     382             : 
     383             : 
     384             : /*
     385             :  * E_ACELP_xh_corr
     386             :  *
     387             :  * Parameters:
     388             :  *    h           I: impulse response (of weighted synthesis filter) (Q12)
     389             :  *    x           I: target signal (Q0)
     390             :  *    y           O: correlation between x[] and h[] <12b
     391             :  *
     392             :  * Function:
     393             :  *    Compute the correlation between the target signal and the impulse
     394             :  *    response of the weighted synthesis filter.
     395             :  *
     396             :  *           y[i]=sum(j=i,l-1) x[j]*h[j-i], i=0,l-1
     397             :  *
     398             :  *    Vector size is L_SUBFR
     399             :  *
     400             :  * Returns:
     401             :  *    void
     402             :  */
     403           0 : static void E_ACELP_xh_corr( Word16 *x /*Qx*/, Word16 *y /*Qy*/, Word16 *h /*Q12*/, Word16 L_subfr /*Q0*/ )
     404             : {
     405             :     Word16 i, j, k;
     406             :     Word32 L_tmp, y32[L_SUBFR16k], L_maxloc, L_tot;
     407             : 
     408           0 :     assert( L_subfr <= L_SUBFR16k );
     409             : 
     410             :     /* first keep the result on 32 bits and find absolute maximum */
     411           0 :     L_tot = L_deposit_l( 1 );
     412             : 
     413           0 :     FOR( k = 0; k < 4; k++ )
     414             :     {
     415           0 :         L_maxloc = L_deposit_l( 0 );
     416           0 :         FOR( i = k; i < L_subfr; i += 4 )
     417             :         {
     418           0 :             L_tmp = L_mac0( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] Qx+Q12*/
     419           0 :             FOR( j = i; j < L_subfr - 1; j++ )
     420             :             {
     421           0 :                 L_tmp = L_mac0( L_tmp, x[j + 1], h[j + 1 - i] ); /*Qx+Q12*/
     422             :             }
     423             : 
     424           0 :             y32[i] = L_tmp; /*Qx+Q12*/
     425           0 :             move32();
     426           0 :             L_tmp = L_abs( L_tmp );              /*Qx+Q12*/
     427           0 :             L_maxloc = L_max( L_tmp, L_maxloc ); /*Qx+Q12*/
     428             :         }
     429             :         /* tot += 3*max / 8 */
     430           0 :         L_maxloc = L_shr( L_maxloc, 2 );
     431             :         /* Do not warn saturation of L_tot, since its for headroom estimation. */
     432             :         BASOP_SATURATE_WARNING_OFF_EVS
     433           0 :         L_tot = L_add_sat( L_tot, L_maxloc );             /* +max/4 */
     434           0 :         L_tot = L_add_sat( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */
     435             :         BASOP_SATURATE_WARNING_ON_EVS
     436             :     }
     437             : 
     438             :     /* Find the number of right shifts to do on y32[] so that    */
     439             :     /* 6.0 x sumation of max of dn[] in each track not saturate. */
     440             : 
     441           0 :     j = sub( norm_l( L_tot ), 4 + 16 ); /* 4 -> 16 x tot */
     442             : 
     443           0 :     Copy_Scale_sig_32_16( y32, y, L_subfr, j ); /*Qy = Qx+Q12+j*/
     444           0 :     return;
     445             : }
     446             : 
     447             : /**
     448             :  * \brief calculate autocorrelation of vector x
     449             :  * \param x input vector 4Q11
     450             :  * \param y output (autocorrelation coefficients)
     451             :  * \param L_subfr length of x (and y)
     452             :  * \param bits amount of target headroom bits for y
     453             :  * \return exponent of y
     454             :  */
     455        6409 : Word16 E_ACELP_hh_corr( Word16 *x /*Q11*/, Word16 *y /*Qy*/, Word16 L_subfr /*Q0*/, Word16 bits /*Q0*/ )
     456             : {
     457        6409 :     Word16 i, j, k = 0; /* initialize just to avoid compiler warning */
     458             :     Word32 L_tmp, L_sum;
     459             : 
     460      410176 :     FOR( i = 0; i < L_subfr - 1; i++ )
     461             :     {
     462             :         Word64 L_tmp_64;
     463             :         Word64 L_sum_64;
     464             : 
     465      403767 :         L_tmp_64 = W_mult0_16_16( x[i], x[0] ); /*Q22*/
     466     6761495 :         FOR( j = i + 2; j < L_subfr; j += 2 )
     467             :         {
     468     6357728 :             L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/
     469             :         }
     470      403767 :         L_sum_64 = L_tmp_64;
     471      403767 :         move64();
     472             : 
     473      403767 :         L_tmp_64 = W_mult0_16_16( x[i + 1], x[1] ); /*Q22*/
     474     6562816 :         FOR( j = i + 3; j < L_subfr; j += 2 )
     475             :         {
     476     6159049 :             L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/
     477             :         }
     478      403767 :         L_sum_64 = W_add_nosat( W_shr( L_sum_64, 1 ), W_shr( L_tmp_64, 1 ) );
     479      403767 :         L_sum = W_sat_l( L_sum_64 ); /*Q22*/
     480             :         /* L_sum = L_shr( L_sum, 1 ); */
     481      403767 :         if ( i == 0 )
     482             :         {
     483        6409 :             k = norm_l( L_sum );
     484             :         }
     485      403767 :         if ( i == 0 )
     486             :         {
     487        6409 :             k = sub( k, bits );
     488             :         }
     489             : 
     490      403767 :         y[i] = round_fx( L_shl( L_sum, k ) ); /*Q22+k-16*/
     491             :     }
     492             : 
     493        6409 :     L_tmp = L_mult0( x[i], x[0] ); /*Q22*/
     494        6409 :     L_sum = L_shr( L_tmp, 1 );
     495        6409 :     y[i] = round_fx( L_shl( L_sum, k ) ); /*Qy = Q22+k-16*/
     496             : 
     497        6409 :     k = add( 1, k );
     498             : 
     499        6409 :     return k;
     500             : }
     501             : 
     502             : /*
     503             :  * E_ACELP_xy1_corr
     504             :  *
     505             :  * Parameters:
     506             :  *    xn          I: target signal
     507             :  *    y1          I: filtered adaptive codebook excitation
     508             :  *    g_coeff     O: correlations <y1,y1>  and -2<xn,y1>
     509             :  *    norm_flag   I: flag to trigger normalization of the result
     510             :  *    L_subfr     I: length of data
     511             :  *    exp_xn      I: common exponent of xn[] and y1[]
     512             :  *
     513             :  * Function:
     514             :  *    Find the correlations between the target xn[] and the filtered adaptive
     515             :  *    codebook excitation y1[]. ( <y1,y1>  and -2<xn,y1> )
     516             :  *    Subframe size = L_SUBFR
     517             :  *
     518             :  * Returns:
     519             :  *    pitch gain  (0 ... 1.2F) (Q14)
     520             :  */
     521        4350 : Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn )
     522             : {
     523             :     Word16 i, Q_xn;
     524             :     Word16 xy, yy, exp_xy, exp_yy, gain;
     525             :     Word32 L_off;
     526             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     527        4350 :     Flag Overflow = 0;
     528        4350 :     move32();
     529             : #endif
     530             : 
     531        4350 :     L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, s_min( add( exp_xn, exp_xn ), 31 ) );
     532        4350 :     L_off = L_max( 1, L_off ); /* ensure at least a '1' */
     533             : 
     534             :     /* Compute scalar product t1: <y1[] * y1[]> */
     535        4350 :     yy = round_fx_o( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ), &Overflow ); /*Q15 - exp_yy*/
     536             : 
     537             :     /* Compute scalar product t0: <xn[] * y1[]> */
     538        4350 :     xy = round_fx_o( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ), &Overflow ); /*Q15 - exp_xy*/
     539             :     /* Compute doubled format out of the exponent */
     540        4350 :     Q_xn = shl( sub( 15, exp_xn ), 1 );
     541        4350 :     g_corr->y1y1 = yy;
     542        4350 :     move16();
     543        4350 :     g_corr->y1y1_e = sub( exp_yy, Q_xn );
     544        4350 :     move16();
     545        4350 :     g_corr->xy1 = xy;
     546        4350 :     move16();
     547        4350 :     g_corr->xy1_e = sub( exp_xy, Q_xn );
     548        4350 :     move16();
     549             : 
     550             :     /* If (xy < 0) gain = 0 */
     551        4350 :     IF( xy < 0 )
     552             :     {
     553          37 :         move16();
     554          37 :         gain = 0;
     555          37 :         GOTO bail;
     556             :     }
     557             : 
     558             :     /* compute gain = xy/yy */
     559             : 
     560        4313 :     xy = mult_r( xy, 0x4000 ); /* Be sure xy < yy Q15 - exp_xy*/
     561        4313 :     gain = div_s( xy, yy );    /*Q14*/
     562             : 
     563        4313 :     i = add( exp_xy, 1 - 1 ); /* -1 -> gain in Q14 */
     564        4313 :     i = sub( i, exp_yy );
     565             :     BASOP_SATURATE_WARNING_OFF_EVS
     566        4313 :     gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */
     567             :     BASOP_SATURATE_WARNING_ON_EVS
     568             :     /* gain = s_max(0, gain); */ /* see above xy < 0. */
     569             : 
     570             :     /* if (gain > 1.2) gain = 1.2  in Q14 */
     571             : 
     572        4313 :     gain = s_min( 19661 /*1.2f Q14*/ /* 19661 */, gain ); /*Q14*/
     573             : 
     574             :     /*Limit the energy of pitch contribution*/
     575        4313 :     IF( norm_flag )
     576             :     {
     577             :         Word16 tmp, exp_tmp, exp_div;
     578             : 
     579             :         /* Compute scalar product <xn[],xn[]> */
     580        4313 :         tmp = round_fx_o( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ), &Overflow ); /*Q15 - exp_tmp*/
     581             :         /* gain_p_snr = sqrt(<xn,xn>/<y1,y1>) */
     582        4313 :         tmp = BASOP_Util_Divide1616_Scale( tmp, yy, &exp_div );
     583        4313 :         exp_tmp = add( sub( exp_tmp, exp_yy ), exp_div );
     584             : 
     585        4313 :         tmp = Sqrt16( tmp, &exp_tmp ); /*Q15 - exp_tmp*/
     586             : 
     587             :         /* Note: shl works as shl or shr. */
     588        4313 :         exp_tmp = sub( exp_tmp, 1 );
     589             :         BASOP_SATURATE_WARNING_OFF_EVS
     590        4313 :         tmp = round_fx_o( L_shl_o( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp, &Overflow ), &Overflow ); /*Q14*/
     591             :         BASOP_SATURATE_WARNING_ON_EVS
     592             : 
     593        4313 :         gain = s_min( gain, tmp ); /*Q14*/
     594             :     }
     595             : 
     596           0 : bail:
     597             : 
     598             : 
     599        4350 :     return ( gain );
     600             : }
     601             : 
     602             : /*
     603             :  * E_ACELP_xy2_corr
     604             :  *
     605             :  * Parameters:
     606             :  *    xn          I: target signal in Q_xn
     607             :  *    y1          I: filtered adaptive codebook excitation in Q_xn
     608             :  *    y2          I: filtered fixed codebook excitation in Q9
     609             :  *    g_corr      O: correlations <y2,y2>, -2<xn,y2>, 2<y1,y2>
     610             :  *    L_subfr     I: subframe size
     611             :  *
     612             :  * Function:
     613             :  *    Find the correlations between the target xn[], the filtered adaptive
     614             :  *    codebook exc. y1[], and the filtered fixed codebook innovation y2[].
     615             :  *    ( <y2,y2> , -2<xn,y2> and 2<y1,y2> )
     616             :  *    Subrame size = L_SUBFR
     617             :  *
     618             :  * Returns:
     619             :  *    pitch gain  (0 ... 1.2F)
     620             :  */
     621       11020 : void E_ACELP_xy2_corr( Word16 xn[] /*Q_xn*/, Word16 y1[] /*Q_xn*/, Word16 y2[] /*Q9*/, ACELP_CbkCorr *g_corr, Word16 L_subfr /*Q0*/, Word16 exp_xn )
     622             : {
     623             :     Word16 xny2, y2y2, y1y2, xx, exp_xny2, exp_y2y2, exp_y1y2, exp_xx;
     624             :     Word32 L_off;
     625             : 
     626             :     BASOP_SATURATE_ERROR_ON_EVS;
     627             : 
     628             :     /* Compute scalar product <y2[],y2[]> */
     629       11020 :     y2y2 = extract_h( Dot_product15_offs( y2, y2, L_subfr, &exp_y2y2, 5243l /*0.01f Q19*/ ) ); /*Q15-exp_y2y2*/
     630             : 
     631             :     /* L_off = 1L; */
     632       11020 :     L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, sub( 30 - 9, exp_xn ) );
     633             : 
     634             :     /* Compute scalar product <xn[],y2[]> */
     635       11020 :     xny2 = extract_h( Dot_product12_offs( xn, y2, L_subfr, &exp_xny2, L_off ) ); /*Q15-exp_xny2*/
     636             : 
     637             :     /* Compute scalar product <y1[],y2[]> */
     638       11020 :     y1y2 = extract_h( Dot_product12_offs( y1, y2, L_subfr, &exp_y1y2, L_off ) ); /*Q15-exp_y1y2*/
     639             : 
     640             :     /* Compute scalar product <xn[],xn[]> */
     641       11020 :     L_off = L_shr( 21474836l /*0.01f Q31*/, s_min( 31, sub( 30, shl( exp_xn, 1 ) ) ) );
     642       11020 :     xx = extract_h( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, L_off ) ); /*Q15-exp_xx*/
     643             : 
     644             : 
     645       11020 :     g_corr->y2y2 = y2y2;
     646       11020 :     move16();
     647       11020 :     g_corr->y2y2_e = exp_y2y2;
     648       11020 :     move16();
     649       11020 :     g_corr->xy2 = xny2;
     650       11020 :     move16();
     651       11020 :     g_corr->xy2_e = exp_xny2;
     652       11020 :     move16();
     653       11020 :     g_corr->y1y2 = y1y2;
     654       11020 :     move16();
     655       11020 :     g_corr->y1y2_e = exp_y1y2;
     656       11020 :     move16();
     657       11020 :     g_corr->xx = xx;
     658       11020 :     move16();
     659       11020 :     g_corr->xx_e = exp_xx;
     660       11020 :     move16();
     661             : 
     662             : 
     663             :     BASOP_SATURATE_ERROR_OFF_EVS;
     664       11020 :     return;
     665             : }
     666             : 
     667             : 
     668             : /*
     669             :  * E_ACELP_codebook_target_update
     670             :  *
     671             :  * Parameters:
     672             :  *    x           I: old target (for pitch search) (Q_xn)
     673             :  *    x2          O: new target (for codebook search) (Q_xn)
     674             :  *    y           I: filtered adaptive codebook vector (Q_xn)
     675             :  *    gain        I: adaptive codebook gain (Q14)
     676             :  *
     677             :  * Function:
     678             :  *    Update the target vector for codebook search.
     679             :  *    Subframe size = L_SUBFR
     680             :  * Returns:
     681             :  *    void
     682             :  */
     683        7370 : void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ )
     684             : {
     685             :     Word16 i, Q15_flag;
     686             :     Word32 L_tmp;
     687             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     688        7370 :     Flag Overflow = 0;
     689        7370 :     move32();
     690             : #endif
     691        7370 :     assert( gain >= 0 );
     692             : 
     693        7370 :     Q15_flag = 0;
     694        7370 :     move16();
     695        7370 :     if ( LT_16( gain, 1 << 14 ) )
     696             :     {
     697        6314 :         Q15_flag = 1;
     698        6314 :         move16();
     699             :     }
     700        7370 :     gain = shl( gain, Q15_flag ); /*Q14*/
     701             : 
     702      479050 :     FOR( i = 0; i < L_subfr; i++ )
     703             :     {
     704      471680 :         L_tmp = L_deposit_h( x[i] ); /*Q_xn+16*/
     705      471680 :         if ( Q15_flag == 0 )
     706             :         {
     707       67584 :             L_tmp = L_msu_o( L_tmp, y[i], gain, &Overflow ); /*Q_xn+15*/
     708             :         }
     709      471680 :         x2[i] = msu_ro( L_tmp, y[i], gain, &Overflow ); /*Q_xn*/
     710      471680 :         move16();
     711             :     }
     712        7370 : }
     713             : 
     714             : 
     715             : /*
     716             :  * E_ACELP_pulsesign
     717             :  *
     718             :  * Parameters:
     719             :  *    cn          I: residual after long term prediction   <12b
     720             :  *    dn          I: corr. between target and h[].         <12b
     721             :  *    dn2         I/O: dn2[] = mix of dn[] and cn[]
     722             :  *    sign        O: sign of pulse 0 or -1
     723             :  *    vec         O: negative sign of pulse
     724             :  *    alp         I: energy of all fixed pulses Q13
     725             :  *    sign_val    I: value for signs
     726             :  *    L_subfr     I: subframe length
     727             :  *
     728             :  * Function:
     729             :  *    Determine sign of each pulse position, store them in "sign"
     730             :  *    and change dn to all positive.
     731             :  *    Subframe size = L_SUBFR
     732             :  * Returns:
     733             :  *    void
     734             :  */
     735      575647 : void E_ACELP_pulsesign( const Word16 cn[] /*Q_xn*/, Word16 dn[] /*Qdn*/, Word16 dn2[] /*Qdn2*/, Word16 sign[] /*Q13*/, Word16 vec[] /*Q15*/, const Word16 alp /*Q13*/, const Word16 sign_val /*Q15*/, const Word16 L_subfr /*Q0*/ )
     736             : {
     737             :     Word16 i;
     738             :     Word32 Lval, Lcor;
     739             :     Word16 k_cn, k_dn, sign_neg, e_dn, e_cn;
     740             :     Word16 signs[3];
     741             :     Word16 *ptr16;
     742             :     Word16 val, index;
     743             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     744      575647 :     Flag Overflow = 0;
     745      575647 :     move32();
     746             : #endif
     747             : 
     748             : 
     749             :     /* calculate energy for normalization of cn[] and dn[] */
     750      575647 :     Lval = L_mac0( 1, cn[0], cn[0] ); /*2*Q_xn*/
     751      575647 :     Lcor = L_mac0( 1, dn[0], dn[0] ); /*2*Qdn*/
     752             : 
     753    36841408 :     FOR( i = 1; i < L_subfr; i++ )
     754             :     {
     755    36265761 :         Lval = L_mac0_o( Lval, cn[i], cn[i], &Overflow ); /*2*Q_xn*/
     756    36265761 :         Lcor = L_mac0( Lcor, dn[i], dn[i] );              /*2*Qdn*/
     757             :     }
     758             : 
     759      575647 :     e_dn = 31;
     760      575647 :     move16();
     761      575647 :     e_cn = 31;
     762      575647 :     move16();
     763             : 
     764      575647 :     Lval = Sqrt32( Lval, &e_dn ); /*Q31 - e_dn*/
     765      575647 :     Lcor = Sqrt32( Lcor, &e_cn ); /*Q31 - e_cn*/
     766      575647 :     i = sub( e_dn, e_cn );
     767      575647 :     if ( i < 0 )
     768      352100 :         Lval = L_shl( Lval, i );
     769      575647 :     if ( i > 0 )
     770       91521 :         Lcor = L_shr( Lcor, i );
     771             : 
     772      575647 :     k_dn = round_fx_o( Lval, &Overflow ); /*Q15 - e_dn*/
     773      575647 :     k_cn = round_fx_o( Lcor, &Overflow ); /*Q15 - e_cn*/
     774             : 
     775      575647 :     k_cn = mult_r( 0x2000, k_cn ); /* 1 in Q13 */
     776      575647 :     k_dn = mult_r( alp, k_dn );    /* alp in Q13 */
     777             : 
     778      575647 :     sign_neg = negate( sign_val ); /*Q15*/
     779             : 
     780      575647 :     signs[0] = sign_neg; /*Q15*/
     781      575647 :     move16();
     782      575647 :     signs[1] = sign_val; /*Q15*/
     783      575647 :     move16();
     784      575647 :     signs[2] = sign_neg; /*Q15*/
     785      575647 :     move16();
     786      575647 :     ptr16 = &signs[1]; /*Q15*/
     787             : 
     788    37417055 :     FOR( i = 0; i < L_subfr; i++ )
     789             :     {
     790             :         /*cor = (s * cn[i]) + (alp * dn[i]);                        MULT(1);MAC(1);*/
     791    36841408 :         Lcor = L_mult( cn[i], k_cn );                                 /*Q_xn + Q15 - e_cn + 1*/
     792    36841408 :         Lcor = L_mac( Lcor, dn[i], k_dn );                            /*Qdn + Q15 - e_dn + 1*/
     793    36841408 :         val = round_fx_o( L_shl_o( Lcor, 4, &Overflow ), &Overflow ); /*shifting by 4 may overflow but improves accuracy Qdn + 4 - e_dn*/
     794             : 
     795    36841408 :         index = shr( val, 15 );
     796    36841408 :         sign[i] = ptr16[index];    /*Q15*/
     797    36841408 :         move16();                  /* yields -1 (when ps < 0) or 0 (when ps >= 0) */
     798    36841408 :         vec[i] = ptr16[index + 1]; /*Q15*/
     799    36841408 :         move16();
     800             : 
     801    36841408 :         if ( val < 0 )
     802             :         {
     803    18557452 :             dn[i] = negate( dn[i] ); /*Qdn*/
     804    18557452 :             move16();
     805             :         }
     806    36841408 :         dn2[i] = abs_s( val ); /*Qdn2 = Qdn + 4 - e_dn*/
     807    36841408 :         move16();              /* dn2[] = mix of dn[] and cn[]            */
     808             :     }
     809      575647 : }
     810             : 
     811             : 
     812      575647 : void E_ACELP_findcandidates( Word16 dn2[] /*Qx*/, Word16 dn2_pos[] /*Q0*/, Word16 pos_max[] /*Q0*/ )
     813             : {
     814             :     Word16 i, k, j, i8;
     815             :     Word16 *ps_ptr;
     816             : 
     817     2878235 :     FOR( i = 0; i < 4; i++ )
     818             :     {
     819     2302588 :         i8 = shl( i, 3 );
     820    20723292 :         FOR( k = i8; k < i8 + 8; k++ )
     821             :         {
     822    18420704 :             ps_ptr = &dn2[i]; /*Qx*/
     823             : 
     824   294731264 :             FOR( j = i + 4; j < L_SUBFR; j += 4 )
     825             :             {
     826   276310560 :                 if ( GT_16( dn2[j], *ps_ptr ) )
     827             :                 {
     828    43353901 :                     ps_ptr = &dn2[j]; /*Qx*/
     829    43353901 :                     move16();
     830             :                 }
     831             :             }
     832             : 
     833    18420704 :             *ps_ptr = -1; /* dn2 < 0 when position is selected */
     834    18420704 :             move16();
     835    18420704 :             dn2_pos[k] = (Word16) ( ps_ptr - dn2 );
     836    18420704 :             move16();
     837             :         }
     838     2302588 :         pos_max[i] = dn2_pos[i8]; /*Q0*/
     839     2302588 :         move16();
     840             :     }
     841      575647 : }
     842             : 
     843             : 
     844    11637568 : static void E_ACELP_apply_sign( Word16 *p0 /*Qx*/, Word16 *psign0 /*Q15*/ )
     845             : {
     846    11637568 :     p0[0] = mult_r( p0[0], psign0[0] ); /*Qx*/
     847    11637568 :     move16();
     848    11637568 :     p0[1] = mult_r( p0[1], psign0[4] );
     849    11637568 :     move16();
     850    11637568 :     p0[2] = mult_r( p0[2], psign0[8] );
     851    11637568 :     move16();
     852    11637568 :     p0[3] = mult_r( p0[3], psign0[12] );
     853    11637568 :     move16();
     854    11637568 :     p0[4] = mult_r( p0[4], psign0[16] );
     855    11637568 :     move16();
     856    11637568 :     p0[5] = mult_r( p0[5], psign0[20] );
     857    11637568 :     move16();
     858    11637568 :     p0[6] = mult_r( p0[6], psign0[24] );
     859    11637568 :     move16();
     860    11637568 :     p0[7] = mult_r( p0[7], psign0[28] );
     861    11637568 :     move16();
     862    11637568 :     p0[8] = mult_r( p0[8], psign0[32] );
     863    11637568 :     move16();
     864    11637568 :     p0[9] = mult_r( p0[9], psign0[36] );
     865    11637568 :     move16();
     866    11637568 :     p0[10] = mult_r( p0[10], psign0[40] );
     867    11637568 :     move16();
     868    11637568 :     p0[11] = mult_r( p0[11], psign0[44] );
     869    11637568 :     move16();
     870    11637568 :     p0[12] = mult_r( p0[12], psign0[48] );
     871    11637568 :     move16();
     872    11637568 :     p0[13] = mult_r( p0[13], psign0[52] );
     873    11637568 :     move16();
     874    11637568 :     p0[14] = mult_r( p0[14], psign0[56] );
     875    11637568 :     move16();
     876    11637568 :     p0[15] = mult_r( p0[15], psign0[60] );
     877    11637568 :     move16();
     878    11637568 : }
     879             : 
     880      181837 : void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ )
     881             : {
     882             :     Word16 i;
     883             : 
     884    11819405 :     FOR( i = 0; i < L_subfr; i++ )
     885             :     {
     886    11637568 :         h_inv[i] = negate( h[i] );
     887    11637568 :         move16();
     888             :     }
     889      181837 : }
     890             : 
     891             : 
     892      181837 : void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ )
     893             : {
     894             : 
     895             :     Word16 *p0, *p1, *p2, *p3, *psign0, *psign1, *psign2, *psign3;
     896             :     Word16 *ptr_h1, *ptr_h2, *ptr_hf;
     897             :     Word32 cor;
     898             :     Word16 i, /* j, */ k, pos;
     899             : 
     900             :     /*
     901             :      * Compute rrixix[][] needed for the codebook search.
     902             :      */
     903             : 
     904             :     /* storage order --> i3i3, i2i2, i1i1, i0i0 */
     905             : 
     906             :     /* Init pointers to last position of rrixix[] */
     907      181837 :     p0 = &rrixix[0][16 - 1]; /* Q9 */
     908      181837 :     p1 = &rrixix[1][16 - 1];
     909      181837 :     p2 = &rrixix[2][16 - 1];
     910      181837 :     p3 = &rrixix[3][16 - 1];
     911             : 
     912      181837 :     ptr_h1 = h; /*Q12*/
     913      181837 :     cor = L_deposit_l( 0 );
     914     3091229 :     FOR( i = 0; i < 16; i++ )
     915             :     {
     916     2909392 :         cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
     917     2909392 :         ptr_h1++;
     918     2909392 :         *p3-- = round_fx( L_shr( cor, 1 ) );  /* Q9 */
     919     2909392 :         cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
     920     2909392 :         ptr_h1++;
     921     2909392 :         *p2-- = round_fx( L_shr( cor, 1 ) );  /* Q9 */
     922     2909392 :         cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
     923     2909392 :         ptr_h1++;
     924     2909392 :         *p1-- = round_fx( L_shr( cor, 1 ) );  /* Q9 */
     925     2909392 :         cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
     926     2909392 :         ptr_h1++;
     927     2909392 :         *p0-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */
     928             :     }
     929             : 
     930             : 
     931             :     /*
     932             :      * Compute rrixiy[][] needed for the codebook search.
     933             :      */
     934             : 
     935             :     /* storage order --> i2i3, i1i2, i0i1, i3i0 */
     936             : 
     937      181837 :     pos = 256 - 1;
     938      181837 :     move16();
     939      181837 :     ptr_hf = h + 1; /*Q12*/
     940     3091229 :     FOR( k = 0; k < 16; k++ )
     941             :     {
     942     2909392 :         p3 = &rrixiy[2][pos]; /* Q9 */
     943     2909392 :         p2 = &rrixiy[1][pos];
     944     2909392 :         p1 = &rrixiy[0][pos];
     945     2909392 :         p0 = &rrixiy[3][pos - 16];
     946             : 
     947     2909392 :         cor = L_deposit_h( 0 );
     948     2909392 :         ptr_h1 = h;      /*Q12*/
     949     2909392 :         ptr_h2 = ptr_hf; /*Q12*/
     950             : 
     951    24729832 :         FOR( i = k; i < 16 - 1; i++ )
     952             :         {
     953    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     954    21820440 :             *p3 = round_fx( cor );                    /*Q9*/
     955    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     956    21820440 :             *p2 = round_fx( cor );                    /*Q9*/
     957    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     958    21820440 :             *p1 = round_fx( cor );                    /*Q9*/
     959    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     960    21820440 :             *p0 = round_fx( cor );                    /*Q9*/
     961             : 
     962    21820440 :             p3 -= ( 16 + 1 );
     963    21820440 :             p2 -= ( 16 + 1 );
     964    21820440 :             p1 -= ( 16 + 1 );
     965    21820440 :             p0 -= ( 16 + 1 );
     966             :         }
     967     2909392 :         cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     968     2909392 :         *p3 = round_fx( cor );                    /*Q9*/
     969     2909392 :         cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     970     2909392 :         *p2 = round_fx( cor );                    /*Q9*/
     971     2909392 :         cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
     972     2909392 :         *p1 = round_fx( cor );                    /*Q9*/
     973     2909392 :         move16();
     974     2909392 :         move16();
     975     2909392 :         move16();
     976             : 
     977     2909392 :         pos -= 16;
     978     2909392 :         move16();
     979     2909392 :         ptr_hf += 4;
     980             :     }
     981             : 
     982             :     /* storage order --> i3i0, i2i3, i1i2, i0i1 */
     983             : 
     984      181837 :     pos = 256 - 1;
     985      181837 :     move16();
     986      181837 :     ptr_hf = h + 3; /*Q12*/
     987     3091229 :     FOR( k = 0; k < 16; k++ )
     988             :     {
     989     2909392 :         p3 = &rrixiy[3][pos]; /*Q9*/
     990     2909392 :         p2 = &rrixiy[2][pos - 1];
     991     2909392 :         p1 = &rrixiy[1][pos - 1];
     992     2909392 :         p0 = &rrixiy[0][pos - 1];
     993             : 
     994     2909392 :         cor = L_deposit_h( 0 );
     995     2909392 :         ptr_h1 = h;      /*Q12*/
     996     2909392 :         ptr_h2 = ptr_hf; /*Q12*/
     997    24729832 :         FOR( i = k; i < 16 - 1; i++ )
     998             :         {
     999    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
    1000    21820440 :             *p3 = round_fx( cor );                    /*Q9*/
    1001    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
    1002    21820440 :             *p2 = round_fx( cor );                    /*Q9*/
    1003    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
    1004    21820440 :             *p1 = round_fx( cor );                    /*Q9*/
    1005    21820440 :             cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
    1006    21820440 :             *p0 = round_fx( cor );                    /*Q9*/
    1007    21820440 :             move16();
    1008    21820440 :             move16();
    1009    21820440 :             move16();
    1010    21820440 :             move16();
    1011             : 
    1012    21820440 :             p3 -= ( 16 + 1 );
    1013    21820440 :             p2 -= ( 16 + 1 );
    1014    21820440 :             p1 -= ( 16 + 1 );
    1015    21820440 :             p0 -= ( 16 + 1 );
    1016             :         }
    1017     2909392 :         cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
    1018     2909392 :         *p3 = round_fx( cor );                    /*Q9*/
    1019     2909392 :         move16();
    1020             : 
    1021     2909392 :         pos--;
    1022     2909392 :         ptr_hf += 4;
    1023             :     }
    1024             : 
    1025             :     /*
    1026             :      * Modification of rrixiy[][] to take signs into account.
    1027             :      */
    1028             : 
    1029      181837 :     p0 = &rrixiy[0][0]; /*Q9*/
    1030             : 
    1031             :     /* speed-up: 11% */
    1032      181837 :     p1 = &rrixiy[1][0];
    1033      181837 :     p2 = &rrixiy[2][0];
    1034      181837 :     p3 = &rrixiy[3][0];
    1035             : 
    1036     3091229 :     FOR( i = 0; i < L_SUBFR; i += 4 )
    1037             :     {
    1038             : 
    1039     2909392 :         psign0 = &vec[1]; /*Q15*/
    1040     2909392 :         if ( sign[i + 0] > 0 )
    1041     1438784 :             psign0 = &sign[1];
    1042             : 
    1043     2909392 :         psign1 = &vec[2]; /*Q15*/
    1044     2909392 :         if ( sign[i + 1] > 0 )
    1045     1439199 :             psign1 = &sign[2];
    1046             : 
    1047     2909392 :         psign2 = &vec[3]; /*Q15*/
    1048     2909392 :         if ( sign[i + 2] > 0 )
    1049     1439007 :             psign2 = &sign[3];
    1050             : 
    1051     2909392 :         psign3 = &vec[0]; /*Q15*/
    1052     2909392 :         if ( sign[i + 3] > 0 )
    1053     1436145 :             psign3 = &sign[0];
    1054             : 
    1055     2909392 :         E_ACELP_apply_sign( p0, psign0 );
    1056     2909392 :         p0 += 16;
    1057             : 
    1058     2909392 :         E_ACELP_apply_sign( p1, psign1 );
    1059     2909392 :         p1 += 16;
    1060             : 
    1061     2909392 :         E_ACELP_apply_sign( p2, psign2 );
    1062     2909392 :         p2 += 16;
    1063             : 
    1064     2909392 :         E_ACELP_apply_sign( p3, psign3 );
    1065     2909392 :         p3 += 16;
    1066             :     }
    1067      181837 :     return;
    1068             : }
    1069             : 
    1070        3683 : void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ )
    1071             : {
    1072             :     Word16 sign[L_SUBFR], vec[L_SUBFR];
    1073             :     Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
    1074             :     Word16 rrixix[4][16];
    1075             :     Word16 rrixiy[4][256];
    1076             :     Word16 dn2[L_SUBFR];
    1077        3683 :     Word16 psk, ps, alpk, alp = 0;
    1078             :     Word16 codvec[NB_PULSE_MAX];
    1079             :     Word16 pos_max[4];
    1080             :     Word16 dn2_pos[8 * 4];
    1081             :     UWord8 ipos[NB_PULSE_MAX];
    1082             :     Word16 *p0, *p1, *p2, *p3;
    1083             :     Word16 *h, *h_inv;
    1084             :     Word16 i, j, k, l, st, pos;
    1085             :     Word16 val, tmp, scale;
    1086             :     Word32 s, L_tmp;
    1087             :     Word16 nb_pulse, nb_pulse_m2;
    1088        3683 :     Word16 check = 0; /* debug code not instrumented */
    1089             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1090        3683 :     Flag Overflow = 0;
    1091        3683 :     move32();
    1092             : #endif
    1093             : 
    1094             : 
    1095        3683 :     alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */
    1096        3683 :     move16();
    1097        3683 :     nb_pulse = config->nb_pulse;
    1098        3683 :     move16();
    1099        3683 :     nb_pulse_m2 = sub( nb_pulse, 2 );
    1100             : 
    1101        3683 :     set16_fx( codvec, 0, nb_pulse );
    1102             : 
    1103             :     /*
    1104             :      * Find sign for each pulse position.
    1105             :      */
    1106             : 
    1107        3683 :     E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR );
    1108             : 
    1109             :     /*
    1110             :      * Select the most important 8 position per track according to dn2[].
    1111             :      */
    1112        3683 :     E_ACELP_findcandidates( dn2, dn2_pos, pos_max );
    1113             : 
    1114             :     /*
    1115             :      * Compute h_inv[i].
    1116             :      */
    1117        3683 :     set16_fx( h_buf, 0, L_SUBFR );
    1118             : 
    1119        3683 :     set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR );
    1120             : 
    1121        3683 :     h = h_buf + L_SUBFR;
    1122        3683 :     h_inv = h_buf + ( 3 * L_SUBFR );
    1123             : 
    1124             :     /*Check the energy if it is too high then scale to prevent an overflow*/
    1125        3683 :     scale = 0;
    1126        3683 :     move16();
    1127        3683 :     L_tmp = L_deposit_l( 0 );
    1128             :     BASOP_SATURATE_WARNING_OFF_EVS
    1129      239395 :     FOR( i = 0; i < L_SUBFR; i++ )
    1130             :     {
    1131      235712 :         L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/
    1132             :     }
    1133        3683 :     val = extract_h( L_tmp ); /*Q9*/
    1134             :     BASOP_SATURATE_WARNING_ON_EVS
    1135             : 
    1136        3683 :     if ( GT_16( val, 0x2000 ) )
    1137             :     {
    1138         112 :         scale = -1;
    1139         112 :         move16();
    1140             :     }
    1141        3683 :     if ( GT_16( val, 0x7000 ) )
    1142             :     {
    1143           1 :         scale = -2;
    1144           1 :         move16();
    1145             :     }
    1146             : 
    1147        3683 :     Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/
    1148             : 
    1149        3683 :     E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR );
    1150             : 
    1151             : 
    1152             :     /*
    1153             :      * Compute correlation matrices needed for the codebook search.
    1154             :      */
    1155        3683 :     E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy );
    1156             : 
    1157             : 
    1158             :     /*
    1159             :      * Deep first search:
    1160             :      * ------------------
    1161             :      * 20 bits (4p):  4 iter x ((4x16)+(8x16))              = 768 tests
    1162             :      * 36 bits (8p):  4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
    1163             :      * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
    1164             :      *                                      +(8x16)+(8x16)) = 1248 tests
    1165             :      * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
    1166             :      *                        +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
    1167             :      */
    1168        3683 :     psk = -1;
    1169        3683 :     move16();
    1170        3683 :     alpk = 1;
    1171        3683 :     move16();
    1172             : 
    1173             :     /*Number of iterations*/
    1174       18273 :     FOR( k = 0; k < config->nbiter; k++ )
    1175             :     {
    1176       14590 :         E_ACELP_setup_pulse_search_pos( config, k, ipos );
    1177             : 
    1178             :         /* format of alp changes to Q(15-ALP2_E) */
    1179             : 
    1180       14590 :         pos = config->fixedpulses;
    1181       14590 :         move16();
    1182             : 
    1183       14590 :         IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
    1184             :         {
    1185       10782 :             ps = 0;
    1186       10782 :             move16();
    1187       10782 :             alp = 0;
    1188       10782 :             move16();
    1189       10782 :             set16_fx( vec, 0, L_SUBFR );
    1190             :         }
    1191        3808 :         ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */
    1192             :         {
    1193             :             /* first stage: fix 2 pulses */
    1194        3808 :             ind[0] = pos_max[ipos[0]];
    1195        3808 :             move16();
    1196        3808 :             ind[1] = pos_max[ipos[1]];
    1197        3808 :             move16();
    1198        3808 :             ps = add( dn[ind[0]], dn[ind[1]] );
    1199             : 
    1200             :             /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
    1201             :                     rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/
    1202             : 
    1203        3808 :             i = shr( ind[0], 2 );
    1204        3808 :             j = shr( ind[1], 2 );
    1205        3808 :             l = add( shl( i, 4 ), j );
    1206        3808 :             s = L_mult( rrixix[ipos[0]][i], _1_ );     /* Q9+Q12+1 */
    1207        3808 :             s = L_mac( s, rrixix[ipos[1]][j], _1_ );   /* Q9+Q12+1 */
    1208        3808 :             alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */
    1209             : 
    1210        3808 :             p0 = h - ind[0]; /*Q12+scale*/
    1211        3808 :             if ( sign[ind[0]] < 0 )
    1212             :             {
    1213        1820 :                 p0 = h_inv - ind[0]; /*Q12+scale*/
    1214             :             }
    1215             : 
    1216        3808 :             p1 = h - ind[1]; /*Q12+scale*/
    1217        3808 :             if ( sign[ind[1]] < 0 )
    1218             :             {
    1219        1820 :                 p1 = h_inv - ind[1]; /*Q12+scale*/
    1220             :             }
    1221             : 
    1222      247520 :             FOR( i = 0; i < L_SUBFR; i++ )
    1223             :             {
    1224      243712 :                 vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/
    1225      243712 :                 move16();
    1226             :             }
    1227             :         }
    1228             :         ELSE /* 3333 and above */
    1229             :         {
    1230             :             /* first stage: fix 4 pulses */
    1231             : 
    1232           0 :             ind[0] = pos_max[ipos[0]]; /*Q0*/
    1233           0 :             move16();
    1234           0 :             ind[1] = pos_max[ipos[1]]; /*Q0*/
    1235           0 :             move16();
    1236           0 :             ind[2] = pos_max[ipos[2]]; /*Q0*/
    1237           0 :             move16();
    1238           0 :             ind[3] = pos_max[ipos[3]]; /*Q0*/
    1239           0 :             move16();
    1240             : 
    1241             :             /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/
    1242           0 :             ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] );
    1243             : 
    1244           0 :             p0 = h - ind[0]; /*Q12+scale*/
    1245           0 :             if ( sign[ind[0]] < 0 )
    1246             :             {
    1247           0 :                 p0 = h_inv - ind[0]; /*Q12+scale*/
    1248             :             }
    1249             : 
    1250           0 :             p1 = h - ind[1]; /*Q12+scale*/
    1251           0 :             if ( sign[ind[1]] < 0 )
    1252             :             {
    1253           0 :                 p1 = h_inv - ind[1]; /*Q12+scale*/
    1254             :             }
    1255             : 
    1256           0 :             p2 = h - ind[2]; /*Q12+scale*/
    1257           0 :             if ( sign[ind[2]] < 0 )
    1258             :             {
    1259           0 :                 p2 = h_inv - ind[2]; /*Q12+scale*/
    1260             :             }
    1261             : 
    1262           0 :             p3 = h - ind[3]; /*Q12+scale*/
    1263           0 :             if ( sign[ind[3]] < 0 )
    1264             :             {
    1265           0 :                 p3 = h_inv - ind[3]; /*Q12+scale*/
    1266             :             }
    1267             : 
    1268           0 :             FOR( i = 0; i < L_SUBFR; i++ )
    1269             :             {
    1270           0 :                 vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/
    1271           0 :                 move16();
    1272             :             }
    1273             : 
    1274           0 :             L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/
    1275           0 :             FOR( i = 1; i < L_SUBFR; i++ )
    1276           0 :             L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/
    1277             : 
    1278           0 :             alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/
    1279             : 
    1280             :             /*alp *= 0.5F;      */
    1281             :         }
    1282             : 
    1283             :         /* other stages of 2 pulses */
    1284       14590 :         st = 0;
    1285       14590 :         move16();
    1286       55576 :         FOR( j = pos; j < nb_pulse; j += 2 )
    1287             :         {
    1288       40986 :             IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */
    1289             :             {
    1290             :                 /*
    1291             :                  * Calculate correlation of all possible positions
    1292             :                  * of the next 2 pulses with previous fixed pulses.
    1293             :                  * Each pulse can have 16 possible positions.
    1294             :                  */
    1295       40986 :                 E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] );
    1296             : 
    1297       40986 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
    1298             : 
    1299             :                 /*
    1300             :                  * Find best positions of 2 pulses.
    1301             :                  */
    1302       40986 :                 E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
    1303       40986 :                                        &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy );
    1304             :             }
    1305             :             ELSE /* single pulse search */
    1306             :             {
    1307           0 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x );
    1308             : 
    1309           0 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
    1310             : 
    1311           0 :                 E_ACELP_1pulse_search( &ipos[j], &ps, &alp,
    1312           0 :                                        &ind[j], dn, cor_x, cor_y );
    1313             :             }
    1314             : 
    1315       40986 :             IF( GT_16( nb_pulse_m2, j ) )
    1316             :             {
    1317       26396 :                 p0 = h - ind[j]; /*Q12+scale*/
    1318       26396 :                 if ( sign[ind[j]] < 0 )
    1319             :                 {
    1320       13264 :                     p0 = h_inv - ind[j]; /*Q12+scale*/
    1321             :                 }
    1322             : 
    1323       26396 :                 p1 = h - ind[j + 1]; /*Q12+scale*/
    1324       26396 :                 if ( sign[ind[j + 1]] < 0 )
    1325             :                 {
    1326       13168 :                     p1 = h_inv - ind[j + 1]; /*Q12+scale*/
    1327             :                 }
    1328             : 
    1329             : 
    1330     1715740 :                 FOR( i = 0; i < L_SUBFR; i++ )
    1331             :                 {
    1332     1689344 :                     tmp = add( *p0++, *p1++ );
    1333     1689344 :                     vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */
    1334     1689344 :                     move16();
    1335             :                 }
    1336             :             }
    1337       40986 :             st = add( st, 1 );
    1338             :         }
    1339             : 
    1340             :         /* memorise the best codevector */
    1341             : 
    1342             :         /*ps = ps * ps;                                            MULT(1);*/
    1343       14590 :         ps = mult( ps, ps );
    1344             :         /*s = (alpk * ps) - (psk * alp);                            MULT(2);ADD(1);*/
    1345       14590 :         s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/
    1346             : 
    1347       14590 :         if ( psk < 0 )
    1348             :         {
    1349        3683 :             s = 1;
    1350        3683 :             move32();
    1351             :         }
    1352       14590 :         IF( s > 0 )
    1353             :         {
    1354        7133 :             psk = ps;
    1355        7133 :             move16();
    1356        7133 :             alpk = alp;
    1357        7133 :             move16();
    1358        7133 :             Copy( ind, codvec, nb_pulse ); /*Q0*/
    1359        7133 :             check = 1;                     /* debug code not instrumented */
    1360             :         }
    1361             :     }
    1362             : 
    1363        3683 :     assert( check ); /* debug code not instrumented */
    1364             : 
    1365             :     /*
    1366             :      * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations.
    1367             :      */
    1368             : 
    1369        3683 :     E_ACELP_build_code( nb_pulse, codvec, sign, code, ind );
    1370             : 
    1371        3683 :     set16_fx( y, 0, L_SUBFR );
    1372       26293 :     FOR( k = 0; k < nb_pulse; ++k )
    1373             :     {
    1374       22610 :         i = codvec[k]; /*Q0*/
    1375       22610 :         move16();
    1376       22610 :         p0 = h_inv - i; /*Q12+scale*/
    1377       22610 :         if ( sign[i] > 0 )
    1378             :         {
    1379       11408 :             p0 -= 2 * L_SUBFR;
    1380             :         }
    1381     1469650 :         FOR( i = 0; i < L_SUBFR; i++ )
    1382             :         {
    1383     1447040 :             y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/
    1384     1447040 :             move16();
    1385             :         }
    1386             :     }
    1387        3683 :     return;
    1388             : }
    1389             : 
    1390      178154 : void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ )
    1391             : {
    1392             :     Word16 sign[L_SUBFR], vec[L_SUBFR];
    1393             :     Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
    1394             :     Word16 rrixix[4][16];
    1395             :     Word16 rrixiy[4][256];
    1396             :     Word16 dn2[L_SUBFR];
    1397      178154 :     Word16 psk, ps, alpk, alp = 0;
    1398             :     Word16 codvec[NB_PULSE_MAX];
    1399             :     Word16 pos_max[4];
    1400             :     Word16 dn2_pos[8 * 4];
    1401             :     UWord8 ipos[NB_PULSE_MAX];
    1402             :     Word16 *p0, *p1, *p2, *p3;
    1403             :     Word16 *h, *h_inv;
    1404             :     Word16 i, j, k, l, st, pos;
    1405             :     Word16 val, tmp, scale;
    1406             :     Word32 s, L_tmp;
    1407             :     Word16 nb_pulse, nb_pulse_m2;
    1408      178154 :     Word16 check = 0; /* debug code not instrumented */
    1409             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1410      178154 :     Flag Overflow = 0;
    1411      178154 :     move32();
    1412             : #endif
    1413             : 
    1414             : 
    1415      178154 :     alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */
    1416      178154 :     move16();
    1417      178154 :     nb_pulse = config->nb_pulse;
    1418      178154 :     move16();
    1419      178154 :     nb_pulse_m2 = sub( nb_pulse, 2 );
    1420             : 
    1421      178154 :     set16_fx( codvec, 0, nb_pulse );
    1422             : 
    1423             :     /*
    1424             :      * Find sign for each pulse position.
    1425             :      */
    1426             : 
    1427      178154 :     E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR );
    1428             : 
    1429             :     /*
    1430             :      * Select the most important 8 position per track according to dn2[].
    1431             :      */
    1432      178154 :     E_ACELP_findcandidates( dn2, dn2_pos, pos_max );
    1433             : 
    1434             :     /*
    1435             :      * Compute h_inv[i].
    1436             :      */
    1437      178154 :     set16_fx( h_buf, 0, L_SUBFR );
    1438             : 
    1439      178154 :     set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR );
    1440             : 
    1441      178154 :     h = h_buf + L_SUBFR;
    1442      178154 :     h_inv = h_buf + ( 3 * L_SUBFR );
    1443             : 
    1444             :     /*Check the energy if it is too high then scale to prevent an overflow*/
    1445      178154 :     scale = 0;
    1446      178154 :     move16();
    1447      178154 :     L_tmp = L_deposit_l( 0 );
    1448             :     BASOP_SATURATE_WARNING_OFF_EVS
    1449    11580010 :     FOR( i = 0; i < L_SUBFR; i++ )
    1450             :     {
    1451    11401856 :         L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/
    1452             :     }
    1453      178154 :     val = extract_h( L_tmp ); /*Q9*/
    1454             :     BASOP_SATURATE_WARNING_ON_EVS
    1455             : 
    1456      178154 :     if ( GT_16( val, 0x2000 ) )
    1457             :     {
    1458        1663 :         scale = -1;
    1459        1663 :         move16();
    1460             :     }
    1461      178154 :     if ( GT_16( val, 0x7000 ) )
    1462             :     {
    1463          33 :         scale = -2;
    1464          33 :         move16();
    1465             :     }
    1466      178154 :     if ( EQ_16( val, 32767 ) )
    1467             :     {
    1468          15 :         scale = -3;
    1469          15 :         move16();
    1470             :     }
    1471             : 
    1472      178154 :     Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/
    1473             : 
    1474      178154 :     E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR );
    1475             : 
    1476             : 
    1477             :     /*
    1478             :      * Compute correlation matrices needed for the codebook search.
    1479             :      */
    1480      178154 :     E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy );
    1481             : 
    1482             : 
    1483             :     /*
    1484             :      * Deep first search:
    1485             :      * ------------------
    1486             :      * 20 bits (4p):  4 iter x ((4x16)+(8x16))              = 768 tests
    1487             :      * 36 bits (8p):  4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
    1488             :      * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
    1489             :      *                                      +(8x16)+(8x16)) = 1248 tests
    1490             :      * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
    1491             :      *                        +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
    1492             :      */
    1493      178154 :     psk = -1;
    1494      178154 :     move16();
    1495      178154 :     alpk = 1;
    1496      178154 :     move16();
    1497             : 
    1498             :     /*Number of iterations*/
    1499      924649 :     FOR( k = 0; k < config->nbiter; k++ )
    1500             :     {
    1501      746495 :         E_ACELP_setup_pulse_search_pos( config, k, ipos );
    1502             : 
    1503             :         /* format of alp changes to Q(15-ALP2_E) */
    1504             : 
    1505      746495 :         pos = config->fixedpulses;
    1506      746495 :         move16();
    1507             : 
    1508      746495 :         IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
    1509             :         {
    1510      711140 :             ps = 0;
    1511      711140 :             move16();
    1512      711140 :             alp = 0;
    1513      711140 :             move16();
    1514      711140 :             set16_fx( vec, 0, L_SUBFR );
    1515             :         }
    1516       35355 :         ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */
    1517             :         {
    1518             :             /* first stage: fix 2 pulses */
    1519       35350 :             ind[0] = pos_max[ipos[0]];
    1520       35350 :             move16();
    1521       35350 :             ind[1] = pos_max[ipos[1]];
    1522       35350 :             move16();
    1523       35350 :             ps = add( dn[ind[0]], dn[ind[1]] );
    1524             : 
    1525             :             /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
    1526             :                     rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/
    1527             : 
    1528       35350 :             i = shr( ind[0], 2 );
    1529       35350 :             j = shr( ind[1], 2 );
    1530       35350 :             l = add( shl( i, 4 ), j );
    1531       35350 :             s = L_mult( rrixix[ipos[0]][i], _1_ );     /* Q9+Q12+1 */
    1532       35350 :             s = L_mac( s, rrixix[ipos[1]][j], _1_ );   /* Q9+Q12+1 */
    1533       35350 :             alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */
    1534             : 
    1535       35350 :             p0 = h - ind[0]; /*Q12+scale*/
    1536       35350 :             IF( sign[ind[0]] < 0 )
    1537             :             {
    1538       17336 :                 p0 = h_inv - ind[0]; /*Q12+scale*/
    1539             :             }
    1540             : 
    1541       35350 :             p1 = h - ind[1]; /*Q12+scale*/
    1542       35350 :             IF( sign[ind[1]] < 0 )
    1543             :             {
    1544       17323 :                 p1 = h_inv - ind[1]; /*Q12+scale*/
    1545             :             }
    1546             : 
    1547     2297750 :             FOR( i = 0; i < L_SUBFR; i++ )
    1548             :             {
    1549     2262400 :                 vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/
    1550     2262400 :                 move16();
    1551             :             }
    1552             :         }
    1553             :         ELSE /* 3333 and above */
    1554             :         {
    1555             :             /* first stage: fix 4 pulses */
    1556             : 
    1557           5 :             ind[0] = pos_max[ipos[0]]; /*Q0*/
    1558           5 :             move16();
    1559           5 :             ind[1] = pos_max[ipos[1]]; /*Q0*/
    1560           5 :             move16();
    1561           5 :             ind[2] = pos_max[ipos[2]]; /*Q0*/
    1562           5 :             move16();
    1563           5 :             ind[3] = pos_max[ipos[3]]; /*Q0*/
    1564           5 :             move16();
    1565             : 
    1566             :             /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/
    1567           5 :             ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] );
    1568             : 
    1569           5 :             p0 = h - ind[0]; /*Q12+scale*/
    1570           5 :             IF( sign[ind[0]] < 0 )
    1571             :             {
    1572           0 :                 p0 = h_inv - ind[0]; /*Q12+scale*/
    1573             :             }
    1574             : 
    1575           5 :             p1 = h - ind[1]; /*Q12+scale*/
    1576           5 :             IF( sign[ind[1]] < 0 )
    1577             :             {
    1578           5 :                 p1 = h_inv - ind[1]; /*Q12+scale*/
    1579             :             }
    1580             : 
    1581           5 :             p2 = h - ind[2]; /*Q12+scale*/
    1582           5 :             IF( sign[ind[2]] < 0 )
    1583             :             {
    1584           5 :                 p2 = h_inv - ind[2]; /*Q12+scale*/
    1585             :             }
    1586             : 
    1587           5 :             p3 = h - ind[3]; /*Q12+scale*/
    1588           5 :             IF( sign[ind[3]] < 0 )
    1589             :             {
    1590           5 :                 p3 = h_inv - ind[3]; /*Q12+scale*/
    1591             :             }
    1592             : 
    1593         325 :             FOR( i = 0; i < L_SUBFR; i++ )
    1594             :             {
    1595         320 :                 vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/
    1596         320 :                 move16();
    1597             :             }
    1598             : 
    1599           5 :             L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/
    1600         320 :             FOR( i = 1; i < L_SUBFR; i++ )
    1601         315 :             L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/
    1602             : 
    1603           5 :             alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/
    1604             : 
    1605             :             /*alp *= 0.5F;      */
    1606             :         }
    1607             : 
    1608             :         /* other stages of 2 pulses */
    1609      746495 :         st = 0;
    1610      746495 :         move16();
    1611     2865274 :         FOR( j = pos; j < nb_pulse; j += 2 )
    1612             :         {
    1613     2118779 :             IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */
    1614             :             {
    1615             :                 /*
    1616             :                  * Calculate correlation of all possible positions
    1617             :                  * of the next 2 pulses with previous fixed pulses.
    1618             :                  * Each pulse can have 16 possible positions.
    1619             :                  */
    1620     1717213 :                 E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] );
    1621             : 
    1622     1717213 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
    1623             : 
    1624             :                 /*
    1625             :                  * Find best positions of 2 pulses.
    1626             :                  */
    1627     1717213 :                 E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
    1628     1717213 :                                        &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy );
    1629             :             }
    1630             :             ELSE /* single pulse search */
    1631             :             {
    1632      401566 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x );
    1633             : 
    1634      401566 :                 E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
    1635             : 
    1636      401566 :                 E_ACELP_1pulse_search( &ipos[j], &ps, &alp,
    1637      401566 :                                        &ind[j], dn, cor_x, cor_y );
    1638             :             }
    1639             : 
    1640     2118779 :             IF( GT_16( nb_pulse_m2, j ) )
    1641             :             {
    1642     1372284 :                 p0 = h - ind[j]; /*Q12+scale*/
    1643     1372284 :                 IF( sign[ind[j]] < 0 )
    1644             :                 {
    1645      692624 :                     p0 = h_inv - ind[j]; /*Q12+scale*/
    1646             :                 }
    1647             : 
    1648     1372284 :                 p1 = h - ind[j + 1]; /*Q12+scale*/
    1649     1372284 :                 IF( sign[ind[j + 1]] < 0 )
    1650             :                 {
    1651      695163 :                     p1 = h_inv - ind[j + 1]; /*Q12+scale*/
    1652             :                 }
    1653             : 
    1654             : 
    1655    89198460 :                 FOR( i = 0; i < L_SUBFR; i++ )
    1656             :                 {
    1657    87826176 :                     tmp = add( *p0++, *p1++ );
    1658    87826176 :                     vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */
    1659    87826176 :                     move16();
    1660             :                 }
    1661             :             }
    1662     2118779 :             st = add( st, 1 );
    1663             :         }
    1664             : 
    1665             :         /* memorise the best codevector */
    1666             : 
    1667             :         /*ps = ps * ps;                                            MULT(1);*/
    1668      746495 :         ps = mult( ps, ps );
    1669             :         /*s = (alpk * ps) - (psk * alp);                            MULT(2);ADD(1);*/
    1670      746495 :         s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/
    1671             : 
    1672      746495 :         if ( psk < 0 )
    1673             :         {
    1674      178154 :             s = 1;
    1675      178154 :             move32();
    1676             :         }
    1677      746495 :         IF( s > 0 )
    1678             :         {
    1679      353045 :             psk = ps;
    1680      353045 :             move16();
    1681      353045 :             alpk = alp;
    1682      353045 :             move16();
    1683      353045 :             Copy( ind, codvec, nb_pulse ); /*Q0*/
    1684      353045 :             check = 1;                     /* debug code not instrumented */
    1685             :         }
    1686             :     }
    1687             : 
    1688      178154 :     assert( check ); /* debug code not instrumented */
    1689             : 
    1690             :     /*
    1691             :      * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations.
    1692             :      */
    1693             : 
    1694      178154 :     E_ACELP_build_code( nb_pulse, codvec, sign, code, ind );
    1695             : 
    1696      178154 :     set16_fx( y, 0, L_SUBFR );
    1697     1142217 :     FOR( k = 0; k < nb_pulse; ++k )
    1698             :     {
    1699      964063 :         i = codvec[k]; /*Q0*/
    1700      964063 :         move16();
    1701      964063 :         p0 = h_inv - i; /*Q12+scale*/
    1702      964063 :         IF( sign[i] > 0 )
    1703             :         {
    1704      476999 :             p0 -= 2 * L_SUBFR;
    1705             :         }
    1706    62664095 :         FOR( i = 0; i < L_SUBFR; i++ )
    1707             :         {
    1708    61700032 :             y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/
    1709    61700032 :             move16();
    1710             :         }
    1711             :     }
    1712      178154 :     return;
    1713             : }
    1714             : 
    1715             : /*
    1716             :  * E_ACELP_4t_fx
    1717             :  *
    1718             :  * Parameters:
    1719             :  *    dn          I: corr. between target and h[].
    1720             :  *    cn          I: residual after Word32 term prediction
    1721             :  *    H           I: impulse response of weighted synthesis filter (Q12)
    1722             :  *    code        O: algebraic (fixed) codebook excitation (Q9)
    1723             :  *    y           O: filtered fixed codebook excitation (Q9)
    1724             :  *    nbbits      I: 20, 36, 44, 52, 64, 72 or 88 bits
    1725             :  *    mode        I: speech mode
    1726             :  *    _index      O: index
    1727             :  *
    1728             :  * Function:
    1729             :  *    20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
    1730             :  *    4 tracks x 16 positions per track = 64 samples.
    1731             :  *
    1732             :  *    20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
    1733             :  *    36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
    1734             :  *    44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
    1735             :  *    52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
    1736             :  *    64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
    1737             :  *                                  16 pulses in a frame of 64 samples.
    1738             :  *    72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
    1739             :  *                                  18 pulses in a frame of 64 samples.
    1740             :  *    88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
    1741             :  *                                  24 pulses in a frame of 64 samples.
    1742             :  *
    1743             :  *    All pulses can have two (2) possible amplitudes: +1 or -1.
    1744             :  *    Each pulse can sixteen (16) possible positions.
    1745             :  *
    1746             :  * Returns:
    1747             :  *    void
    1748             :  */
    1749        3020 : void E_ACELP_4t_fx(
    1750             :     Word16 dn[], /*Qdn*/
    1751             :     Word16 cn[] /* Q_xn */,
    1752             :     Word16 H[],                /*Q12*/
    1753             :     Word16 R[],                /*Qx*/
    1754             :     Word8 acelpautoc,          /*Q0*/
    1755             :     Word16 code[],             /*Q9*/
    1756             :     Word16 cdk_index,          /*Q0*/
    1757             :     Word16 _index[],           /*Q0*/
    1758             :     const Word16 L_frame,      /*Q0*/
    1759             :     const Word16 last_L_frame, /*Q0*/
    1760             :     const Word32 total_brate,  /*Q0*/
    1761             :     const Word16 i_subfr,      /*Q0*/
    1762             :     const Word16 cmpl_flag /*Q0*/ )
    1763             : {
    1764             :     PulseConfig config;
    1765             :     Word16 ind[NPMAXPT * 4];
    1766             :     Word16 y[L_SUBFR];
    1767             : 
    1768        3020 :     move16();
    1769        3020 :     move16();
    1770        3020 :     move16();
    1771        3020 :     move16();
    1772        3020 :     move16();
    1773        3020 :     move16();
    1774        3020 :     move16();
    1775        3020 :     move16();
    1776        3020 :     move16();
    1777        3020 :     move16();
    1778        3020 :     move16();
    1779        3020 :     move16();
    1780        3020 :     move16();
    1781        3020 :     move16();
    1782        3020 :     move16();
    1783        3020 :     move16();
    1784        3020 :     memcpy( &config, &PulseConfTable[cdk_index], sizeof( PulseConfTable[cdk_index] ) );
    1785             : 
    1786             : 
    1787        3020 :     if ( cmpl_flag > 0 )
    1788             :     {
    1789           0 :         config.nbiter = cmpl_flag;
    1790           0 :         move16();
    1791             :     }
    1792        3020 :     test();
    1793        3020 :     test();
    1794        3020 :     IF( NE_16( L_frame, last_L_frame ) && EQ_32( total_brate, ACELP_24k40 ) && LT_32( i_subfr, 5 * L_SUBFR ) )
    1795             :     {
    1796           0 :         config.nbiter = sub( config.nbiter, 1 );
    1797           0 :         config.nbiter = s_max( config.nbiter, 1 );
    1798             :     }
    1799             : 
    1800        3020 :     IF( acelpautoc )
    1801             :     {
    1802        3020 :         E_ACELP_4tsearchx_fx( dn, cn, R, code, &config, ind );
    1803             :     }
    1804             :     ELSE
    1805             :     {
    1806           0 :         E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y );
    1807             :     }
    1808        3020 :     E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index );
    1809        3020 :     return;
    1810             : }
    1811             : 
    1812      507800 : void E_ACELP_4t_ivas_fx(
    1813             :     Word16 dn[], /*Qdn*/
    1814             :     Word16 cn[] /* Q_xn */,
    1815             :     Word16 H[],                /*Q12*/
    1816             :     Word16 R[],                /*Qx*/
    1817             :     Word8 acelpautoc,          /*Q0*/
    1818             :     Word16 code[],             /*Q9*/
    1819             :     Word16 cdk_index,          /*Q0*/
    1820             :     Word16 _index[],           /*Q0*/
    1821             :     const Word16 L_frame,      /*Q0*/
    1822             :     const Word16 last_L_frame, /*Q0*/
    1823             :     const Word32 total_brate,  /*Q0*/
    1824             :     const Word16 i_subfr,      /*Q0*/
    1825             :     const Word16 cmpl_flag,    /*Q0*/
    1826             :     Word16 element_mode /*Q0*/ )
    1827             : {
    1828             :     PulseConfig config;
    1829             :     Word16 ind[NPMAXPT * 4];
    1830             :     Word16 y[L_SUBFR];
    1831             : 
    1832      507800 :     move16();
    1833      507800 :     move16();
    1834      507800 :     move16();
    1835      507800 :     move16();
    1836      507800 :     move16();
    1837      507800 :     move16();
    1838      507800 :     move16();
    1839      507800 :     move16();
    1840      507800 :     move16();
    1841      507800 :     move16();
    1842      507800 :     move16();
    1843      507800 :     move16();
    1844      507800 :     move16();
    1845      507800 :     move16();
    1846      507800 :     move16();
    1847      507800 :     move16();
    1848      507800 :     memcpy( &config, &PulseConfTable[cdk_index], sizeof( PulseConfTable[cdk_index] ) );
    1849             : 
    1850             : 
    1851      507800 :     if ( cmpl_flag > 0 )
    1852             :     {
    1853       10467 :         config.nbiter = cmpl_flag;
    1854       10467 :         move16();
    1855             :     }
    1856      507800 :     test();
    1857      507800 :     test();
    1858      507800 :     IF( NE_16( L_frame, last_L_frame ) && EQ_32( total_brate, ACELP_24k40 ) && LT_32( i_subfr, 5 * L_SUBFR ) )
    1859             :     {
    1860           0 :         config.nbiter = sub( config.nbiter, 1 );
    1861           0 :         config.nbiter = s_max( config.nbiter, 1 );
    1862             :     }
    1863             : 
    1864      507800 :     IF( acelpautoc )
    1865             :     {
    1866      329646 :         E_ACELP_4tsearchx_ivas_fx( dn, cn, R, code, &config, ind, element_mode );
    1867             :     }
    1868             :     ELSE
    1869             :     {
    1870      178154 :         E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y );
    1871             :     }
    1872      507800 :     E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index );
    1873      507800 :     return;
    1874             : }
    1875             : 
    1876      575647 : static void E_ACELP_indexing_shift(
    1877             :     Word16 wordcnt,      /* i: 16-bit word count including the newly shifted-in bits Q0*/
    1878             :     Word16 shift_bits,   /* i: number of bits to shift in from the lsb               Q0*/
    1879             :     UWord16 lsb_bits,    /* i: bits to shift in from the lsb                         Q0*/
    1880             :     const UWord16 src[], /* i: source buffer                                         Q0*/
    1881             :     UWord16 dst[]        /* o: destination buffer                                    Q(shift_bits)*/
    1882             : )
    1883             : {
    1884             :     Word16 right_shift, i;
    1885             : 
    1886      575647 :     assert( shift_bits <= 16 );
    1887             : 
    1888      575647 :     right_shift = sub( 16, shift_bits );
    1889             : 
    1890     1844654 :     FOR( i = sub( wordcnt, 1 ); i > 0; --i )
    1891             :     {
    1892     1269007 :         dst[i] = s_or( lshl( src[i], shift_bits ), lshr( src[i - 1], right_shift ) ); /*Q0+shift_bits*/
    1893     1269007 :         move16();
    1894             :     }
    1895      575647 :     dst[i] = s_or( lshl( src[i], shift_bits ), lsb_bits ); /*Q(shift_bits)*/
    1896      575647 :     move16();
    1897      575647 :     return;
    1898             : }
    1899             : 
    1900             : #define MAX_IDX_LEN 9
    1901             : 
    1902      575647 : Word16 E_ACELP_indexing_fx(
    1903             :     const Word16 code[], /*Q9*/
    1904             :     const PulseConfig *config,
    1905             :     Word16 num_tracks, /*Q0*/
    1906             :     Word16 prm[] /*Q(shift_bits)*/ )
    1907             : {
    1908             :     Word16 track, shift_bits;
    1909             :     Word16 p[NB_TRACK_FCB_4T], wordcnt;
    1910             :     UWord32 s[NB_TRACK_FCB_4T], n[NB_TRACK_FCB_4T];
    1911             :     UWord16 idx[MAX_IDX_LEN];
    1912             :     Word16 saved_bits;
    1913             : 
    1914      575647 :     assert( num_tracks == NB_TRACK_FCB_4T );
    1915             : 
    1916      575647 :     saved_bits = 0;
    1917      575647 :     move16();
    1918             : 
    1919             :     /*
    1920             :      * Code state of pulses of all tracks
    1921             :      * */
    1922      575647 :     wordcnt = shr( add( config->bits, 15 ), 4 ); /* ceil(bits/16) */
    1923             : 
    1924      575647 :     set16_fx( (Word16 *) idx, 0, wordcnt );
    1925             : 
    1926      575647 :     IF( EQ_16( config->bits, 43 ) ) /* EVS pulse indexing */
    1927             :     {
    1928       33480 :         saved_bits = E_ACELP_code43bit_fx( code, s, p, idx );
    1929             :     }
    1930             :     ELSE
    1931             :     {
    1932     2710835 :         FOR( track = 0; track < num_tracks; track++ )
    1933             :         {
    1934             :             /* Code track of length 2^4 where step between tracks is 4. */
    1935     2168668 :             E_ACELP_codearithp_fx( code + track, &n[track], &s[track], &p[track] );
    1936             :         }
    1937      542167 :         fcb_pulse_track_joint_fx( idx, wordcnt, s, p, num_tracks );
    1938             :     }
    1939             : 
    1940             :     /* check if we need to code track positions */
    1941      575647 :     track = 0;
    1942      575647 :     move16();
    1943      575647 :     shift_bits = 0;
    1944      575647 :     move16();
    1945      575647 :     SWITCH( config->codetrackpos )
    1946             :     {
    1947       74275 :         case TRACKPOS_FIXED_TWO:
    1948             :             /* Code position of consecutive tracks with single extra pulses */
    1949             :             /* Find track with one pulse less. */
    1950       74275 :             if ( NE_16( p[0], p[1] ) )
    1951             :             {
    1952             :                 /* Either 0110 or 1001 */
    1953       37190 :                 track = 1;
    1954       37190 :                 move16();
    1955             :             }
    1956       74275 :             if ( GT_16( p[3], p[1] ) )
    1957             :             {
    1958       37211 :                 track = add( track, 2 );
    1959       37211 :                 move16();
    1960             :             }
    1961       74275 :             shift_bits = 2;
    1962       74275 :             move16();
    1963       74275 :             BREAK;
    1964             : 
    1965       66863 :         case TRACKPOS_FREE_THREE:
    1966             :             /* Code position of track with one pulse less than others */
    1967             :             /* Find track with one pulse less. */
    1968       66863 :             if ( LT_16( p[1], p[0] ) )
    1969             :             {
    1970       16728 :                 track = 1;
    1971       16728 :                 move16();
    1972             :             }
    1973       66863 :             if ( LT_16( p[2], p[0] ) )
    1974             :             {
    1975       16534 :                 track = 2;
    1976       16534 :                 move16();
    1977             :             }
    1978       66863 :             if ( LT_16( p[3], p[0] ) )
    1979             :             {
    1980       16922 :                 track = 3;
    1981       16922 :                 move16();
    1982             :             }
    1983       66863 :             shift_bits = 2;
    1984       66863 :             move16();
    1985       66863 :             BREAK;
    1986             : 
    1987       22175 :         case TRACKPOS_FREE_ONE:
    1988             :             /* Code position of track with one pulse less than others */
    1989             :             /* Find track with one pulse less. */
    1990       22175 :             if ( GT_16( p[1], p[0] ) )
    1991             :             {
    1992        5496 :                 track = 1;
    1993        5496 :                 move16();
    1994             :             }
    1995       22175 :             if ( GT_16( p[2], p[0] ) )
    1996             :             {
    1997        5504 :                 track = 2;
    1998        5504 :                 move16();
    1999             :             }
    2000       22175 :             if ( GT_16( p[3], p[0] ) )
    2001             :             {
    2002        5710 :                 track = 3;
    2003        5710 :                 move16();
    2004             :             }
    2005       22175 :             shift_bits = 2;
    2006       22175 :             move16();
    2007       22175 :             BREAK;
    2008             : 
    2009      412334 :         case TRACKPOS_FIXED_EVEN:
    2010             :         case TRACKPOS_FIXED_FIRST:
    2011      412334 :             BREAK;
    2012             : 
    2013           0 :         default:
    2014           0 :             printf( "Codebook mode not implemented.\n" );
    2015           0 :             assert( 0 ); /* mode not yet implemented*/
    2016             :             BREAK;
    2017             :     }
    2018             : 
    2019      575647 :     E_ACELP_indexing_shift( wordcnt, shift_bits, track, idx, (UWord16 *) prm );
    2020             : 
    2021      575647 :     return saved_bits;
    2022             : }
    2023             : 
    2024             : /*--------------------------------------------------------------------------*
    2025             :  * E_ACELP_adaptive_codebook
    2026             :  *
    2027             :  * Find adaptive codebook.
    2028             :  *--------------------------------------------------------------------------*/
    2029        3020 : void E_ACELP_adaptive_codebook(
    2030             :     Word16 *exc,           /* i/o: pointer to the excitation frame            Q_new */
    2031             :     Word16 T0,             /* i  : integer pitch lag                             Q0 */
    2032             :     Word16 T0_frac,        /* i  : fraction of lag                               Q0   */
    2033             :     Word16 T0_res,         /* i  : pitch resolution                              Q0   */
    2034             :     Word16 T0_res_max,     /* i  : maximum pitch resolution                      Q0   */
    2035             :     Word16 mode,           /* i  : filtering mode (0: no, 1: yes, 2: adaptive)   Q0   */
    2036             :     Word16 i_subfr,        /* i  : subframe index                                   */
    2037             :     Word16 L_subfr,        /* i  : subframe length                               Q0   */
    2038             :     Word16 L_frame,        /* i  : subframe length                               Q0   */
    2039             :     Word16 *h1,            /* i  : impulse response of weighted synthesis filter 1Q14+shift */
    2040             :     Word16 clip_gain,      /* i  : flag to indicate ???                          Q14   */
    2041             :     Word16 *xn,            /* i  : Close-loop Pitch search target vector       Q_xn */
    2042             :     Word16 *y1,            /* o  : zero-memory filtered adaptive excitation    Q_xn */
    2043             :     ACELP_CbkCorr *g_corr, /* o  : ACELP correlation values                         */
    2044             :     Word16 **pt_indice,    /* i/o: quantization indices pointer                     */
    2045             :     Word16 *pitch_gain,    /* o  : adaptive codebook gain                      1Q14 */
    2046             :     Word16 exp_xn          /* i  : exponent of xn (Q_xn-15)                         */
    2047             :     ,
    2048             :     Word16 rf_mode,
    2049             :     Word16 rf_coder_type,
    2050             :     Word16 *lp_select
    2051             : 
    2052             : )
    2053             : {
    2054             :     Word16 y2[L_SUBFR], xn2[L_SUBFR], code[L_SUBFR];
    2055             :     ACELP_CbkCorr g_corr2;
    2056        3020 :     Word16 gain1 = 0, gain2 = 0, fac_m, fac_n;
    2057        3020 :     move16();
    2058        3020 :     move16();
    2059             :     Word16 i, select, exp_ener;
    2060             :     Word32 L_tmp, L_ener;
    2061             :     const Word16 *pitch_inter;
    2062             :     Word16 pit_L_interpol, pit_up_samp;
    2063        3020 :     Word16 use_prev_sf_pit_gain = 0;
    2064        3020 :     move16();
    2065             : 
    2066        3020 :     test();
    2067        3020 :     IF( EQ_16( rf_mode, 1 ) && EQ_16( rf_coder_type, 100 ) )
    2068             :     {
    2069           0 :         use_prev_sf_pit_gain = 1;
    2070           0 :         move16();
    2071             :     }
    2072             : 
    2073             :     BASOP_SATURATE_ERROR_ON_EVS;
    2074             : 
    2075        3020 :     L_ener = L_deposit_l( 0 );
    2076             : 
    2077             :     /* find pitch excitation */
    2078             :     /*for &exc[i_subfr]*/
    2079        3020 :     IF( EQ_16( T0_res, shr( T0_res_max, 1 ) ) )
    2080             :     {
    2081        2903 :         T0_frac = shl( T0_frac, 1 ); /*Q0*/
    2082             :     }
    2083             : 
    2084        3020 :     test();
    2085        3020 :     IF( EQ_16( T0_res_max, 6 ) && rf_mode == 0 )
    2086             :     {
    2087        3020 :         pitch_inter = pitch_inter6_2; /*Q14*/
    2088        3020 :         pit_L_interpol = PIT_L_INTERPOL6_2;
    2089        3020 :         move16();
    2090        3020 :         pit_up_samp = PIT_UP_SAMP6;
    2091        3020 :         move16();
    2092             :     }
    2093             :     ELSE
    2094             :     {
    2095           0 :         pitch_inter = pitch_inter4_2; /*Q14*/
    2096           0 :         pit_L_interpol = L_INTERPOL2;
    2097           0 :         move16();
    2098           0 :         pit_up_samp = PIT_UP_SAMP;
    2099           0 :         move16();
    2100             :     }
    2101             : 
    2102        3020 :     pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter, pit_L_interpol, pit_up_samp );
    2103             : 
    2104        3020 :     test();
    2105        3020 :     IF( EQ_16( mode, NORMAL_OPERATION ) || ( EQ_16( mode, FULL_BAND ) ) )
    2106             :     {
    2107        1330 :         E_UTIL_f_convolve( &exc[i_subfr], h1, y1, L_subfr );
    2108             : 
    2109        1330 :         IF( use_prev_sf_pit_gain == 0 )
    2110             :         {
    2111        1330 :             gain1 = E_ACELP_xy1_corr_fx( xn, y1, g_corr, 1, L_subfr, exp_xn ); /*Q14*/
    2112             : 
    2113             :             /* clip gain if necessary to avoid problem at decoder */
    2114        1330 :             test();
    2115        1330 :             IF( clip_gain && GT_16( gain1, 15565 /*0.95 Q14*/ ) )
    2116             :             {
    2117           0 :                 gain1 = 15565 /*0.95f Q14*/;
    2118           0 :                 move16();
    2119             :             }
    2120        1330 :             *pitch_gain = gain1; /*Q14*/
    2121        1330 :             move16();
    2122             :         }
    2123             : 
    2124             :         /* find energy of new target xn2[] */
    2125        1330 :         E_ACELP_codebook_target_update_fx( xn, xn2, y1, gain1, L_subfr );
    2126        1330 :         L_ener = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31-exp_ener*/
    2127        1330 :         L_ener = L_shr( L_ener, sub( 31, exp_ener ) );                  /*Q0*/
    2128             :     }
    2129             : 
    2130             :     /*-----------------------------------------------------------------*
    2131             :      * - find pitch excitation filtered by 1st order LP filter.        *
    2132             :      * - find filtered pitch exc. y2[]=exc[] convolved with h1[])      *
    2133             :      * - compute pitch gain2                                           *
    2134             :      *-----------------------------------------------------------------*/
    2135        3020 :     test();
    2136        3020 :     IF( EQ_16( mode, NORMAL_OPERATION ) || EQ_16( mode, LOW_PASS ) )
    2137             :     {
    2138             :         /* find pitch excitation with lp filter */
    2139        3020 :         fac_m = 20972 /*0.64f Q15*/;
    2140        3020 :         move16();
    2141        3020 :         if ( EQ_16( L_frame, L_FRAME16k ) )
    2142             :         {
    2143        3020 :             fac_m = 19005 /*0.58f Q15*/;
    2144        3020 :             move16();
    2145             :         }
    2146             :         /* fac_n = 0.5*(1.0-fac_m); */
    2147        3020 :         fac_n = mult_r( sub( 0x7FFF, fac_m ), 0x4000 ); /*Q15*/
    2148      196300 :         FOR( i = 0; i < L_subfr; i++ )
    2149             :         {
    2150      193280 :             L_tmp = L_mult( fac_n, exc[i - 1 + i_subfr] );         /*Q_new+Q16*/
    2151      193280 :             L_tmp = L_mac( L_tmp, fac_m, exc[i + 0 + i_subfr] );   /*Q_new+Q16*/
    2152      193280 :             code[i] = mac_r( L_tmp, fac_n, exc[i + 1 + i_subfr] ); /*Q_new*/
    2153      193280 :             move16();
    2154             :         }
    2155        3020 :         E_UTIL_f_convolve( code, h1, y2, L_subfr );
    2156        3020 :         gain2 = E_ACELP_xy1_corr_fx( xn, y2, &g_corr2, 1, L_subfr, exp_xn ); /*Q14*/
    2157             : 
    2158             :         /* clip gain if necessary to avoid problem at decoder */
    2159        3020 :         test();
    2160        3020 :         IF( clip_gain && GT_16( gain2, 15565 /*0.95 Q14*/ ) )
    2161             :         {
    2162           0 :             gain2 = 15565 /*0.95f Q14*/;
    2163           0 :             move16();
    2164             :         }
    2165             : 
    2166             :         /* find energy of new target xn2[] */
    2167        3020 :         E_ACELP_codebook_target_update_fx( xn, xn2, y2, gain2, L_subfr );
    2168        3020 :         L_tmp = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31 - exp_ener*/
    2169        3020 :         L_tmp = L_shr( L_tmp, sub( 31, exp_ener ) );                   /*Q0*/
    2170             : 
    2171             :         /*-----------------------------------------------------------------*
    2172             :          * use the best prediction (minimise quadratic error).             *
    2173             :          *-----------------------------------------------------------------*/
    2174        3020 :         test();
    2175        3020 :         IF( EQ_16( mode, LOW_PASS ) || LT_32( L_tmp, L_ener ) )
    2176             :         {
    2177             :             /* use the lp filter for pitch excitation prediction */
    2178        2629 :             select = LOW_PASS;
    2179        2629 :             move16();
    2180        2629 :             Copy( code, &exc[i_subfr], L_subfr ); /*Q_new*/
    2181        2629 :             Copy( y2, y1, L_subfr );              /*Q_xn*/
    2182        2629 :             *pitch_gain = gain2;                  /*Q14*/
    2183        2629 :             move16();
    2184        2629 :             g_corr->y1y1 = g_corr2.y1y1;
    2185        2629 :             move16();
    2186        2629 :             g_corr->xy1 = g_corr2.xy1;
    2187        2629 :             move16();
    2188        2629 :             g_corr->y1y1_e = g_corr2.y1y1_e;
    2189        2629 :             move16();
    2190        2629 :             g_corr->xy1_e = g_corr2.xy1_e;
    2191        2629 :             move16();
    2192             :         }
    2193             :         ELSE
    2194             :         {
    2195             :             /* no filter used for pitch excitation prediction */
    2196         391 :             select = FULL_BAND;
    2197         391 :             move16();
    2198         391 :             *pitch_gain = gain1; /*Q14*/
    2199         391 :             move16();
    2200             :         }
    2201             : 
    2202        3020 :         IF( EQ_16( mode, NORMAL_OPERATION ) )
    2203             :         {
    2204        1330 :             **pt_indice = select;
    2205        1330 :             ( *pt_indice )++;
    2206        1330 :             move16();
    2207             :         }
    2208             :     }
    2209             :     ELSE
    2210             :     {
    2211             :         /* no filter used for pitch excitation prediction */
    2212           0 :         select = FULL_BAND;
    2213           0 :         move16();
    2214             :     }
    2215        3020 :     *lp_select = select;
    2216        3020 :     move16();
    2217             : 
    2218             :     BASOP_SATURATE_ERROR_OFF_EVS;
    2219        3020 : }
    2220             : 
    2221             : 
    2222             : /*--------------------------------------------------------------------------*
    2223             :  * E_ACELP_innovative_codebook_fx
    2224             :  *
    2225             :  * Find innovative codebook.
    2226             :  *--------------------------------------------------------------------------*/
    2227        3020 : void E_ACELP_innovative_codebook_fx(
    2228             :     Word16 *exc,               /* i  : pointer to the excitation frame                Q_new  */
    2229             :     Word16 T0,                 /* i  : integer pitch lag                                 Q0 */
    2230             :     Word16 T0_frac,            /* i  : fraction of lag                                   Q0 */
    2231             :     Word16 T0_res,             /* i  : pitch resolution                                  Q0 */
    2232             :     Word16 pitch_gain,         /* i  : adaptive codebook gain                          1Q14 */
    2233             :     Word16 tilt_code,          /* i  : tilt factor                                      Q15 */
    2234             :     ACELP_config *acelp_cfg,   /* i/o: configuration of the ACELP                       */
    2235             :     Word16 i_subfr,            /* i  : subframe index                                       */
    2236             :     const Word16 *Aq,          /* i  : quantized LPC coefficients                      3Q12 */
    2237             :     Word16 *h1,                /* i  : impulse response of weighted synthesis filter   1Q14+shift */
    2238             :     Word16 *xn,                /* i  : Close-loop Pitch search target vector           Q_xn  */
    2239             :     Word16 *cn,                /* i  : Innovative codebook search target vector        Q_new */
    2240             :     Word16 *y1,                /* i  : zero-memory filtered adaptive excitation         Q_xn */
    2241             :     Word16 *y2,                /* o  : zero-memory filtered algebraic excitation          Q9 */
    2242             :     Word8 acelpautoc,          /* i  : autocorrelation mode enabled                          */
    2243             :     Word16 **pt_indice,        /* i/o: quantization indices pointer                          */
    2244             :     Word16 *code,              /* o  : innovative codebook Q9                             Q9 */
    2245             :     Word16 shift,              /* i  : Scaling to get 12 bits                                */
    2246             :     const Word16 L_frame,      /* i  : length of the frame                                   Q0*/
    2247             :     const Word16 last_L_frame, /* i  : length of the last frame                              Q0*/
    2248             :     const Word32 total_brate   /* i  : ttoal bit-rate                                        Q0*/
    2249             : )
    2250             : {
    2251             :     Word16 xn2[L_SUBFR] /* Q_xn */, cn2[L_SUBFR] /* Q_xn */, dn[L_SUBFR] /* Rw2*cn2 */, h2[L_SUBFR] /* 4Q11 */;
    2252             :     Word16 Rw2[L_SUBFR];
    2253             :     Word16 pitch, idx;
    2254             : 
    2255             : 
    2256        3020 :     pitch = T0;
    2257        3020 :     move16();
    2258        3020 :     idx = shr( i_subfr, 6 );
    2259        3020 :     if ( GT_16( T0_frac, shr( T0_res, 1 ) ) )
    2260             :     {
    2261         723 :         pitch = add( pitch, 1 );
    2262             :     }
    2263             : 
    2264             :     BASOP_SATURATE_ERROR_ON_EVS;
    2265             : 
    2266             :     /* Update target vector for ACELP codebook search */
    2267        3020 :     E_ACELP_codebook_target_update_fx( xn, xn2, y1, pitch_gain, L_SUBFR );
    2268             : 
    2269             :     /* Include fixed-gain pitch contribution into impulse resp. h1[] */
    2270        3020 :     Copy_Scale_sig( h1, h2, L_SUBFR, sub( -3, shift ) ); /*h2 1Q14+shift -> 4Q11, 1bit of headroom for Residu and xh_corr*/
    2271             : 
    2272        3020 :     cb_shape_fx( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt,
    2273        3020 :                  acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, h2, tilt_code, pitch, 1, L_SUBFR );
    2274             : 
    2275             :     /* Correlation between target xn2[] and impulse response h1[] */
    2276        3020 :     IF( acelpautoc )
    2277             :     {
    2278             :         /* h2: 4Q11, Rw2: (Rw2_e)Q */
    2279        3020 :         /* Rw2_e = */ E_ACELP_hh_corr( h2, Rw2, L_SUBFR, 3 );
    2280             : 
    2281        3020 :         E_ACELP_conv( xn2, h2, cn2 );
    2282             : 
    2283             :         /* dn_e -> Rw2_e*Q_xn */
    2284        3020 :         /*dn_e = */ E_ACELP_toeplitz_mul_fx( Rw2, cn2, dn, L_SUBFR, sub( (Word16) PulseConfTable[acelp_cfg->fixed_cdk_index[idx]].nb_pulse, 24 ) > 0 );
    2285             :     }
    2286             :     ELSE
    2287             :     {
    2288             :         BASOP_SATURATE_WARNING_OFF_EVS;
    2289           0 :         E_ACELP_codebook_target_update_fx( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR );
    2290             :         BASOP_SATURATE_WARNING_ON_EVS;
    2291           0 :         Scale_sig( cn2, L_SUBFR, shift );
    2292           0 :         E_ACELP_xh_corr( xn2, dn, h2, L_SUBFR );
    2293             :     }
    2294             : 
    2295             :     /* Innovative codebook search */
    2296        3020 :     assert( acelp_cfg->fixed_cdk_index[idx] < ACELP_FIXED_CDK_NB );
    2297             : 
    2298        3020 :     E_ACELP_4t_fx( dn, cn2, h2, Rw2, acelpautoc, code, acelp_cfg->fixed_cdk_index[idx], *pt_indice, L_frame, last_L_frame, total_brate, i_subfr, 0 );
    2299             : 
    2300        3020 :     *pt_indice += 8;
    2301             : 
    2302             :     /* Generate weighted code */
    2303        3020 :     E_ACELP_weighted_code( code, h2, 11, y2 );
    2304             : 
    2305             :     /*-------------------------------------------------------*
    2306             :      * - Add the fixed-gain pitch contribution to code[].    *
    2307             :      *-------------------------------------------------------*/
    2308             : 
    2309        3020 :     cb_shape_fx( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt,
    2310        3020 :                  acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, code, tilt_code, pitch, 1, L_SUBFR );
    2311             : 
    2312             :     BASOP_SATURATE_ERROR_OFF_EVS;
    2313        3020 :     return;
    2314             : }
    2315             : 
    2316             : 
    2317             : /*--------------------------------------------------------------------------*
    2318             :  * E_ACELP_codearithp_fx
    2319             :  *
    2320             :  * Fixed bit-length arithmetic coding of pulses
    2321             :  * v - (input) pulse vector
    2322             :  * ps - (output) encoded state
    2323             :  * n - (output) range of possible states (0...n-1)
    2324             :  * p - (output) number of pulses found
    2325             :  *--------------------------------------------------------------------------*/
    2326     2168668 : static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ )
    2327             : {
    2328             :     Word16 k, nb_pulse, i, t, pos[NPMAXPT], posno;
    2329             :     Word16 sign, m;
    2330             :     UWord32 s;
    2331             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2332     2168668 :     Flag Overflow = 0;
    2333     2168668 :     Flag Carry = 0;
    2334     2168668 :     move32();
    2335     2168668 :     move32();
    2336             : #endif
    2337             : 
    2338             :     /* Collect different pulse positions to pos[], number of them to posno */
    2339     2168668 :     posno = 0;
    2340     2168668 :     move16();
    2341     2168668 :     t = 0;
    2342     2168668 :     move16();
    2343    36867356 :     FOR( k = 0; k < L_SUBFR; k += 4 )
    2344             :     {
    2345    34698688 :         if ( v[k] != 0 )
    2346             :         {
    2347     5283913 :             pos[posno++] = t;
    2348     5283913 :             move16();
    2349             :         }
    2350    34698688 :         t = add( t, 1 );
    2351    34698688 :         move16();
    2352    34698688 :         if ( sub( posno, NPMAXPT ) >= 0 )
    2353             :         {
    2354           0 :             BREAK;
    2355             :         }
    2356             :     }
    2357             : 
    2358             :     /* Iterate over the different pulse positions */
    2359     2168668 :     s = L_deposit_l( 0 );
    2360     2168668 :     t = 0;
    2361     2168668 :     move16();
    2362     2168668 :     nb_pulse = 0;
    2363     2168668 :     move16();
    2364     7452581 :     FOR( k = 0; k < posno; ++k )
    2365             :     {
    2366     5283913 :         sign = shr( v[( pos[k] * 4 )], 9 ); /* sign with multiplicity Q0*/
    2367     5283913 :         m = abs_s( sign );                  /* multiplicity */
    2368     5283913 :         nb_pulse = add( nb_pulse, m );
    2369             :         /* Code m-1 pulses */
    2370     5603259 :         FOR( i = 1; i < m; ++i )
    2371             :         {
    2372      319346 :             Carry = 0;
    2373      319346 :             move32();
    2374      319346 :             s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow );
    2375      319346 :             t = add( t, 1 );
    2376      319346 :             if ( sub( t, NPMAXPT ) > 0 )
    2377             :             {
    2378           0 :                 BREAK;
    2379             :             }
    2380             :         }
    2381             : 
    2382             :         /* Code sign */
    2383             :         /* We use L_add_c since we want to work with unsigned UWord32 */
    2384             :         /* Therefore, we have to clear carry */
    2385     5283913 :         Carry = 0;
    2386     5283913 :         move32();
    2387     5283913 :         s = L_lshl( s, 1 );
    2388     5283913 :         if ( sign < 0 )
    2389             :         {
    2390     2674115 :             s = L_add_co( s, 1, &Carry, &Overflow );
    2391             :         }
    2392             : 
    2393             :         /* Code last pulse */
    2394     5283913 :         Carry = 0;
    2395     5283913 :         move32();
    2396     5283913 :         s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow );
    2397     5283913 :         t = add( t, 1 );
    2398             :     }
    2399             : 
    2400     2168668 :     *ps = s; /*Q0*/
    2401     2168668 :     move32();
    2402     2168668 :     *n = L_deposit_l( 0 );
    2403     2168668 :     if ( nb_pulse )
    2404             :     {
    2405     2145268 :         *n = pulsestostates[NB_POS_FCB_4T][nb_pulse - 1]; /*Q0*/
    2406     2145268 :         move32();
    2407             :     }
    2408             : 
    2409     2168668 :     *p = nb_pulse; /*Q0*/
    2410     2168668 :     move16();
    2411     2168668 :     return;
    2412             : }
    2413             : 
    2414      542167 : void fcb_pulse_track_joint_fx( UWord16 *idxs /*Q0*/, Word16 wordcnt /*Q0*/, UWord32 *index_n /*Q0*/, Word16 *pulse_num /*Q0*/, Word16 track_num /*Q0*/ )
    2415             : {
    2416             :     Word16 hi_to_low[10];
    2417             :     UWord32 index, index_mask;
    2418             :     Word32 indx_tmp;
    2419             :     Word16 indx_flag, indx_flag_1;
    2420             :     Word16 track, track_num1, pulse_num0, pulse_num1;
    2421             :     Word16 indx_flag_2;
    2422             : 
    2423      542167 :     Copy( hi_to_low_tmpl, hi_to_low, 10 ); /*Q0*/
    2424             : 
    2425      542167 :     indx_flag = 0;
    2426      542167 :     move16();
    2427      542167 :     indx_flag_1 = 0;
    2428      542167 :     move16();
    2429      542167 :     indx_flag_2 = 0;
    2430      542167 :     move16();
    2431             : 
    2432     2710835 :     FOR( track = 0; track < track_num; track++ )
    2433             :     {
    2434     2168668 :         indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
    2435     2168668 :         indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
    2436     2168668 :         indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
    2437             :     }
    2438             : 
    2439      542167 :     IF( GE_16( indx_flag_2, 1 ) )
    2440             :     {
    2441          46 :         hi_to_low[7] = 9;
    2442          46 :         move16();
    2443          46 :         index_mask = 0xFFFFFF; /*Q0*/
    2444          46 :         move32();
    2445             :     }
    2446             :     ELSE
    2447             :     {
    2448      542121 :         if ( LT_16( indx_flag, track_num ) )
    2449             :         {
    2450      459747 :             hi_to_low[4] = 1;
    2451      459747 :             move16();
    2452             :         }
    2453      542121 :         index_mask = L_shr( 0xFFFF, sub( 9, hi_to_low[4] ) ); /*Q0*/
    2454             :     }
    2455             : 
    2456      542167 :     IF( GE_16( indx_flag_1, track_num ) )
    2457             :     {
    2458      344702 :         indx_tmp = L_deposit_l( 0 );
    2459      344702 :         index = L_shr( index_n[0], low_len[pulse_num[0]] ); /*Q0*/
    2460     1378808 :         FOR( track = 1; track < track_num; track++ )
    2461             :         {
    2462     1034106 :             pulse_num0 = pulse_num[track - 1]; /*Q0*/
    2463     1034106 :             move16();
    2464     1034106 :             pulse_num1 = pulse_num[track]; /*Q0*/
    2465     1034106 :             move16();
    2466     1034106 :             indx_tmp = L_lshr( index_n[track], low_len[pulse_num1] ); /*Q0*/
    2467             :             /* index = index * indx_fact[pulse_num1] + indx_tmp; */
    2468     1034106 :             index = UL_Mpy_32_32( index, UL_deposit_l( indx_fact[pulse_num1] ) ); /*Q0*/
    2469     1034106 :             index = UL_addNsD( index, indx_tmp );
    2470     1034106 :             index_n[track - 1] = L_add( L_and( index_n[track - 1], low_mask[pulse_num0] ),
    2471     1034106 :                                         L_and( L_lshl( index, low_len[pulse_num0] ), index_mask ) ); /*Q0*/
    2472             : 
    2473     1034106 :             index = L_lshr( index, hi_to_low[pulse_num0] );
    2474             :         }
    2475      344702 :         track_num1 = sub( track_num, 1 );
    2476      344702 :         move16();
    2477      344702 :         pulse_num1 = pulse_num[track_num1]; /*Q0*/
    2478      344702 :         move16();
    2479      344702 :         index_n[track_num1] = L_and( L_add( L_and( index_n[track_num1], low_mask[pulse_num1] ),
    2480      344702 :                                             L_lshl( index, low_len[pulse_num1] ) ),
    2481             :                                      index_mask ); /*Q0*/
    2482      344702 :         index = L_lshr( index, hi_to_low[pulse_num1] );
    2483      344702 :         IF( GE_16( indx_flag, track_num ) )
    2484             :         {
    2485       82420 :             IF( GE_16( indx_flag_2, 1 ) )
    2486             :             {
    2487          46 :                 idxs[0] = extract_l( index_n[0] );
    2488          46 :                 idxs[1] = extract_l( L_add( L_lshl( index_n[1], 8 ), L_lshr( index_n[0], 16 ) ) );
    2489          46 :                 idxs[2] = extract_l( L_lshr( index_n[1], 8 ) );
    2490          46 :                 idxs[3] = extract_l( index_n[2] );
    2491          46 :                 idxs[4] = extract_l( L_add( L_lshl( index_n[3], 8 ), L_lshr( index_n[2], 16 ) ) );
    2492          46 :                 idxs[5] = extract_l( L_lshr( index_n[3], 8 ) );
    2493          46 :                 track = 6;
    2494          46 :                 move16();
    2495             :             }
    2496             :             ELSE
    2497             :             {
    2498      411870 :                 FOR( track = 0; track < track_num; track++ )
    2499             :                 {
    2500      329496 :                     idxs[track] = extract_l( index_n[track] );
    2501             :                 }
    2502             :             }
    2503             :         }
    2504             :         ELSE
    2505             :         {
    2506      262282 :             idxs[0] = extract_l( L_add( L_lshl( index_n[0], 8 ), index_n[1] ) );
    2507      262282 :             idxs[1] = extract_l( L_add( L_lshl( index_n[2], 8 ), index_n[3] ) );
    2508      262282 :             track = 2;
    2509      262282 :             move16();
    2510             :         }
    2511             :     }
    2512             :     ELSE
    2513             :     {
    2514      197465 :         index = index_n[0]; /*Q0*/
    2515      197465 :         move32();
    2516      789860 :         FOR( track = 1; track < 4; track++ )
    2517             :         {
    2518      592395 :             pulse_num1 = pulse_num[track]; /*Q0*/
    2519      592395 :             index = L_add( L_lshl( index, index_len[pulse_num1] ), index_n[track] );
    2520             :         }
    2521      197465 :         track = 0;
    2522      197465 :         move16();
    2523             :     }
    2524     1432045 :     FOR( ; track < wordcnt; track++ )
    2525             :     {
    2526      889878 :         idxs[track] = extract_l( index );
    2527      889878 :         index = L_lshr( index, 16 );
    2528             :     }
    2529      542167 :     return;
    2530             : }

Generated by: LCOV version 1.14