LCOV - code coverage report
Current view: top level - lib_enc - enc_acelp.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 617 635 97.2 %
Date: 2025-05-23 08:37:30 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #ifdef DEBUGGING
      41             : #include "debug.h"
      42             : #endif
      43             : #include <math.h>
      44             : #include "prot.h"
      45             : #include "rom_com.h"
      46             : #include "rom_enc.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : 
      50             : /*---------------------------------------------------------------------*
      51             :  * Local function prototypes
      52             :  *---------------------------------------------------------------------*/
      53             : 
      54             : static void E_ACELP_codearithp( const float v[], uint32_t *n, uint32_t *ps, int16_t *p, const int16_t trackstep, const int16_t tracklen );
      55             : 
      56             : 
      57             : /*---------------------------------------------------------------------*
      58             :  * Local constants
      59             :  *---------------------------------------------------------------------*/
      60             : 
      61             : #define NB_MAX 8
      62             : 
      63             : /*
      64             :  * E_ACELP_h_vec_corrx
      65             :  *
      66             :  * Parameters:
      67             :  *    h              I: scaled impulse response
      68             :  *    vec            I: vector to correlate with h[]
      69             :  *    track          I: track to use
      70             :  *    sign           I: sign vector
      71             :  *    rrixix         I: correlation of h[x] with h[x]
      72             :  *    cor            O: result of correlation (16 elements)
      73             :  *
      74             :  * Function:
      75             :  *    Calculate the correlations of h[] with vec[] for the specified track
      76             :  *
      77             :  * Returns:
      78             :  *    void
      79             :  */
      80     1760753 : static void acelp_h_vec_corr1(
      81             :     float h[],
      82             :     float vec[],
      83             :     int16_t track,
      84             :     float sign[],
      85             :     float ( *rrixix )[16],
      86             :     float cor[],
      87             :     int16_t dn2_pos[],
      88             :     int16_t nb_pulse )
      89             : {
      90             :     int16_t i, j;
      91             :     int16_t dn;
      92             :     int16_t *dn2;
      93             :     float *p0;
      94             :     float s;
      95             : 
      96     1760753 :     dn2 = &dn2_pos[track * 8];
      97     1760753 :     p0 = rrixix[track];
      98    13357811 :     for ( i = 0; i < nb_pulse; i++ )
      99             :     {
     100    11597058 :         dn = dn2[i];
     101    11597058 :         s = 0.0F;
     102             :         /* L_SUBFR-dn */
     103             :         /* vec[dn] */
     104   415984260 :         for ( j = 0; j < ( L_SUBFR - dn ); j++ )
     105             :         {
     106   404387202 :             s += h[j] * vec[dn + j];
     107             :         }
     108             : 
     109    11597058 :         cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];
     110             :     }
     111             : 
     112     1760753 :     return;
     113             : }
     114             : 
     115             : 
     116     2561085 : static void acelp_h_vec_corr2(
     117             :     float h[],
     118             :     float vec[],
     119             :     int16_t track,
     120             :     float sign[],
     121             :     float ( *rrixix )[16],
     122             :     float cor[] )
     123             : {
     124             :     int16_t i, j;
     125             :     float *p0;
     126             :     float s;
     127             : 
     128     2561085 :     p0 = rrixix[track];
     129             :     /* sign[track] */
     130    43538445 :     for ( i = 0; i < 16; i++ )
     131             :     {
     132    40977360 :         s = 0.0F;
     133             :         /* h[0], vec[track] */
     134             :         /* L_SUBFR-track */
     135  1374713440 :         for ( j = 0; j < L_SUBFR - track; j++ )
     136             :         {
     137  1333736080 :             s += h[j] * vec[track + j];
     138             :         }
     139             : 
     140    40977360 :         cor[i] = s * sign[track] + p0[i];
     141    40977360 :         track += 4;
     142             :     }
     143     2561085 :     return;
     144             : }
     145             : 
     146             : 
     147             : /*
     148             :  * acelp_2pulse_search
     149             :  *
     150             :  * Parameters:
     151             :  *    nb_pos_ix      I: nb of pos for pulse 1 (1..8)
     152             :  *    track_x        I: track of pulse 1
     153             :  *    track_y        I: track of pulse 2
     154             :  *    ps           I/O: correlation of all fixed pulses
     155             :  *    alp          I/O: energy of all fixed pulses
     156             :  *    ix             O: position of pulse 1
     157             :  *    iy             O: position of pulse 2
     158             :  *    dn             I: corr. between target and h[]
     159             :  *    dn2            I: vector of selected positions
     160             :  *    cor_x          I: corr. of pulse 1 with fixed pulses
     161             :  *    cor_y          I: corr. of pulse 2 with fixed pulses
     162             :  *    rrixiy         I: corr. of pulse 1 with pulse 2
     163             :  *
     164             :  * Function:
     165             :  *    Find the best positions of 2 pulses in a subframe
     166             :  *
     167             :  * Returns:
     168             :  *    void
     169             :  */
     170     1760753 : static void acelp_2pulse_search(
     171             :     int16_t nb_pos_ix,
     172             :     int16_t track_x,
     173             :     int16_t track_y,
     174             :     float *ps,
     175             :     float *alp,
     176             :     int16_t *ix,
     177             :     int16_t *iy,
     178             :     float dn[],
     179             :     int16_t *dn2,
     180             :     float cor_x[],
     181             :     float cor_y[],
     182             :     float ( *rrixiy )[256] )
     183             : {
     184     1760753 :     int16_t x, x2, y, x_save = 0, y_save = 0, i, *pos_x;
     185             :     float ps0, alp0;
     186             :     float ps1, ps2, sq, sqk;
     187             :     float alp1, alp2, alpk;
     188             :     float *p1, *p2;
     189             :     float s;
     190             : 
     191             :     /* x_save=y_save=0 */
     192             :     /* eight dn2 max positions per track */
     193     1760753 :     pos_x = &dn2[track_x << 3];
     194             :     /* save these to limit memory searches */
     195     1760753 :     ps0 = *ps;
     196     1760753 :     alp0 = *alp;
     197             : 
     198     1760753 :     alpk = 1.0F;
     199     1760753 :     sqk = -1.0F;
     200     1760753 :     x2 = pos_x[0] >> 2;
     201     1760753 :     if ( ( alp0 + cor_x[x2] + cor_y[0] + rrixiy[track_x][x2 << 4] ) < 0 )
     202             :     {
     203           0 :         sqk = 1.0F;
     204             :     }
     205             : 
     206             :     /* loop track 1 */
     207    13357811 :     for ( i = 0; i < nb_pos_ix; i++ )
     208             :     {
     209    11597058 :         x = pos_x[i];
     210    11597058 :         x2 = x >> 2;
     211             :         /* dn[x] has only nb_pos_ix positions saved */
     212    11597058 :         ps1 = ps0 + dn[x];
     213    11597058 :         alp1 = alp0 + cor_x[x2];
     214    11597058 :         p1 = cor_y;
     215    11597058 :         p2 = &rrixiy[track_x][x2 << 4];
     216   197149986 :         for ( y = track_y; y < L_SUBFR; y += 4 )
     217             :         {
     218   185552928 :             ps2 = ps1 + dn[y];
     219   185552928 :             alp2 = alp1 + ( *p1++ ) + ( *p2++ );
     220             : 
     221   185552928 :             sq = ps2 * ps2;
     222             : 
     223   185552928 :             s = ( alpk * sq ) - ( sqk * alp2 );
     224             : 
     225   185552928 :             if ( s > 0.0F )
     226             :             {
     227     8596904 :                 sqk = sq;
     228     8596904 :                 alpk = alp2;
     229     8596904 :                 y_save = y;
     230     8596904 :                 x_save = x;
     231             :             }
     232             :         }
     233             :     }
     234             : 
     235     1760753 :     *ps = ps0 + dn[x_save] + dn[y_save];
     236     1760753 :     *alp = alpk;
     237     1760753 :     *ix = x_save;
     238     1760753 :     *iy = y_save;
     239             : 
     240     1760753 :     return;
     241             : }
     242             : 
     243             : 
     244             : /*
     245             :  * E_ACELP_1pulse_search
     246             :  *
     247             :  * Parameters:
     248             :  *    track_x        I: track of pulse 1
     249             :  *    track_y        I: track of pulse 2
     250             :  *    ps           I/O: correlation of all fixed pulses
     251             :  *    alp          I/O: energy of all fixed pulses
     252             :  *    ix             O: position of pulse 1
     253             :  *    dn             I: corr. between target and h[]
     254             :  *    cor_x          I: corr. of pulse 1 with fixed pulses
     255             :  *    cor_y          I: corr. of pulse 2 with fixed pulses
     256             :  *
     257             :  * Function:
     258             :  *    Find the best positions of 1 pulse in a subframe
     259             :  *
     260             :  * Returns:
     261             :  *    void
     262             :  */
     263      400166 : static void E_ACELP_1pulse_search(
     264             :     int16_t track_x,
     265             :     int16_t track_y,
     266             :     float *ps,
     267             :     float *alp,
     268             :     int16_t *ix,
     269             :     float dn[],
     270             :     float cor_x[],
     271             :     float cor_y[] )
     272             : {
     273      400166 :     int16_t x, x_save = 0;
     274             :     float ps0, alp0;
     275             :     float ps1, sq, sqk;
     276             :     float alp1, alpk;
     277             :     float s;
     278             : 
     279             :     /* save these to limit memory searches */
     280      400166 :     ps0 = *ps;
     281      400166 :     alp0 = *alp;
     282      400166 :     alpk = 1.0F;
     283      400166 :     sqk = -1.0F;
     284             : 
     285      400166 :     if ( ( alp0 + cor_x[( track_x >> 2 )] ) < 0 )
     286             :     {
     287           0 :         sqk = 1.0F;
     288             :     }
     289     6802822 :     for ( x = track_x; x < L_SUBFR; x += 4 )
     290             :     {
     291     6402656 :         ps1 = ps0 + dn[x];
     292     6402656 :         alp1 = alp0 + cor_x[x >> 2];
     293     6402656 :         sq = ps1 * ps1;
     294     6402656 :         s = ( alpk * sq ) - ( sqk * alp1 );
     295             : 
     296     6402656 :         if ( s > 0.0F )
     297             :         {
     298     1539282 :             sqk = sq;
     299     1539282 :             alpk = alp1;
     300     1539282 :             x_save = x;
     301             :         }
     302             :     }
     303      400166 :     if ( track_y != track_x )
     304             :     {
     305     4065057 :         for ( x = track_y; x < L_SUBFR; x += 4 )
     306             :         {
     307     3825936 :             ps1 = ps0 + dn[x];
     308     3825936 :             alp1 = alp0 + cor_y[x >> 2];
     309     3825936 :             sq = ps1 * ps1;
     310     3825936 :             s = ( alpk * sq ) - ( sqk * alp1 );
     311             : 
     312     3825936 :             if ( s > 0.0F )
     313             :             {
     314      142564 :                 sqk = sq;
     315      142564 :                 alpk = alp1;
     316      142564 :                 x_save = x;
     317             :             }
     318             :         }
     319             :     }
     320             : 
     321      400166 :     *ps = ps0 + dn[x_save];
     322      400166 :     *alp = alpk;
     323      400166 :     *ix = x_save;
     324             : 
     325      400166 :     return;
     326             : }
     327             : 
     328             : 
     329             : /*
     330             :  * acelp_pulsesign
     331             :  *
     332             :  * Parameters:
     333             :  *    cn          I: residual after int32_t term prediction
     334             :  *    dn          I: corr. between target and h[].
     335             :  *    dn2         O: dn2[] = mix of dn[] and cn[]
     336             :  *    sign        O: sign of pulse
     337             :  *    vec         O: negative sign of pulse
     338             :  *
     339             :  * Function:
     340             :  *    Determine sign of each pulse position, store them in "sign"
     341             :  *    and change dn to all positive.
     342             :  *    Subframe size = L_SUBFR
     343             :  * Returns:
     344             :  *    void
     345             :  */
     346      577182 : void acelp_pulsesign(
     347             :     const float cn[],
     348             :     float dn[],
     349             :     float dn2[],
     350             :     float sign[],
     351             :     float vec[],
     352             :     const float alp )
     353             : {
     354             :     int16_t i;
     355             :     float val;
     356             :     float s, cor;
     357             : 
     358             :     /* calculate energy for normalization of cn[] and dn[] */
     359      577182 :     val = ( cn[0] * cn[0] ) + 1.0F;
     360      577182 :     cor = ( dn[0] * dn[0] ) + 1.0F;
     361    36939648 :     for ( i = 1; i < L_SUBFR; i++ )
     362             :     {
     363    36362466 :         val += ( cn[i] * cn[i] );
     364    36362466 :         cor += ( dn[i] * dn[i] );
     365             :     }
     366             : 
     367      577182 :     s = (float) sqrt( cor / val );
     368    37516830 :     for ( i = 0; i < L_SUBFR; i++ )
     369             :     {
     370    36939648 :         cor = ( s * cn[i] ) + ( alp * dn[i] );
     371    36939648 :         if ( cor >= 0.0F )
     372             :         {
     373    18491950 :             sign[i] = 1.0F;
     374    18491950 :             vec[i] = -1.0F;
     375    18491950 :             dn2[i] = cor; /* dn2[] = mix of dn[] and cn[]   */
     376             :         }
     377             :         else
     378             :         {
     379    18447698 :             sign[i] = -1.0F;
     380    18447698 :             vec[i] = 1.0F;
     381    18447698 :             dn[i] = -dn[i]; /* modify dn[] according to the fixed sign */
     382    18447698 :             dn2[i] = -cor;  /* dn2[] = mix of dn[] and cn[]            */
     383             :         }
     384             :     }
     385             : 
     386      577182 :     return;
     387             : }
     388             : 
     389             : 
     390      577182 : void acelp_findcandidates(
     391             :     float dn2[],
     392             :     int16_t dn2_pos[],
     393             :     int16_t pos_max[],
     394             :     const int16_t L_subfr,
     395             :     const int16_t tracks )
     396             : {
     397             :     int16_t i, k, j;
     398             :     float *ps_ptr;
     399             : 
     400             :     /* &pos_max[0], &dn2_pos[0] */
     401     2885910 :     for ( i = 0; i < tracks; i++ )
     402             :     {
     403    20778552 :         for ( k = 0; k < NB_MAX; k++ )
     404             :         {
     405    18469824 :             ps_ptr = &dn2[i];
     406   295517184 :             for ( j = i + tracks; j < L_subfr; j += tracks )
     407             :             {
     408   277047360 :                 if ( dn2[j] > *ps_ptr )
     409             :                 {
     410    44854993 :                     ps_ptr = &dn2[j];
     411             :                 }
     412             :             }
     413    18469824 :             *ps_ptr = (float) k - NB_MAX; /* dn2 < 0 when position is selected */
     414    18469824 :             dn2_pos[i * 8 + k] = (int16_t) ( ps_ptr - dn2 );
     415             :         }
     416     2308728 :         pos_max[i] = dn2_pos[i * 8];
     417             :     }
     418             : 
     419      577182 :     return;
     420             : }
     421             : 
     422             : 
     423      181619 : static void acelp_hbuf(
     424             :     float *h_buf,
     425             :     float **h,
     426             :     float **h_inv,
     427             :     const float *H )
     428             : {
     429             :     int16_t i;
     430             : 
     431      181619 :     *h = h_buf + L_SUBFR;
     432      181619 :     *h_inv = h_buf + ( 3 * L_SUBFR );
     433    11805235 :     for ( i = 0; i < L_SUBFR; i++ )
     434             :     {
     435    11623616 :         ( *h )[-1 - i] = 0.0f;
     436    11623616 :         ( *h_inv )[-1 - i] = 0.0f;
     437    11623616 :         ( *h )[i] = H[i];
     438    11623616 :         ( *h_inv )[i] = -H[i];
     439             :     }
     440             : 
     441      181619 :     return;
     442             : }
     443             : 
     444             : 
     445      181619 : static void E_ACELP_corrmatrix(
     446             :     float h[],
     447             :     float sign[],
     448             :     float vec[],
     449             :     float rrixix[4][16],
     450             :     float rrixiy[4][256] )
     451             : {
     452             :     float *p0, *p1, *p2, *p3, *psign0, *psign1, *psign2, *psign3;
     453             :     float *ptr_h1, *ptr_h2, *ptr_hf;
     454             :     float cor;
     455             :     int16_t i, k, pos;
     456             : 
     457             :     /* Compute rrixix[][] needed for the codebook search. */
     458             :     /* storage order --> i3i3, i2i2, i1i1, i0i0 */
     459             : 
     460             :     /* Init pointers to last position of rrixix[] */
     461      181619 :     p0 = &rrixix[0][16 - 1];
     462      181619 :     p1 = &rrixix[1][16 - 1];
     463      181619 :     p2 = &rrixix[2][16 - 1];
     464      181619 :     p3 = &rrixix[3][16 - 1];
     465             : 
     466      181619 :     ptr_h1 = h;
     467      181619 :     cor = 0.0F;
     468     3087523 :     for ( i = 0; i < 16; i++ )
     469             :     {
     470     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     471     2905904 :         ptr_h1++;
     472     2905904 :         *p3-- = cor * 0.5F;
     473     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     474     2905904 :         ptr_h1++;
     475     2905904 :         *p2-- = cor * 0.5F;
     476     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     477     2905904 :         ptr_h1++;
     478     2905904 :         *p1-- = cor * 0.5F;
     479     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     480     2905904 :         ptr_h1++;
     481     2905904 :         *p0-- = cor * 0.5F;
     482             :     }
     483             : 
     484             :     /* Compute rrixiy[][] needed for the codebook search. */
     485             :     /* storage order --> i2i3, i1i2, i0i1, i3i0 */
     486             : 
     487      181619 :     pos = 256 - 1;
     488      181619 :     ptr_hf = h + 1;
     489     3087523 :     for ( k = 0; k < 16; k++ )
     490             :     {
     491             : 
     492     2905904 :         p3 = &rrixiy[2][pos];
     493     2905904 :         p2 = &rrixiy[1][pos];
     494     2905904 :         p1 = &rrixiy[0][pos];
     495     2905904 :         p0 = &rrixiy[3][pos - 16];
     496             : 
     497     2905904 :         cor = 0.0F;
     498     2905904 :         ptr_h1 = h;
     499     2905904 :         ptr_h2 = ptr_hf;
     500    24700184 :         for ( i = k; i < 15; i++ )
     501             :         {
     502    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     503    21794280 :             ptr_h1++;
     504    21794280 :             ptr_h2++;
     505    21794280 :             *p3 = cor;
     506    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     507    21794280 :             ptr_h1++;
     508    21794280 :             ptr_h2++;
     509    21794280 :             *p2 = cor;
     510    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     511    21794280 :             ptr_h1++;
     512    21794280 :             ptr_h2++;
     513    21794280 :             *p1 = cor;
     514    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     515    21794280 :             ptr_h1++;
     516    21794280 :             ptr_h2++;
     517    21794280 :             *p0 = cor;
     518             : 
     519    21794280 :             p3 -= ( 16 + 1 );
     520    21794280 :             p2 -= ( 16 + 1 );
     521    21794280 :             p1 -= ( 16 + 1 );
     522    21794280 :             p0 -= ( 16 + 1 );
     523             :         }
     524             : 
     525     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     526     2905904 :         ptr_h1++;
     527     2905904 :         ptr_h2++;
     528     2905904 :         *p3 = cor;
     529     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     530     2905904 :         ptr_h1++;
     531     2905904 :         ptr_h2++;
     532     2905904 :         *p2 = cor;
     533     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     534     2905904 :         ptr_h1++;
     535     2905904 :         ptr_h2++;
     536     2905904 :         *p1 = cor;
     537             : 
     538     2905904 :         pos -= 16;
     539     2905904 :         ptr_hf += 4;
     540             :     }
     541             : 
     542             :     /* storage order --> i3i0, i2i3, i1i2, i0i1 */
     543             : 
     544      181619 :     pos = 256 - 1;
     545      181619 :     ptr_hf = h + 3;
     546     3087523 :     for ( k = 0; k < 16; k++ )
     547             :     {
     548             : 
     549     2905904 :         p3 = &rrixiy[3][pos];
     550     2905904 :         p2 = &rrixiy[2][pos - 1];
     551     2905904 :         p1 = &rrixiy[1][pos - 1];
     552     2905904 :         p0 = &rrixiy[0][pos - 1];
     553             : 
     554     2905904 :         cor = 0.0F;
     555     2905904 :         ptr_h1 = h;
     556     2905904 :         ptr_h2 = ptr_hf;
     557    24700184 :         for ( i = k + 1; i < 16; i++ )
     558             :         {
     559    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     560    21794280 :             ptr_h1++;
     561    21794280 :             ptr_h2++;
     562    21794280 :             *p3 = cor;
     563    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     564    21794280 :             ptr_h1++;
     565    21794280 :             ptr_h2++;
     566    21794280 :             *p2 = cor;
     567    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     568    21794280 :             ptr_h1++;
     569    21794280 :             ptr_h2++;
     570    21794280 :             *p1 = cor;
     571    21794280 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     572    21794280 :             ptr_h1++;
     573    21794280 :             ptr_h2++;
     574    21794280 :             *p0 = cor;
     575             : 
     576    21794280 :             p3 -= ( 16 + 1 );
     577    21794280 :             p2 -= ( 16 + 1 );
     578    21794280 :             p1 -= ( 16 + 1 );
     579    21794280 :             p0 -= ( 16 + 1 );
     580             :         }
     581             : 
     582     2905904 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     583     2905904 :         *p3 = cor;
     584             : 
     585     2905904 :         pos--;
     586     2905904 :         ptr_hf += 4;
     587             :     }
     588             : 
     589             :     /* Modification of rrixiy[][] to take signs into account. */
     590             : 
     591      181619 :     p0 = &rrixiy[0][0];
     592             :     /* speed-up: 11% */
     593      181619 :     p1 = &rrixiy[1][0];
     594      181619 :     p2 = &rrixiy[2][0];
     595      181619 :     p3 = &rrixiy[3][0];
     596     3087523 :     for ( i = 0; i < L_SUBFR; i += 4 )
     597             :     {
     598     2905904 :         if ( sign[i + 0] < 0.0F )
     599     1455355 :             psign0 = &vec[1];
     600             :         else
     601     1450549 :             psign0 = &sign[1];
     602     2905904 :         if ( sign[i + 1] < 0.0F )
     603     1454651 :             psign1 = &vec[2];
     604             :         else
     605     1451253 :             psign1 = &sign[2];
     606     2905904 :         if ( sign[i + 2] < 0.0F )
     607     1454391 :             psign2 = &vec[3];
     608             :         else
     609     1451513 :             psign2 = &sign[3];
     610     2905904 :         if ( sign[i + 3] < 0.0F )
     611     1456173 :             psign3 = &vec[0];
     612             :         else
     613     1449731 :             psign3 = &sign[0];
     614     2905904 :         p0[0] = p0[0] * psign0[0];
     615     2905904 :         p0[1] = p0[1] * psign0[4];
     616     2905904 :         p0[2] = p0[2] * psign0[8];
     617     2905904 :         p0[3] = p0[3] * psign0[12];
     618     2905904 :         p0[4] = p0[4] * psign0[16];
     619     2905904 :         p0[5] = p0[5] * psign0[20];
     620     2905904 :         p0[6] = p0[6] * psign0[24];
     621     2905904 :         p0[7] = p0[7] * psign0[28];
     622     2905904 :         p0[8] = p0[8] * psign0[32];
     623     2905904 :         p0[9] = p0[9] * psign0[36];
     624     2905904 :         p0[10] = p0[10] * psign0[40];
     625     2905904 :         p0[11] = p0[11] * psign0[44];
     626     2905904 :         p0[12] = p0[12] * psign0[48];
     627     2905904 :         p0[13] = p0[13] * psign0[52];
     628     2905904 :         p0[14] = p0[14] * psign0[56];
     629     2905904 :         p0[15] = p0[15] * psign0[60];
     630     2905904 :         p0 += 16;
     631             : 
     632     2905904 :         p1[0] = p1[0] * psign1[0];
     633     2905904 :         p1[1] = p1[1] * psign1[4];
     634     2905904 :         p1[2] = p1[2] * psign1[8];
     635     2905904 :         p1[3] = p1[3] * psign1[12];
     636     2905904 :         p1[4] = p1[4] * psign1[16];
     637     2905904 :         p1[5] = p1[5] * psign1[20];
     638     2905904 :         p1[6] = p1[6] * psign1[24];
     639     2905904 :         p1[7] = p1[7] * psign1[28];
     640     2905904 :         p1[8] = p1[8] * psign1[32];
     641     2905904 :         p1[9] = p1[9] * psign1[36];
     642     2905904 :         p1[10] = p1[10] * psign1[40];
     643     2905904 :         p1[11] = p1[11] * psign1[44];
     644     2905904 :         p1[12] = p1[12] * psign1[48];
     645     2905904 :         p1[13] = p1[13] * psign1[52];
     646     2905904 :         p1[14] = p1[14] * psign1[56];
     647     2905904 :         p1[15] = p1[15] * psign1[60];
     648     2905904 :         p1 += 16;
     649             : 
     650     2905904 :         p2[0] = p2[0] * psign2[0];
     651     2905904 :         p2[1] = p2[1] * psign2[4];
     652     2905904 :         p2[2] = p2[2] * psign2[8];
     653     2905904 :         p2[3] = p2[3] * psign2[12];
     654     2905904 :         p2[4] = p2[4] * psign2[16];
     655     2905904 :         p2[5] = p2[5] * psign2[20];
     656     2905904 :         p2[6] = p2[6] * psign2[24];
     657     2905904 :         p2[7] = p2[7] * psign2[28];
     658     2905904 :         p2[8] = p2[8] * psign2[32];
     659     2905904 :         p2[9] = p2[9] * psign2[36];
     660     2905904 :         p2[10] = p2[10] * psign2[40];
     661     2905904 :         p2[11] = p2[11] * psign2[44];
     662     2905904 :         p2[12] = p2[12] * psign2[48];
     663     2905904 :         p2[13] = p2[13] * psign2[52];
     664     2905904 :         p2[14] = p2[14] * psign2[56];
     665     2905904 :         p2[15] = p2[15] * psign2[60];
     666     2905904 :         p2 += 16;
     667             : 
     668     2905904 :         p3[0] = p3[0] * psign3[0];
     669     2905904 :         p3[1] = p3[1] * psign3[4];
     670     2905904 :         p3[2] = p3[2] * psign3[8];
     671     2905904 :         p3[3] = p3[3] * psign3[12];
     672     2905904 :         p3[4] = p3[4] * psign3[16];
     673     2905904 :         p3[5] = p3[5] * psign3[20];
     674     2905904 :         p3[6] = p3[6] * psign3[24];
     675     2905904 :         p3[7] = p3[7] * psign3[28];
     676     2905904 :         p3[8] = p3[8] * psign3[32];
     677     2905904 :         p3[9] = p3[9] * psign3[36];
     678     2905904 :         p3[10] = p3[10] * psign3[40];
     679     2905904 :         p3[11] = p3[11] * psign3[44];
     680     2905904 :         p3[12] = p3[12] * psign3[48];
     681     2905904 :         p3[13] = p3[13] * psign3[52];
     682     2905904 :         p3[14] = p3[14] * psign3[56];
     683     2905904 :         p3[15] = p3[15] * psign3[60];
     684     2905904 :         p3 += 16;
     685             :     }
     686             : 
     687      181619 :     return;
     688             : }
     689             : 
     690      181619 : void E_ACELP_4tsearch(
     691             :     float dn[],
     692             :     const float cn[],
     693             :     const float H[],
     694             :     float code[],
     695             :     PulseConfig *config,
     696             :     int16_t ind[],
     697             :     float y[] )
     698             : {
     699             :     float sign[L_SUBFR], vec[L_SUBFR];
     700             :     float cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
     701             :     float rrixix[4][16];
     702             :     float rrixiy[4][256];
     703             :     float dn2[L_SUBFR];
     704      181619 :     float psk, ps, alpk, alp = 0.0F;
     705             :     int16_t codvec[NB_PULSE_MAX];
     706             :     int16_t pos_max[4];
     707             :     int16_t dn2_pos[8 * 4];
     708             :     int16_t ipos[NB_PULSE_MAX];
     709             :     float *p0, *p1, *p2, *p3;
     710             :     float *h, *h_inv;
     711      181619 :     int16_t i, j, k, l, st, pos = 0, track;
     712             :     int16_t index, iPulse;
     713             :     float val;
     714             :     float s;
     715             :     int16_t restpulses;
     716             : 
     717      181619 :     alp = config->alp; /* initial value for energy of all fixed pulses */
     718             : 
     719     1169875 :     for ( k = 0; k < config->nb_pulse; k++ )
     720             :     {
     721      988256 :         codvec[k] = 0;
     722             :     }
     723             : 
     724             :     /* Find sign for each pulse position. */
     725      181619 :     acelp_pulsesign( cn, dn, dn2, sign, vec, alp );
     726             : 
     727             :     /* Select the most important 8 position per track according to dn2[]. */
     728      181619 :     acelp_findcandidates( dn2, dn2_pos, pos_max, L_SUBFR, NB_TRACK_FCB_4T );
     729             : 
     730             :     /* Compute h_inv[i]. */
     731      181619 :     acelp_hbuf( h_buf, &h, &h_inv, H );
     732             : 
     733             :     /* Compute correlation matrices needed for the codebook search. */
     734      181619 :     E_ACELP_corrmatrix( h, sign, vec, rrixix, rrixiy );
     735             : 
     736             :     /*
     737             :      * Deep first search:
     738             :      * ------------------
     739             :      * 20 bits (4p):  4 iter x ((4x16)+(8x16))              = 768 tests
     740             :      * 36 bits (8p):  4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
     741             :      * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     742             :      *                                      +(8x16)+(8x16)) = 1248 tests
     743             :      * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     744             :      *                        +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
     745             :      */
     746      181619 :     psk = -1.0;
     747      181619 :     alpk = 1.0;
     748             :     /*Number of iterations*/
     749      940789 :     for ( k = 0; k < config->nbiter; k++ )
     750             :     {
     751             :         /* copy search order from hash-table */
     752     4758214 :         for ( l = 0; l < config->nb_pulse; l++ )
     753             :         {
     754     3999044 :             ipos[l] = tipos[( k * 4 ) + l];
     755             :         }
     756             : 
     757             :         /* if all tracks do not have equal number of pulses */
     758      759170 :         restpulses = config->nb_pulse & 3;
     759      759170 :         if ( restpulses )
     760             :         {
     761      588327 :             switch ( config->codetrackpos )
     762             :             {
     763      217112 :                 case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
     764             :                     /* add tracks from left */
     765      683061 :                     for ( iPulse = 0; iPulse < restpulses; iPulse++ )
     766             :                     {
     767      465949 :                         ipos[config->nb_pulse - restpulses + iPulse] = iPulse;
     768             :                     }
     769             :                     /* Put the same track on the next position, because the 1-pulse search
     770             :                      * will access it to determine if this could be in any track. */
     771      217112 :                     ipos[config->nb_pulse] = ipos[config->nb_pulse - 1];
     772      217112 :                     break;
     773           0 :                 case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */
     774             :                     /* odd tracks, switch order for every iteration */
     775           0 :                     ipos[config->nb_pulse - restpulses] = ( k << 1 ) & 2;                              /* 0 for even k, 2 for odd*/
     776           0 :                     ipos[config->nb_pulse - restpulses + 1] = ipos[config->nb_pulse - restpulses] ^ 2; /* 2 for even k, 0 for odd*/
     777           0 :                     break;
     778      132094 :                 case TRACKPOS_FIXED_TWO: /* two tracks instead of four */
     779             :                     /* Put the next track on the next position, because the 1-pulse search
     780             :                      * will access it to determine if this could be in any track. */
     781      132094 :                     ipos[config->nb_pulse] = ( ipos[config->nb_pulse - 1] + 1 ) & 3;
     782      132094 :                     break;
     783      239121 :                 default: /* one or three free track positions */
     784             :                     /* copy an extra position from table - 1pulse search will access this */
     785      239121 :                     ipos[config->nb_pulse] = tipos[( k * 4 ) + config->nb_pulse];
     786      239121 :                     break;
     787             :             }
     788      170843 :         }
     789      759170 :         if ( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
     790             :         {
     791      720489 :             pos = 0;
     792      720489 :             ps = 0.0F;
     793      720489 :             alp = 0.0F;
     794    46831785 :             for ( i = 0; i < L_SUBFR; i++ )
     795             :             {
     796    46111296 :                 vec[i] = 0;
     797             :             }
     798             :         }
     799       38681 :         else if ( config->fixedpulses == 2 ) /* 2222 and 3322 */
     800             :         {
     801             :             /* first stage: fix 2 pulses */
     802       38676 :             pos = 2;
     803             : 
     804       38676 :             ind[0] = pos_max[ipos[0]];
     805       38676 :             ind[1] = pos_max[ipos[1]];
     806       38676 :             ps = dn[ind[0]] + dn[ind[1]];
     807             : 
     808             :             /*ind[1]>>2 and ind[0]>>2 and save*/
     809             :             /* ipos[1] and ipos[0]    and save*/
     810       38676 :             alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
     811       38676 :                   rrixiy[ipos[0]][( ( ind[0] >> 2 ) << 4 ) + ( ind[1] >> 2 )];
     812             : 
     813       38676 :             if ( sign[ind[0]] < 0.0 )
     814             :             {
     815       18675 :                 p0 = h_inv - ind[0];
     816             :             }
     817             :             else
     818             :             {
     819       20001 :                 p0 = h - ind[0];
     820             :             }
     821       38676 :             if ( sign[ind[1]] < 0.0 )
     822             :             {
     823       18662 :                 p1 = h_inv - ind[1];
     824             :             }
     825             :             else
     826             :             {
     827       20014 :                 p1 = h - ind[1];
     828             :             }
     829             :             /*ptx = &vec   p1 and p0 already initialize*/
     830       38676 :             vec[0] = p0[0] + p1[0];
     831       38676 :             vec[1] = p0[1] + p1[1];
     832       38676 :             vec[2] = p0[2] + p1[2];
     833       38676 :             vec[3] = p0[3] + p1[3];
     834      425436 :             for ( i = 4; i < L_SUBFR; i += 6 )
     835             :             {
     836      386760 :                 vec[i] = p0[i] + p1[i];
     837      386760 :                 vec[i + 1] = p0[i + 1] + p1[i + 1];
     838      386760 :                 vec[i + 2] = p0[i + 2] + p1[i + 2];
     839      386760 :                 vec[i + 3] = p0[i + 3] + p1[i + 3];
     840      386760 :                 vec[i + 4] = p0[i + 4] + p1[i + 4];
     841      386760 :                 vec[i + 5] = p0[i + 5] + p1[i + 5];
     842             :             }
     843             :         }
     844             :         else /* 3333 and above */
     845             :         {
     846             :             /* first stage: fix 4 pulses */
     847           5 :             pos = 4;
     848             : 
     849           5 :             ind[0] = pos_max[ipos[0]];
     850           5 :             ind[1] = pos_max[ipos[1]];
     851           5 :             ind[2] = pos_max[ipos[2]];
     852           5 :             ind[3] = pos_max[ipos[3]];
     853           5 :             ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];
     854             : 
     855           5 :             p0 = h - ind[0];
     856           5 :             if ( sign[ind[0]] < 0.0 )
     857             :             {
     858           5 :                 p0 = h_inv - ind[0];
     859             :             }
     860             : 
     861           5 :             p1 = h - ind[1];
     862           5 :             if ( sign[ind[1]] < 0.0 )
     863             :             {
     864           5 :                 p1 = h_inv - ind[1];
     865             :             }
     866             : 
     867           5 :             p2 = h - ind[2];
     868           5 :             if ( sign[ind[2]] < 0.0 )
     869             :             {
     870           5 :                 p2 = h_inv - ind[2];
     871             :             }
     872             : 
     873           5 :             p3 = h - ind[3];
     874           5 :             if ( sign[ind[3]] < 0.0 )
     875             :             {
     876           5 :                 p3 = h_inv - ind[3];
     877             :             }
     878             :             /* pt =&vec; others already defined*/
     879           5 :             vec[0] = p0[0] + p1[0] + p2[0] + p3[0];
     880         110 :             for ( i = 1; i < L_SUBFR; i += 3 )
     881             :             {
     882         105 :                 vec[i] = p0[i] + p1[i] + p2[i] + p3[i];
     883         105 :                 vec[i + 1] = p0[i + 1] + p1[i + 1] + p2[i + 1] + p3[i + 1];
     884         105 :                 vec[i + 2] = p0[i + 2] + p1[i + 2] + p2[i + 2] + p3[i + 2];
     885             :             }
     886             : 
     887           5 :             alp = 0.0F;
     888           5 :             alp += vec[0] * vec[0] + vec[1] * vec[1];
     889           5 :             alp += vec[2] * vec[2] + vec[3] * vec[3];
     890             : 
     891          55 :             for ( i = 4; i < L_SUBFR; i += 6 )
     892             :             {
     893          50 :                 alp += vec[i] * vec[i];
     894          50 :                 alp += vec[i + 1] * vec[i + 1];
     895          50 :                 alp += vec[i + 2] * vec[i + 2];
     896          50 :                 alp += vec[i + 3] * vec[i + 3];
     897          50 :                 alp += vec[i + 4] * vec[i + 4];
     898          50 :                 alp += vec[i + 5] * vec[i + 5];
     899             :             }
     900             : 
     901           5 :             alp *= 0.5F;
     902             :         }
     903             : 
     904             :         /* other stages of 2 pulses */
     905     2920089 :         for ( j = pos, st = 0; j < config->nb_pulse; j += 2, st++ )
     906             :         {
     907     2160919 :             if ( ( config->nb_pulse - j ) >= 2 ) /*pair-wise search*/
     908             :             {
     909             :                 /* Calculate correlation of all possible positions
     910             :                  * of the next 2 pulses with previous fixed pulses.
     911             :                  * Each pulse can have 16 possible positions. */
     912     1760753 :                 acelp_h_vec_corr1( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] );
     913     1760753 :                 acelp_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y );
     914             : 
     915             :                 /* Find best positions of 2 pulses. */
     916     1760753 :                 acelp_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp, &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy );
     917             :             }
     918             :             else /*single pulse search*/
     919             :             {
     920      400166 :                 acelp_h_vec_corr2( h, vec, ipos[j], sign, rrixix, cor_x );
     921      400166 :                 acelp_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y );
     922      400166 :                 E_ACELP_1pulse_search( ipos[j], ipos[j + 1], &ps, &alp, &ind[j], dn, cor_x, cor_y );
     923             :             }
     924     2160919 :             if ( j < ( config->nb_pulse - 2 ) )
     925             :             {
     926     1401749 :                 p0 = h - ind[j];
     927     1401749 :                 if ( sign[ind[j]] < 0.0 )
     928             :                 {
     929      700262 :                     p0 = h_inv - ind[j];
     930             :                 }
     931             : 
     932     1401749 :                 p1 = h - ind[j + 1];
     933     1401749 :                 if ( sign[ind[j + 1]] < 0.0 )
     934             :                 {
     935      702298 :                     p1 = h_inv - ind[j + 1];
     936             :                 }
     937             : 
     938     1401749 :                 vec[0] += p0[0] + p1[0];
     939     1401749 :                 vec[1] += p0[1] + p1[1];
     940     1401749 :                 vec[2] += p0[2] + p1[2];
     941     1401749 :                 vec[3] += p0[3] + p1[3];
     942    15419239 :                 for ( i = 4; i < L_SUBFR; i += 6 )
     943             :                 {
     944    14017490 :                     vec[i] += p0[i] + p1[i];
     945    14017490 :                     vec[i + 1] += p0[i + 1] + p1[i + 1];
     946    14017490 :                     vec[i + 2] += p0[i + 2] + p1[i + 2];
     947    14017490 :                     vec[i + 3] += p0[i + 3] + p1[i + 3];
     948    14017490 :                     vec[i + 4] += p0[i + 4] + p1[i + 4];
     949    14017490 :                     vec[i + 5] += p0[i + 5] + p1[i + 5];
     950             :                 }
     951             :             }
     952             :         }
     953             : 
     954             :         /* memorise the best codevector */
     955      759170 :         ps = ps * ps;
     956      759170 :         s = ( alpk * ps ) - ( psk * alp );
     957      759170 :         if ( psk < 0 )
     958             :         {
     959      181619 :             s = 1.0F;
     960             :         }
     961      759170 :         if ( s > 0.0F )
     962             :         {
     963      364845 :             psk = ps;
     964      364845 :             alpk = alp;
     965     2343536 :             for ( i = 0; i < config->nb_pulse; i++ )
     966             :             {
     967     1978691 :                 codvec[i] = ind[i];
     968             :             }
     969             :         }
     970             :     }
     971             : 
     972             :     /* Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations. */
     973      181619 :     set_f( code, 0, L_SUBFR );
     974      181619 :     set_f( y, 0, L_SUBFR );
     975      181619 :     set_s( ind, -1, NPMAXPT * 4 );
     976             : 
     977     1169875 :     for ( k = 0; k < config->nb_pulse; k++ )
     978             :     {
     979      988256 :         i = codvec[k]; /* read pulse position  */
     980      988256 :         val = sign[i]; /* read sign            */
     981             : 
     982      988256 :         index = (int16_t) ( i / 4 ); /* pos of pulse (0..15) */
     983      988256 :         track = i % 4;
     984      988256 :         if ( val > 0 )
     985             :         {
     986      495023 :             code[i] += 1.0f;
     987      495023 :             codvec[k] += ( 2 * L_SUBFR );
     988             :         }
     989             :         else
     990             :         {
     991      493233 :             code[i] -= 1.0f;
     992      493233 :             index += 16;
     993             :         }
     994             : 
     995      988256 :         i = track * NPMAXPT;
     996     1275321 :         while ( ind[i] >= 0 )
     997             :         {
     998      287065 :             i++;
     999             :         }
    1000             : 
    1001      988256 :         ind[i] = index;
    1002             : 
    1003      988256 :         p0 = h_inv - codvec[k];
    1004    64236640 :         for ( i = 0; i < L_SUBFR; i++ )
    1005             :         {
    1006    63248384 :             y[i] += *p0++;
    1007             :         }
    1008             :     }
    1009             : 
    1010      181619 :     return;
    1011             : }
    1012             : 
    1013             : 
    1014             : /*
    1015             :  * E_ACELP_4t
    1016             :  *
    1017             :  * Parameters:
    1018             :  *    dn          I: corr. between target and h[].
    1019             :  *    cn          I: residual after int32_t term prediction
    1020             :  *    H           I: impulse response of weighted synthesis filter (Q12)
    1021             :  *    code        O: algebraic (fixed) codebook excitation (Q9)
    1022             :  *    y           O: filtered fixed codebook excitation (Q9)
    1023             :  *    nbbits      I: 20, 36, 44, 52, 64, 72 or 88 bits
    1024             :  *    mode        I: speech mode
    1025             :  *    _index      O: index
    1026             :  *
    1027             :  * Function:
    1028             :  *    20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
    1029             :  *    4 tracks x 16 positions per track = 64 samples.
    1030             :  *
    1031             :  *    20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
    1032             :  *    36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
    1033             :  *    44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
    1034             :  *    52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
    1035             :  *    64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
    1036             :  *                                  16 pulses in a frame of 64 samples.
    1037             :  *    72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
    1038             :  *                                  18 pulses in a frame of 64 samples.
    1039             :  *    88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
    1040             :  *                                  24 pulses in a frame of 64 samples.
    1041             :  *
    1042             :  *    All pulses can have two (2) possible amplitudes: +1 or -1.
    1043             :  *    Each pulse can sixteen (16) possible positions.
    1044             :  *
    1045             :  * Returns:
    1046             :  *    void
    1047             :  */
    1048             : 
    1049      512623 : void E_ACELP_4t(
    1050             :     float dn[],
    1051             :     float cn[],
    1052             :     float H[],
    1053             :     float R[],
    1054             :     const int16_t acelpautoc,
    1055             :     float code[],
    1056             :     const int16_t cdk_index,
    1057             :     int16_t _index[],
    1058             :     const int16_t L_frame,
    1059             :     const int16_t last_L_frame,
    1060             :     const int32_t total_brate,
    1061             :     const int16_t i_subfr,
    1062             :     const int16_t cmpl_flag )
    1063             : {
    1064             :     PulseConfig config;
    1065             :     int16_t ind[NPMAXPT * 4];
    1066             :     float y[L_SUBFR];
    1067             : 
    1068      512623 :     config = PulseConfTable[cdk_index];
    1069             : 
    1070      512623 :     if ( cmpl_flag > 0 )
    1071             :     {
    1072       10297 :         config.nbiter = cmpl_flag;
    1073             :     }
    1074             : 
    1075      512623 :     if ( L_frame != last_L_frame && total_brate == ACELP_24k40 && i_subfr < 5 * L_SUBFR )
    1076             :     {
    1077           0 :         ( config.nbiter )--;
    1078           0 :         config.nbiter = max( config.nbiter, 1 );
    1079             :     }
    1080             : 
    1081      512623 :     if ( acelpautoc & 0x01 )
    1082             :     {
    1083      334638 :         E_ACELP_4tsearchx( dn, cn, R, code, &config, ind );
    1084             :     }
    1085             :     else
    1086             :     {
    1087      177985 :         E_ACELP_4tsearch( dn, cn, H, code, &config, ind, y );
    1088             :     }
    1089             : 
    1090      512623 :     E_ACELP_indexing( code, config, NB_TRACK_FCB_4T, _index );
    1091             : 
    1092      512623 :     return;
    1093             : }
    1094             : 
    1095             : 
    1096      577182 : int16_t E_ACELP_indexing(
    1097             :     float code[],
    1098             :     PulseConfig config,
    1099             :     const int16_t num_tracks,
    1100             :     int16_t prm[] )
    1101             : {
    1102             :     uint16_t track;
    1103             :     int16_t p[NB_TRACK_FCB_4T], wordcnt;
    1104             :     int16_t k;
    1105             :     uint16_t idxs[MAX_IDX_LEN], maxppos;
    1106             :     uint32_t s[NB_TRACK_FCB_4T], n[NB_TRACK_FCB_4T];
    1107             :     int16_t maxp;
    1108             :     int16_t saved_bits;
    1109             : 
    1110      577182 :     assert( num_tracks == NB_TRACK_FCB_4T );
    1111             : 
    1112      577182 :     saved_bits = 0;
    1113             : 
    1114             :     /* Code state of pulses of all tracks */
    1115      577182 :     wordcnt = ( config.bits + 15 ) >> 4; /* ceil(bits/16) */
    1116     2428567 :     for ( k = 0; k < wordcnt; k++ )
    1117             :     {
    1118     1851385 :         idxs[k] = 0;
    1119             :     }
    1120      577182 :     if ( config.bits == 43 ) /* EVS pulse indexing */
    1121             :     {
    1122       33648 :         saved_bits = E_ACELP_code43bit( code, s, p, idxs );
    1123             :     }
    1124             :     else
    1125             :     {
    1126     2717670 :         for ( track = 0; track < num_tracks; track++ )
    1127             :         {
    1128             :             /* Code track of length 2^4 where step between tracks is 4. */
    1129     2174136 :             E_ACELP_codearithp( code + track, n + track, s + track, p + track, num_tracks, 16 );
    1130             :         }
    1131      543534 :         fcb_pulse_track_joint( idxs, wordcnt, s, p, num_tracks );
    1132             :     }
    1133             : 
    1134             :     /* check if we need to code track positions */
    1135      577182 :     switch ( config.codetrackpos )
    1136             :     {
    1137       75030 :         case TRACKPOS_FIXED_TWO:
    1138             :             /* Code position of consecutive tracks with single extra pulses */
    1139             : 
    1140             :             /* Find track with one pulse less. */
    1141       75030 :             if ( p[0] == p[1] )
    1142             :             {
    1143             :                 /* Either 1100 or 0011 */
    1144       37727 :                 if ( p[1] > p[2] )
    1145             :                 {
    1146       18654 :                     track = 0; /* 1100 */
    1147             :                 }
    1148             :                 else
    1149             :                 {
    1150       19073 :                     track = 2; /* 0011 */
    1151             :                 }
    1152             :             }
    1153             :             else
    1154             :             {
    1155             :                 /* Either 0110 or 1001 */
    1156       37303 :                 if ( p[0] < p[1] )
    1157             :                 {
    1158       18886 :                     track = 1; /* 0110 */
    1159             :                 }
    1160             :                 else
    1161             :                 {
    1162       18417 :                     track = 3; /* 1001 */
    1163             :                 }
    1164             :             }
    1165             :             /* Multiply by number of possible states (=shift by two) and
    1166             :              * add actual state. */
    1167       75030 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1168       75030 :             longadd( idxs, &track, wordcnt, 1 );
    1169       75030 :             break;
    1170       67285 :         case TRACKPOS_FREE_THREE:
    1171             :             /* Code position of track with one pulse less than others */
    1172             : 
    1173             :             /* Find track with one pulse less. */
    1174       67285 :             maxp = p[0];
    1175       67285 :             maxppos = 0;
    1176      167692 :             for ( track = 1; track < 4; track++ )
    1177             :             {
    1178      151143 :                 if ( p[track] < maxp )
    1179             :                 {
    1180       50736 :                     maxppos = track;
    1181       50736 :                     break;
    1182             :                 }
    1183             :             }
    1184             :             /* Multiply by number of possible states (=shift by two) and
    1185             :              * add actual state. */
    1186       67285 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1187       67285 :             longadd( idxs, &maxppos, wordcnt, 1 );
    1188       67285 :             break;
    1189       21950 :         case TRACKPOS_FREE_ONE:
    1190             :             /* Code position of track with one pulse more than others */
    1191             : 
    1192             :             /* Find track with one pulse more. */
    1193       21950 :             maxp = p[0];
    1194       21950 :             maxppos = 0;
    1195       55061 :             for ( track = 1; track < 4; track++ )
    1196             :             {
    1197       49588 :                 if ( p[track] > maxp )
    1198             :                 {
    1199       16477 :                     maxppos = track;
    1200       16477 :                     break;
    1201             :                 }
    1202             :             }
    1203             :             /* Multiply by number of possible states (=shift by two) and
    1204             :              * add actual state. */
    1205       21950 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1206       21950 :             longadd( idxs, &maxppos, wordcnt, 1 );
    1207       21950 :             break;
    1208      412917 :         case TRACKPOS_FIXED_EVEN:
    1209             :         case TRACKPOS_FIXED_FIRST:
    1210      412917 :             break;
    1211           0 :         default:
    1212           0 :             printf( "Codebook mode not implemented." );
    1213           0 :             assert( 0 ); /* mode not yet implemented*/
    1214             :             break;
    1215             :     }
    1216             : 
    1217             :     /* cast to output buffer */
    1218     2428567 :     for ( k = 0; k < wordcnt; k++ )
    1219             :     {
    1220     1851385 :         prm[k] = idxs[k];
    1221             :     }
    1222             : 
    1223      577182 :     return ( saved_bits );
    1224             : }
    1225             : 
    1226             : 
    1227             : /*--------------------------------------------------------------------------*
    1228             :  * E_ACELP_innovative_codebook
    1229             :  *
    1230             :  * Find innovative codebook.
    1231             :  *--------------------------------------------------------------------------*/
    1232             : 
    1233        3020 : void E_ACELP_innovative_codebook(
    1234             :     const float *exc,           /* i  : pointer to the excitation frame                  */
    1235             :     const int16_t T0,           /* i  : integer pitch lag                                */
    1236             :     const int16_t T0_frac,      /* i  : fraction of lag                                  */
    1237             :     const int16_t T0_res,       /* i  : pitch resolution                                 */
    1238             :     const float pitch_gain,     /* i  : adaptive codebook gain                           */
    1239             :     const float tilt_code,      /* i  : tilt factor                                      */
    1240             :     ACELP_config *acelp_cfg,    /* i/o: configuration of the ACELP                       */
    1241             :     const int16_t i_subfr,      /* i  : subframe index                                   */
    1242             :     const float *Aq,            /* i  : quantized LPC coefficients                       */
    1243             :     const float *h1,            /* i  : impulse response of weighted synthesis filter    */
    1244             :     const float *xn,            /* i  : Close-loop Pitch search target vector            */
    1245             :     const float *cn,            /* i  : Innovative codebook search target vector         */
    1246             :     const float *y1,            /* i  : zero-memory filtered adaptive excitation         */
    1247             :     float *y2,                  /* o  : zero-memory filtered algebraic excitation        */
    1248             :     const int16_t acelpautoc,   /* i  : autocorrelation mode enabled                     */
    1249             :     int16_t **pt_indice,        /* i/o: quantization indices pointer                     */
    1250             :     float *code,                /* o  : innovative codebook                              */
    1251             :     const int16_t L_frame,      /* i  : length of the frame                              */
    1252             :     const int16_t last_L_frame, /* i  : length of the last frame                         */
    1253             :     const int32_t total_brate   /* i  : total bitrate                                    */
    1254             : )
    1255             : {
    1256             :     float xn2[L_SUBFR], cn2[L_SUBFR], dn[L_SUBFR], h2[L_SUBFR];
    1257             :     float Rw2[L_SUBFR];
    1258             :     int16_t i, k;
    1259             :     float pitch;
    1260             : 
    1261        3020 :     pitch = (float) T0 + (float) T0_frac / (float) T0_res;
    1262             : 
    1263             :     /* Update target vector for ACELP codebook search */
    1264        3020 :     updt_tar( xn, xn2, y1, pitch_gain, L_SUBFR );
    1265             : 
    1266             :     /* Include fixed-gain pitch contribution into impulse resp. h1[] */
    1267        3020 :     mvr2r( h1, h2, L_SUBFR );
    1268        3020 :     cb_shape( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt, acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, h2, tilt_code, pitch, L_SUBFR );
    1269             : 
    1270             :     /* Correlation between target xn2[] and impulse response h1[] */
    1271        3020 :     if ( acelpautoc & 0x01 )
    1272             :     {
    1273        3020 :         corr_xh( h2, Rw2, h2, L_SUBFR );
    1274      196300 :         for ( k = 0; k < L_SUBFR; k++ )
    1275             :         {
    1276      193280 :             cn2[k] = xn2[k];
    1277     6281600 :             for ( i = 0; i < k; i++ )
    1278             :             {
    1279     6088320 :                 cn2[k] -= cn2[i] * h2[k - i];
    1280             :             }
    1281             :         }
    1282             : 
    1283        3020 :         E_ACELP_toeplitz_mul( Rw2, cn2, dn );
    1284             :     }
    1285             :     else
    1286             :     {
    1287           0 :         updt_tar( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR );
    1288           0 :         corr_xh( xn2, dn, h2, L_SUBFR );
    1289             :     }
    1290             : 
    1291             :     /* Innovative codebook search */
    1292        3020 :     if ( acelp_cfg->fixed_cdk_index[i_subfr / L_SUBFR] < ACELP_FIXED_CDK_NB )
    1293             :     {
    1294        3020 :         E_ACELP_4t( dn, cn2, h2, Rw2, acelpautoc, code, acelp_cfg->fixed_cdk_index[i_subfr / L_SUBFR], *pt_indice, L_frame, last_L_frame, total_brate, i_subfr, 0 );
    1295             :     }
    1296             :     else
    1297             :     {
    1298           0 :         assert( 0 );
    1299             :     }
    1300        3020 :     *pt_indice += 8;
    1301             :     /* Generate weighted code */
    1302        3020 :     set_f( y2, 0.0f, L_SUBFR );
    1303      196300 :     for ( i = 0; i < L_SUBFR; i++ )
    1304             :     {
    1305             :         /* Code is sparse, so check which samples are non-zero */
    1306      193280 :         if ( code[i] != 0 )
    1307             :         {
    1308     1515162 :             for ( k = 0; k < L_SUBFR - i; k++ )
    1309             :             {
    1310     1469570 :                 y2[i + k] += code[i] * h2[k];
    1311             :             }
    1312             :         }
    1313             :     }
    1314             : 
    1315             :     /*-------------------------------------------------------*
    1316             :      * - Add the fixed-gain pitch contribution to code[].    *
    1317             :      *-------------------------------------------------------*/
    1318             : 
    1319        3020 :     cb_shape( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt, acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, code, tilt_code, pitch, L_SUBFR );
    1320             : 
    1321        3020 :     return;
    1322             : }
    1323             : 
    1324             : 
    1325             : /*--------------------------------------------------------------------------*
    1326             :  * E_ACELP_codearithp
    1327             :  *
    1328             :  * Fixed bit-length arithmetic coding of pulses
    1329             :  * v - (input) pulse vector
    1330             :  * s - (output) encoded state
    1331             :  * n - (output) range of possible states (0...n-1)
    1332             :  * p - (output) number of pulses found
    1333             :  * len - (input) length of pulse vector
    1334             :  * trackstep - (input) step between tracks
    1335             :  *--------------------------------------------------------------------------*/
    1336             : 
    1337     2174136 : static void E_ACELP_codearithp(
    1338             :     const float v[],
    1339             :     uint32_t *n,
    1340             :     uint32_t *ps,
    1341             :     int16_t *p,
    1342             :     const int16_t trackstep,
    1343             :     const int16_t tracklen )
    1344             : {
    1345             :     int16_t k, h, t, pos[9], sig[9], posno, tmp, L_subfr;
    1346             :     uint32_t s;
    1347             : 
    1348     2174136 :     posno = 0;
    1349     2174136 :     L_subfr = trackstep * tracklen;
    1350             : 
    1351    36960312 :     for ( k = t = 0; k < L_subfr; k += trackstep, t++ )
    1352             :     {
    1353    34786176 :         tmp = ( v[k] > 0 ? 1 : -1 ); /* sign */
    1354    40419847 :         for ( h = 0; h < v[k] * tmp; h++ )
    1355             :         {
    1356     5633671 :             pos[posno] = t;
    1357     5633671 :             sig[posno] = tmp;
    1358     5633671 :             posno++;
    1359     5633671 :             if ( posno > 9 )
    1360             :             {
    1361           0 :                 break;
    1362             :             }
    1363             :         }
    1364    34786176 :         if ( posno >= 9 )
    1365             :         {
    1366           0 :             break;
    1367             :         }
    1368             :     }
    1369     2174136 :     *p = posno;
    1370             : 
    1371     2174136 :     s = 0;
    1372     7807807 :     for ( k = 0; k < posno; k++ )
    1373             :     {
    1374             :         /* check if next position is the same as this one */
    1375     5633671 :         if ( ( k == posno - 1 ) || ( pos[k] != pos[k + 1] ) )
    1376             :         {
    1377             :             /* next position is not the same (or we are at the last position)
    1378             :              * -> save sign */
    1379     5311096 :             s <<= 1;
    1380     5311096 :             if ( sig[k] < 0 )
    1381             :             {
    1382     2661391 :                 s++;
    1383             :             }
    1384             :         }
    1385     5633671 :         s += pulsestostates[pos[k]][k];
    1386             :     }
    1387     2174136 :     *ps = s;
    1388     2174136 :     if ( posno )
    1389             :     {
    1390     2151230 :         *n = pulsestostates[tracklen][posno - 1];
    1391             :     }
    1392             :     else
    1393             :     {
    1394       22906 :         *n = 0;
    1395             :     }
    1396             : 
    1397     2174136 :     return;
    1398             : }
    1399             : 
    1400             : 
    1401      543534 : void fcb_pulse_track_joint(
    1402             :     uint16_t *idxs,
    1403             :     const int16_t wordcnt,
    1404             :     uint32_t *index_n,
    1405             :     const int16_t *pulse_num,
    1406             :     const int16_t track_num )
    1407             : {
    1408      543534 :     int16_t hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
    1409             : 
    1410             :     uint32_t index, indx_tmp;
    1411             :     uint32_t index_mask;
    1412             :     int16_t indx_flag, indx_flag_1;
    1413             :     int16_t track, track_num1, pulse_num0, pulse_num1;
    1414             :     int16_t indx_flag_2;
    1415             : 
    1416      543534 :     indx_flag = 0;
    1417      543534 :     indx_flag_1 = 0;
    1418      543534 :     indx_flag_2 = 0;
    1419     2717670 :     for ( track = 0; track < track_num; track++ )
    1420             :     {
    1421     2174136 :         indx_flag += ( pulse_num[track] >> 2 );
    1422     2174136 :         indx_flag_1 += ( pulse_num[track] >> 1 );
    1423     2174136 :         indx_flag_2 += ( pulse_num[track] >> 3 );
    1424             :     }
    1425             : 
    1426      543534 :     if ( indx_flag_2 >= 1 )
    1427             :     {
    1428          31 :         hi_to_low[7] = 9;
    1429          31 :         index_mask = 0xffffff;
    1430             :     }
    1431             :     else
    1432             :     {
    1433      543503 :         hi_to_low[7] = 1;
    1434      543503 :         if ( indx_flag >= track_num )
    1435             :         {
    1436       83435 :             hi_to_low[4] = 9;
    1437       83435 :             index_mask = 0xffff;
    1438             :         }
    1439             :         else
    1440             :         {
    1441      460068 :             hi_to_low[4] = 1;
    1442      460068 :             index_mask = 0xff;
    1443             :         }
    1444             :     }
    1445             : 
    1446      543534 :     if ( indx_flag_1 >= track_num )
    1447             :     {
    1448      345689 :         indx_tmp = 0;
    1449      345689 :         index = index_n[0] >> low_len[pulse_num[0]];
    1450     1382756 :         for ( track = 1; track < track_num; track++ )
    1451             :         {
    1452     1037067 :             pulse_num0 = pulse_num[track - 1];
    1453     1037067 :             pulse_num1 = pulse_num[track];
    1454     1037067 :             indx_tmp = index_n[track] >> low_len[pulse_num1];
    1455     1037067 :             index = index * indx_fact[pulse_num1] + indx_tmp;
    1456             : 
    1457     1037067 :             index_n[track - 1] = ( index_n[track - 1] & low_mask[pulse_num0] ) + ( ( index << low_len[pulse_num0] ) & index_mask );
    1458     1037067 :             index = index >> hi_to_low[pulse_num0];
    1459             :         }
    1460      345689 :         track_num1 = track_num - 1;
    1461      345689 :         pulse_num1 = pulse_num[track_num1];
    1462      345689 :         index_n[track_num1] = ( ( index_n[track_num1] & low_mask[pulse_num1] ) + ( index << low_len[pulse_num1] ) ) & index_mask;
    1463      345689 :         index = index >> hi_to_low[pulse_num1];
    1464      345689 :         if ( indx_flag >= track_num )
    1465             :         {
    1466       83466 :             if ( indx_flag_2 >= 1 )
    1467             :             {
    1468          31 :                 idxs[0] = index_n[0] & 0xffff;
    1469          31 :                 idxs[1] = ( ( index_n[1] << 8 ) + ( index_n[0] >> 16 ) ) & 0xffff;
    1470          31 :                 idxs[2] = ( index_n[1] >> 8 ) & 0xffff;
    1471          31 :                 idxs[3] = index_n[2] & 0xffff;
    1472          31 :                 idxs[4] = ( ( index_n[3] << 8 ) + ( index_n[2] >> 16 ) ) & 0xffff;
    1473          31 :                 idxs[5] = ( index_n[3] >> 8 ) & 0xffff;
    1474          31 :                 for ( track = 6; track < wordcnt; track++ )
    1475             :                 {
    1476           0 :                     idxs[track] = index & 0xffff;
    1477           0 :                     index = index >> 16;
    1478             :                 }
    1479             :             }
    1480             :             else
    1481             :             {
    1482      417175 :                 for ( track = 0; track < track_num; track++ )
    1483             :                 {
    1484      333740 :                     idxs[track] = index_n[track] & 0xffff;
    1485             :                 }
    1486      174332 :                 for ( track = track_num; track < wordcnt; track++ )
    1487             :                 {
    1488       90897 :                     idxs[track] = index & 0xffff;
    1489       90897 :                     index = index >> 16;
    1490             :                 }
    1491             :             }
    1492             :         }
    1493             :         else
    1494             :         {
    1495      262223 :             idxs[0] = ( ( index_n[0] << 8 ) + index_n[1] ) & 0xffff;
    1496      262223 :             idxs[1] = ( ( index_n[2] << 8 ) + index_n[3] ) & 0xffff;
    1497      644308 :             for ( track = 2; track < wordcnt; track++ )
    1498             :             {
    1499      382085 :                 idxs[track] = index & 0xffff;
    1500      382085 :                 index = index >> 16;
    1501             :             }
    1502             :         }
    1503             :     }
    1504             :     else
    1505             :     {
    1506      197845 :         index = index_n[0];
    1507      791380 :         for ( track = 1; track < 4; track++ )
    1508             :         {
    1509      593535 :             pulse_num1 = pulse_num[track];
    1510      593535 :             index = ( index << index_len[pulse_num1] ) + index_n[track];
    1511             :         }
    1512      616932 :         for ( track = 0; track < wordcnt; track++ )
    1513             :         {
    1514      419087 :             idxs[track] = index & 0xffff;
    1515      419087 :             index = index >> 16;
    1516             :         }
    1517             :     }
    1518             : 
    1519      543534 :     return;
    1520             : }

Generated by: LCOV version 1.14