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

Generated by: LCOV version 1.14