LCOV - code coverage report
Current view: top level - lib_enc - enc_acelpx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 185 192 96.4 %
Date: 2025-05-28 04:28:20 Functions: 3 3 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 "prot.h"
      44             : #include "rom_enc.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /* Iterations: nb_pos_ix*16 */
      49    64629829 : static void E_ACELP_2pulse_searchx(
      50             :     const int16_t nb_pos_ix,
      51             :     const int16_t track_x,
      52             :     const int16_t track_y,
      53             :     float *R,
      54             :     float *ps,
      55             :     float *alp,
      56             :     int16_t *ix,
      57             :     int16_t *iy,
      58             :     float dn[],
      59             :     int16_t *dn2,
      60             :     float cor[],
      61             :     float sign[] )
      62             : {
      63             :     int16_t i;
      64    64629829 :     int16_t x, y, *pos_x, x_save = 0, y_save = 0;
      65             :     float ps0, alp0, alp1, ps1, alp2, ps2, sq, s, sqk, alpk, *pR, sgnx, *pRx, *pRy, sign_x, sign_y;
      66             : 
      67             :     /* x_save=y_save=0 */
      68             :     /* eight dn2 max positions per track */
      69    64629829 :     pos_x = &dn2[track_x << 3];
      70             :     /* save these to limit memory searches */
      71    64629829 :     ps0 = *ps;
      72    64629829 :     alp0 = *alp + 2.0f * R[0];
      73             : 
      74    64629829 :     sqk = -1.0F;
      75    64629829 :     alpk = 1.0F;
      76             : 
      77    64629829 :     x = pos_x[0];
      78    64629829 :     sgnx = sign[track_y];
      79    64629829 :     if ( sign[x] < 0 )
      80             :     {
      81    31440686 :         sgnx = -sgnx;
      82             :     }
      83    64629829 :     if ( ( alp0 + ( cor[x] * sign[x] ) + ( cor[track_y] * sign[track_y] ) + ( R[track_y - x] * sgnx ) ) < 0.0F )
      84             :     {
      85           0 :         sqk = 1.0F;
      86             :     }
      87             : 
      88             :     /* loop track 1 */
      89   466627977 :     for ( i = 0; i < nb_pos_ix; i++ )
      90             :     {
      91   401998148 :         x = pos_x[i];
      92   401998148 :         sgnx = sign[x];
      93             :         /* dn[x] has only nb_pos_ix positions saved */
      94   401998148 :         ps1 = ps0 + dn[x];
      95   401998148 :         alp1 = alp0 + 2 * sgnx * cor[x];
      96   401998148 :         pR = R - x;
      97             : 
      98  6833968516 :         for ( y = track_y; y < L_SUBFR; y += 4 )
      99             :         {
     100  6431970368 :             ps2 = ps1 + dn[y];
     101  6431970368 :             alp2 = alp1 + 2.0f * sign[y] * ( cor[y] + sgnx * pR[y] );
     102  6431970368 :             sq = ps2 * ps2;
     103             : 
     104  6431970368 :             s = ( alpk * sq ) - ( sqk * alp2 );
     105  6431970368 :             if ( s > 0.0F )
     106             :             {
     107   373852605 :                 sqk = sq;
     108   373852605 :                 alpk = alp2;
     109   373852605 :                 y_save = y;
     110   373852605 :                 x_save = x;
     111             :             }
     112             :         }
     113             :     }
     114             :     /* Update numerator */
     115    64629829 :     *ps = ps0 + dn[x_save] + dn[y_save];
     116             :     /* Update denominator */
     117    64629829 :     *alp = alpk;
     118             : 
     119             :     /* Update product of autocorrelation and already fixed pulses. with the
     120             :      * two newly found ones */
     121    64629829 :     pRx = R - x_save;
     122    64629829 :     pRy = R - y_save;
     123    64629829 :     sign_x = sign[x_save];
     124    64629829 :     sign_y = sign[y_save];
     125             : 
     126  4200938885 :     for ( i = 0; i < L_SUBFR; i++ )
     127             :     {
     128  4136309056 :         cor[i] += pRx[i] * sign_x + pRy[i] * sign_y;
     129             :     }
     130             : 
     131    64629829 :     *ix = x_save;
     132    64629829 :     *iy = y_save;
     133    64629829 :     if ( ( ( x_save & 3 ) != track_x ) || ( ( y_save & 3 ) != track_y ) )
     134             :     {
     135             :         /* sanity check */
     136           0 :         assert( 0 );
     137             :     }
     138             : 
     139    64629829 :     return;
     140             : }
     141             : 
     142     6418766 : static void E_ACELP_1pulse_searchx(
     143             :     int16_t track_x,
     144             :     int16_t track_y,
     145             :     float *R,
     146             :     float *ps,
     147             :     float *alp,
     148             :     int16_t *ix,
     149             :     float dn[],
     150             :     float cor[],
     151             :     float sign[] )
     152             : {
     153     6418766 :     int16_t x, x_save = 0;
     154             :     float ps0, alp0;
     155             :     float ps1, sq, sqk;
     156             :     float alp1, alpk;
     157             :     float s;
     158             : 
     159             :     /* save these to limit memory searches */
     160     6418766 :     ps0 = *ps;
     161     6418766 :     alp0 = *alp + R[0];
     162     6418766 :     sqk = -1.0F;
     163     6418766 :     alpk = 1.0F;
     164             : 
     165     6418766 :     if ( ( alp0 + ( cor[track_x] * sign[track_x] ) ) < 0 )
     166             :     {
     167           0 :         sqk = 1.0F;
     168             :     }
     169             : 
     170     6418766 :     x_save = track_x;
     171   109119022 :     for ( x = track_x; x < L_SUBFR; x += 4 )
     172             :     {
     173   102700256 :         ps1 = ps0 + dn[x];
     174   102700256 :         alp1 = alp0 + 2 * sign[x] * cor[x];
     175   102700256 :         sq = ps1 * ps1;
     176   102700256 :         s = ( alpk * sq ) - ( sqk * alp1 );
     177   102700256 :         if ( s > 0.0F )
     178             :         {
     179    22100156 :             sqk = sq;
     180    22100156 :             alpk = alp1;
     181    22100156 :             x_save = x;
     182             :         }
     183             :     }
     184             : 
     185     6418766 :     if ( track_y != track_x )
     186             :     {
     187    29708809 :         for ( x = track_y; x < L_SUBFR; x += 4 )
     188             :         {
     189    27961232 :             ps1 = ps0 + dn[x];
     190    27961232 :             alp1 = alp0 + 2 * sign[x] * cor[x];
     191    27961232 :             sq = ps1 * ps1;
     192    27961232 :             s = ( alpk * sq ) - ( sqk * alp1 );
     193    27961232 :             if ( s > 0.0F )
     194             :             {
     195     1128450 :                 sqk = sq;
     196     1128450 :                 alpk = alp1;
     197     1128450 :                 x_save = x;
     198             :             }
     199             :         }
     200             :     }
     201             : 
     202     6418766 :     *ps = ps0 + dn[x_save];
     203     6418766 :     *alp = alpk;
     204     6418766 :     *ix = x_save;
     205             : 
     206     6418766 :     return;
     207             : }
     208             : 
     209             : 
     210             : /* Autocorrelation method for searching pulse positions effectively
     211             :  * Algorithm is identical to traditional covariance method. */
     212     3922797 : void E_ACELP_4tsearchx(
     213             :     float dn[],
     214             :     const float cn[],
     215             :     float Rw[],
     216             :     float code[],
     217             :     PulseConfig *config,
     218             :     int16_t ind[] )
     219             : {
     220             :     float sign[L_SUBFR], vec[L_SUBFR];
     221             :     float cor[L_SUBFR];
     222             :     float R_buf[2 * L_SUBFR - 1], *R;
     223             :     float dn2[L_SUBFR];
     224     3922797 :     float psk = 0.0F, ps2k, ps, ps2, alpk, alp = 0.0F;
     225             :     int16_t codvec[NB_PULSE_MAX];
     226             :     int16_t pos_max[4];
     227             :     int16_t dn2_pos[8 * 4];
     228             :     int16_t ipos[NB_PULSE_MAX];
     229             :     float *p0;
     230     3922797 :     int16_t i, j, k, l, st, pos = 0, index, track;
     231             :     int16_t iPulse;
     232             :     float val;
     233             :     float s;
     234             :     int16_t restpulses;
     235             : 
     236     3922797 :     alp = config->alp;
     237    55422609 :     for ( k = 0; k < config->nb_pulse; k++ )
     238             :     {
     239    51499812 :         codvec[k] = ( k & 3 );
     240             :     }
     241             : 
     242     3922797 :     set_f( cor, 0.0f, L_SUBFR );
     243             : 
     244             :     /* Set up autocorrelation vector */
     245     3922797 :     R = R_buf + L_SUBFR - 1;
     246     3922797 :     R[0] = Rw[0];
     247   251059008 :     for ( k = 1; k < L_SUBFR; k++ )
     248             :     {
     249   247136211 :         R[k] = R[-k] = Rw[k];
     250             :     }
     251             : 
     252             :     /* Find sign for each pulse position. */
     253     3922797 :     acelp_pulsesign( cn, dn, dn2, sign, vec, alp );
     254             : 
     255             :     /* Select the most important 8 position per track according to dn2[]. */
     256     3922797 :     acelp_findcandidates( dn2, dn2_pos, pos_max, L_SUBFR, NB_TRACK_FCB_4T );
     257             : 
     258             :     /*
     259             :      * Deep first search:
     260             :      * ------------------
     261             :      * 20 bits (4p):  4 iter x ((4x16)+(8x16))              = 768 tests
     262             :      * 36 bits (8p):  4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
     263             :      * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     264             :      *                                      +(8x16)+(8x16)) = 1248 tests
     265             :      * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
     266             :      *                        +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
     267             :      */
     268     3922797 :     ps2k = -1.0;
     269     3922797 :     alpk = 1000.0;
     270             :     /*Number of iterations*/
     271    17858679 :     for ( k = 0; k < config->nbiter; k++ )
     272             :     {
     273             :         /* copy search order from hash-table */
     274   191946702 :         for ( l = 0; l < config->nb_pulse; l++ )
     275             :         {
     276   178010820 :             ipos[l] = tipos[( k * 4 ) + l];
     277             :         }
     278             : 
     279             :         /* if all tracks do not have equal number of pulses */
     280    13935882 :         restpulses = config->nb_pulse & 3;
     281    13935882 :         if ( restpulses )
     282             :         {
     283    10141755 :             switch ( config->codetrackpos )
     284             :             {
     285     6998505 :                 case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
     286             :                     /* add tracks from left */
     287    21092042 :                     for ( iPulse = 0; iPulse < restpulses; iPulse++ )
     288             :                     {
     289    14093537 :                         ipos[config->nb_pulse - restpulses + iPulse] = iPulse;
     290             :                     }
     291             :                     /* Put the same track on the next position, because the 1-pulse search
     292             :                      * will access it to determine if this could be in any track. */
     293     6998505 :                     ipos[config->nb_pulse] = ipos[config->nb_pulse - 1];
     294     6998505 :                     break;
     295           0 :                 case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */
     296             :                     /* odd tracks, switch order for every iteration */
     297           0 :                     ipos[config->nb_pulse - restpulses] = ( k << 1 ) & 2;                              /* 0 for even k, 2 for odd*/
     298           0 :                     ipos[config->nb_pulse - restpulses + 1] = ipos[config->nb_pulse - restpulses] ^ 2; /* 2 for even k, 0 for odd*/
     299           0 :                     break;
     300     1395673 :                 case TRACKPOS_FIXED_TWO: /* two tracks instead of four */
     301             :                     /* Put the next track on the next position, because the 1-pulse search
     302             :                      * will access it to determine if this could be in any track. */
     303     1395673 :                     ipos[config->nb_pulse] = ( ipos[config->nb_pulse - 1] + 1 ) & 3;
     304     1395673 :                     break;
     305     1747577 :                 default: /* one or three free track positions */
     306             :                     /* copy an extra position from table - 1pulse search will access this */
     307     1747577 :                     ipos[config->nb_pulse] = tipos[( k * 4 ) + config->nb_pulse];
     308     1747577 :                     break;
     309             :             }
     310     3794127 :         }
     311    13935882 :         if ( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
     312             :         {
     313      854249 :             pos = 0;
     314      854249 :             ps = 0.0F;
     315      854249 :             alp = 0.0F;
     316    55526185 :             for ( i = 0; i < L_SUBFR; i++ )
     317             :             {
     318    54671936 :                 cor[i] = 0;
     319             :             }
     320             :         }
     321    13081633 :         else if ( config->fixedpulses == 2 ) /* 2222 and 3322 */
     322             :         {
     323             :             /* --- first stage: fix 2 pulses --- */
     324             :             /* index to first non-fixed position */
     325     4997068 :             pos = 2;
     326             : 
     327             :             /* set fixed positions */
     328     4997068 :             ind[0] = pos_max[ipos[0]];
     329     4997068 :             ind[1] = pos_max[ipos[1]];
     330             : 
     331             :             /* correlation of fixed part with residual */
     332     4997068 :             ps = dn[ind[0]] + dn[ind[1]];
     333             : 
     334             :             /* multiplication of autocorrelation with signed fixed pulses */
     335             :             /* first pulse */
     336     4997068 :             p0 = R - ind[0];
     337     4997068 :             if ( sign[ind[0]] > 0 )
     338             :             {
     339   166246015 :                 for ( i = 0; i < L_SUBFR; i++ )
     340             :                 {
     341   163688384 :                     cor[i] = *p0;
     342   163688384 :                     p0++;
     343             :                 }
     344             :             }
     345             :             else
     346             :             {
     347   158563405 :                 for ( i = 0; i < L_SUBFR; i++ )
     348             :                 {
     349   156123968 :                     cor[i] = -*p0;
     350   156123968 :                     p0++;
     351             :                 }
     352             :             }
     353             :             /* second pulse */
     354     4997068 :             p0 = R - ind[1];
     355     4997068 :             if ( sign[ind[1]] > 0 )
     356             :             {
     357   166233145 :                 for ( i = 0; i < L_SUBFR; i++ )
     358             :                 {
     359   163675712 :                     cor[i] += *p0;
     360   163675712 :                     p0++;
     361             :                 }
     362             :             }
     363             :             else
     364             :             {
     365   158576275 :                 for ( i = 0; i < L_SUBFR; i++ )
     366             :                 {
     367   156136640 :                     cor[i] -= *p0;
     368   156136640 :                     p0++;
     369             :                 }
     370             :             }
     371             : 
     372             :             /* normalisation contribution of fixed part */
     373     4997068 :             alp = sign[ind[0]] * cor[ind[0]] + sign[ind[1]] * cor[ind[1]];
     374             :         }
     375             :         else /* if (config->fixedpulses == 4) */ /* 3333 and above */
     376             :         {
     377             :             /* first stage: fix 4 pulses */
     378     8084565 :             pos = 4;
     379             : 
     380     8084565 :             ind[0] = pos_max[ipos[0]];
     381     8084565 :             ind[1] = pos_max[ipos[1]];
     382     8084565 :             ind[2] = pos_max[ipos[2]];
     383     8084565 :             ind[3] = pos_max[ipos[3]];
     384             : 
     385             :             /* correlation of fixed part with residual */
     386     8084565 :             ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];
     387             : 
     388             :             /* multiplication of autocorrelation with signed fixed pulses */
     389             :             /* first pulse */
     390     8084565 :             p0 = R - ind[0];
     391     8084565 :             if ( sign[ind[0]] > 0 )
     392             :             {
     393   270046790 :                 for ( i = 0; i < L_SUBFR; i++ )
     394             :                 {
     395   265892224 :                     cor[i] = *p0;
     396   265892224 :                     p0++;
     397             :                 }
     398             :             }
     399             :             else
     400             :             {
     401   255449935 :                 for ( i = 0; i < L_SUBFR; i++ )
     402             :                 {
     403   251519936 :                     cor[i] = -*p0;
     404   251519936 :                     p0++;
     405             :                 }
     406             :             }
     407             :             /* pulses 1..3 */
     408    32338260 :             for ( j = 1; j < 4; j++ )
     409             :             {
     410    24253695 :                 p0 = R - ind[j];
     411    24253695 :                 if ( sign[ind[j]] > 0 )
     412             :                 {
     413   810609865 :                     for ( i = 0; i < L_SUBFR; i++ )
     414             :                     {
     415   798138944 :                         cor[i] += *p0;
     416   798138944 :                         p0++;
     417             :                     }
     418             :                 }
     419             :                 else
     420             :                 {
     421   765880310 :                     for ( i = 0; i < L_SUBFR; i++ )
     422             :                     {
     423   754097536 :                         cor[i] -= *p0;
     424   754097536 :                         p0++;
     425             :                     }
     426             :                 }
     427             :             }
     428             : 
     429             :             /* normalisation contribution of fixed part */
     430     8084565 :             alp = sign[ind[0]] * cor[ind[0]] + sign[ind[1]] * cor[ind[1]] + sign[ind[2]] * cor[ind[2]] + sign[ind[3]] * cor[ind[3]];
     431             :         }
     432             : 
     433             :         /* other stages of 2 pulses */
     434    84984477 :         for ( j = pos, st = 0; j < config->nb_pulse; j += 2, st++ )
     435             :         {
     436    71048595 :             if ( ( config->nb_pulse - j ) >= 2 )
     437             :             {
     438             :                 /*pair-wise search*/
     439             : 
     440             :                 /* Calculate correlation of all possible positions
     441             :                  * of the next 2 pulses with previous fixed pulses.
     442             :                  * Each pulse can have 16 possible positions. */
     443             : 
     444    64629829 :                 E_ACELP_2pulse_searchx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign );
     445             :             }
     446             :             else
     447             :             {
     448             :                 /*single pulse search*/
     449     6418766 :                 E_ACELP_1pulse_searchx( ipos[j], ipos[j + 1], R, &ps, &alp, &ind[j], dn, cor, sign );
     450             :             }
     451             :         }
     452             : 
     453             :         /* memorise the best codevector */
     454    13935882 :         ps2 = ps * ps;
     455    13935882 :         s = ( alpk * ps2 ) - ( ps2k * alp );
     456    13935882 :         if ( s > 0.0F )
     457             :         {
     458     7669241 :             ps2k = ps2;
     459     7669241 :             psk = ps;
     460     7669241 :             alpk = alp;
     461   107128080 :             for ( i = 0; i < config->nb_pulse; i++ )
     462             :             {
     463    99458839 :                 codvec[i] = ind[i];
     464             :             }
     465             :         }
     466             :     }
     467             : 
     468             :     /* Store weighted energy of code, build the codeword and index of codevector. */
     469     3922797 :     set_f( code, 0, L_SUBFR );
     470     3922797 :     set_s( ind, -1, NPMAXPT * 4 );
     471             : 
     472    55422609 :     for ( k = 0; k < config->nb_pulse; k++ )
     473             :     {
     474    51499812 :         i = codvec[k]; /* read pulse position  */
     475    51499812 :         val = sign[i]; /* read sign            */
     476             : 
     477    51499812 :         index = i / 4; /* pos of pulse (0..15) */
     478    51499812 :         track = i % 4;
     479    51499812 :         if ( val * psk > 0 )
     480             :         {
     481    25621039 :             code[i] += 1.0f;
     482    25621039 :             codvec[k] += ( 2 * L_SUBFR );
     483             :         }
     484             :         else
     485             :         {
     486    25878773 :             code[i] -= 1.0f;
     487    25878773 :             index += 16;
     488             :         }
     489             : 
     490    51499812 :         i = track * NPMAXPT;
     491   121884712 :         while ( ind[i] >= 0 )
     492             :         {
     493    70384900 :             i++;
     494             :         }
     495             : 
     496    51499812 :         ind[i] = index;
     497             :     }
     498             : 
     499     3922797 :     return;
     500             : }

Generated by: LCOV version 1.14