LCOV - code coverage report
Current view: top level - lib_enc - enc_acelp.c (source / functions) Hit Total Coverage
Test: Coverage on main -- conformance test test_26252.py @ 0c5691e6405a865cd50088c4936e8acb16f658a1 Lines: 620 636 97.5 %
Date: 2025-12-18 05:24:35 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     1366801 : 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     1366801 :     dn2 = &dn2_pos[track * 8];
      97     1366801 :     p0 = rrixix[track];
      98    10303443 :     for ( i = 0; i < nb_pulse; i++ )
      99             :     {
     100     8936642 :         dn = dn2[i];
     101     8936642 :         s = 0.0F;
     102             :         /* L_SUBFR-dn */
     103             :         /* vec[dn] */
     104   320794652 :         for ( j = 0; j < ( L_SUBFR - dn ); j++ )
     105             :         {
     106   311858010 :             s += h[j] * vec[dn + j];
     107             :         }
     108             : 
     109     8936642 :         cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];
     110             :     }
     111             : 
     112     1366801 :     return;
     113             : }
     114             : 
     115             : 
     116     1953771 : 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     1953771 :     p0 = rrixix[track];
     129             :     /* sign[track] */
     130    33214107 :     for ( i = 0; i < 16; i++ )
     131             :     {
     132    31260336 :         s = 0.0F;
     133             :         /* h[0], vec[track] */
     134             :         /* L_SUBFR-track */
     135  1049698448 :         for ( j = 0; j < L_SUBFR - track; j++ )
     136             :         {
     137  1018438112 :             s += h[j] * vec[track + j];
     138             :         }
     139             : 
     140    31260336 :         cor[i] = s * sign[track] + p0[i];
     141    31260336 :         track += 4;
     142             :     }
     143     1953771 :     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     1366801 : 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     1366801 :     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     1366801 :     pos_x = &dn2[track_x << 3];
     194             :     /* save these to limit memory searches */
     195     1366801 :     ps0 = *ps;
     196     1366801 :     alp0 = *alp;
     197             : 
     198     1366801 :     alpk = 1.0F;
     199     1366801 :     sqk = -1.0F;
     200     1366801 :     x2 = pos_x[0] >> 2;
     201     1366801 :     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    10303443 :     for ( i = 0; i < nb_pos_ix; i++ )
     208             :     {
     209     8936642 :         x = pos_x[i];
     210     8936642 :         x2 = x >> 2;
     211             :         /* dn[x] has only nb_pos_ix positions saved */
     212     8936642 :         ps1 = ps0 + dn[x];
     213     8936642 :         alp1 = alp0 + cor_x[x2];
     214     8936642 :         p1 = cor_y;
     215     8936642 :         p2 = &rrixiy[track_x][x2 << 4];
     216   151922914 :         for ( y = track_y; y < L_SUBFR; y += 4 )
     217             :         {
     218   142986272 :             ps2 = ps1 + dn[y];
     219   142986272 :             alp2 = alp1 + ( *p1++ ) + ( *p2++ );
     220             : 
     221   142986272 :             sq = ps2 * ps2;
     222             : 
     223   142986272 :             s = ( alpk * sq ) - ( sqk * alp2 );
     224             : 
     225   142986272 :             if ( s > 0.0F )
     226             :             {
     227     6672388 :                 sqk = sq;
     228     6672388 :                 alpk = alp2;
     229     6672388 :                 y_save = y;
     230     6672388 :                 x_save = x;
     231             :             }
     232             :         }
     233             :     }
     234             : 
     235     1366801 :     *ps = ps0 + dn[x_save] + dn[y_save];
     236     1366801 :     *alp = alpk;
     237     1366801 :     *ix = x_save;
     238     1366801 :     *iy = y_save;
     239             : 
     240     1366801 :     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      293485 : 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      293485 :     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      293485 :     ps0 = *ps;
     281      293485 :     alp0 = *alp;
     282      293485 :     alpk = 1.0F;
     283      293485 :     sqk = -1.0F;
     284             : 
     285      293485 :     if ( ( alp0 + cor_x[( track_x >> 2 )] ) < 0 )
     286             :     {
     287           0 :         sqk = 1.0F;
     288             :     }
     289     4989245 :     for ( x = track_x; x < L_SUBFR; x += 4 )
     290             :     {
     291     4695760 :         ps1 = ps0 + dn[x];
     292     4695760 :         alp1 = alp0 + cor_x[x >> 2];
     293     4695760 :         sq = ps1 * ps1;
     294     4695760 :         s = ( alpk * sq ) - ( sqk * alp1 );
     295             : 
     296     4695760 :         if ( s > 0.0F )
     297             :         {
     298     1133773 :             sqk = sq;
     299     1133773 :             alpk = alp1;
     300     1133773 :             x_save = x;
     301             :         }
     302             :     }
     303      293485 :     if ( track_y != track_x )
     304             :     {
     305     2867985 :         for ( x = track_y; x < L_SUBFR; x += 4 )
     306             :         {
     307     2699280 :             ps1 = ps0 + dn[x];
     308     2699280 :             alp1 = alp0 + cor_y[x >> 2];
     309     2699280 :             sq = ps1 * ps1;
     310     2699280 :             s = ( alpk * sq ) - ( sqk * alp1 );
     311             : 
     312     2699280 :             if ( s > 0.0F )
     313             :             {
     314      100299 :                 sqk = sq;
     315      100299 :                 alpk = alp1;
     316      100299 :                 x_save = x;
     317             :             }
     318             :         }
     319             :     }
     320             : 
     321      293485 :     *ps = ps0 + dn[x_save];
     322      293485 :     *alp = alpk;
     323      293485 :     *ix = x_save;
     324             : 
     325      293485 :     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      482464 : 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      482464 :     val = ( cn[0] * cn[0] ) + 1.0F;
     360      482464 :     cor = ( dn[0] * dn[0] ) + 1.0F;
     361    30877696 :     for ( i = 1; i < L_SUBFR; i++ )
     362             :     {
     363    30395232 :         val += ( cn[i] * cn[i] );
     364    30395232 :         cor += ( dn[i] * dn[i] );
     365             :     }
     366             : 
     367      482464 :     s = (float) sqrt( cor / val );
     368    31360160 :     for ( i = 0; i < L_SUBFR; i++ )
     369             :     {
     370    30877696 :         cor = ( s * cn[i] ) + ( alp * dn[i] );
     371    30877696 :         if ( cor >= 0.0F )
     372             :         {
     373    15537921 :             sign[i] = 1.0F;
     374    15537921 :             vec[i] = -1.0F;
     375    15537921 :             dn2[i] = cor; /* dn2[] = mix of dn[] and cn[]   */
     376             :         }
     377             :         else
     378             :         {
     379    15339775 :             sign[i] = -1.0F;
     380    15339775 :             vec[i] = 1.0F;
     381    15339775 :             dn[i] = -dn[i]; /* modify dn[] according to the fixed sign */
     382    15339775 :             dn2[i] = -cor;  /* dn2[] = mix of dn[] and cn[]            */
     383             :         }
     384             :     }
     385             : 
     386      482464 :     return;
     387             : }
     388             : 
     389             : 
     390      482464 : 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     2412320 :     for ( i = 0; i < tracks; i++ )
     402             :     {
     403    17368704 :         for ( k = 0; k < NB_MAX; k++ )
     404             :         {
     405    15438848 :             ps_ptr = &dn2[i];
     406   247021568 :             for ( j = i + tracks; j < L_subfr; j += tracks )
     407             :             {
     408   231582720 :                 if ( dn2[j] > *ps_ptr )
     409             :                 {
     410    37691415 :                     ps_ptr = &dn2[j];
     411             :                 }
     412             :             }
     413    15438848 :             *ps_ptr = (float) k - NB_MAX; /* dn2 < 0 when position is selected */
     414    15438848 :             dn2_pos[i * 8 + k] = (int16_t) ( ps_ptr - dn2 );
     415             :         }
     416     1929856 :         pos_max[i] = dn2_pos[i * 8];
     417             :     }
     418             : 
     419      482464 :     return;
     420             : }
     421             : 
     422             : 
     423      141147 : 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      141147 :     *h = h_buf + L_SUBFR;
     432      141147 :     *h_inv = h_buf + ( 3 * L_SUBFR );
     433     9174555 :     for ( i = 0; i < L_SUBFR; i++ )
     434             :     {
     435     9033408 :         ( *h )[-1 - i] = 0.0f;
     436     9033408 :         ( *h_inv )[-1 - i] = 0.0f;
     437     9033408 :         ( *h )[i] = H[i];
     438     9033408 :         ( *h_inv )[i] = -H[i];
     439             :     }
     440             : 
     441      141147 :     return;
     442             : }
     443             : 
     444             : 
     445      141147 : 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      141147 :     p0 = &rrixix[0][16 - 1];
     462      141147 :     p1 = &rrixix[1][16 - 1];
     463      141147 :     p2 = &rrixix[2][16 - 1];
     464      141147 :     p3 = &rrixix[3][16 - 1];
     465             : 
     466      141147 :     ptr_h1 = h;
     467      141147 :     cor = 0.0F;
     468     2399499 :     for ( i = 0; i < 16; i++ )
     469             :     {
     470     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     471     2258352 :         ptr_h1++;
     472     2258352 :         *p3-- = cor * 0.5F;
     473     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     474     2258352 :         ptr_h1++;
     475     2258352 :         *p2-- = cor * 0.5F;
     476     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     477     2258352 :         ptr_h1++;
     478     2258352 :         *p1-- = cor * 0.5F;
     479     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h1 );
     480     2258352 :         ptr_h1++;
     481     2258352 :         *p0-- = cor * 0.5F;
     482             :     }
     483             : 
     484             :     /* Compute rrixiy[][] needed for the codebook search. */
     485             :     /* storage order --> i2i3, i1i2, i0i1, i3i0 */
     486             : 
     487      141147 :     pos = 256 - 1;
     488      141147 :     ptr_hf = h + 1;
     489     2399499 :     for ( k = 0; k < 16; k++ )
     490             :     {
     491             : 
     492     2258352 :         p3 = &rrixiy[2][pos];
     493     2258352 :         p2 = &rrixiy[1][pos];
     494     2258352 :         p1 = &rrixiy[0][pos];
     495             : #ifdef FIX_2274_OOB_INDEXING_IN_CORRMATRIX
     496     2258352 :         p0 = &rrixiy[3][pos];
     497             :         /* decrement pointer instead of indexing the array to avoid CLANG Usan complaint */
     498             :         /* for last loop iteration, this points to rrixiy[3][-1], but is not actually accessed in later loop (k = 15 then, so inner loop will not run) */
     499     2258352 :         p0 -= 16;
     500             : #else
     501             :         p0 = &rrixiy[3][pos - 16];
     502             : #endif
     503             : 
     504     2258352 :         cor = 0.0F;
     505     2258352 :         ptr_h1 = h;
     506     2258352 :         ptr_h2 = ptr_hf;
     507    19195992 :         for ( i = k; i < 15; i++ )
     508             :         {
     509    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     510    16937640 :             ptr_h1++;
     511    16937640 :             ptr_h2++;
     512    16937640 :             *p3 = cor;
     513    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     514    16937640 :             ptr_h1++;
     515    16937640 :             ptr_h2++;
     516    16937640 :             *p2 = cor;
     517    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     518    16937640 :             ptr_h1++;
     519    16937640 :             ptr_h2++;
     520    16937640 :             *p1 = cor;
     521    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     522    16937640 :             ptr_h1++;
     523    16937640 :             ptr_h2++;
     524    16937640 :             *p0 = cor;
     525             : 
     526    16937640 :             p3 -= ( 16 + 1 );
     527    16937640 :             p2 -= ( 16 + 1 );
     528    16937640 :             p1 -= ( 16 + 1 );
     529    16937640 :             p0 -= ( 16 + 1 );
     530             :         }
     531             : 
     532     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     533     2258352 :         ptr_h1++;
     534     2258352 :         ptr_h2++;
     535     2258352 :         *p3 = cor;
     536     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     537     2258352 :         ptr_h1++;
     538     2258352 :         ptr_h2++;
     539     2258352 :         *p2 = cor;
     540     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     541     2258352 :         ptr_h1++;
     542     2258352 :         ptr_h2++;
     543     2258352 :         *p1 = cor;
     544             : 
     545     2258352 :         pos -= 16;
     546     2258352 :         ptr_hf += 4;
     547             :     }
     548             : 
     549             :     /* storage order --> i3i0, i2i3, i1i2, i0i1 */
     550             : 
     551      141147 :     pos = 256 - 1;
     552      141147 :     ptr_hf = h + 3;
     553     2399499 :     for ( k = 0; k < 16; k++ )
     554             :     {
     555             : 
     556     2258352 :         p3 = &rrixiy[3][pos];
     557     2258352 :         p2 = &rrixiy[2][pos - 1];
     558     2258352 :         p1 = &rrixiy[1][pos - 1];
     559     2258352 :         p0 = &rrixiy[0][pos - 1];
     560             : 
     561     2258352 :         cor = 0.0F;
     562     2258352 :         ptr_h1 = h;
     563     2258352 :         ptr_h2 = ptr_hf;
     564    19195992 :         for ( i = k + 1; i < 16; i++ )
     565             :         {
     566    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     567    16937640 :             ptr_h1++;
     568    16937640 :             ptr_h2++;
     569    16937640 :             *p3 = cor;
     570    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     571    16937640 :             ptr_h1++;
     572    16937640 :             ptr_h2++;
     573    16937640 :             *p2 = cor;
     574    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     575    16937640 :             ptr_h1++;
     576    16937640 :             ptr_h2++;
     577    16937640 :             *p1 = cor;
     578    16937640 :             cor += ( *ptr_h1 ) * ( *ptr_h2 );
     579    16937640 :             ptr_h1++;
     580    16937640 :             ptr_h2++;
     581    16937640 :             *p0 = cor;
     582             : 
     583    16937640 :             p3 -= ( 16 + 1 );
     584    16937640 :             p2 -= ( 16 + 1 );
     585    16937640 :             p1 -= ( 16 + 1 );
     586    16937640 :             p0 -= ( 16 + 1 );
     587             :         }
     588             : 
     589     2258352 :         cor += ( *ptr_h1 ) * ( *ptr_h2 );
     590     2258352 :         *p3 = cor;
     591             : 
     592     2258352 :         pos--;
     593     2258352 :         ptr_hf += 4;
     594             :     }
     595             : 
     596             :     /* Modification of rrixiy[][] to take signs into account. */
     597             : 
     598      141147 :     p0 = &rrixiy[0][0];
     599             :     /* speed-up: 11% */
     600      141147 :     p1 = &rrixiy[1][0];
     601      141147 :     p2 = &rrixiy[2][0];
     602      141147 :     p3 = &rrixiy[3][0];
     603     2399499 :     for ( i = 0; i < L_SUBFR; i += 4 )
     604             :     {
     605     2258352 :         if ( sign[i + 0] < 0.0F )
     606     1127842 :             psign0 = &vec[1];
     607             :         else
     608     1130510 :             psign0 = &sign[1];
     609     2258352 :         if ( sign[i + 1] < 0.0F )
     610     1127148 :             psign1 = &vec[2];
     611             :         else
     612     1131204 :             psign1 = &sign[2];
     613     2258352 :         if ( sign[i + 2] < 0.0F )
     614     1127174 :             psign2 = &vec[3];
     615             :         else
     616     1131178 :             psign2 = &sign[3];
     617     2258352 :         if ( sign[i + 3] < 0.0F )
     618     1128446 :             psign3 = &vec[0];
     619             :         else
     620     1129906 :             psign3 = &sign[0];
     621     2258352 :         p0[0] = p0[0] * psign0[0];
     622     2258352 :         p0[1] = p0[1] * psign0[4];
     623     2258352 :         p0[2] = p0[2] * psign0[8];
     624     2258352 :         p0[3] = p0[3] * psign0[12];
     625     2258352 :         p0[4] = p0[4] * psign0[16];
     626     2258352 :         p0[5] = p0[5] * psign0[20];
     627     2258352 :         p0[6] = p0[6] * psign0[24];
     628     2258352 :         p0[7] = p0[7] * psign0[28];
     629     2258352 :         p0[8] = p0[8] * psign0[32];
     630     2258352 :         p0[9] = p0[9] * psign0[36];
     631     2258352 :         p0[10] = p0[10] * psign0[40];
     632     2258352 :         p0[11] = p0[11] * psign0[44];
     633     2258352 :         p0[12] = p0[12] * psign0[48];
     634     2258352 :         p0[13] = p0[13] * psign0[52];
     635     2258352 :         p0[14] = p0[14] * psign0[56];
     636     2258352 :         p0[15] = p0[15] * psign0[60];
     637     2258352 :         p0 += 16;
     638             : 
     639     2258352 :         p1[0] = p1[0] * psign1[0];
     640     2258352 :         p1[1] = p1[1] * psign1[4];
     641     2258352 :         p1[2] = p1[2] * psign1[8];
     642     2258352 :         p1[3] = p1[3] * psign1[12];
     643     2258352 :         p1[4] = p1[4] * psign1[16];
     644     2258352 :         p1[5] = p1[5] * psign1[20];
     645     2258352 :         p1[6] = p1[6] * psign1[24];
     646     2258352 :         p1[7] = p1[7] * psign1[28];
     647     2258352 :         p1[8] = p1[8] * psign1[32];
     648     2258352 :         p1[9] = p1[9] * psign1[36];
     649     2258352 :         p1[10] = p1[10] * psign1[40];
     650     2258352 :         p1[11] = p1[11] * psign1[44];
     651     2258352 :         p1[12] = p1[12] * psign1[48];
     652     2258352 :         p1[13] = p1[13] * psign1[52];
     653     2258352 :         p1[14] = p1[14] * psign1[56];
     654     2258352 :         p1[15] = p1[15] * psign1[60];
     655     2258352 :         p1 += 16;
     656             : 
     657     2258352 :         p2[0] = p2[0] * psign2[0];
     658     2258352 :         p2[1] = p2[1] * psign2[4];
     659     2258352 :         p2[2] = p2[2] * psign2[8];
     660     2258352 :         p2[3] = p2[3] * psign2[12];
     661     2258352 :         p2[4] = p2[4] * psign2[16];
     662     2258352 :         p2[5] = p2[5] * psign2[20];
     663     2258352 :         p2[6] = p2[6] * psign2[24];
     664     2258352 :         p2[7] = p2[7] * psign2[28];
     665     2258352 :         p2[8] = p2[8] * psign2[32];
     666     2258352 :         p2[9] = p2[9] * psign2[36];
     667     2258352 :         p2[10] = p2[10] * psign2[40];
     668     2258352 :         p2[11] = p2[11] * psign2[44];
     669     2258352 :         p2[12] = p2[12] * psign2[48];
     670     2258352 :         p2[13] = p2[13] * psign2[52];
     671     2258352 :         p2[14] = p2[14] * psign2[56];
     672     2258352 :         p2[15] = p2[15] * psign2[60];
     673     2258352 :         p2 += 16;
     674             : 
     675     2258352 :         p3[0] = p3[0] * psign3[0];
     676     2258352 :         p3[1] = p3[1] * psign3[4];
     677     2258352 :         p3[2] = p3[2] * psign3[8];
     678     2258352 :         p3[3] = p3[3] * psign3[12];
     679     2258352 :         p3[4] = p3[4] * psign3[16];
     680     2258352 :         p3[5] = p3[5] * psign3[20];
     681     2258352 :         p3[6] = p3[6] * psign3[24];
     682     2258352 :         p3[7] = p3[7] * psign3[28];
     683     2258352 :         p3[8] = p3[8] * psign3[32];
     684     2258352 :         p3[9] = p3[9] * psign3[36];
     685     2258352 :         p3[10] = p3[10] * psign3[40];
     686     2258352 :         p3[11] = p3[11] * psign3[44];
     687     2258352 :         p3[12] = p3[12] * psign3[48];
     688     2258352 :         p3[13] = p3[13] * psign3[52];
     689     2258352 :         p3[14] = p3[14] * psign3[56];
     690     2258352 :         p3[15] = p3[15] * psign3[60];
     691     2258352 :         p3 += 16;
     692             :     }
     693             : 
     694      141147 :     return;
     695             : }
     696             : 
     697      141147 : void E_ACELP_4tsearch(
     698             :     float dn[],
     699             :     const float cn[],
     700             :     const float H[],
     701             :     float code[],
     702             :     PulseConfig *config,
     703             :     int16_t ind[],
     704             :     float y[] )
     705             : {
     706             :     float sign[L_SUBFR], vec[L_SUBFR];
     707             :     float cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
     708             :     float rrixix[4][16];
     709             :     float rrixiy[4][256];
     710             :     float dn2[L_SUBFR];
     711      141147 :     float psk, ps, alpk, alp = 0.0F;
     712             :     int16_t codvec[NB_PULSE_MAX];
     713             :     int16_t pos_max[4];
     714             :     int16_t dn2_pos[8 * 4];
     715             :     int16_t ipos[NB_PULSE_MAX];
     716             :     float *p0, *p1, *p2, *p3;
     717             :     float *h, *h_inv;
     718      141147 :     int16_t i, j, k, l, st, pos = 0, track;
     719             :     int16_t index, iPulse;
     720             :     float val;
     721             :     float s;
     722             :     int16_t restpulses;
     723             : 
     724      141147 :     alp = config->alp; /* initial value for energy of all fixed pulses */
     725             : 
     726      905872 :     for ( k = 0; k < config->nb_pulse; k++ )
     727             :     {
     728      764725 :         codvec[k] = 0;
     729             :     }
     730             : 
     731             :     /* Find sign for each pulse position. */
     732      141147 :     acelp_pulsesign( cn, dn, dn2, sign, vec, alp );
     733             : 
     734             :     /* Select the most important 8 position per track according to dn2[]. */
     735      141147 :     acelp_findcandidates( dn2, dn2_pos, pos_max, L_SUBFR, NB_TRACK_FCB_4T );
     736             : 
     737             :     /* Compute h_inv[i]. */
     738      141147 :     acelp_hbuf( h_buf, &h, &h_inv, H );
     739             : 
     740             :     /* Compute correlation matrices needed for the codebook search. */
     741      141147 :     E_ACELP_corrmatrix( h, sign, vec, rrixix, rrixiy );
     742             : 
     743             :     /*
     744             :      * Deep first search:
     745             :      * ------------------
     746             :      * 20 bits (4p):  4 iter x ((4x16)+(8x16))              = 768 tests
     747             :      * 36 bits (8p):  4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
     748             :      * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     749             :      *                                      +(8x16)+(8x16)) = 1248 tests
     750             :      * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     751             :      *                        +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
     752             :      */
     753      141147 :     psk = -1.0;
     754      141147 :     alpk = 1.0;
     755             :     /*Number of iterations*/
     756      728053 :     for ( k = 0; k < config->nbiter; k++ )
     757             :     {
     758             :         /* copy search order from hash-table */
     759     3685019 :         for ( l = 0; l < config->nb_pulse; l++ )
     760             :         {
     761     3098113 :             ipos[l] = tipos[( k * 4 ) + l];
     762             :         }
     763             : 
     764             :         /* if all tracks do not have equal number of pulses */
     765      586906 :         restpulses = config->nb_pulse & 3;
     766      586906 :         if ( restpulses )
     767             :         {
     768      440603 :             switch ( config->codetrackpos )
     769             :             {
     770      182533 :                 case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
     771             :                     /* add tracks from left */
     772      546581 :                     for ( iPulse = 0; iPulse < restpulses; iPulse++ )
     773             :                     {
     774      364048 :                         ipos[config->nb_pulse - restpulses + iPulse] = iPulse;
     775             :                     }
     776             :                     /* Put the same track on the next position, because the 1-pulse search
     777             :                      * will access it to determine if this could be in any track. */
     778      182533 :                     ipos[config->nb_pulse] = ipos[config->nb_pulse - 1];
     779      182533 :                     break;
     780           0 :                 case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */
     781             :                     /* odd tracks, switch order for every iteration */
     782           0 :                     ipos[config->nb_pulse - restpulses] = ( k << 1 ) & 2;                              /* 0 for even k, 2 for odd*/
     783           0 :                     ipos[config->nb_pulse - restpulses + 1] = ipos[config->nb_pulse - restpulses] ^ 2; /* 2 for even k, 0 for odd*/
     784           0 :                     break;
     785       89365 :                 case TRACKPOS_FIXED_TWO: /* two tracks instead of four */
     786             :                     /* Put the next track on the next position, because the 1-pulse search
     787             :                      * will access it to determine if this could be in any track. */
     788       89365 :                     ipos[config->nb_pulse] = ( ipos[config->nb_pulse - 1] + 1 ) & 3;
     789       89365 :                     break;
     790      168705 :                 default: /* one or three free track positions */
     791             :                     /* copy an extra position from table - 1pulse search will access this */
     792      168705 :                     ipos[config->nb_pulse] = tipos[( k * 4 ) + config->nb_pulse];
     793      168705 :                     break;
     794             :             }
     795      146303 :         }
     796      586906 :         if ( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
     797             :         {
     798      551394 :             pos = 0;
     799      551394 :             ps = 0.0F;
     800      551394 :             alp = 0.0F;
     801    35840610 :             for ( i = 0; i < L_SUBFR; i++ )
     802             :             {
     803    35289216 :                 vec[i] = 0;
     804             :             }
     805             :         }
     806       35512 :         else if ( config->fixedpulses == 2 ) /* 2222 and 3322 */
     807             :         {
     808             :             /* first stage: fix 2 pulses */
     809       35511 :             pos = 2;
     810             : 
     811       35511 :             ind[0] = pos_max[ipos[0]];
     812       35511 :             ind[1] = pos_max[ipos[1]];
     813       35511 :             ps = dn[ind[0]] + dn[ind[1]];
     814             : 
     815             :             /*ind[1]>>2 and ind[0]>>2 and save*/
     816             :             /* ipos[1] and ipos[0]    and save*/
     817       35511 :             alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
     818       35511 :                   rrixiy[ipos[0]][( ( ind[0] >> 2 ) << 4 ) + ( ind[1] >> 2 )];
     819             : 
     820       35511 :             if ( sign[ind[0]] < 0.0 )
     821             :             {
     822       16979 :                 p0 = h_inv - ind[0];
     823             :             }
     824             :             else
     825             :             {
     826       18532 :                 p0 = h - ind[0];
     827             :             }
     828       35511 :             if ( sign[ind[1]] < 0.0 )
     829             :             {
     830       16986 :                 p1 = h_inv - ind[1];
     831             :             }
     832             :             else
     833             :             {
     834       18525 :                 p1 = h - ind[1];
     835             :             }
     836             :             /*ptx = &vec   p1 and p0 already initialize*/
     837       35511 :             vec[0] = p0[0] + p1[0];
     838       35511 :             vec[1] = p0[1] + p1[1];
     839       35511 :             vec[2] = p0[2] + p1[2];
     840       35511 :             vec[3] = p0[3] + p1[3];
     841      390621 :             for ( i = 4; i < L_SUBFR; i += 6 )
     842             :             {
     843      355110 :                 vec[i] = p0[i] + p1[i];
     844      355110 :                 vec[i + 1] = p0[i + 1] + p1[i + 1];
     845      355110 :                 vec[i + 2] = p0[i + 2] + p1[i + 2];
     846      355110 :                 vec[i + 3] = p0[i + 3] + p1[i + 3];
     847      355110 :                 vec[i + 4] = p0[i + 4] + p1[i + 4];
     848      355110 :                 vec[i + 5] = p0[i + 5] + p1[i + 5];
     849             :             }
     850             :         }
     851             :         else /* 3333 and above */
     852             :         {
     853             :             /* first stage: fix 4 pulses */
     854           1 :             pos = 4;
     855             : 
     856           1 :             ind[0] = pos_max[ipos[0]];
     857           1 :             ind[1] = pos_max[ipos[1]];
     858           1 :             ind[2] = pos_max[ipos[2]];
     859           1 :             ind[3] = pos_max[ipos[3]];
     860           1 :             ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];
     861             : 
     862           1 :             p0 = h - ind[0];
     863           1 :             if ( sign[ind[0]] < 0.0 )
     864             :             {
     865           1 :                 p0 = h_inv - ind[0];
     866             :             }
     867             : 
     868           1 :             p1 = h - ind[1];
     869           1 :             if ( sign[ind[1]] < 0.0 )
     870             :             {
     871           1 :                 p1 = h_inv - ind[1];
     872             :             }
     873             : 
     874           1 :             p2 = h - ind[2];
     875           1 :             if ( sign[ind[2]] < 0.0 )
     876             :             {
     877           1 :                 p2 = h_inv - ind[2];
     878             :             }
     879             : 
     880           1 :             p3 = h - ind[3];
     881           1 :             if ( sign[ind[3]] < 0.0 )
     882             :             {
     883           1 :                 p3 = h_inv - ind[3];
     884             :             }
     885             :             /* pt =&vec; others already defined*/
     886           1 :             vec[0] = p0[0] + p1[0] + p2[0] + p3[0];
     887          22 :             for ( i = 1; i < L_SUBFR; i += 3 )
     888             :             {
     889          21 :                 vec[i] = p0[i] + p1[i] + p2[i] + p3[i];
     890          21 :                 vec[i + 1] = p0[i + 1] + p1[i + 1] + p2[i + 1] + p3[i + 1];
     891          21 :                 vec[i + 2] = p0[i + 2] + p1[i + 2] + p2[i + 2] + p3[i + 2];
     892             :             }
     893             : 
     894           1 :             alp = 0.0F;
     895           1 :             alp += vec[0] * vec[0] + vec[1] * vec[1];
     896           1 :             alp += vec[2] * vec[2] + vec[3] * vec[3];
     897             : 
     898          11 :             for ( i = 4; i < L_SUBFR; i += 6 )
     899             :             {
     900          10 :                 alp += vec[i] * vec[i];
     901          10 :                 alp += vec[i + 1] * vec[i + 1];
     902          10 :                 alp += vec[i + 2] * vec[i + 2];
     903          10 :                 alp += vec[i + 3] * vec[i + 3];
     904          10 :                 alp += vec[i + 4] * vec[i + 4];
     905          10 :                 alp += vec[i + 5] * vec[i + 5];
     906             :             }
     907             : 
     908           1 :             alp *= 0.5F;
     909             :         }
     910             : 
     911             :         /* other stages of 2 pulses */
     912     2247192 :         for ( j = pos, st = 0; j < config->nb_pulse; j += 2, st++ )
     913             :         {
     914     1660286 :             if ( ( config->nb_pulse - j ) >= 2 ) /*pair-wise search*/
     915             :             {
     916             :                 /* Calculate correlation of all possible positions
     917             :                  * of the next 2 pulses with previous fixed pulses.
     918             :                  * Each pulse can have 16 possible positions. */
     919     1366801 :                 acelp_h_vec_corr1( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] );
     920     1366801 :                 acelp_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y );
     921             : 
     922             :                 /* Find best positions of 2 pulses. */
     923     1366801 :                 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 );
     924             :             }
     925             :             else /*single pulse search*/
     926             :             {
     927      293485 :                 acelp_h_vec_corr2( h, vec, ipos[j], sign, rrixix, cor_x );
     928      293485 :                 acelp_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y );
     929      293485 :                 E_ACELP_1pulse_search( ipos[j], ipos[j + 1], &ps, &alp, &ind[j], dn, cor_x, cor_y );
     930             :             }
     931     1660286 :             if ( j < ( config->nb_pulse - 2 ) )
     932             :             {
     933     1073380 :                 p0 = h - ind[j];
     934     1073380 :                 if ( sign[ind[j]] < 0.0 )
     935             :                 {
     936      534076 :                     p0 = h_inv - ind[j];
     937             :                 }
     938             : 
     939     1073380 :                 p1 = h - ind[j + 1];
     940     1073380 :                 if ( sign[ind[j + 1]] < 0.0 )
     941             :                 {
     942      535783 :                     p1 = h_inv - ind[j + 1];
     943             :                 }
     944             : 
     945     1073380 :                 vec[0] += p0[0] + p1[0];
     946     1073380 :                 vec[1] += p0[1] + p1[1];
     947     1073380 :                 vec[2] += p0[2] + p1[2];
     948     1073380 :                 vec[3] += p0[3] + p1[3];
     949    11807180 :                 for ( i = 4; i < L_SUBFR; i += 6 )
     950             :                 {
     951    10733800 :                     vec[i] += p0[i] + p1[i];
     952    10733800 :                     vec[i + 1] += p0[i + 1] + p1[i + 1];
     953    10733800 :                     vec[i + 2] += p0[i + 2] + p1[i + 2];
     954    10733800 :                     vec[i + 3] += p0[i + 3] + p1[i + 3];
     955    10733800 :                     vec[i + 4] += p0[i + 4] + p1[i + 4];
     956    10733800 :                     vec[i + 5] += p0[i + 5] + p1[i + 5];
     957             :                 }
     958             :             }
     959             :         }
     960             : 
     961             :         /* memorise the best codevector */
     962      586906 :         ps = ps * ps;
     963      586906 :         s = ( alpk * ps ) - ( psk * alp );
     964      586906 :         if ( psk < 0 )
     965             :         {
     966      141147 :             s = 1.0F;
     967             :         }
     968      586906 :         if ( s > 0.0F )
     969             :         {
     970      283102 :             psk = ps;
     971      283102 :             alpk = alp;
     972     1813298 :             for ( i = 0; i < config->nb_pulse; i++ )
     973             :             {
     974     1530196 :                 codvec[i] = ind[i];
     975             :             }
     976             :         }
     977             :     }
     978             : 
     979             :     /* Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations. */
     980      141147 :     set_f( code, 0, L_SUBFR );
     981      141147 :     set_f( y, 0, L_SUBFR );
     982      141147 :     set_s( ind, -1, NPMAXPT * 4 );
     983             : 
     984      905872 :     for ( k = 0; k < config->nb_pulse; k++ )
     985             :     {
     986      764725 :         i = codvec[k]; /* read pulse position  */
     987      764725 :         val = sign[i]; /* read sign            */
     988             : 
     989      764725 :         index = (int16_t) ( i / 4 ); /* pos of pulse (0..15) */
     990      764725 :         track = i % 4;
     991      764725 :         if ( val > 0 )
     992             :         {
     993      384230 :             code[i] += 1.0f;
     994      384230 :             codvec[k] += ( 2 * L_SUBFR );
     995             :         }
     996             :         else
     997             :         {
     998      380495 :             code[i] -= 1.0f;
     999      380495 :             index += 16;
    1000             :         }
    1001             : 
    1002      764725 :         i = track * NPMAXPT;
    1003      980903 :         while ( ind[i] >= 0 )
    1004             :         {
    1005      216178 :             i++;
    1006             :         }
    1007             : 
    1008      764725 :         ind[i] = index;
    1009             : 
    1010      764725 :         p0 = h_inv - codvec[k];
    1011    49707125 :         for ( i = 0; i < L_SUBFR; i++ )
    1012             :         {
    1013    48942400 :             y[i] += *p0++;
    1014             :         }
    1015             :     }
    1016             : 
    1017      141147 :     return;
    1018             : }
    1019             : 
    1020             : 
    1021             : /*
    1022             :  * E_ACELP_4t
    1023             :  *
    1024             :  * Parameters:
    1025             :  *    dn          I: corr. between target and h[].
    1026             :  *    cn          I: residual after int32_t term prediction
    1027             :  *    H           I: impulse response of weighted synthesis filter (Q12)
    1028             :  *    code        O: algebraic (fixed) codebook excitation (Q9)
    1029             :  *    y           O: filtered fixed codebook excitation (Q9)
    1030             :  *    nbbits      I: 20, 36, 44, 52, 64, 72 or 88 bits
    1031             :  *    mode        I: speech mode
    1032             :  *    _index      O: index
    1033             :  *
    1034             :  * Function:
    1035             :  *    20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
    1036             :  *    4 tracks x 16 positions per track = 64 samples.
    1037             :  *
    1038             :  *    20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
    1039             :  *    36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
    1040             :  *    44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
    1041             :  *    52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
    1042             :  *    64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
    1043             :  *                                  16 pulses in a frame of 64 samples.
    1044             :  *    72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
    1045             :  *                                  18 pulses in a frame of 64 samples.
    1046             :  *    88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
    1047             :  *                                  24 pulses in a frame of 64 samples.
    1048             :  *
    1049             :  *    All pulses can have two (2) possible amplitudes: +1 or -1.
    1050             :  *    Each pulse can sixteen (16) possible positions.
    1051             :  *
    1052             :  * Returns:
    1053             :  *    void
    1054             :  */
    1055             : 
    1056      401984 : void E_ACELP_4t(
    1057             :     float dn[],
    1058             :     float cn[],
    1059             :     float H[],
    1060             :     float R[],
    1061             :     const int16_t acelpautoc,
    1062             :     float code[],
    1063             :     const int16_t cdk_index,
    1064             :     int16_t _index[],
    1065             :     const int16_t L_frame,
    1066             :     const int16_t last_L_frame,
    1067             :     const int32_t total_brate,
    1068             :     const int16_t i_subfr,
    1069             :     const int16_t cmpl_flag )
    1070             : {
    1071             :     PulseConfig config;
    1072             :     int16_t ind[NPMAXPT * 4];
    1073             :     float y[L_SUBFR];
    1074             : 
    1075      401984 :     config = PulseConfTable[cdk_index];
    1076             : 
    1077      401984 :     if ( cmpl_flag > 0 )
    1078             :     {
    1079        5325 :         config.nbiter = cmpl_flag;
    1080             :     }
    1081             : 
    1082      401984 :     if ( L_frame != last_L_frame && total_brate == ACELP_24k40 && i_subfr < 5 * L_SUBFR )
    1083             :     {
    1084          10 :         ( config.nbiter )--;
    1085          10 :         config.nbiter = max( config.nbiter, 1 );
    1086             :     }
    1087             : 
    1088      401984 :     if ( acelpautoc & 0x01 )
    1089             :     {
    1090      266914 :         E_ACELP_4tsearchx( dn, cn, R, code, &config, ind );
    1091             :     }
    1092             :     else
    1093             :     {
    1094      135070 :         E_ACELP_4tsearch( dn, cn, H, code, &config, ind, y );
    1095             :     }
    1096             : 
    1097      401984 :     E_ACELP_indexing( code, config, NB_TRACK_FCB_4T, _index );
    1098             : 
    1099      401984 :     return;
    1100             : }
    1101             : 
    1102             : 
    1103      482464 : int16_t E_ACELP_indexing(
    1104             :     float code[],
    1105             :     PulseConfig config,
    1106             :     const int16_t num_tracks,
    1107             :     int16_t prm[] )
    1108             : {
    1109             :     uint16_t track;
    1110             :     int16_t p[NB_TRACK_FCB_4T], wordcnt;
    1111             :     int16_t k;
    1112             :     uint16_t idxs[MAX_IDX_LEN], maxppos;
    1113             :     uint32_t s[NB_TRACK_FCB_4T], n[NB_TRACK_FCB_4T];
    1114             :     int16_t maxp;
    1115             :     int16_t saved_bits;
    1116             : 
    1117      482464 :     assert( num_tracks == NB_TRACK_FCB_4T );
    1118             : 
    1119      482464 :     saved_bits = 0;
    1120             : 
    1121             :     /* Code state of pulses of all tracks */
    1122      482464 :     wordcnt = ( config.bits + 15 ) >> 4; /* ceil(bits/16) */
    1123     2044113 :     for ( k = 0; k < wordcnt; k++ )
    1124             :     {
    1125     1561649 :         idxs[k] = 0;
    1126             :     }
    1127      482464 :     if ( config.bits == 43 ) /* EVS pulse indexing */
    1128             :     {
    1129       23478 :         saved_bits = E_ACELP_code43bit( code, s, p, idxs );
    1130             :     }
    1131             :     else
    1132             :     {
    1133     2294930 :         for ( track = 0; track < num_tracks; track++ )
    1134             :         {
    1135             :             /* Code track of length 2^4 where step between tracks is 4. */
    1136     1835944 :             E_ACELP_codearithp( code + track, n + track, s + track, p + track, num_tracks, 16 );
    1137             :         }
    1138      458986 :         fcb_pulse_track_joint( idxs, wordcnt, s, p, num_tracks );
    1139             :     }
    1140             : 
    1141             :     /* check if we need to code track positions */
    1142      482464 :     switch ( config.codetrackpos )
    1143             :     {
    1144       48541 :         case TRACKPOS_FIXED_TWO:
    1145             :             /* Code position of consecutive tracks with single extra pulses */
    1146             : 
    1147             :             /* Find track with one pulse less. */
    1148       48541 :             if ( p[0] == p[1] )
    1149             :             {
    1150             :                 /* Either 1100 or 0011 */
    1151       24183 :                 if ( p[1] > p[2] )
    1152             :                 {
    1153       12136 :                     track = 0; /* 1100 */
    1154             :                 }
    1155             :                 else
    1156             :                 {
    1157       12047 :                     track = 2; /* 0011 */
    1158             :                 }
    1159             :             }
    1160             :             else
    1161             :             {
    1162             :                 /* Either 0110 or 1001 */
    1163       24358 :                 if ( p[0] < p[1] )
    1164             :                 {
    1165       12285 :                     track = 1; /* 0110 */
    1166             :                 }
    1167             :                 else
    1168             :                 {
    1169       12073 :                     track = 3; /* 1001 */
    1170             :                 }
    1171             :             }
    1172             :             /* Multiply by number of possible states (=shift by two) and
    1173             :              * add actual state. */
    1174       48541 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1175       48541 :             longadd( idxs, &track, wordcnt, 1 );
    1176       48541 :             break;
    1177       44614 :         case TRACKPOS_FREE_THREE:
    1178             :             /* Code position of track with one pulse less than others */
    1179             : 
    1180             :             /* Find track with one pulse less. */
    1181       44614 :             maxp = p[0];
    1182       44614 :             maxppos = 0;
    1183      111045 :             for ( track = 1; track < 4; track++ )
    1184             :             {
    1185      100130 :                 if ( p[track] < maxp )
    1186             :                 {
    1187       33699 :                     maxppos = track;
    1188       33699 :                     break;
    1189             :                 }
    1190             :             }
    1191             :             /* Multiply by number of possible states (=shift by two) and
    1192             :              * add actual state. */
    1193       44614 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1194       44614 :             longadd( idxs, &maxppos, wordcnt, 1 );
    1195       44614 :             break;
    1196       19860 :         case TRACKPOS_FREE_ONE:
    1197             :             /* Code position of track with one pulse more than others */
    1198             : 
    1199             :             /* Find track with one pulse more. */
    1200       19860 :             maxp = p[0];
    1201       19860 :             maxppos = 0;
    1202       49761 :             for ( track = 1; track < 4; track++ )
    1203             :             {
    1204       44751 :                 if ( p[track] > maxp )
    1205             :                 {
    1206       14850 :                     maxppos = track;
    1207       14850 :                     break;
    1208             :                 }
    1209             :             }
    1210             :             /* Multiply by number of possible states (=shift by two) and
    1211             :              * add actual state. */
    1212       19860 :             longshiftleft( idxs, 2, idxs, wordcnt );
    1213       19860 :             longadd( idxs, &maxppos, wordcnt, 1 );
    1214       19860 :             break;
    1215      369449 :         case TRACKPOS_FIXED_EVEN:
    1216             :         case TRACKPOS_FIXED_FIRST:
    1217      369449 :             break;
    1218           0 :         default:
    1219           0 :             printf( "Codebook mode not implemented." );
    1220           0 :             assert( 0 ); /* mode not yet implemented*/
    1221             :             break;
    1222             :     }
    1223             : 
    1224             :     /* cast to output buffer */
    1225     2044113 :     for ( k = 0; k < wordcnt; k++ )
    1226             :     {
    1227     1561649 :         prm[k] = idxs[k];
    1228             :     }
    1229             : 
    1230      482464 :     return ( saved_bits );
    1231             : }
    1232             : 
    1233             : 
    1234             : /*--------------------------------------------------------------------------*
    1235             :  * E_ACELP_innovative_codebook
    1236             :  *
    1237             :  * Find innovative codebook.
    1238             :  *--------------------------------------------------------------------------*/
    1239             : 
    1240        6040 : void E_ACELP_innovative_codebook(
    1241             :     const float *exc,           /* i  : pointer to the excitation frame                  */
    1242             :     const int16_t T0,           /* i  : integer pitch lag                                */
    1243             :     const int16_t T0_frac,      /* i  : fraction of lag                                  */
    1244             :     const int16_t T0_res,       /* i  : pitch resolution                                 */
    1245             :     const float pitch_gain,     /* i  : adaptive codebook gain                           */
    1246             :     const float tilt_code,      /* i  : tilt factor                                      */
    1247             :     ACELP_config *acelp_cfg,    /* i/o: configuration of the ACELP                       */
    1248             :     const int16_t i_subfr,      /* i  : subframe index                                   */
    1249             :     const float *Aq,            /* i  : quantized LPC coefficients                       */
    1250             :     const float *h1,            /* i  : impulse response of weighted synthesis filter    */
    1251             :     const float *xn,            /* i  : Close-loop Pitch search target vector            */
    1252             :     const float *cn,            /* i  : Innovative codebook search target vector         */
    1253             :     const float *y1,            /* i  : zero-memory filtered adaptive excitation         */
    1254             :     float *y2,                  /* o  : zero-memory filtered algebraic excitation        */
    1255             :     const int16_t acelpautoc,   /* i  : autocorrelation mode enabled                     */
    1256             :     int16_t **pt_indice,        /* i/o: quantization indices pointer                     */
    1257             :     float *code,                /* o  : innovative codebook                              */
    1258             :     const int16_t L_frame,      /* i  : length of the frame                              */
    1259             :     const int16_t last_L_frame, /* i  : length of the last frame                         */
    1260             :     const int32_t total_brate   /* i  : total bitrate                                    */
    1261             : )
    1262             : {
    1263             :     float xn2[L_SUBFR], cn2[L_SUBFR], dn[L_SUBFR], h2[L_SUBFR];
    1264             :     float Rw2[L_SUBFR];
    1265             :     int16_t i, k;
    1266             :     float pitch;
    1267             : 
    1268        6040 :     pitch = (float) T0 + (float) T0_frac / (float) T0_res;
    1269             : 
    1270             :     /* Update target vector for ACELP codebook search */
    1271        6040 :     updt_tar( xn, xn2, y1, pitch_gain, L_SUBFR );
    1272             : 
    1273             :     /* Include fixed-gain pitch contribution into impulse resp. h1[] */
    1274        6040 :     mvr2r( h1, h2, L_SUBFR );
    1275        6040 :     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 );
    1276             : 
    1277             :     /* Correlation between target xn2[] and impulse response h1[] */
    1278        6040 :     if ( acelpautoc & 0x01 )
    1279             :     {
    1280        6040 :         corr_xh( h2, Rw2, h2, L_SUBFR );
    1281      392600 :         for ( k = 0; k < L_SUBFR; k++ )
    1282             :         {
    1283      386560 :             cn2[k] = xn2[k];
    1284    12563200 :             for ( i = 0; i < k; i++ )
    1285             :             {
    1286    12176640 :                 cn2[k] -= cn2[i] * h2[k - i];
    1287             :             }
    1288             :         }
    1289             : 
    1290        6040 :         E_ACELP_toeplitz_mul( Rw2, cn2, dn );
    1291             :     }
    1292             :     else
    1293             :     {
    1294           0 :         updt_tar( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR );
    1295           0 :         corr_xh( xn2, dn, h2, L_SUBFR );
    1296             :     }
    1297             : 
    1298             :     /* Innovative codebook search */
    1299        6040 :     if ( acelp_cfg->fixed_cdk_index[i_subfr / L_SUBFR] < ACELP_FIXED_CDK_NB )
    1300             :     {
    1301        6040 :         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 );
    1302             :     }
    1303             :     else
    1304             :     {
    1305           0 :         assert( 0 );
    1306             :     }
    1307        6040 :     *pt_indice += 8;
    1308             :     /* Generate weighted code */
    1309        6040 :     set_f( y2, 0.0f, L_SUBFR );
    1310      392600 :     for ( i = 0; i < L_SUBFR; i++ )
    1311             :     {
    1312             :         /* Code is sparse, so check which samples are non-zero */
    1313      386560 :         if ( code[i] != 0 )
    1314             :         {
    1315     3030324 :             for ( k = 0; k < L_SUBFR - i; k++ )
    1316             :             {
    1317     2939140 :                 y2[i + k] += code[i] * h2[k];
    1318             :             }
    1319             :         }
    1320             :     }
    1321             : 
    1322             :     /*-------------------------------------------------------*
    1323             :      * - Add the fixed-gain pitch contribution to code[].    *
    1324             :      *-------------------------------------------------------*/
    1325             : 
    1326        6040 :     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 );
    1327             : 
    1328        6040 :     return;
    1329             : }
    1330             : 
    1331             : 
    1332             : /*--------------------------------------------------------------------------*
    1333             :  * E_ACELP_codearithp
    1334             :  *
    1335             :  * Fixed bit-length arithmetic coding of pulses
    1336             :  * v - (input) pulse vector
    1337             :  * s - (output) encoded state
    1338             :  * n - (output) range of possible states (0...n-1)
    1339             :  * p - (output) number of pulses found
    1340             :  * len - (input) length of pulse vector
    1341             :  * trackstep - (input) step between tracks
    1342             :  *--------------------------------------------------------------------------*/
    1343             : 
    1344     1835944 : static void E_ACELP_codearithp(
    1345             :     const float v[],
    1346             :     uint32_t *n,
    1347             :     uint32_t *ps,
    1348             :     int16_t *p,
    1349             :     const int16_t trackstep,
    1350             :     const int16_t tracklen )
    1351             : {
    1352             :     int16_t k, h, t, pos[9], sig[9], posno, tmp, L_subfr;
    1353             :     uint32_t s;
    1354             : 
    1355     1835944 :     posno = 0;
    1356     1835944 :     L_subfr = trackstep * tracklen;
    1357             : 
    1358    31211048 :     for ( k = t = 0; k < L_subfr; k += trackstep, t++ )
    1359             :     {
    1360    29375104 :         tmp = ( v[k] > 0 ? 1 : -1 ); /* sign */
    1361    34155885 :         for ( h = 0; h < v[k] * tmp; h++ )
    1362             :         {
    1363     4780781 :             pos[posno] = t;
    1364     4780781 :             sig[posno] = tmp;
    1365     4780781 :             posno++;
    1366     4780781 :             if ( posno > 9 )
    1367             :             {
    1368           0 :                 break;
    1369             :             }
    1370             :         }
    1371    29375104 :         if ( posno >= 9 )
    1372             :         {
    1373           0 :             break;
    1374             :         }
    1375             :     }
    1376     1835944 :     *p = posno;
    1377             : 
    1378     1835944 :     s = 0;
    1379     6616725 :     for ( k = 0; k < posno; k++ )
    1380             :     {
    1381             :         /* check if next position is the same as this one */
    1382     4780781 :         if ( ( k == posno - 1 ) || ( pos[k] != pos[k + 1] ) )
    1383             :         {
    1384             :             /* next position is not the same (or we are at the last position)
    1385             :              * -> save sign */
    1386     4491112 :             s <<= 1;
    1387     4491112 :             if ( sig[k] < 0 )
    1388             :             {
    1389     2247088 :                 s++;
    1390             :             }
    1391             :         }
    1392     4780781 :         s += pulsestostates[pos[k]][k];
    1393             :     }
    1394     1835944 :     *ps = s;
    1395     1835944 :     if ( posno )
    1396             :     {
    1397     1821320 :         *n = pulsestostates[tracklen][posno - 1];
    1398             :     }
    1399             :     else
    1400             :     {
    1401       14624 :         *n = 0;
    1402             :     }
    1403             : 
    1404     1835944 :     return;
    1405             : }
    1406             : 
    1407             : 
    1408      458986 : void fcb_pulse_track_joint(
    1409             :     uint16_t *idxs,
    1410             :     const int16_t wordcnt,
    1411             :     uint32_t *index_n,
    1412             :     const int16_t *pulse_num,
    1413             :     const int16_t track_num )
    1414             : {
    1415      458986 :     int16_t hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
    1416             : 
    1417             :     uint32_t index, indx_tmp;
    1418             :     uint32_t index_mask;
    1419             :     int16_t indx_flag, indx_flag_1;
    1420             :     int16_t track, track_num1, pulse_num0, pulse_num1;
    1421             :     int16_t indx_flag_2;
    1422             : 
    1423      458986 :     indx_flag = 0;
    1424      458986 :     indx_flag_1 = 0;
    1425      458986 :     indx_flag_2 = 0;
    1426     2294930 :     for ( track = 0; track < track_num; track++ )
    1427             :     {
    1428     1835944 :         indx_flag += ( pulse_num[track] >> 2 );
    1429     1835944 :         indx_flag_1 += ( pulse_num[track] >> 1 );
    1430     1835944 :         indx_flag_2 += ( pulse_num[track] >> 3 );
    1431             :     }
    1432             : 
    1433      458986 :     if ( indx_flag_2 >= 1 )
    1434             :     {
    1435          30 :         hi_to_low[7] = 9;
    1436          30 :         index_mask = 0xffffff;
    1437             :     }
    1438             :     else
    1439             :     {
    1440      458956 :         hi_to_low[7] = 1;
    1441      458956 :         if ( indx_flag >= track_num )
    1442             :         {
    1443       77336 :             hi_to_low[4] = 9;
    1444       77336 :             index_mask = 0xffff;
    1445             :         }
    1446             :         else
    1447             :         {
    1448      381620 :             hi_to_low[4] = 1;
    1449      381620 :             index_mask = 0xff;
    1450             :         }
    1451             :     }
    1452             : 
    1453      458986 :     if ( indx_flag_1 >= track_num )
    1454             :     {
    1455      309878 :         indx_tmp = 0;
    1456      309878 :         index = index_n[0] >> low_len[pulse_num[0]];
    1457     1239512 :         for ( track = 1; track < track_num; track++ )
    1458             :         {
    1459      929634 :             pulse_num0 = pulse_num[track - 1];
    1460      929634 :             pulse_num1 = pulse_num[track];
    1461      929634 :             indx_tmp = index_n[track] >> low_len[pulse_num1];
    1462      929634 :             index = index * indx_fact[pulse_num1] + indx_tmp;
    1463             : 
    1464      929634 :             index_n[track - 1] = ( index_n[track - 1] & low_mask[pulse_num0] ) + ( ( index << low_len[pulse_num0] ) & index_mask );
    1465      929634 :             index = index >> hi_to_low[pulse_num0];
    1466             :         }
    1467      309878 :         track_num1 = track_num - 1;
    1468      309878 :         pulse_num1 = pulse_num[track_num1];
    1469      309878 :         index_n[track_num1] = ( ( index_n[track_num1] & low_mask[pulse_num1] ) + ( index << low_len[pulse_num1] ) ) & index_mask;
    1470      309878 :         index = index >> hi_to_low[pulse_num1];
    1471      309878 :         if ( indx_flag >= track_num )
    1472             :         {
    1473       77366 :             if ( indx_flag_2 >= 1 )
    1474             :             {
    1475          30 :                 idxs[0] = index_n[0] & 0xffff;
    1476          30 :                 idxs[1] = ( ( index_n[1] << 8 ) + ( index_n[0] >> 16 ) ) & 0xffff;
    1477          30 :                 idxs[2] = ( index_n[1] >> 8 ) & 0xffff;
    1478          30 :                 idxs[3] = index_n[2] & 0xffff;
    1479          30 :                 idxs[4] = ( ( index_n[3] << 8 ) + ( index_n[2] >> 16 ) ) & 0xffff;
    1480          30 :                 idxs[5] = ( index_n[3] >> 8 ) & 0xffff;
    1481          30 :                 for ( track = 6; track < wordcnt; track++ )
    1482             :                 {
    1483           0 :                     idxs[track] = index & 0xffff;
    1484           0 :                     index = index >> 16;
    1485             :                 }
    1486             :             }
    1487             :             else
    1488             :             {
    1489      386680 :                 for ( track = 0; track < track_num; track++ )
    1490             :                 {
    1491      309344 :                     idxs[track] = index_n[track] & 0xffff;
    1492             :                 }
    1493      158324 :                 for ( track = track_num; track < wordcnt; track++ )
    1494             :                 {
    1495       80988 :                     idxs[track] = index & 0xffff;
    1496       80988 :                     index = index >> 16;
    1497             :                 }
    1498             :             }
    1499             :         }
    1500             :         else
    1501             :         {
    1502      232512 :             idxs[0] = ( ( index_n[0] << 8 ) + index_n[1] ) & 0xffff;
    1503      232512 :             idxs[1] = ( ( index_n[2] << 8 ) + index_n[3] ) & 0xffff;
    1504      554886 :             for ( track = 2; track < wordcnt; track++ )
    1505             :             {
    1506      322374 :                 idxs[track] = index & 0xffff;
    1507      322374 :                 index = index >> 16;
    1508             :             }
    1509             :         }
    1510             :     }
    1511             :     else
    1512             :     {
    1513      149108 :         index = index_n[0];
    1514      596432 :         for ( track = 1; track < 4; track++ )
    1515             :         {
    1516      447324 :             pulse_num1 = pulse_num[track];
    1517      447324 :             index = ( index << index_len[pulse_num1] ) + index_n[track];
    1518             :         }
    1519      462413 :         for ( track = 0; track < wordcnt; track++ )
    1520             :         {
    1521      313305 :             idxs[track] = index & 0xffff;
    1522      313305 :             index = index >> 16;
    1523             :         }
    1524             :     }
    1525             : 
    1526      458986 :     return;
    1527             : }

Generated by: LCOV version 1.14