LCOV - code coverage report
Current view: top level - lib_enc - enc_acelpx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 287 294 97.6 %
Date: 2025-09-14 03:13:15 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : //#include "prot_fx.h"
       8             : #include "basop_util.h"
       9             : #include "options.h"
      10             : #include "rom_enc.h"
      11             : #include "prot_fx.h"     /* Function prototypes                    */
      12             : #include "prot_fx_enc.h" /* Function prototypes                    */
      13             : 
      14             : /*--------------------------------------------------------------------------------------*
      15             :  * Local constant
      16             :  *--------------------------------------------------------------------------------------*/
      17             : 
      18             : #define _1_Q11 ( 2048 /*1.0f Q11*/ ) /* 1.0f in 4Q11 */
      19             : /*--------------------------------------------------------------------------------------*
      20             :  * E_ACELP_update_cor
      21             :  *--------------------------------------------------------------------------------------*/
      22     8838575 : static void E_ACELP_update_cor_fx(
      23             :     const Word16 pos[],    /* i Q0*/
      24             :     Word16 nb_pulse,       /* i Q0*/
      25             :     const Word16 sign[],   /* i Q13*/
      26             :     const Word16 R[],      /* i Q9+scale*/
      27             :     const Word16 cor_in[], /* i Q9*/
      28             :     Word16 cor_out[]       /* o Q9*/
      29             : )
      30             : {
      31             :     Word16 sign_x, sign_y;
      32             :     const Word16 *pRx, *pRy;
      33             :     Word16 i, tmp;
      34             : 
      35     8838575 :     IF( EQ_16( nb_pulse, 2 ) )
      36             :     {
      37             :         /* Update product of autocorrelation and already fixed pulses. with the
      38             :          * two newly found ones */
      39     8180113 :         sign_x = sign[pos[0]]; /*Q13*/
      40     8180113 :         move16();
      41     8180113 :         sign_y = sign[pos[1]]; /*Q13*/
      42     8180113 :         move16();
      43             : 
      44     8180113 :         IF( s_xor( sign_x, sign_y ) < 0 )
      45             :         {
      46     4789415 :             i = 1;
      47     4789415 :             move16();
      48     4789415 :             if ( sign_x > 0 )
      49             :             {
      50     2402032 :                 i = 0;
      51     2402032 :                 move16();
      52             :             }
      53     4789415 :             pRx = R - pos[i];     /*Q9+scale*/
      54     4789415 :             pRy = R - pos[1 - i]; /*Q9+scale*/
      55             :             /* different sign x and y */
      56   311311975 :             FOR( i = 0; i < L_SUBFR; i++ )
      57             :             {
      58   306522560 :                 tmp = sub( pRx[i], pRy[i] );
      59   306522560 :                 if ( cor_in != NULL )
      60             :                 {
      61   279765440 :                     tmp = add( tmp, cor_in[i] ); /* Q9 */
      62             :                 }
      63   306522560 :                 cor_out[i] = tmp; /* Q9 */
      64   306522560 :                 move16();
      65             :             }
      66             :         }
      67             :         ELSE
      68             :         {
      69     3390698 :             pRx = R - pos[0]; /*Q9+scale*/
      70     3390698 :             pRy = R - pos[1]; /*Q9+scale*/
      71     3390698 :             IF( sign_x > 0 )
      72             :             {
      73             :                 /* sign x and y is positive */
      74   109419050 :                 FOR( i = 0; i < L_SUBFR; i++ )
      75             :                 {
      76   107735680 :                     tmp = add( pRx[i], pRy[i] );
      77   107735680 :                     if ( cor_in != NULL )
      78             :                     {
      79    79296512 :                         tmp = add( tmp, cor_in[i] ); /* Q9 */
      80             :                     }
      81   107735680 :                     cor_out[i] = tmp; /* Q9 */
      82   107735680 :                     move16();
      83             :                 }
      84             :             }
      85             :             ELSE
      86             :             {
      87             :                 /* sign x and y is negative */
      88   110976320 :                 FOR( i = 0; i < L_SUBFR; i++ )
      89             :                 {
      90   109268992 :                     tmp = add( pRx[i], pRy[i] );
      91   109268992 :                     if ( cor_in != NULL )
      92             :                     {
      93    81462016 :                         tmp = sub( cor_in[i], tmp ); /* Q9 */
      94             :                     }
      95   109268992 :                     if ( cor_in == NULL )
      96             :                     {
      97    27806976 :                         tmp = negate( tmp );
      98             :                     }
      99   109268992 :                     cor_out[i] = tmp; /* Q9 */
     100   109268992 :                     move16();
     101             :                 }
     102             :             }
     103             :         }
     104             :     }
     105      658462 :     ELSE IF( EQ_16( nb_pulse, 4 ) )
     106             :     {
     107      658462 :         E_ACELP_update_cor_fx( pos, 2, sign, R, cor_in, cor_out );
     108      658462 :         E_ACELP_update_cor_fx( pos + 2, 2, sign, R, cor_out, cor_out );
     109             :     }
     110             :     else
     111             :     {
     112           0 :         assert( !"Number of pulses not supported" );
     113             :     }
     114     8838575 : }
     115             : /*--------------------------------------------------------------------------------------*
     116             :  * E_ACELP_2pulse_searchx
     117             :  * Iterations: nb_pos_ix*16
     118             :  *--------------------------------------------------------------------------------------*/
     119     6224725 : static void E_ACELP_2pulse_searchx_fx(
     120             :     const Word16 nb_pos_ix, /*Q0*/
     121             :     const Word16 track_x,   /*Q0*/
     122             :     const Word16 track_y,   /*Q0*/
     123             :     Word16 *R,              /*Q9+scale*/
     124             :     Word16 *ps,             /*Qdn*/
     125             :     Word16 *alp,            /*Q6*/
     126             :     Word16 *ix,             /*Q0*/
     127             :     Word16 *iy,             /*Q0*/
     128             :     Word16 dn[],            /*Qdn*/
     129             :     Word16 *dn2,            /*Q0*/
     130             :     Word16 cor[],           /*Q9*/
     131             :     Word16 sign[],          /*Q13*/
     132             :     Word16 sign_val_2 /*Q15*/ )
     133             : {
     134             :     Word16 i, x;
     135             :     Word32 y;
     136             :     Word16 *pos_x, pos[2];
     137             :     Word32 xy_save;
     138             :     Word16 ps0, ps1, alp2_16, ps2, sq;
     139             :     Word32 alp0, alp1, alp2, s;
     140             :     Word16 *pR, sgnx;
     141             :     Word16 sqk[2], alpk[2], ik;
     142             : #ifndef ISSUE_1867_replace_overflow_libenc
     143             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     144             :     Flag Overflow = 0;
     145             :     move32();
     146             : #endif
     147             : #endif
     148             : 
     149             :     /* eight dn2 max positions per track */
     150     6224725 :     pos_x = &dn2[( track_x * 8 )]; /*Qdn*/
     151     6224725 :     move16();
     152             :     /* save these to limit memory searches */
     153     6224725 :     ps0 = *ps; /*Qdn*/
     154     6224725 :     move16();
     155             :     /*alp0 = *alp + 2.0f*R[0];                         move16();*/
     156     6224725 :     alp0 = L_deposit_h( *alp );                 /* Qalp = Q_R*Q_signval */
     157     6224725 :     alp0 = L_mac_sat( alp0, R[0], sign_val_2 ); /*Q9+scale+Q15*/
     158             : 
     159             :     /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
     160     6224725 :     sqk[0] = -1;
     161     6224725 :     move16();
     162     6224725 :     alpk[0] = 1;
     163     6224725 :     move16();
     164     6224725 :     x = pos_x[0];
     165     6224725 :     move16();
     166     6224725 :     sgnx = sign[track_y]; /*Q13*/
     167     6224725 :     move16();
     168     6224725 :     if ( sign[x] < 0 )
     169             :     {
     170     3082074 :         sgnx = negate( sgnx );
     171             :     }
     172             : #ifdef ISSUE_1867_replace_overflow_libenc
     173     6224725 :     if ( mac_r_sat( L_mac_sat( L_mac_sat( alp0, cor[x], sign[x] ), cor[track_y], sign[track_y] ), R[track_y - x], sgnx ) < 0 )
     174             : #else
     175             :     if ( mac_ro( L_mac_o( L_mac_o( alp0, cor[x], sign[x], &Overflow ), cor[track_y], sign[track_y], &Overflow ), R[track_y - x], sgnx, &Overflow ) < 0 )
     176             : #endif
     177             :     {
     178           0 :         sqk[0] = 1;
     179           0 :         move16();
     180             :     }
     181     6224725 :     ik = 0;
     182     6224725 :     move16();
     183             : 
     184     6224725 :     xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/
     185             : 
     186             :     /* loop track 1 */
     187    45420767 :     FOR( i = 0; i < nb_pos_ix; i++ )
     188             :     {
     189    39196042 :         x = pos_x[i]; /*Q0*/
     190    39196042 :         move16();
     191    39196042 :         sgnx = sign[x]; /*Q13*/
     192    39196042 :         move16();
     193             :         /* dn[x] has only nb_pos_ix positions saved */
     194             :         /*ps1 = ps0 + dn[x];                            INDIRECT(1);ADD(1);*/
     195    39196042 :         ps1 = add_sat( ps0, dn[x] ); /*Qdn*/
     196             :                                      /*alp1 = alp0 + 2*sgnx*cor[x];                  INDIRECT(1);MULT(1); MAC(1);*/
     197             : #ifdef ISSUE_1867_replace_overflow_libenc
     198    39196042 :         alp1 = L_mac_sat( alp0, cor[x], sgnx ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     199             : #else
     200             :         alp1 = L_mac_o( alp0, cor[x], sgnx, &Overflow );                        /* Qalp = (Q_R=Q_cor)*Q_signval */
     201             : #endif
     202    39196042 :         pR = R - x; /*Q9+scale*/
     203             : 
     204   666332714 :         FOR( y = track_y; y < L_SUBFR; y += 4 )
     205             :         {
     206             :             /*ps2 = ps1 + dn[y];                         ADD(1);*/
     207   627136672 :             ps2 = add_sat( ps1, dn[y] ); /*Qdn*/
     208             :             /*alp2 = alp1 + 2.0f*sign[y]*(cor[y] + sgnx*pR[y]);   MULT(1); MAC(2);*/
     209             :             /*alp2 = alp1 + 2.0f*sign[y]*cor[y] + 2.0f*sign[y]*sgnx*pR[y];   MULT(1); MAC(2);*/
     210   627136672 :             assert( sign[y] == sign_val_2 || sign[y] == -sign_val_2 );
     211             : 
     212             :             /* Compiler warning workaround (not instrumented) */
     213   627136672 :             assert( sgnx != 0 );
     214   627136672 :             alp2_16 = 0;
     215             : 
     216             : #ifdef ISSUE_1867_replace_overflow_libenc
     217   627136672 :             alp2 = L_mac_sat( alp1, cor[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     218             : #else
     219             :             alp2 = L_mac_o( alp1, cor[y], sign[y], &Overflow );                 /* Qalp = (Q_R=Q_cor)*Q_signval */
     220             : #endif
     221   627136672 :             if ( sgnx > 0 )
     222             :             {
     223             : #ifdef ISSUE_1867_replace_overflow_libenc
     224   311372848 :                 alp2_16 = mac_r_sat( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     225             : #else
     226             :                 alp2_16 = mac_ro( alp2, pR[y], sign[y], &Overflow );            /* Qalp = (Q_R=Q_cor)*Q_signval */
     227             : #endif
     228             :             }
     229   627136672 :             if ( sgnx < 0 )
     230             :             {
     231             : #ifdef ISSUE_1867_replace_overflow_libenc
     232   315763824 :                 alp2_16 = msu_r_sat( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     233             : #else
     234             :                 alp2_16 = msu_ro( alp2, pR[y], sign[y], &Overflow );            /* Qalp = (Q_R=Q_cor)*Q_signval */
     235             : #endif
     236             :             }
     237   627136672 :             alpk[1 - ik] = alp2_16; /* Qalp */
     238   627136672 :             move16();
     239             : 
     240             :             /*sq = ps2 * ps2;                            MULT(1);*/
     241   627136672 :             sq = mult_r( ps2, ps2 ); /* (3+3)Q -> 6Q9 */
     242   627136672 :             sqk[1 - ik] = sq;        /* Q9 */
     243   627136672 :             move16();
     244             : 
     245             : 
     246             :             /*s = (alpk * sq) - (sqk * alp2);            MULT(1);MAC(1);*/
     247             : #ifdef ISSUE_1867_replace_overflow_libenc
     248   627136672 :             s = L_msu_sat( L_mult( alpk[ik], sq ), sqk[ik], alp2_16 ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */
     249             : #else
     250             :             s = L_msu_o( L_mult( alpk[ik], sq ), sqk[ik], alp2_16, &Overflow ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */
     251             : #endif
     252   627136672 :             if ( s > 0 )
     253             :             {
     254    35887661 :                 ik = sub( 1, ik );
     255             :             }
     256   627136672 :             if ( s > 0 )
     257             :             {
     258    35887661 :                 xy_save = L_mac0( y, x, L_SUBFR ); /* Q0 */
     259             :             }
     260   627136672 :             assert( ( ( s >= 0 && i == 0 && y == track_y ) ) || ( y > track_y ) || ( i > 0 ) );
     261             :         }
     262             :     }
     263     6224725 :     ps1 = extract_l( xy_save );
     264     6224725 :     pos[1] = s_and( ps1, L_SUBFR - 1 );
     265     6224725 :     move16();
     266     6224725 :     pos[0] = lshr( ps1, 6 ); /* Q0 */
     267     6224725 :     move16();
     268             :     /* Update numerator */
     269     6224725 :     *ps = add( add( ps0, dn[pos[0]] ), dn[pos[1]] ); /* Qdn */
     270     6224725 :     move16();
     271             : 
     272             :     /* Update denominator */
     273     6224725 :     *alp = alpk[ik]; /* Q_alp */
     274     6224725 :     move16();
     275             : 
     276     6224725 :     E_ACELP_update_cor_fx( pos, 2, sign, R, cor, cor );
     277             : 
     278     6224725 :     *ix = pos[0]; /* Q0 */
     279     6224725 :     move16();
     280     6224725 :     *iy = pos[1]; /* Q0 */
     281     6224725 :     move16();
     282             : 
     283     6224725 :     assert( ( ( pos[0] & 3 ) == track_x ) && ( ( pos[1] & 3 ) == track_y ) ); /* sanity check */
     284     6224725 : }
     285             : 
     286             : /*--------------------------------------------------------------------------------------*
     287             :  * E_ACELP_1pulse_searchx
     288             :  *--------------------------------------------------------------------------------------*/
     289      609296 : static void E_ACELP_1pulse_searchx_fx(
     290             :     UWord8 tracks[2], /*Q0*/
     291             :     Word16 *R,        /*Q9+scale*/
     292             :     Word16 *ps,       /* Qdn */
     293             :     Word16 *alp,      /*Q6*/
     294             :     Word16 *ix,       /*Q0*/
     295             :     Word16 dn[],      /* Qdn */
     296             :     Word16 cor[],     /* Q9 */
     297             :     Word16 sign[],    /* Q13 */
     298             :     Word16 sign_val_1 /* Q15 */ )
     299             : {
     300      609296 :     Word16 x, x_save = 0;
     301             :     Word16 ps0;
     302             :     Word32 alp0;
     303             :     Word16 ps1, sq;
     304             :     Word16 alp1;
     305             :     Word32 s;
     306             :     Word16 ntracks, t;
     307             :     Word16 sqk[2], alpk[2], ik;
     308      609296 :     move16();
     309             : #ifndef ISSUE_1867_replace_overflow_libenc
     310             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     311             :     Flag Overflow = 0;
     312             :     move32();
     313             : #endif
     314             : #endif
     315             :     /* save these to limit memory searches */
     316             :     /*alp0 = *alp + R[0];                              INDIRECT(1);*/
     317      609296 :     ps0 = *ps; /* Qdn */
     318      609296 :     move16();
     319      609296 :     alp0 = L_deposit_h( *alp );             /* Q22 */
     320      609296 :     alp0 = L_mac( alp0, R[0], sign_val_1 ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     321             : 
     322             :     /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
     323      609296 :     move16();
     324      609296 :     move16();
     325      609296 :     alpk[0] = 1;
     326      609296 :     sqk[0] = -1;
     327      609296 :     ik = 0;
     328      609296 :     move16();
     329             : #ifdef ISSUE_1867_replace_overflow_libenc
     330      609296 :     if ( mac_r_sat( alp0, cor[tracks[0]], sign[tracks[0]] ) < 0 )
     331             : #else
     332             :     if ( mac_ro( alp0, cor[tracks[0]], sign[tracks[0]], &Overflow ) < 0 )
     333             : #endif
     334             :     {
     335           0 :         sqk[0] = 1;
     336           0 :         move16();
     337             :     }
     338             : 
     339      609296 :     x_save = tracks[0]; /* Q0 */
     340      609296 :     move16();
     341             : 
     342      609296 :     ntracks = 1;
     343      609296 :     move16();
     344      609296 :     if ( NE_16( tracks[1], tracks[0] ) )
     345             :     {
     346      159238 :         ntracks = 2;
     347      159238 :         move16();
     348             :     }
     349     1377830 :     FOR( t = 0; t < ntracks; ++t )
     350             :     {
     351    13065078 :         FOR( x = tracks[t]; x < L_SUBFR; x += 4 )
     352             :         {
     353             :             /* ps1 = ps0 + dn[x];                             ADD(1);*/
     354    12296544 :             ps1 = add( ps0, dn[x] );
     355             :             /* alp1 = alp0 + 2*sign[x]*cor[x];                MAC(1); MULT(1);*/
     356    12296544 :             assert( sign[x] == sign_val_1 << 1 || sign[x] == -( sign_val_1 << 1 ) );
     357             : #ifdef ISSUE_1867_replace_overflow_libenc
     358    12296544 :             alp1 = mac_r_sat( alp0, cor[x], sign[x] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
     359             : #else
     360             :             alp1 = mac_ro( alp0, cor[x], sign[x], &Overflow );                            /* Qalp = (Q_R=Q_cor)*Q_signval */
     361             : #endif
     362    12296544 :             alpk[1 - ik] = alp1; /* Qalp */
     363    12296544 :             move16();
     364             : 
     365             : 
     366             :             /*sq = ps1 * ps1;                                MULT(1);*/
     367    12296544 :             sq = mult_r( ps1, ps1 ); /* 6Q9 */
     368    12296544 :             sqk[1 - ik] = sq;        /* Q9 */
     369    12296544 :             move16();
     370             : 
     371             :             /*s = (alpk[ik] * sq) - (sqk[ik] * alp1);                MULT(1);MAC(1);*/
     372             : #ifdef ISSUE_1867_replace_overflow_libenc
     373    12296544 :             s = L_msu_sat( L_mult_sat( alpk[ik], sq ), sqk[ik], alp1 ); /* Q9+Qalp+1 */
     374             : #else
     375             :             s = L_msu_o( L_mult_o( alpk[ik], sq, &Overflow ), sqk[ik], alp1, &Overflow ); /* Q9+Qalp+1 */
     376             : #endif
     377    12296544 :             if ( s > 0 )
     378             :             {
     379     2217000 :                 ik = sub( 1, ik );
     380             :             }
     381    12296544 :             if ( s > 0 )
     382             :             {
     383     2217000 :                 x_save = x;
     384     2217000 :                 move16();
     385             :             }
     386    12296544 :             assert( t > 0 || ( ( s >= 0 ) && ( x == tracks[t] ) ) || x > tracks[t] );
     387             :         }
     388             :     }
     389             : 
     390      609296 :     *ps = add( ps0, dn[x_save] ); /* Qdn */
     391      609296 :     move16();
     392      609296 :     *alp = alpk[ik]; /* Qalp */
     393      609296 :     move16();
     394      609296 :     *ix = x_save; /* Q0 */
     395      609296 :     move16();
     396      609296 : }
     397             : 
     398             : /*--------------------------------------------------------------------------------------*
     399             :  * E_ACELP_4tsearchx_fx
     400             :  * Autocorrelation method for searching pulse positions effectively
     401             :  * Algorithm is identical to traditional covariance method
     402             :  *--------------------------------------------------------------------------------------*/
     403      394697 : void E_ACELP_4tsearchx_fx(
     404             :     Word16 dn[],       /*Qdn*/
     405             :     const Word16 cn[], /*Q_new*/
     406             :     Word16 Rw[],       /*Q9*/
     407             :     Word16 code[],     /*Q9*/
     408             :     const PulseConfig *config,
     409             :     Word16 ind[] /*Q0*/
     410             :     ,
     411             :     const Word16 element_mode )
     412             : {
     413             :     Word16 sign[L_SUBFR], vec[L_SUBFR];
     414             :     Word16 cor[L_SUBFR];
     415             :     Word16 R_buf[2 * L_SUBFR - 1], *R;
     416             :     Word16 dn2[L_SUBFR];
     417      394697 :     Word16 ps2k, ps /* same format as dn[] */, ps2, alpk, alp = 0 /* Q13 and later Q_Rw*Q_signval=Q_cor*Q_signval */;
     418             :     Word32 s;
     419             :     Word16 codvec[NB_PULSE_MAX];
     420             :     Word16 pos_max[4];
     421             :     Word16 dn2_pos[8 * 4];
     422             :     UWord8 ipos[NB_PULSE_MAX];
     423      394697 :     Word16 i, j, k, st, pos = 0;
     424             :     Word16 scale;
     425             :     Word16 sign_val_1, sign_val_2;
     426             :     Word16 nb_pulse, nb_pulse_m2;
     427      394697 :     Word16 psk = 0;
     428             :     Word16 val, index, track;
     429      394697 :     move16();
     430      394697 :     move16();
     431      394697 :     move16();
     432             : 
     433      394697 :     ps = 0; /* to avoid compilation warnings */
     434      394697 :     move16();
     435             : 
     436             : 
     437      394697 :     alp = config->alp; /* Q13 */
     438      394697 :     move16();
     439      394697 :     nb_pulse = config->nb_pulse;
     440      394697 :     move16();
     441      394697 :     move16();
     442      394697 :     nb_pulse_m2 = sub( nb_pulse, 2 );
     443             : 
     444             :     /* Init to avoid crash when the search does not find a solution */
     445      394697 :     IF( EQ_16( element_mode, EVS_MONO ) )
     446             :     {
     447       82458 :         FOR( k = 0; k < nb_pulse; k++ )
     448             :         {
     449       76007 :             codvec[k] = k;
     450       76007 :             move16();
     451             :         }
     452             :     }
     453             :     ELSE
     454             :     {
     455     5277753 :         FOR( k = 0; k < nb_pulse; k++ )
     456             :         {
     457     4889507 :             codvec[k] = s_and( k, 3 );
     458     4889507 :             move16();
     459             :         }
     460             :     }
     461      394697 :     scale = 0;
     462      394697 :     move16();
     463      394697 :     s = L_mult0( Rw[0], Rw[0] ); /*Q18*/
     464    25260608 :     FOR( i = 1; i < L_SUBFR; i++ )
     465             :     {
     466    24865911 :         s = L_mac0( s, Rw[i], Rw[i] ); /*Q18*/
     467             :     }
     468      394697 :     if ( s_and( (Word16) GE_16( nb_pulse, 9 ), (Word16) GT_32( s, 0x800000 ) ) )
     469             :     {
     470      292418 :         scale = -1;
     471      292418 :         move16();
     472             :     }
     473      394697 :     if ( s_and( (Word16) GE_16( nb_pulse, 13 ), (Word16) GT_32( s, 0x4000000 ) ) )
     474             :     {
     475       48561 :         scale = -2;
     476       48561 :         move16();
     477             :     }
     478      394697 :     IF( GE_16( nb_pulse, 18 ) )
     479             :     {
     480       53966 :         if ( GT_32( s, 0x200000 ) )
     481             :         {
     482       53966 :             scale = -1;
     483       53966 :             move16();
     484             :         }
     485       53966 :         if ( GT_32( s, 0x400000 ) )
     486             :         {
     487       53966 :             scale = -2;
     488       53966 :             move16();
     489             :         }
     490       53966 :         if ( GT_32( s, 0x4000000 ) )
     491             :         {
     492       13862 :             scale = -3;
     493       13862 :             move16();
     494             :         }
     495             :     }
     496      394697 :     if ( s_and( (Word16) GE_16( nb_pulse, 28 ), (Word16) GT_32( s, 0x800000 ) ) )
     497             :     {
     498         463 :         scale = -3;
     499         463 :         move16();
     500             :     }
     501      394697 :     if ( s_and( (Word16) GE_16( nb_pulse, 36 ), (Word16) GT_32( s, 0x4000000 ) ) )
     502             :     {
     503           0 :         scale = -4;
     504           0 :         move16();
     505             :     }
     506             : 
     507             :     /* Set up autocorrelation vector */
     508      394697 :     R = R_buf + L_SUBFR - 1;
     509      394697 :     Copy_Scale_sig( Rw, R, L_SUBFR, scale ); /*Q9+scale*/
     510    25260608 :     FOR( k = 1; k < L_SUBFR; k++ )
     511             :     {
     512    24865911 :         R[-k] = R[k];
     513    24865911 :         move16();
     514             :     }
     515             : 
     516             :     /* Sign value */
     517      394697 :     sign_val_2 = 0x2000; /* Q15 */
     518      394697 :     move16();
     519      394697 :     if ( GE_16( nb_pulse, 24 ) )
     520             :     {
     521       25152 :         sign_val_2 = shr( sign_val_2, 1 ); /* Q15 */
     522             :     }
     523      394697 :     sign_val_1 = shr( sign_val_2, 1 ); /* Q15 */
     524             : 
     525             :     /*
     526             :      * Find sign for each pulse position.
     527             :      */
     528      394697 :     E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, sign_val_2, L_SUBFR );
     529             : 
     530             :     /*
     531             :      * Select the most important 8 position per track according to dn2[].
     532             :      */
     533      394697 :     E_ACELP_findcandidates( dn2, dn2_pos, pos_max );
     534             : 
     535             :     /*
     536             :      * Deep first search:
     537             :      */
     538             : 
     539             :     /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
     540      394697 :     ps2k = -1;
     541      394697 :     move16();
     542      394697 :     alpk = 1;
     543      394697 :     move16();
     544             : 
     545             :     /* Number of iterations */
     546     1796989 :     FOR( k = 0; k < config->nbiter; k++ )
     547             :     {
     548     1402292 :         E_ACELP_setup_pulse_search_pos( config, k, ipos );
     549             : 
     550             :         /* index to first non-fixed position */
     551     1402292 :         pos = config->fixedpulses; /* Q0 */
     552     1402292 :         move16();
     553             : 
     554     1402292 :         IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
     555             :         {
     556      105366 :             ps = 0;
     557      105366 :             move16();
     558      105366 :             alp = 0;
     559      105366 :             move16();
     560      105366 :             set16_fx( cor, 0, L_SUBFR );
     561             :         }
     562             :         ELSE
     563             :         {
     564     1296926 :             assert( config->fixedpulses == 2 || config->fixedpulses == 4 );
     565             : 
     566             :             /* set fixed positions */
     567     5207702 :             FOR( i = 0; i < pos; ++i )
     568             :             {
     569     3910776 :                 ind[i] = pos_max[ipos[i]]; /* Q0 */
     570     3910776 :                 move16();
     571             :             }
     572             : 
     573             :             /* multiplication of autocorrelation with signed fixed pulses */
     574     1296926 :             E_ACELP_update_cor_fx( ind, config->fixedpulses, sign, R, NULL, cor );
     575             : 
     576             :             /* normalisation contribution of fixed part */
     577     1296926 :             s = L_mult0( cor[ind[0]], sign[ind[0]] ); /* Q22 */
     578     1296926 :             ps = dn[ind[0]];                          /* Qdn */
     579     1296926 :             move16();
     580     3910776 :             FOR( i = 1; i < pos; ++i )
     581             :             {
     582     2613850 :                 s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q22 */
     583     2613850 :                 ps = add( ps, dn[ind[i]] );                 /* Qdn */
     584             :             }
     585     1296926 :             alp = round_fx( s ); /*mac0 >>1 sign = 2 Q6*/
     586             :         }
     587             : 
     588             :         /* other stages of 2 pulses */
     589     1402292 :         st = 0;
     590     1402292 :         move16();
     591     8236313 :         FOR( j = pos; j < nb_pulse; j += 2 )
     592             :         {
     593     6834021 :             IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */
     594             :             {
     595             :                 /*
     596             :                  * Calculate correlation of all possible positions
     597             :                  * of the next 2 pulses with previous fixed pulses.
     598             :                  * Each pulse can have 16 possible positions.
     599             :                  */
     600             : 
     601     6224725 :                 E_ACELP_2pulse_searchx_fx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp,
     602     6224725 :                                            &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 );
     603             :             }
     604             :             ELSE /* single pulse search */
     605             :             {
     606      609296 :                 E_ACELP_1pulse_searchx_fx( &ipos[j], R, &ps, &alp,
     607      609296 :                                            &ind[j], dn, cor, sign, sign_val_1 );
     608             :             }
     609             : 
     610     6834021 :             test();
     611     6834021 :             IF( GT_16( alp, ONE_IN_Q14 ) && ( element_mode > EVS_MONO ) )
     612             :             {
     613        1850 :                 alp = shr( alp, 1 );
     614        1850 :                 Scale_sig( cor, L_SUBFR, -1 );           /*Q8*/
     615        1850 :                 Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/
     616        1850 :                 Scale_sig( dn, L_SUBFR, -1 );            /*Qdn-1*/
     617             :             }
     618     6834021 :             st = add( st, 1 );
     619             :         }
     620             : 
     621             :         /* memorise the best codevector */
     622             :         /*ps2 = ps * ps;                                            MULT(1);*/
     623     1402292 :         ps2 = mult( ps, ps ); /* 2*Qdn+1 */
     624             : 
     625             :         /*s = (alpk * ps2) - (ps2k * alp);                          MULT(2);ADD(1);*/
     626     1402292 :         s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); /* 2*Qdn+8 */
     627             : 
     628     1402292 :         IF( s > 0 )
     629             :         {
     630      768183 :             ps2k = ps2;
     631      768183 :             move16();
     632      768183 :             psk = ps;
     633      768183 :             move16();
     634      768183 :             alpk = alp;
     635      768183 :             move16();
     636      768183 :             Copy( ind, codvec, nb_pulse ); /* Q0 */
     637             :         }
     638             :     }
     639             : 
     640             : 
     641             :     /*
     642             :      * Store weighted energy of code, build the codeword and index of codevector.
     643             :      */
     644      394697 :     IF( EQ_16( element_mode, EVS_MONO ) )
     645             :     {
     646        6451 :         E_ACELP_build_code( nb_pulse, codvec, sign, code, ind );
     647             :     }
     648             :     ELSE
     649             :     {
     650             :         /* Store weighted energy of code, build the codeword and index of codevector. */
     651      388246 :         set16_fx( code, 0, L_SUBFR );
     652      388246 :         set16_fx( ind, -1, NPMAXPT * 4 );
     653             : 
     654     5277753 :         FOR( k = 0; k < config->nb_pulse; k++ )
     655             :         {
     656     4889507 :             i = codvec[k]; /* read pulse position  Q0*/
     657     4889507 :             move16();
     658     4889507 :             val = sign[i]; /* read sign            Q13*/
     659     4889507 :             move16();
     660             : 
     661     4889507 :             index = shr( i, 2 ); /* pos of pulse (0..15) */
     662             :             // track = i % 4;
     663     4889507 :             track = s_and( i, 3 );
     664     4889507 :             IF( L_mult0( val, psk ) > 0 )
     665             :             {
     666     2413175 :                 code[i] = add( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */
     667     2413175 :                 move16();
     668     2413175 :                 codvec[k] = add( codvec[k], 2 * L_SUBFR ); /* Q0 */
     669     2413175 :                 move16();
     670             :             }
     671             :             ELSE
     672             :             {
     673     2476332 :                 code[i] = sub( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */
     674     2476332 :                 move16();
     675     2476332 :                 index = add( index, 16 ); /* Q0 */
     676             :             }
     677             : 
     678     4889507 :             i = imult1616( track, NPMAXPT );
     679    11424024 :             WHILE( ind[i] >= 0 )
     680             :             {
     681     6534517 :                 i++;
     682             :             }
     683             : 
     684     4889507 :             ind[i] = index;
     685     4889507 :             move16();
     686             :         }
     687             :     }
     688      394697 : }

Generated by: LCOV version 1.14