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 @ a53d7b5498aebe2d66400d10e953da7c3789f796 Lines: 624 636 98.1 %
Date: 2026-01-25 05:59:30 Functions: 14 14 100.0 %

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

Generated by: LCOV version 1.14