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

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #include <math.h>
      40             : #include "prot.h"
      41             : #include "rom_com.h"
      42             : #include "cnst.h"
      43             : #include "wmc_auto.h"
      44             : #include "ivas_prot.h"
      45             : 
      46             : /*-----------------------------------------------------------------*
      47             :  * Local function prototypes
      48             :  *-----------------------------------------------------------------*/
      49             : 
      50             : static float quantize_data( float *data, const float *w_in, float *qin, float *cv_out, int16_t *idx_lead, int16_t *idx_scale, const float *sigma, const float *inv_sigma, const float *scales, Word8 *no_leaders );
      51             : static float q_data( float *pTmp1, const float *w1, float *quant, float *cv_out, int16_t *idx_lead, int16_t *idx_scale, const float *p_inv_sigma, const float *p_sigma, const float *p_scales, Word8 *no_leaders );
      52             : static void prepare_data( float *xsort, int16_t *sign, float *data, float *w, const float *w_in, const float *sigma, const float *inv_sigma, int16_t *p_sig );
      53             : static float calculate_min_dist( float cv_pot[LATTICE_DIM], const float *scale, const float *w, int16_t *p_best_scale, int16_t *p_best_idx, Word8 *no_leaders, int16_t sig, int16_t *indx );
      54             : static int16_t find_pos( float *c, const int16_t len, float arg, int16_t *p );
      55             : static void take_out_val( float *v, float *v_out, const float val, const int16_t len );
      56             : static UWord32 index_leaders( float *cv, int16_t idx_lead, const int16_t dim );
      57             : static UWord32 c2idx( const int16_t n, int16_t *p, const int16_t k );
      58             : static UWord32 encode_sign_pc1( const int16_t parity, float *cv );
      59             : static UWord32 encode_comb( float *cv, const int16_t idx_lead );
      60             : 
      61             : 
      62             : /*-----------------------------------------------------------------*
      63             :  * mslvq()
      64             :  *
      65             :  * Encodes the LSF residual
      66             :  *-----------------------------------------------------------------*/
      67             : 
      68      696088 : float mslvq(
      69             :     float *pTmp,            /* i  : M-dimensional input vector */
      70             :     float *quant,           /* o  : quantized vector */
      71             :     float *cv_out,          /* o  : corresponding 8-dim lattice codevectors (without the scaling) */
      72             :     int16_t *idx_lead,      /* o  : leader index for each 8-dim subvector  */
      73             :     int16_t *idx_scale,     /* o  : scale index for each subvector */
      74             :     const float *w,         /* i  : weights for LSF quantization */
      75             :     const int16_t mode,     /* i  : number indicating the coding type (V/UV/G...)*/
      76             :     const int16_t mode_glb, /* i  : LVQ coding mode */
      77             :     const int16_t pred_flag /* i  : prediction flag (0: safety net, 1,2 - predictive  )*/
      78             : )
      79             : {
      80             :     float dist;
      81             :     const float *p_scales, *p_sigma, *p_inv_sigma;
      82             :     int16_t i, tmp, tmp1;
      83             :     Word8 p_no_lead[MAX_NO_SCALES * 2];
      84             : 
      85      696088 :     dist = 0.0f;
      86             : 
      87      696088 :     if ( pred_flag == 0 )
      88             :     {
      89      182946 :         p_sigma = sigma_MSLVQ[mode];
      90             :         /* inverse sigma is precomputed to save complexity */
      91      182946 :         p_inv_sigma = inv_sigma_MSLVQ[mode];
      92      182946 :         p_scales = scales[mode_glb];
      93             : 
      94      182946 :         tmp = no_lead_idx[mode_glb][0];
      95      182946 :         tmp1 = no_lead_idx[mode_glb][1];
      96      182946 :         if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
      97             :         {
      98           0 :             tmp += DELTA_LEADER;
      99             :         }
     100      731784 :         for ( i = 0; i < MAX_NO_SCALES; i++ )
     101             :         {
     102      548838 :             p_no_lead[i] = (int16_t) leaders_short[tmp][i];
     103      548838 :             p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[tmp1][i];
     104             :         }
     105             :     }
     106             :     else
     107             :     {
     108      513142 :         if ( pred_flag >= 5 )
     109             :         {
     110             :             /* assert( pred_flag >= 12 && pred_flag <= 15 ); */
     111             :             /* pred_flag is here the number of bits for MSLVQ */
     112             : 
     113        3338 :             p_sigma = &sigma_BWE[mode_glb * LATTICE_DIM];
     114             : 
     115             :             /* inverse sigma is precomputed to save complexity */
     116        3338 :             p_inv_sigma = &inv_sigma_BWE[mode_glb * LATTICE_DIM];
     117             : 
     118        3338 :             if ( mode_glb == 0 )
     119             :             {
     120        3338 :                 p_scales = &scales_BWE[( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
     121       13352 :                 for ( i = 0; i < MAX_NO_SCALES; i++ )
     122             :                 {
     123       10014 :                     p_no_lead[i] = no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
     124             :                 }
     125             :             }
     126             :             else
     127             :             {
     128           0 :                 p_scales = &scales_BWE_3b[( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
     129           0 :                 for ( i = 0; i < MAX_NO_SCALES; i++ )
     130             :                 {
     131           0 :                     p_no_lead[i] = no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
     132             :                 }
     133             :             }
     134             :         }
     135             :         else
     136             :         {
     137      509804 :             p_sigma = sigma_p[mode];
     138             : 
     139             :             /* inverse sigma is precomputed to save complexity */
     140      509804 :             p_inv_sigma = inv_sigma_p[mode];
     141      509804 :             p_scales = scales_p[mode_glb];
     142             : 
     143      509804 :             tmp = no_lead_p_idx[mode_glb][0];
     144      509804 :             tmp1 = no_lead_p_idx[mode_glb][1];
     145             : 
     146      509804 :             if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
     147             :             {
     148       11144 :                 tmp += DELTA_LEADER;
     149             :             }
     150             : 
     151      509804 :             if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
     152             :             {
     153           0 :                 tmp += DELTA_LEADER;
     154           0 :                 tmp1 += DELTA_LEADER;
     155             :             }
     156             : 
     157     2039216 :             for ( i = 0; i < MAX_NO_SCALES; i++ )
     158             :             {
     159     1529412 :                 p_no_lead[i] = (int16_t) leaders_short[tmp][i];
     160     1529412 :                 p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[tmp1][i];
     161             :             }
     162             :         }
     163             :     }
     164             : 
     165             :     /* first subvector */
     166      696088 :     dist += quantize_data( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     167             : 
     168      696088 :     if ( pred_flag < 5 )
     169             :     {
     170             :         /* second subvector */
     171      692750 :         dist += quantize_data( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES );
     172             :     }
     173             : 
     174      696088 :     return dist;
     175             : }
     176             : 
     177             : 
     178             : /*-----------------------------------------------------------------*
     179             :  * q_data()
     180             :  *
     181             :  * (used for LSF quantization in CNG)
     182             :  *-----------------------------------------------------------------*/
     183             : 
     184         433 : static float q_data(
     185             :     float *pTmp1,
     186             :     const float *w1,
     187             :     float *quant,
     188             :     float *cv_out,
     189             :     int16_t *idx_lead,
     190             :     int16_t *idx_scale,
     191             :     const float *p_sigma,
     192             :     const float *p_inv_sigma,
     193             :     const float *p_scales,
     194             :     Word8 *p_no_lead )
     195             : {
     196         433 :     float dist = 0.0f;
     197             :     /* first subvector */
     198         433 :     dist += quantize_data( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     199             :     /* second subvector */
     200         433 :     dist += quantize_data( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES );
     201             : 
     202         433 :     return dist;
     203             : }
     204             : 
     205             : /*-----------------------------------------------------------------*
     206             :  * mslvq_cng()
     207             :  *
     208             :  * Encodes the LSF residual in SID frames
     209             :  *-----------------------------------------------------------------*/
     210             : 
     211         433 : float mslvq_cng(
     212             :     int16_t idx_cv,     /* i  : index of cv from previous stage */
     213             :     float *pTmp,        /* i  : 16 dimensional input vector */
     214             :     float *quant,       /* o  : quantized vector */
     215             :     float *cv_out,      /* o  : corresponding 8-dim lattice codevectors (without the scaling) */
     216             :     int16_t *idx_lead,  /* o  : leader index for each 8-dim subvector  */
     217             :     int16_t *idx_scale, /* o  : scale index for each subvector */
     218             :     const float *w      /* i  : weights for LSF quantization */
     219             : )
     220             : {
     221             :     float dist;
     222             :     const float *p_scales, *p_sigma, *p_inv_sigma;
     223             :     Word8 p_no_lead[MAX_NO_SCALES * 2];
     224             :     int16_t no_scales[2];
     225             :     int16_t mode_glb, mode, i;
     226             :     float pTmp1[M], w1[M];
     227             : 
     228         433 :     dist = 0.0f;
     229         433 :     mode = LVQ_COD_MODES + idx_cv;
     230             : 
     231             :     /* for CNG there is only one bitrate but several quantizer structures, depending on the previous VQ stage */
     232         433 :     mode_glb = START_CNG + idx_cv;
     233             : 
     234         433 :     p_sigma = sigma_MSLVQ[mode];
     235         433 :     p_inv_sigma = inv_sigma_MSLVQ[mode];
     236         433 :     p_scales = scales[mode_glb];
     237             : 
     238         433 :     no_scales[0] = 0;
     239         433 :     no_scales[1] = 0;
     240             : 
     241        1732 :     for ( i = 0; i < MAX_NO_SCALES; i++ )
     242             :     {
     243        1299 :         p_no_lead[i] = (int16_t) leaders_short[no_lead_idx[mode_glb][0]][i];
     244        1299 :         p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[no_lead_idx[mode_glb][1]][i];
     245             : 
     246        1299 :         if ( p_scales[i] > 0.0f )
     247             :         {
     248        1143 :             no_scales[0] += 1;
     249             :         }
     250        1299 :         if ( p_scales[i + MAX_NO_SCALES] > 0.0f )
     251             :         {
     252        1262 :             no_scales[1] += 1;
     253             :         }
     254             :     }
     255             : 
     256             :     /* check if LSF component permutation is needed or not */
     257         433 :     if ( cng_sort[idx_cv] )
     258             :     {
     259             :         /* change order in subvecs */
     260        7242 :         for ( i = 0; i < M; i++ )
     261             :         {
     262        6816 :             pTmp1[i] = pTmp[i];
     263        6816 :             w1[i] = w[i];
     264             :         }
     265             :         /* sorting the quantizer input and the corresponding weights according to the specified permutations */
     266         426 :         permute( pTmp1, perm_MSLVQ[idx_cv] );
     267         426 :         permute( w1, perm_MSLVQ[idx_cv] );
     268             : 
     269         426 :         dist = q_data( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     270             :         /* permute back */
     271         426 :         permute( quant, perm_MSLVQ[idx_cv] );
     272             :     }
     273             :     else
     274             :     {
     275           7 :         dist = q_data( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     276             :     }
     277             : 
     278         433 :     return dist;
     279             : }
     280             : /*-----------------------------------------------------------------*
     281             :  * prepare_data()
     282             :  *
     283             :  *-----------------------------------------------------------------*/
     284             : 
     285     1373450 : static void prepare_data(
     286             :     float *xsort,
     287             :     int16_t *sign,
     288             :     float *data,
     289             :     float *w,
     290             :     const float *w_in,
     291             :     const float *sigma,
     292             :     const float *inv_sigma,
     293             :     int16_t *p_sig )
     294             : {
     295             :     int16_t j, sig;
     296             :     float s, inv_s;
     297             : 
     298             :     /* scale data */
     299    12361050 :     for ( j = 0; j < LATTICE_DIM; j++ )
     300             :     {
     301    10987600 :         s = sigma[j];
     302    10987600 :         inv_s = inv_sigma[j];
     303    10987600 :         xsort[j] = data[j] * inv_s;
     304    10987600 :         w[j] = w_in[j] * ( s * s );
     305             :     }
     306             : 
     307     1373450 :     sig = 1;
     308    12361050 :     for ( j = 0; j < LATTICE_DIM; j++ )
     309             :     {
     310    10987600 :         if ( xsort[j] < 0 )
     311             :         {
     312     5226713 :             sign[j] = -1;
     313     5226713 :             sig = -sig;
     314     5226713 :             xsort[j] = -xsort[j];
     315             :         }
     316             :         else
     317             :         {
     318     5760887 :             sign[j] = 1;
     319             :         }
     320             :     }
     321     1373450 :     *p_sig = sig;
     322             : 
     323     1373450 :     return;
     324             : }
     325             : 
     326             : /*-----------------------------------------------------------------*
     327             :  * calculate_min_dist()
     328             :  *
     329             :  *-----------------------------------------------------------------*/
     330             : 
     331     1373450 : static float calculate_min_dist(
     332             :     float cv_pot[LATTICE_DIM],
     333             :     const float *scale,
     334             :     const float *w,
     335             :     int16_t *p_best_scale,
     336             :     int16_t *p_best_idx,
     337             :     Word8 *no_leaders,
     338             :     int16_t sig,
     339             :     int16_t *indx )
     340             : {
     341     1373450 :     int16_t k, l, j, best_scale = -1, best_idx = -1;
     342             :     float s, s2, tmp_dist, min_dist, wx[LATTICE_DIM], wind[LATTICE_DIM];
     343             :     float sum1[NO_LEADERS], sum2[NO_LEADERS];
     344             :     const float *pl_crt;
     345             :     float p;
     346             : 
     347             :     /* compare first with the origin */
     348     1373450 :     min_dist = 0.0f;
     349    12361050 :     for ( j = 0; j < LATTICE_DIM; j++ )
     350             :     {
     351             :         /* sorting the weight based on the ordering indx[] of the input vector */
     352    10987600 :         wind[j] = w[indx[j]];
     353    10987600 :         wx[j] = 2.0f * wind[j] * cv_pot[j];
     354             :     }
     355     1373450 :     s = scale[0];
     356     1373450 :     s2 = s * s;
     357     1373450 :     pl_crt = &pl_HQ[0];
     358             : 
     359    19193823 :     for ( j = 0; j < no_leaders[0]; j++ )
     360             :     {
     361    17820373 :         sum1[j] = 0;
     362    17820373 :         sum2[j] = 0;
     363    17820373 :         l = 0;
     364   116565249 :         while ( l < LATTICE_DIM - 1 )
     365             :         {
     366    98744876 :             p = *pl_crt;
     367    98744876 :             if ( p )
     368             :             {
     369    88907247 :                 sum1[j] += wx[l] * p;
     370    88907247 :                 sum2[j] += wind[l] * p * p;
     371    88907247 :                 pl_crt++;
     372    88907247 :                 l++;
     373             :             }
     374             :             else
     375             :             {
     376     9837629 :                 pl_crt += LATTICE_DIM - l;
     377     9837629 :                 l = LATTICE_DIM;
     378             :             }
     379             :         }
     380    17820373 :         if ( ( l - LATTICE_DIM + 1 ) == 0 )
     381             :         {
     382     7982744 :             p = *pl_crt;
     383             :             /* if it went up to 7th position */
     384     7982744 :             if ( pl_par[j] )
     385             :             {
     386     6389612 :                 if ( sig != pl_par[j] )
     387             :                 {
     388     3174011 :                     sum1[j] -= wx[l] * p;
     389     3174011 :                     sum2[j] += wind[l] * p * p;
     390     3174011 :                     pl_crt++;
     391             :                 }
     392             :                 else
     393             :                 {
     394     3215601 :                     sum1[j] += wx[l] * p;
     395     3215601 :                     sum2[j] += wind[l] * p * p;
     396     3215601 :                     pl_crt++;
     397             :                 }
     398             :             }
     399             :             else
     400             :             {
     401     1593132 :                 sum1[j] += wx[l] * p;
     402     1593132 :                 sum2[j] += wind[l] * p * p;
     403     1593132 :                 pl_crt++;
     404             :             }
     405             :         }
     406             :         /* distance between the potential codevector and the input calculated in ordered space */
     407    17820373 :         tmp_dist = s2 * sum2[j] - s * sum1[j];
     408    17820373 :         if ( tmp_dist < min_dist )
     409             :         {
     410     6288213 :             min_dist = tmp_dist;
     411     6288213 :             best_scale = 0;
     412     6288213 :             best_idx = j;
     413             :         }
     414             :     }
     415             : 
     416     1373450 :     tmp_dist = min_dist + 1.0f;
     417             : 
     418     4120350 :     for ( k = 1; k < MAX_NO_SCALES; k++ )
     419             :     {
     420     2746900 :         s = scale[k];
     421             : 
     422     2746900 :         if ( s > 0.0f )
     423             :         {
     424     2384643 :             s2 = s * s;
     425    24999894 :             for ( j = 0; j < no_leaders[k]; j++ )
     426             :             {
     427             :                 /* distance between the potential codevector and the input calculated in ordered space */
     428    22615251 :                 tmp_dist = s2 * sum2[j] - s * sum1[j];
     429    22615251 :                 if ( tmp_dist < min_dist )
     430             :                 {
     431     1138763 :                     min_dist = tmp_dist;
     432     1138763 :                     best_scale = k;
     433     1138763 :                     best_idx = j;
     434             :                 }
     435             :             }
     436             :         }
     437             :     }
     438     1373450 :     *p_best_scale = best_scale;
     439     1373450 :     *p_best_idx = best_idx;
     440             : 
     441     1373450 :     return min_dist;
     442             : }
     443             : 
     444             : 
     445             : /*-----------------------------------------------------------------*
     446             :  * quantize_data()
     447             :  *
     448             :  *-----------------------------------------------------------------*/
     449             : 
     450     1389704 : static float quantize_data(
     451             :     float *data,            /* i  : residual LSF data to quantize */
     452             :     const float *w_in,      /* i  : weights                       */
     453             :     float *qin,             /* o  : quantized output (scaled)     */
     454             :     float *cv_out,          /* o  : codevectors                   */
     455             :     int16_t *idx_lead,      /* o  : leader indexes for each subvector */
     456             :     int16_t *idx_scale,     /* o  : scale indexes for each subvector  */
     457             :     const float *sigma,     /* i  : standard deviation             */
     458             :     const float *inv_sigma, /* i  : inverse of standard deviation  */
     459             :     const float *scale,     /* i  : scales for each truncation     */
     460             :     Word8 *no_leaders       /* i  : number of leader vectors for each truncation of each subvector */
     461             : )
     462             : {
     463             :     int16_t j;
     464     1389704 :     float w[LATTICE_DIM], min_dist = 0;
     465     1389704 :     int16_t best_idx = 0, best_scale = -1;
     466             :     float s;
     467             :     float cv_pot[LATTICE_DIM];
     468             :     int16_t indx[LATTICE_DIM];
     469             :     int16_t sig, sign[LATTICE_DIM];
     470             :     int16_t smallest;
     471             :     int16_t id[LATTICE_DIM];
     472             : 
     473     1389704 :     if ( scale[0] > 0.0f )
     474             :     {
     475     1373450 :         prepare_data( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
     476             :         /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
     477     1373450 :         sort_desc_ind( cv_pot, LATTICE_DIM, indx );
     478     1373450 :         smallest = indx[LATTICE_DIM - 1];
     479     1373450 :         min_dist = calculate_min_dist( cv_pot, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
     480     1373450 :         if ( best_scale > -1 )
     481             :         {
     482    12276504 :             for ( j = 0; j < LATTICE_DIM; j++ )
     483             :             {
     484    10912448 :                 id[indx[j]] = j;
     485             :             }
     486    12276504 :             for ( j = 0; j < LATTICE_DIM; j++ )
     487             :             {
     488    10912448 :                 cv_out[j] = sign[j] * pl_HQ[best_idx * LATTICE_DIM + id[j]];
     489             :             }
     490     1364056 :             if ( pl_par[best_idx] )
     491             :             {
     492      576530 :                 if ( sig - pl_par[best_idx] != 0 )
     493             :                 {
     494      150096 :                     cv_out[smallest] = -cv_out[smallest];
     495             :                 }
     496             :             }
     497     1364056 :             s = scale[best_scale];
     498    12276504 :             for ( j = 0; j < LATTICE_DIM; j++ )
     499             :             {
     500    10912448 :                 qin[j] = cv_out[j] * s * sigma[j];
     501             :             }
     502     1364056 :             *idx_lead = best_idx;
     503     1364056 :             *idx_scale = best_scale;
     504             :         }
     505             :         else
     506             :         {
     507       84546 :             for ( j = 0; j < LATTICE_DIM; j++ )
     508             :             {
     509       75152 :                 qin[j] = 0;
     510             :             }
     511             : 
     512        9394 :             *idx_lead = best_idx;
     513        9394 :             *idx_scale = best_scale;
     514             :         }
     515             :     }
     516             :     else
     517             :     {
     518       16254 :         *idx_lead = 0;
     519       16254 :         *idx_scale = -1;
     520      146286 :         for ( j = 0; j < LATTICE_DIM; j++ )
     521             :         {
     522      130032 :             cv_out[j] = 0;
     523      130032 :             qin[j] = 0;
     524             :         }
     525             :     }
     526             : 
     527     1389704 :     return min_dist;
     528             : }
     529             : 
     530             : /*-----------------------------------------------------------------*
     531             :  * index_lvq()
     532             :  *
     533             :  * sorts in descending order and computes indices in the sorted vector
     534             :  *-----------------------------------------------------------------*/
     535             : 
     536      346808 : void index_lvq(
     537             :     float *quant,       /* i  : codevector to be indexed (2 8-dim subvectors)                      */
     538             :     int16_t *idx_lead,  /* i  : leader class index for each subvector                              */
     539             :     int16_t *idx_scale, /* i  : scale index for each subvector                                     */
     540             :     const int16_t mode, /* i  : integer signaling the quantizer structure for the current bitrate */
     541             :     int16_t *index,     /* o  : encoded index (represented on 3 short each with 15 bits )          */
     542             :     const int16_t prediction_flag )
     543             : {
     544             :     UWord32 index1, index2, tmp, idx[2];
     545             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     546             : 
     547             : 
     548      346808 :     index1 = 0;
     549      346808 :     create_offset( offset_scale1, offset_scale2, mode, prediction_flag );
     550             : 
     551             :     /* for first subvector */
     552      346808 :     if ( idx_scale[0] > -1 )
     553             :     {
     554             :         /* create offset */
     555      346655 :         index1 = encode_comb( quant, idx_lead[0] ) + table_no_cv[idx_lead[0]] + offset_scale1[idx_scale[0]];
     556             :     }
     557             : 
     558             :     /* for second subvector */
     559      346808 :     index2 = 0;
     560      346808 :     if ( idx_scale[1] > -1 )
     561             :     {
     562      333277 :         index2 = encode_comb( &quant[LATTICE_DIM], idx_lead[1] ) + table_no_cv[idx_lead[1]] + offset_scale2[idx_scale[1]];
     563             :     }
     564             : 
     565      346808 :     multiply32_32_64( index1, offset_scale2[MAX_NO_SCALES], idx );
     566             : 
     567      346808 :     tmp = idx[0] + index2;
     568      346808 :     if ( tmp < idx[0] || tmp < index2 )
     569             :     {
     570           1 :         idx[1] += 1;
     571             :     }
     572             : 
     573      346808 :     idx[0] = tmp;
     574             : 
     575             :     /* convert to 3 short */
     576      346808 :     index[0] = (int16_t) ( ( idx[0] ) & ( 0xffff >> 1 ) );
     577      346808 :     index[1] = (int16_t) ( ( idx[0] ) >> 15 ) & ( 0xffff >> 1 );
     578      346808 :     index[2] = (int16_t) ( ( idx[0] ) >> 30 ) + ( ( ( idx[1] ) << 2 ) & ( 0xffff >> 1 ) );
     579             : 
     580      346808 :     return;
     581             : }
     582             : 
     583             : 
     584             : /*-----------------------------------------------------------------*
     585             :  * encode_comb()
     586             :  *
     587             :  * creates an index for the lattice codevector
     588             :  *-----------------------------------------------------------------*/
     589             : 
     590             : /*! r: index of the absolute valued codevector */
     591      683270 : static UWord32 encode_comb(
     592             :     float *cv,             /* i  : codevector to be indexed               */
     593             :     const int16_t idx_lead /* i  : leader class index, to know the values */
     594             : )
     595             : {
     596             :     UWord32 idx_sign;
     597             :     UWord32 idx_ld_class;
     598             : 
     599      683270 :     idx_sign = encode_sign_pc1( pl_par[idx_lead], cv );
     600      683270 :     idx_ld_class = index_leaders( cv, idx_lead, LATTICE_DIM );
     601             : 
     602      683270 :     return idx_sign * (UWord32) pi0[idx_lead] + idx_ld_class;
     603             : }
     604             : 
     605             : 
     606             : /*-----------------------------------------------------------------*
     607             :  * index_leaders()
     608             :  *
     609             :  * gives the index in a class of leaders without considering the sign yet
     610             :  *-----------------------------------------------------------------*/
     611             : 
     612             : /*! r: index */
     613      683270 : static UWord32 index_leaders(
     614             :     float *cv,        /* i  : codevector to be indexed */
     615             :     int16_t idx_lead, /* i  : leader class index       */
     616             :     const int16_t dim /* i  : vector dimension         */
     617             : )
     618             : {
     619             :     UWord32 index;
     620             :     int16_t p[LATTICE_DIM];
     621             :     int16_t i, no_vals_loc, nr, dim_loc;
     622             :     float cv_copy[LATTICE_DIM], val_crt;
     623             : 
     624      683270 :     no_vals_loc = no_vals[idx_lead];
     625             : 
     626      683270 :     if ( no_vals_loc == 1 )
     627             :     {
     628       71474 :         return 0;
     629             :     }
     630             : 
     631     5506164 :     for ( i = 0; i < LATTICE_DIM; i++ )
     632             :     {
     633     4894368 :         cv_copy[i] = (float) fabs( cv[i] );
     634             :     }
     635             : 
     636      611796 :     val_crt = vals[idx_lead][0];
     637      611796 :     nr = find_pos( cv_copy, dim, val_crt, p );
     638      611796 :     index = c2idx( LATTICE_DIM, p, nr );
     639             : 
     640      611796 :     if ( no_vals_loc == 2 )
     641             :     {
     642      423889 :         return index;
     643             :     }
     644             : 
     645      187907 :     take_out_val( cv_copy, cv_copy, val_crt, dim );
     646      187907 :     dim_loc = dim - no_vals_ind[idx_lead][0];
     647      187907 :     index *= C_VQ[dim_loc][no_vals_ind[idx_lead][1]];
     648      187907 :     val_crt = vals[idx_lead][1];
     649      187907 :     nr = find_pos( cv_copy, dim_loc, val_crt, p );
     650      187907 :     index += c2idx( dim_loc, p, nr );
     651             : 
     652      187907 :     if ( no_vals_loc == 3 )
     653             :     {
     654      186539 :         return index;
     655             :     }
     656             : 
     657        1368 :     take_out_val( cv_copy, cv_copy, val_crt, dim_loc );
     658        1368 :     dim_loc = dim_loc - no_vals_ind[idx_lead][1];
     659        1368 :     index *= C_VQ[dim_loc][no_vals_ind[idx_lead][2]];
     660        1368 :     val_crt = vals[idx_lead][2];
     661        1368 :     nr = find_pos( cv_copy, dim_loc, val_crt, p );
     662        1368 :     index += c2idx( dim_loc, p, nr );
     663             :     /* maximum 4 values */
     664             : 
     665        1368 :     return index;
     666             : }
     667             : 
     668             : /*-----------------------------------------------------------------*
     669             :  * find_pos()
     670             :  *
     671             :  * Finds the positions in vector c for which the vector components are equal to 'arg'.
     672             :  * It returns the number of such positions and their values in the array 'p'.
     673             :  *-----------------------------------------------------------------*/
     674             : 
     675             : /*! r: number of positions */
     676      801071 : int16_t find_pos(
     677             :     float *c,          /* i  : input vector                 */
     678             :     const int16_t len, /* i  : input vector dim             */
     679             :     float arg,         /* i  : argument to be compared with */
     680             :     int16_t *p         /* o  : vector of positions          */
     681             : )
     682             : {
     683      801071 :     int16_t i = 0, j = 0;
     684             : 
     685             :     /* how many (j) and which (p) positions are in the relation pred(arg,c[i]) */
     686     6971927 :     for ( i = 0; i < len; i++ )
     687             :     {
     688     6170856 :         if ( (int16_t) ( arg * 10 ) == (int16_t) ( c[i] * 10 ) )
     689             :         {
     690     2142838 :             p[j++] = i;
     691             :         }
     692             :     }
     693             : 
     694      801071 :     return j;
     695             : }
     696             : 
     697             : /*-----------------------------------------------------------------*
     698             :  * encode_sign_pc1()
     699             :  *
     700             :  * Creates an index for signs of the significant codevector components
     701             :  * Gives the index of the signs - binary representation where negative sign stands for 1
     702             :  * and positive sign stands for 1.
     703             :  *-----------------------------------------------------------------*/
     704             : 
     705             : /*! r: index of signs */
     706      683270 : static UWord32 encode_sign_pc1(
     707             :     const int16_t parity, /* i  : parity of the leader class to which the codevector belongs */
     708             :     float *cv             /* i  : input codevector                                           */
     709             : )
     710             : {
     711             :     UWord32 idx_sign;
     712      683270 :     int16_t cnt, i, len = LATTICE_DIM;
     713             : 
     714      683270 :     idx_sign = 0;
     715      683270 :     cnt = 0;
     716             : 
     717      683270 :     if ( parity )
     718             :     {
     719      287828 :         len -= 1;
     720             :     }
     721             : 
     722     5861602 :     for ( i = 0; i < len; i++ )
     723             :     {
     724     5178332 :         if ( cv[i] < 0 )
     725             :         {
     726     1807244 :             idx_sign += ( 1 << cnt );
     727     1807244 :             cnt++;
     728             :         }
     729             : 
     730     5178332 :         if ( cv[i] > 0 )
     731             :         {
     732     1931696 :             cnt++;
     733             :         }
     734             :     }
     735             : 
     736      683270 :     return idx_sign;
     737             : }
     738             : 
     739             : /*-----------------------------------------------------------------*
     740             :  * take_out_val()
     741             :  *
     742             :  * removes the value val from the vector v
     743             :  *-----------------------------------------------------------------*/
     744             : 
     745      189275 : static void take_out_val(
     746             :     float *v,         /* i  : input vector                       */
     747             :     float *v_out,     /* o  : output vector without the value val*/
     748             :     const float val,  /* i  : value to be removed                */
     749             :     const int16_t len /* i  : input vector length                */
     750             : )
     751             : {
     752             :     int16_t i, cnt;
     753             : 
     754      189275 :     cnt = 0;
     755             : 
     756     1702107 :     for ( i = 0; i < len; i++ )
     757             :     {
     758     1512832 :         if ( (int16_t) ( v[i] * 10 ) != (int16_t) ( val * 10 ) )
     759             :         {
     760     1276488 :             v_out[cnt++] = v[i];
     761             :         }
     762             :     }
     763             : 
     764      189275 :     return;
     765             : }
     766             : 
     767             : 
     768             : /*-----------------------------------------------------------------*
     769             :  * c2idx()
     770             :  *
     771             :  *-----------------------------------------------------------------*/
     772             : 
     773     2142838 : static UWord32 c2idx(
     774             :     const int16_t n,
     775             :     int16_t *p,
     776             :     const int16_t k )
     777             : {
     778             :     int16_t i, p0;
     779             :     UWord32 skip;
     780             : 
     781     2142838 :     if ( k == 1 )
     782             :     {
     783      801071 :         return (UWord32) ( p[0] );
     784             :     }
     785             :     else
     786             :     {
     787     1341767 :         skip = 0;
     788     2412734 :         for ( i = 1; i <= p[0]; i++ )
     789             :         {
     790     1070967 :             skip += C_VQ[n - i][k - 1];
     791             :         }
     792             : 
     793     1341767 :         p0 = p[0];
     794     4072735 :         for ( i = 1; i < k; i++ )
     795             :         {
     796     2730968 :             p[i] -= p0 + 1;
     797             :         }
     798             : 
     799     1341767 :         return skip + c2idx( n - p0 - 1, p + 1, k - 1 );
     800             :     }
     801             : }
     802             : 
     803             : /*-----------------------------------------------------------------*
     804             :  * index_lvq_SHB()
     805             :  *
     806             :  *-----------------------------------------------------------------*/
     807             : 
     808        3338 : UWord32 index_lvq_SHB(
     809             :     const int16_t idx_lead,
     810             :     const int16_t idx_scale,
     811             :     const int16_t nbits,
     812             :     float *lat_cv,
     813             :     const int16_t mode )
     814             : {
     815             :     uint16_t i;
     816             :     const Word8 *p_no_lead;
     817             :     UWord32 index;
     818             : 
     819        3338 :     if ( mode == 0 )
     820             :     {
     821        3338 :         p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3];
     822             :     }
     823             :     else
     824             :     {
     825           0 :         p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3];
     826             :     }
     827             : 
     828        3338 :     index = 0;
     829        3338 :     if ( idx_lead > -1 )
     830             :     {
     831        3338 :         index = 1;
     832        4389 :         for ( i = 0; i < idx_scale; i++ )
     833             :         {
     834        1051 :             index += table_no_cv[p_no_lead[i]];
     835             :         }
     836             : 
     837        3338 :         if ( idx_lead > 0 )
     838             :         {
     839        3249 :             index += table_no_cv[idx_lead];
     840             :         }
     841             : 
     842        3338 :         index += encode_comb( lat_cv, idx_lead );
     843             :     }
     844             : 
     845        3338 :     return index;
     846             : }

Generated by: LCOV version 1.14