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

Generated by: LCOV version 1.14