LCOV - code coverage report
Current view: top level - lib_enc - mslvq_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ cede165d26d1b794bfc5f5f6f9ec19d4d64a9a3b Lines: 473 526 89.9 %
Date: 2025-11-01 03:16:20 Functions: 18 20 90.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "cnst.h"
       8             : #include "rom_com.h"
       9             : #include "stl.h"
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "basop32.h"     /* Function prototypes                    */
      12             : #include "prot_fx_enc.h" /* Function prototypes                    */
      13             : 
      14             : 
      15             : /*-----------------------------------------------------------------*
      16             :  * Local functions
      17             :  *-----------------------------------------------------------------*/
      18             : 
      19             : static Word32 quantize_data_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, Word16 no_scales, const Word16 *no_lead );
      20             : Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead );
      21             : static Word32 q_data_fx( Word16 *pTmp1, const Word16 *w1, Word16 *quant, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *p_sigma, const Word16 *p_inv_sigma, const Word16 *p_scales, Word16 *p_no_scales, const Word16 *p_no_lead );
      22             : static void prepare_data_fx( Word16 *xsort, Word16 *sign, Word16 *data, Word32 *w, const Word16 *w_in, const Word16 *sigma, const Word16 *inv_sigma, Word16 *p_sig );
      23             : static Word32 calculate_min_dist_fx( Word16 cv_pot[LATTICE_DIM], Word16 no_scales, const Word16 *scale, const Word32 *w, Word16 *p_best_scale, Word16 *p_best_idx, const Word16 *no_leaders, Word16 sig, Word16 *indx );
      24             : static Word16 find_pos_fx( Word16 *c, Word16 len, Word16 arg, Word16 *p );
      25             : static void take_out_val_fx( Word16 *v, Word16 *v_out, Word16 val, Word16 len );
      26             : static Word16 index_leaders_fx( Word16 *cv, Word16 idx_lead, Word16 dim );
      27             : static Word16 c2idx_fx( Word16 n, Word16 *p, Word16 k );
      28             : static Word16 encode_sign_pc1_fx( Word16 parity, Word16 *cv );
      29             : Word32 encode_comb_fx( Word16 *cv, Word16 idx_lead );
      30             : static void sort_desc_ind_fx( Word16 *s, Word16 len, Word16 *ind );
      31             : 
      32             : 
      33             : /*-----------------------------------------------------------------*
      34             :  * mslvq_fx()
      35             :  *
      36             :  * Encodes the LSF residual
      37             :  *-----------------------------------------------------------------*/
      38        5016 : Word32 mslvq_fx(
      39             :     Word16 *pTmp,      /* i  : M-dimensional input vector  x2.56*/
      40             :     Word16 *quant,     /* o  : quantized vector  x2.56*/
      41             :     Word16 *cv_out,    /* o  : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
      42             :     Word16 *idx_lead,  /* o  : leader index for each 8-dim subvector  */
      43             :     Word16 *idx_scale, /* o  : scale index for each subvector */
      44             :     Word16 *w,         /* i  : weights for LSF quantization  Q10*/
      45             :     Word16 mode,       /* i  : number indicating the coding type (V/UV/G...)*/
      46             :     Word16 mode_glb,   /* i  : LVQ coding mode */
      47             :     Word16 pred_flag,  /* i  : prediction flag (0: safety net, 1,2 - predictive  )*/
      48             :     Word16 no_scales[][2] )
      49             : {
      50             :     Word32 dist, L_tmp;
      51             :     const Word16 *p_scales, *p_sigma, *p_inv_sigma;
      52             :     const Word16 *p_no_lead;
      53             :     Word16 *p_no_scales;
      54             : 
      55             : 
      56        5016 :     dist = L_deposit_l( 0 );
      57        5016 :     p_no_scales = no_scales[mode_glb];
      58        5016 :     move16();
      59             : 
      60        5016 :     IF( pred_flag == 0 )
      61             :     {
      62        1196 :         p_sigma = sigma_MSLVQ_fx[mode]; // Qlog2(2.56)
      63             :         /* inverse sigma is precomputed to save complexity */
      64        1196 :         p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
      65        1196 :         p_scales = scales_fx[mode_glb];         // Q11
      66        1196 :         p_no_lead = no_lead_fx[mode_glb];       // Q0
      67             :     }
      68             :     ELSE
      69             :     {
      70        3820 :         p_sigma = sigma_p_fx[mode]; // Qlog2(2.56)
      71             :         /* inverse sigma is precomputed to save complexity */
      72        3820 :         p_inv_sigma = inv_sigma_p_fx[mode]; // Q15
      73        3820 :         p_scales = scales_p_fx[mode_glb];   // Q11
      74        3820 :         p_no_lead = no_lead_p_fx[mode_glb]; // Q0
      75             :     }
      76             : 
      77             :     /* first subvector */
      78        5016 :     dist = quantize_data_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale,
      79        5016 :                              p_sigma, p_inv_sigma, p_scales, p_no_scales[0], p_no_lead );
      80             :     /* second subvector */
      81        5016 :     L_tmp = quantize_data_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM,
      82             :                               cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
      83             :                               p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
      84        5016 :                               p_no_scales[1], p_no_lead + MAX_NO_SCALES );
      85             : 
      86        5016 :     dist = L_add( dist, L_tmp );
      87             : 
      88        5016 :     return dist;
      89             : }
      90             : 
      91             : 
      92             : /*-----------------------------------------------------------------*
      93             :  * q_data()
      94             :  *
      95             :  * (used for LSF quantization in CNG)
      96             :  *-----------------------------------------------------------------*/
      97             : 
      98           0 : static Word32 q_data_fx(
      99             :     Word16 *pTmp1,             /* i: M-dimensional input vector x2.56                         */
     100             :     const Word16 *w1,          /* i: M-dimensional weight vector    Q8                        */
     101             :     Word16 *quant,             /* o: quantized vector            x2.56                        */
     102             :     Word16 *cv_out,            /* o: non-scaled lattice codevector x2.56                      */
     103             :     Word16 *idx_lead,          /* o: leader indexes for each subvector                        */
     104             :     Word16 *idx_scale,         /* o: scale indexes for each subvector                         */
     105             :     const Word16 *p_sigma,     /* i: standard deviation x2.56                                 */
     106             :     const Word16 *p_inv_sigma, /* i: inverse standard deviation Q15                           */
     107             :     const Word16 *p_scales,    /* i: scale values Q11                                         */
     108             :     Word16 *p_no_scales,       /* i: number of scales/truncations for each subvector          */
     109             :     const Word16 *p_no_lead    /* i: number of leaders for each truncation and each subvector */
     110             : )
     111             : {
     112             :     Word32 dist, L_tmp;
     113             :     /* first subvector */
     114           0 :     dist = quantize_data_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale,
     115           0 :                              p_sigma, p_inv_sigma, p_scales, p_no_scales[0], p_no_lead );
     116             :     /* second subvector */
     117           0 :     L_tmp = quantize_data_fx( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM,
     118             :                               quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
     119             :                               p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
     120           0 :                               p_no_scales[1], p_no_lead + MAX_NO_SCALES );
     121             : 
     122           0 :     dist = L_add( dist, L_tmp );
     123             : 
     124           0 :     return dist;
     125             : }
     126             : 
     127         447 : static Word32 q_data_ivas_fx(
     128             :     Word16 *pTmp1,             /* i: M-dimensional input vector x2.56                         */
     129             :     const Word16 *w1,          /* i: M-dimensional weight vector    Q8                        */
     130             :     Word16 *quant,             /* o: quantized vector            x2.56                        */
     131             :     Word16 *cv_out,            /* o: non-scaled lattice codevector x2.56                      */
     132             :     Word16 *idx_lead,          /* o: leader indexes for each subvector                        */
     133             :     Word16 *idx_scale,         /* o: scale indexes for each subvector                         */
     134             :     const Word16 *p_sigma,     /* i: standard deviation x2.56                                 */
     135             :     const Word16 *p_inv_sigma, /* i: inverse standard deviation Q15                           */
     136             :     const Word16 *p_scales,    /* i: scale values Q11                                         */
     137             :     const Word16 *p_no_lead    /* i: number of leaders for each truncation and each subvector */
     138             : )
     139             : {
     140             :     Word32 dist, L_tmp;
     141             :     /* first subvector */
     142         447 :     dist = quantize_data_ivas_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale,
     143             :                                   p_sigma, p_inv_sigma, p_scales, p_no_lead );
     144             :     /* second subvector */
     145         447 :     L_tmp = quantize_data_ivas_fx( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM,
     146             :                                    quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
     147             :                                    p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
     148             :                                    p_no_lead + MAX_NO_SCALES );
     149             : 
     150         447 :     dist = L_add( dist, L_tmp );
     151             : 
     152         447 :     return dist;
     153             : }
     154             : /*-----------------------------------------------------------------*
     155             :  * mslvq_cng()
     156             :  *
     157             :  * Encodes the LSF residual in SID frames with LVQ
     158             :  * LVQ has separate codebook for each individual first stage index
     159             :  *-----------------------------------------------------------------*/
     160             : 
     161             : 
     162           0 : Word32 mslvq_cng_fx(
     163             :     Word16 idx_cv,     /* i  : index of cv from previous stage                                  */
     164             :     Word16 *pTmp,      /* i  : 16 dimensional input vector                                 x2.56*/
     165             :     Word16 *quant,     /* o  : quantized vector                                            x2.56*/
     166             :     Word16 *cv_out,    /* o  : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
     167             :     Word16 *idx_lead,  /* o  : leader index for each 8-dim subvector                            */
     168             :     Word16 *idx_scale, /* o  : scale index for each subvector                                   */
     169             :     const Word16 *w,   /* i  : weights for LSF quantization                                  Q10*/
     170             :     Word16 *no_scales )
     171             : {
     172             :     Word32 dist;
     173             :     const Word16 *p_scales, *p_sigma, *p_inv_sigma;
     174             :     const Word16 *p_no_lead;
     175             :     Word16 *p_no_scales;
     176             :     Word16 mode_glb, mode, i;
     177             :     Word16 pTmp1[M], w1[M];
     178             : 
     179           0 :     dist = L_deposit_l( 0 );
     180           0 :     mode = add( LVQ_COD_MODES, idx_cv );
     181           0 :     move16();
     182             : 
     183             :     /* for CNG there is only one bitrate but several lattice quantizer structures,
     184             :        depending on the previous VQ stage */
     185           0 :     mode_glb = add( START_CNG, idx_cv );
     186           0 :     move16();
     187             : 
     188           0 :     p_sigma = sigma_MSLVQ_fx[mode]; // x2.56
     189           0 :     move16();
     190           0 :     p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
     191           0 :     move16();
     192           0 :     p_scales = scales_fx[mode_glb]; // Q11
     193           0 :     move16();
     194           0 :     p_no_lead = no_lead_fx[mode_glb]; // Q0
     195           0 :     move16();
     196           0 :     p_no_scales = &no_scales[( mode_glb << 1 )];
     197           0 :     move16();
     198             : 
     199             :     /* check if LSF component permutation is needed or not */
     200           0 :     IF( cng_sort[idx_cv] )
     201             :     {
     202           0 :         FOR( i = 0; i < M; i++ )
     203             :         {
     204           0 :             pTmp1[i] = pTmp[i];
     205           0 :             move16();
     206           0 :             w1[i] = w[i];
     207           0 :             move16();
     208             :         }
     209             :         /* sorting the quantizer input and the corresponding weights according to the specified permutations */
     210           0 :         permute_fx( pTmp1, perm_MSLVQ[idx_cv] );
     211           0 :         permute_fx( w1, perm_MSLVQ[idx_cv] );
     212             : 
     213           0 :         dist = q_data_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_scales, p_no_lead );
     214             :         /* permute back */
     215           0 :         permute_fx( quant, perm_MSLVQ[idx_cv] );
     216             :     }
     217             :     ELSE
     218             :     {
     219           0 :         dist = q_data_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_scales, p_no_lead );
     220             :     }
     221             : 
     222           0 :     return dist;
     223             : }
     224             : 
     225         447 : Word32 mslvq_cng_ivas_fx(
     226             :     Word16 idx_cv,     /* i  : index of cv from previous stage                                  */
     227             :     Word16 *pTmp,      /* i  : 16 dimensional input vector                                 x2.56*/
     228             :     Word16 *quant,     /* o  : quantized vector                                            x2.56*/
     229             :     Word16 *cv_out,    /* o  : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
     230             :     Word16 *idx_lead,  /* o  : leader index for each 8-dim subvector                            */
     231             :     Word16 *idx_scale, /* o  : scale index for each subvector                                   */
     232             :     const Word16 *w    /* i  : weights for LSF quantization                                  Q10*/
     233             : )
     234             : {
     235             :     Word32 dist;
     236             :     const Word16 *p_scales, *p_sigma, *p_inv_sigma;
     237             :     Word16 no_scales[2];
     238             :     Word16 mode_glb, mode, i;
     239             :     Word16 pTmp1[M], w1[M];
     240             :     Word16 p_no_lead[MAX_NO_SCALES * 2];
     241             : 
     242         447 :     dist = L_deposit_l( 0 );
     243         447 :     mode = add( LVQ_COD_MODES, idx_cv );
     244         447 :     move16();
     245             : 
     246             :     /* for CNG there is only one bitrate but several lattice quantizer structures,
     247             :        depending on the previous VQ stage */
     248         447 :     mode_glb = add( START_CNG_IVAS, idx_cv );
     249         447 :     move16();
     250             : 
     251         447 :     p_sigma = sigma_MSLVQ_fx[mode]; // x2.56
     252         447 :     move16();
     253         447 :     p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
     254         447 :     move16();
     255         447 :     p_scales = scales_ivas_fx[mode_glb]; // Q11
     256         447 :     move16();
     257             : 
     258         447 :     no_scales[0] = 0;
     259         447 :     no_scales[1] = 0;
     260             : 
     261        1788 :     FOR( i = 0; i < MAX_NO_SCALES; i++ )
     262             :     {
     263        1341 :         p_no_lead[i] = (Word16) leaders_short[no_lead_idx[mode_glb][0]][i];
     264        1341 :         p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[no_lead_idx[mode_glb][1]][i];
     265             : 
     266        1341 :         IF( p_scales[i] > 0 )
     267             :         {
     268        1171 :             no_scales[0] += 1;
     269             :         }
     270        1341 :         IF( p_scales[i + MAX_NO_SCALES] > 0 )
     271             :         {
     272        1304 :             no_scales[1] += 1;
     273             :         }
     274             :     }
     275             : 
     276             :     /* check if LSF component permutation is needed or not */
     277         447 :     IF( cng_sort[idx_cv] )
     278             :     {
     279        7480 :         FOR( i = 0; i < M; i++ )
     280             :         {
     281        7040 :             pTmp1[i] = pTmp[i];
     282        7040 :             move16();
     283        7040 :             w1[i] = w[i];
     284        7040 :             move16();
     285             :         }
     286             :         /* sorting the quantizer input and the corresponding weights according to the specified permutations */
     287         440 :         permute_fx( pTmp1, perm_MSLVQ[idx_cv] );
     288         440 :         permute_fx( w1, perm_MSLVQ[idx_cv] );
     289             : 
     290         440 :         dist = q_data_ivas_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     291             :         /* permute back */
     292         440 :         permute_fx( quant, perm_MSLVQ[idx_cv] );
     293             :     }
     294             :     ELSE
     295             :     {
     296           7 :         dist = q_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
     297             :     }
     298             : 
     299         447 :     return dist;
     300             : }
     301             : /*-----------------------------------------------------------------*
     302             :  * prepare_data_fx()
     303             :  *
     304             :  *-----------------------------------------------------------------*/
     305     1380125 : static void prepare_data_fx(
     306             :     Word16 *xsort,           /* o: normalized absolute valued input vector Q10 */
     307             :     Word16 *sign,            /* o: signs of input vector                       */
     308             :     Word16 *data,            /* i: input vector                          x2.56 */
     309             :     Word32 *w,               /* o; scaled weights                          Q-4 */
     310             :     const Word16 *w_in,      /* i: input weights                            Q8 */
     311             :     const Word16 *sigma,     /* i: standard deviation                    x2.56 */
     312             :     const Word16 *inv_sigma, /* i: inverse standard deviation              Q15 */
     313             :     Word16 *p_sig            /* o: parity of input vector                      */
     314             : )
     315             : {
     316             :     Word16 j, sig;
     317             :     Word16 s, inv_s;
     318             :     Word32 L_in;
     319             : 
     320             : 
     321             :     /* scale data */
     322    12421125 :     FOR( j = 0; j < LATTICE_DIM; j++ )
     323             :     {
     324    11041000 :         inv_s = inv_sigma[j];
     325    11041000 :         move16(); /*Q15 */
     326    11041000 :         s = sigma[j];
     327    11041000 :         move16(); /*Qx2.56 */
     328    11041000 :         L_in = L_mult0( inv_s, data[j] );
     329    11041000 :         move16();                                 /*x2.56 + Q15 */
     330    11041000 :         L_in = Mult_32_16( L_in, 100 );           /*  100 = 25*4 Q15+6+4 = Q25 -Q15 = Q8 */
     331    11041000 :         xsort[j] = extract_l( L_shl( L_in, 2 ) ); /*Q10 */
     332             : 
     333    11041000 :         w[j] = L_shr( L_mult0( s, s ), 4 );                          /*x2.56 + x2.56 - Q4 */
     334    11041000 :         w[j] = Mult_32_16( L_shl( w_in[j], 5 ), extract_l( w[j] ) ); /*Q6 + Q5 +x2.56 +x2.56- Q15 */
     335    11041000 :         w[j] = L_shl( w[j], 2 );
     336             :     }
     337             : 
     338             : 
     339     1380125 :     sig = 1;
     340     1380125 :     move16();
     341    12421125 :     FOR( j = 0; j < LATTICE_DIM; j++ ){
     342    11041000 :         IF( xsort[j] < 0 ){
     343     5223502 :             sign[j] = -1;
     344     5223502 :     move16();
     345     5223502 :     sig = negate( sig );
     346     5223502 :     move16();
     347     5223502 :     xsort[j] = negate( xsort[j] ); /*Q10 */
     348             : }
     349             : ELSE
     350             : {
     351     5817498 :     sign[j] = 1;
     352     5817498 :     move16();
     353             : }
     354             : }
     355     1380125 : *p_sig = sig;
     356     1380125 : move16();
     357             : 
     358     1380125 : return;
     359             : }
     360             : 
     361             : /*-----------------------------------------------------------------*
     362             :  * calculate_min_dist()
     363             :  *
     364             :  *-----------------------------------------------------------------*/
     365     1380125 : static Word32 calculate_min_dist_fx(
     366             :     Word16 cv_pot[LATTICE_DIM], /* i: sorted absolute valued normalized input vector            Q10 */
     367             :     Word16 no_scales,           /* i: number of scales                                              */
     368             :     const Word16 *scale,        /* i: scale values                                              Q11 */
     369             :     const Word32 *w,            /* i: scaled weights                                            Q-4 */
     370             :     Word16 *p_best_scale,       /* o: pointer to obtained scale value                               */
     371             :     Word16 *p_best_idx,         /* o: pointer to obtained leader index                              */
     372             :     const Word16 *no_leaders,   /* i: number of leaders for each truncation                         */
     373             :     Word16 sig,                 /* i: parity of input vector                                        */
     374             :     Word16 *indx                /* i: permutation vector indicating the order of the sorted input vector */
     375             : )
     376             : {
     377     1380125 :     Word16 k, l, j, best_scale = -1, best_idx = -1;
     378             :     Word16 s, p;
     379             :     Word32 tmp_dist, min_dist;
     380             :     Word32 w_norm[LATTICE_DIM];
     381             : 
     382             : 
     383             :     Word16 wx[LATTICE_DIM];
     384             :     const Word16 *pl_crt;
     385             :     Word32 sum1[NO_LEADERS], sum2[NO_LEADERS];
     386             :     Word16 s2, p1;
     387     1380125 :     Word16 low_prec = 0;
     388             :     Word16 max_nb, nb, max_nb1;
     389             : 
     390     1380125 :     max_nb = 0;
     391    12421125 :     FOR( l = 0; l < LATTICE_DIM; l++ )
     392             :     {
     393    11041000 :         nb = sub( 31, norm_l( w[l] ) );
     394    11041000 :         if ( GT_16( nb, max_nb ) )
     395             :         {
     396     1668561 :             max_nb = nb;
     397     1668561 :             move16();
     398             :         }
     399             :     }
     400     1380125 :     max_nb1 = 0;
     401    12421125 :     FOR( l = 0; l < LATTICE_DIM; l++ )
     402             :     {
     403    11041000 :         nb = sub( 15, norm_s( cv_pot[l] ) );
     404    11041000 :         if ( GT_16( nb, max_nb1 ) )
     405             :         {
     406     1401823 :             max_nb1 = nb;
     407     1401823 :             move16();
     408             :         }
     409             :     }
     410     1380125 :     nb = sub( max_nb1, 13 );
     411     1380125 :     if ( nb < 0 )
     412             :     {
     413     1286111 :         nb = 0;
     414             :     }
     415             : 
     416     1380125 :     nb = sub( 30, add( max_nb, nb ) );
     417             :     /* sorting the weight based on the ordering indx[] of the input vector */
     418    12421125 :     FOR( l = 0; l < LATTICE_DIM; l++ )
     419             :     {
     420    11041000 :         w_norm[l] = L_shl( w[indx[l]], nb ); /* Q(26-nb)  here nb = 30-nb;*/
     421             :     }
     422             : 
     423             :     /* compare first with the origin */
     424     1380125 :     min_dist = L_deposit_l( 0 );
     425    12421125 :     FOR( j = 0; j < LATTICE_DIM; j++ )
     426             :     {
     427    11041000 :         wx[j] = extract_h( L_shl( Mult_32_16( w_norm[j], cv_pot[j] ), 3 ) ); /*Q(26-nb) + Q10 -Q15 +Q2 -Q16 = Q(7-nb)   //it is multiplicated by 2 */
     428             :     }
     429             : 
     430     1380125 :     s = scale[0];
     431     1380125 :     move16();                                     /*Q11 */
     432     1380125 :     s2 = extract_h( L_shl( L_mult( s, s ), 3 ) ); /*Q11+Q11++Q1+Q3-Q16 = Q10 */
     433     1380125 :     pl_crt = &pl_HQ_fx[0];
     434     1380125 :     move16();
     435             : 
     436    19245057 :     FOR( j = 0; j < no_leaders[0]; j++ )
     437             :     {
     438    17864932 :         sum1[j] = L_deposit_l( 0 );
     439    17864932 :         sum2[j] = L_deposit_l( 0 );
     440             : 
     441    17864932 :         l = 0;
     442    17864932 :         move16();
     443   116828241 :         WHILE( l < LATTICE_DIM - 1 )
     444             :         {
     445    98963309 :             p = *pl_crt;
     446    98963309 :             IF( p )
     447             :             {
     448    89095849 :                 sum1[j] = L_mac( sum1[j], wx[l], p );                    /* Q(7-nb) + Q1 + Q1 = Q(9-nb) */
     449    89095849 :                 p1 = i_mult2( p, p );                                    /*Q2 */
     450    89095849 :                 sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb) */
     451    89095849 :                 pl_crt++;
     452    89095849 :                 l++;
     453             :             }
     454             :             ELSE
     455             :             {
     456     9867460 :                 pl_crt += ( sub( LATTICE_DIM, l ) );
     457     9867460 :                 l = LATTICE_DIM;
     458     9867460 :                 move16();
     459             :             }
     460             :         }
     461    17864932 :         IF( EQ_16( l, LATTICE_DIM - 1 ) )
     462             :         {
     463     7997472 :             p = *pl_crt;
     464             :             /* if it went up to 7th position */
     465     7997472 :             IF( pl_par[j] )
     466             :             {
     467     6401853 :                 IF( NE_16( sig, pl_par[j] ) )
     468             :                 {
     469     3180408 :                     sum1[j] = L_msu( sum1[j], wx[l], p );                    /* Q(7-nb) + Q1 + Q1 = Q(9-nb) //Q-7 + Q1 + Q1 = Q-5 */
     470     3180408 :                     p1 = i_mult2( p, p );                                    /*Q2 */
     471     3180408 :                     sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb)   //Q12 + Q2 -Q15 = Q-1 */
     472     3180408 :                     pl_crt++;
     473             :                 }
     474             :                 ELSE
     475             :                 {
     476     3221445 :                     sum1[j] = L_mac( sum1[j], wx[l], p );                    /* Q(7-nb) + Q1 + Q1 = Q(9-nb)   //Q-7 + Q1 + Q1 = Q-5 */
     477     3221445 :                     p1 = i_mult2( p, p );                                    /*Q2 */
     478     3221445 :                     sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb)    //Q12 + Q2 -Q15 = Q-1 */
     479     3221445 :                     pl_crt++;
     480             :                 }
     481             :             }
     482             :             ELSE
     483             :             {
     484     1595619 :                 sum1[j] = L_mac( sum1[j], wx[l], p );                    /* Q(7-nb) + Q1 + Q1 = Q(9-nb)   //Q-7 + Q1 + Q1 = Q-5 */
     485     1595619 :                 p1 = i_mult2( p, p );                                    /*Q2 */
     486     1595619 :                 sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb)  // Q12 + Q2 -Q15 = Q-1 */
     487     1595619 :                 pl_crt++;
     488             :             }
     489             :         }
     490             :         /* distance between the potential codevector and the input calculated in ordered space */
     491    17864932 :         tmp_dist = L_sub( Mult_32_16( sum2[j], s2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q(13-nb) + Q10 -Q15= Q(8-nb)   Q(9-nb) + Q3+Q11 -Q15 = Q(8-nb) */
     492    17864932 :         IF( LT_32( tmp_dist, min_dist ) )
     493             :         {
     494     6323237 :             min_dist = L_add( tmp_dist, 0 );
     495     6323237 :             best_scale = 0;
     496     6323237 :             move16(); /* scale(truncation) index of potential codevector */
     497     6323237 :             best_idx = j;
     498     6323237 :             move16(); /* leader class index of potential codevector */
     499             :         }
     500             :     }
     501     1380125 :     tmp_dist = L_add( min_dist, 1 ); /* initialization */
     502     4138407 :     FOR( k = 1; k < no_scales; k++ )
     503             :     {
     504     2758282 :         s = scale[k];
     505     2758282 :         move16(); /*Q11 */
     506     2758282 :         IF( LE_16( 16, norm_l( s ) ) )
     507             :         {
     508     2395595 :             s2 = extract_h( L_shl( L_mult( s, s ), 1 ) ); /*Q11+Q11+Q1+Q1-Q16 = Q7 */
     509     2395595 :             low_prec = 1;
     510             :         }
     511             :         ELSE
     512             :         {
     513      362687 :             s2 = extract_h( L_shl( L_mult( s, s ), 3 ) ); /*Q11+Q11++Q1+Q3-Q16 = Q10 */
     514             :         }
     515    25452535 :         FOR( j = 0; j < no_leaders[k]; j++ )
     516             :         {
     517             :             /* distance between the potential codevector and the input calculated in ordered space */
     518    22694253 :             IF( EQ_16( low_prec, 1 ) )
     519             :             {
     520    22694253 :                 tmp_dist = L_sub( L_shl( Mult_32_16( sum2[j], s2 ), 2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q-1 + Q7 + 3-Q15= Q-6   Q-5 + Q3+Q11 -Q15 = Q-6 */
     521             :             }
     522             :             ELSE
     523             :             {
     524           0 :                 tmp_dist = L_sub( Mult_32_16( sum2[j], s2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q-1 + Q10 -Q15= Q-6   Q-5 + Q3+Q11 -Q15 = Q-6 */
     525             :             }
     526    22694253 :             IF( LT_32( tmp_dist, min_dist ) )
     527             :             {
     528     1154202 :                 min_dist = L_add( tmp_dist, 0 );
     529     1154202 :                 best_scale = k;
     530     1154202 :                 move16(); /* scale(truncation) index of the potential codevector */
     531     1154202 :                 best_idx = j;
     532     1154202 :                 move16(); /* leader class index of the potential codevector */
     533             :             }
     534             :         }
     535     2758282 :         low_prec = 0;
     536     2758282 :         move16();
     537             :     }
     538     1380125 :     *p_best_scale = best_scale;
     539     1380125 :     move16();
     540     1380125 :     *p_best_idx = best_idx;
     541     1380125 :     move16();
     542             : 
     543     1380125 :     return min_dist;
     544             : }
     545             : 
     546             : /*-----------------------------------------------------------------*
     547             :  * quantize_data_fx()
     548             :  *
     549             :  *-----------------------------------------------------------------*/
     550             : 
     551             : 
     552       10032 : static Word32 quantize_data_fx(
     553             :     Word16 *data,            /* i  : residual LSF data to quantize                              x2.56*/
     554             :     const Word16 *w_in,      /* i  : weights                                                      Q10*/
     555             :     Word16 *qin,             /* o  : quantized output (scaled)                                  x2.56*/
     556             :     Word16 *cv_out,          /* o  : codevectors                                                   Q1*/
     557             :     Word16 *idx_lead,        /* o  : leader indexes for each subvector                               */
     558             :     Word16 *idx_scale,       /* o  : scale indexes for each subvector                                */
     559             :     const Word16 *sigma,     /* i  : standard deviation                                        x2.56 */
     560             :     const Word16 *inv_sigma, /* i  : inverse of standard deviation                               Q15 */
     561             :     const Word16 *scale,     /* i  : scales for each truncation                                   Q11*/
     562             :     Word16 no_scales,        /* i  : number of truncation for each subvector                         */
     563             :     const Word16 *no_leaders /* i  : number of leader vectors for each truncation of each subvector   */
     564             : )
     565             : {
     566             :     Word16 j;
     567             :     Word32 w[LATTICE_DIM];
     568       10032 :     Word32 min_dist = 0;
     569       10032 :     Word16 best_idx = 0, best_scale = -1;
     570             :     Word16 s;
     571             :     Word16 indx[LATTICE_DIM];
     572             :     Word16 sig, sign[LATTICE_DIM];
     573             :     Word16 cv_pot[LATTICE_DIM];
     574             :     Word16 id[8];
     575             :     Word16 smallest;
     576             :     Word32 L_tmp;
     577             : 
     578       10032 :     IF( no_scales > 0 )
     579             :     {
     580       10032 :         prepare_data_fx( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
     581       10032 :         move16();
     582             :         /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
     583       10032 :         sort_desc_ind_fx( cv_pot, LATTICE_DIM, indx );
     584       10032 :         smallest = indx[LATTICE_DIM - 1];
     585       10032 :         move16();
     586             : 
     587       10032 :         min_dist = calculate_min_dist_fx( cv_pot, no_scales, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
     588             : 
     589       10032 :         IF( GT_16( best_scale, -1 ) )
     590             :         {
     591       90009 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     592             :             {
     593       80008 :                 id[indx[j]] = j;
     594             :             }
     595       90009 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     596             :             {
     597       80008 :                 cv_out[j] = i_mult2( sign[j], pl_HQ_fx[best_idx * LATTICE_DIM + id[j]] );
     598       80008 :                 move16();
     599             :             }
     600       10001 :             IF( pl_par[best_idx] )
     601             :             {
     602        4061 :                 IF( NE_16( sig, pl_par[best_idx] ) )
     603             :                 {
     604        1103 :                     cv_out[smallest] = negate( cv_out[smallest] );
     605             :                 }
     606             :             }
     607       10001 :             s = scale[best_scale];
     608       10001 :             move16(); /*Q11 */
     609       90009 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     610             :             {
     611             :                 /*qin[j] = s * cv_out[j] * sigma[j]; */
     612       80008 :                 L_tmp = L_mult( cv_out[j], s );                  /* Q1+Q11+Q1  = Q13 */
     613       80008 :                 L_tmp = Mult_32_16( L_tmp, shl( sigma[j], 2 ) ); /* Q13 + Q2 +x2.56 -Q15 */
     614             : 
     615       80008 :                 qin[j] = extract_l( L_tmp ); /*x2.56 */
     616             :             }
     617       10001 :             *idx_lead = best_idx;
     618       10001 :             move16();
     619       10001 :             *idx_scale = best_scale;
     620       10001 :             move16();
     621             :         }
     622             :         ELSE
     623             :         {
     624         279 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     625             :             {
     626         248 :                 qin[j] = 0;
     627         248 :                 move16();
     628             :             }
     629             : 
     630          31 :             *idx_lead = best_idx;
     631          31 :             move16();
     632          31 :             *idx_scale = best_scale;
     633          31 :             move16();
     634             :         }
     635             :     }
     636             :     ELSE
     637             :     {
     638           0 :         *idx_lead = 0;
     639           0 :         move16();
     640           0 :         *idx_scale = -1;
     641           0 :         move16();
     642             : 
     643           0 :         FOR( j = 0; j < LATTICE_DIM; j++ )
     644             :         {
     645           0 :             cv_out[j] = 0;
     646           0 :             move16();
     647           0 :             qin[j] = 0;
     648           0 :             move16();
     649             :         }
     650             :     }
     651             : 
     652       10032 :     return min_dist;
     653             : }
     654             : 
     655     1386405 : Word32 quantize_data_ivas_fx(
     656             :     Word16 *data,            /* i  : residual LSF data to quantize                              x2.56*/
     657             :     const Word16 *w_in,      /* i  : weights                                                      Q10*/
     658             :     Word16 *qin,             /* o  : quantized output (scaled)                                  x2.56*/
     659             :     Word16 *cv_out,          /* o  : codevectors                                                   Q1*/
     660             :     Word16 *idx_lead,        /* o  : leader indexes for each subvector                               */
     661             :     Word16 *idx_scale,       /* o  : scale indexes for each subvector                                */
     662             :     const Word16 *sigma,     /* i  : standard deviation                                        x2.56 */
     663             :     const Word16 *inv_sigma, /* i  : inverse of standard deviation                               Q15 */
     664             :     const Word16 *scale,     /* i  : scales for each truncation                                   Q11*/
     665             :     const Word16 *no_leaders /* i  : number of leader vectors for each truncation of each subvector   */
     666             : )
     667             : {
     668             :     Word16 j;
     669             :     Word32 w[LATTICE_DIM];
     670     1386405 :     Word32 min_dist = 0;
     671     1386405 :     Word16 best_idx = 0, best_scale = -1;
     672             :     Word16 s;
     673             :     Word16 indx[LATTICE_DIM];
     674             :     Word16 sig, sign[LATTICE_DIM];
     675             :     Word16 cv_pot[LATTICE_DIM];
     676             :     Word16 id[8];
     677             :     Word16 smallest;
     678             :     Word32 L_tmp;
     679             : 
     680     1386405 :     IF( scale[0] > 0 )
     681             :     {
     682     1370093 :         prepare_data_fx( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
     683     1370093 :         move16();
     684             :         /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
     685     1370093 :         sort_desc_ind_fx( cv_pot, LATTICE_DIM, indx );
     686     1370093 :         smallest = indx[LATTICE_DIM - 1];
     687     1370093 :         move16();
     688             : 
     689     1370093 :         min_dist = calculate_min_dist_fx( cv_pot, MAX_NO_SCALES, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
     690             : 
     691     1370093 :         IF( GT_16( best_scale, -1 ) )
     692             :         {
     693    12243132 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     694             :             {
     695    10882784 :                 id[indx[j]] = j;
     696             :             }
     697    12243132 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     698             :             {
     699    10882784 :                 cv_out[j] = i_mult2( sign[j], pl_HQ_fx[best_idx * LATTICE_DIM + id[j]] );
     700    10882784 :                 move16();
     701             :             }
     702     1360348 :             IF( pl_par[best_idx] )
     703             :             {
     704      574858 :                 IF( NE_16( sig, pl_par[best_idx] ) )
     705             :                 {
     706      150077 :                     cv_out[smallest] = negate( cv_out[smallest] );
     707             :                 }
     708             :             }
     709     1360348 :             s = scale[best_scale];
     710     1360348 :             move16(); /*Q11 */
     711    12243132 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     712             :             {
     713             :                 /*qin[j] = s * cv_out[j] * sigma[j]; */
     714    10882784 :                 L_tmp = L_mult( cv_out[j], s );                  /* Q1+Q11+Q1  = Q13 */
     715    10882784 :                 L_tmp = Mult_32_16( L_tmp, shl( sigma[j], 2 ) ); /* Q13 + Q2 +x2.56 -Q15 */
     716             : 
     717    10882784 :                 qin[j] = extract_l( L_tmp ); /*x2.56 */
     718             :             }
     719     1360348 :             *idx_lead = best_idx;
     720     1360348 :             move16();
     721     1360348 :             *idx_scale = best_scale;
     722     1360348 :             move16();
     723             :         }
     724             :         ELSE
     725             :         {
     726       87705 :             FOR( j = 0; j < LATTICE_DIM; j++ )
     727             :             {
     728       77960 :                 qin[j] = 0;
     729       77960 :                 move16();
     730             :             }
     731             : 
     732        9745 :             *idx_lead = best_idx;
     733        9745 :             move16();
     734        9745 :             *idx_scale = best_scale;
     735        9745 :             move16();
     736             :         }
     737             :     }
     738             :     ELSE
     739             :     {
     740       16312 :         *idx_lead = 0;
     741       16312 :         move16();
     742       16312 :         *idx_scale = -1;
     743       16312 :         move16();
     744             : 
     745      146808 :         FOR( j = 0; j < LATTICE_DIM; j++ )
     746             :         {
     747      130496 :             cv_out[j] = 0;
     748      130496 :             move16();
     749      130496 :             qin[j] = 0;
     750      130496 :             move16();
     751             :         }
     752             :     }
     753             : 
     754     1386405 :     return min_dist;
     755             : }
     756             : /*-----------------------------------------------------------------*
     757             :  * sort_desc_ind()
     758             :  *
     759             :  * sorts in descending order and computes indices in the sorted vector
     760             :  *-----------------------------------------------------------------*/
     761             : 
     762     1380125 : static void sort_desc_ind_fx(
     763             :     Word16 *s,  /* i/o: vector to be sorted  Q10*/
     764             :     Word16 len, /* i  : vector length         */
     765             :     Word16 *ind /* o  : array of indices      */
     766             : )
     767             : {
     768             :     Word16 i, k, sorted, a;
     769             :     Word16 t;
     770             : 
     771    12421125 :     FOR( i = 0; i < len; i++ )
     772             :     {
     773    11041000 :         ind[i] = i;
     774    11041000 :         move16();
     775             :     }
     776     1380125 :     sorted = 0;
     777     9137162 :     FOR( k = ( len - 1 ); k > 0; k-- )
     778             :     {
     779     8685392 :         IF( sorted )
     780             :         {
     781      928355 :             BREAK;
     782             :         }
     783             : 
     784     7757037 :         sorted = 1;
     785     7757037 :         move16();
     786    43016056 :         FOR( i = 0; i < k; i++ )
     787             :         {
     788    35259019 :             IF( LT_16( s[i], s[i + 1] ) )
     789             :             {
     790    19012254 :                 sorted = 0;
     791    19012254 :                 move16();
     792    19012254 :                 t = s[i];
     793    19012254 :                 move16();
     794    19012254 :                 s[i] = s[i + 1];
     795    19012254 :                 move16();
     796    19012254 :                 s[i + 1] = t;
     797    19012254 :                 move16();
     798    19012254 :                 a = ind[i];
     799    19012254 :                 move16();
     800    19012254 :                 ind[i] = ind[i + 1];
     801    19012254 :                 move16();
     802    19012254 :                 ind[i + 1] = a;
     803    19012254 :                 move16();
     804             :             }
     805             :         }
     806             :     }
     807             : 
     808     1380125 :     return;
     809             : }
     810             : 
     811             : /*-----------------------------------------------------------------*
     812             :  * index_lvq()
     813             :  *
     814             :  * sorts in descending order and computes indices in the sorted vector
     815             :  *-----------------------------------------------------------------*/
     816        2508 : void index_lvq_fx(
     817             :     Word16 *quant,           /* i : codevector to be indexed (2 8-dim subvectors)                   Q13*/
     818             :     Word16 *idx_lead,        /* i : leader class index for each subvector                              */
     819             :     Word16 *idx_scale,       /* i :scale index for each subvector                                      */
     820             :     Word16 mode,             /* i : integer signalling the quantizer structure for the current bitrate */
     821             :     Word16 *index,           /* o : encoded index (represented on 3 short each with 15 bits )          */
     822             :     Word32 *p_offset_scale1, /* i : scales for first subvector                                         */
     823             :     Word32 *p_offset_scale2, /* i : scales for second subvector                                        */
     824             :     Word16 *p_no_scales      /* i : number of scales for each subvector                                */
     825             : )
     826             : {
     827             :     Word32 index1, index2;
     828             :     Word16 len_offset;
     829             :     Word64 idx64;
     830             :     Word64 index2_64;
     831             : 
     832        2508 :     len_offset = add( MAX_NO_SCALES, 1 );
     833        2508 :     move16();
     834             : 
     835        2508 :     index1 = 0;
     836        2508 :     move16();
     837             : 
     838             :     /* for first subvector */
     839        2508 :     IF( GT_16( idx_scale[0], -1 ) )
     840             :     {
     841        2508 :         index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[( mode * len_offset ) + idx_scale[0]] ) );
     842             :     }
     843             : 
     844             :     /* for second subvector */
     845        2508 :     index2 = L_deposit_l( 0 );
     846             : 
     847        2508 :     IF( GT_16( idx_scale[1], -1 ) )
     848             :     {
     849        2490 :         index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[( mode * len_offset ) + idx_scale[1]] ) );
     850             :     }
     851        2508 :     idx64 = W_mult0_32_32( index1, p_offset_scale2[mode * len_offset + p_no_scales[mode * 2 + 1]] );
     852        2508 :     index2_64 = W_deposit32_l( index2 );
     853        2508 :     idx64 = W_add_nosat( idx64, index2_64 );
     854             : 
     855             :     /* convert to 3 short */
     856        2508 :     index[0] = ( ( idx64 ) & ( 0x7fff ) );
     857        2508 :     move16();
     858        2508 :     index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff );
     859        2508 :     move16();
     860        2508 :     index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff );
     861        2508 :     move16();
     862        2508 :     return;
     863             : }
     864             : 
     865      345984 : void index_lvq_ivas_fx(
     866             :     Word16 *quant,     /* i : codevector to be indexed (2 8-dim subvectors)                   Q13*/
     867             :     Word16 *idx_lead,  /* i : leader class index for each subvector                              */
     868             :     Word16 *idx_scale, /* i :scale index for each subvector                                      */
     869             :     Word16 mode,       /* i : integer signalling the quantizer structure for the current bitrate */
     870             :     Word16 *index,     /* o : encoded index (represented on 3 short each with 15 bits )          */
     871             :     const Word16 prediction_flag )
     872             : {
     873             :     Word32 index1, index2;
     874             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     875             :     Word64 idx64;
     876             :     Word64 index2_64;
     877             : 
     878      345984 :     index1 = 0;
     879      345984 :     move16();
     880             : 
     881      345984 :     create_offset( offset_scale1, offset_scale2, mode, prediction_flag );
     882             : 
     883             :     /* for first subvector */
     884      345984 :     IF( GT_16( idx_scale[0], -1 ) )
     885             :     {
     886      345834 :         index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], offset_scale1[idx_scale[0]] ) );
     887             :     }
     888             : 
     889             :     /* for second subvector */
     890      345984 :     index2 = L_deposit_l( 0 );
     891             : 
     892      345984 :     IF( GT_16( idx_scale[1], -1 ) )
     893             :     {
     894      332405 :         index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], offset_scale2[idx_scale[1]] ) );
     895             :     }
     896             : 
     897      345984 :     idx64 = W_mult0_32_32( index1, offset_scale2[MAX_NO_SCALES] );
     898      345984 :     index2_64 = W_deposit32_l( index2 );
     899      345984 :     idx64 = W_add_nosat( idx64, index2_64 );
     900             : 
     901             :     /* convert to 3 short */
     902      345984 :     index[0] = ( ( idx64 ) & ( 0x7fff ) );
     903      345984 :     move16();
     904      345984 :     index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff );
     905      345984 :     move16();
     906      345984 :     index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff );
     907      345984 :     move16();
     908             : 
     909      345984 :     return;
     910             : }
     911             : /*-----------------------------------------------------------------*
     912             :  * encode_comb()
     913             :  *
     914             :  * creates an index for the lattice codevector
     915             :  *-----------------------------------------------------------------*/
     916             : 
     917      686600 : Word32 encode_comb_fx(                 /* o  : index of the absolute valued codevector*/
     918             :                        Word16 *cv,     /* i  : codevector to be indexed            Q13*/
     919             :                        Word16 idx_lead /* i  : leader class index, to know the values */
     920             : )
     921             : {
     922             :     Word16 idx_sign, idx_ld_class;
     923             :     Word32 L_tmp;
     924             : 
     925      686600 :     idx_sign = encode_sign_pc1_fx( pl_par[idx_lead], cv );
     926      686600 :     move16();
     927      686600 :     idx_ld_class = index_leaders_fx( cv, idx_lead, LATTICE_DIM );
     928      686600 :     move16();
     929             : 
     930      686600 :     L_tmp = L_mac0( idx_ld_class, idx_sign, pi0[idx_lead] );
     931             : 
     932      686600 :     return L_tmp;
     933             : }
     934             : 
     935             : /*-----------------------------------------------------------------*
     936             :  * index_leaders()
     937             :  *
     938             :  * gives the index in a class of leaders without considering the sign yet
     939             :  *-----------------------------------------------------------------*/
     940             : 
     941      686600 : static Word16 index_leaders_fx(                  /* o  : index                        */
     942             :                                 Word16 *cv,      /* i  : codevector to be indexed  Q13*/
     943             :                                 Word16 idx_lead, /* i  : leader class index           */
     944             :                                 Word16 dim       /* i  : vector dimension             */
     945             : )
     946             : {
     947             :     Word16 index;
     948             :     Word16 i, no_vals_loc, nr, p[LATTICE_DIM], dim_loc;
     949             :     Word16 cv_copy[LATTICE_DIM], val_crt;
     950             : 
     951      686600 :     no_vals_loc = no_vals[idx_lead];
     952      686600 :     move16();
     953             : 
     954      686600 :     IF( EQ_16( no_vals_loc, 1 ) )
     955             :     {
     956       71586 :         return 0;
     957             :     }
     958             : 
     959     5535126 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     960             :     {
     961     4920112 :         cv_copy[i] = abs_s( cv[i] ); /*Q13 */
     962             :     }
     963             : 
     964      615014 :     val_crt = vals_fx[idx_lead][0];
     965      615014 :     move16(); /*Q13 */
     966      615014 :     nr = find_pos_fx( cv_copy, dim, val_crt, p );
     967      615014 :     move16();
     968      615014 :     index = c2idx_fx( LATTICE_DIM, p, nr );
     969      615014 :     move16();
     970             : 
     971      615014 :     IF( EQ_16( no_vals_loc, 2 ) )
     972             :     {
     973      425533 :         return index;
     974             :     }
     975             : 
     976      189481 :     take_out_val_fx( cv_copy, cv_copy, val_crt, dim );
     977      189481 :     dim_loc = sub( dim, no_vals_ind[idx_lead][0] );
     978      189481 :     index = extract_l( L_mult0( index, C_VQ[dim_loc][no_vals_ind[idx_lead][1]] ) );
     979             : 
     980      189481 :     val_crt = vals_fx[idx_lead][1];
     981      189481 :     move16(); /*Q13 */
     982      189481 :     nr = find_pos_fx( cv_copy, dim_loc, val_crt, p );
     983      189481 :     move16();
     984      189481 :     index = add( index, c2idx_fx( dim_loc, p, nr ) );
     985             : 
     986      189481 :     IF( EQ_16( no_vals_loc, 3 ) )
     987             :     {
     988      188052 :         return index;
     989             :     }
     990             : 
     991        1429 :     take_out_val_fx( cv_copy, cv_copy, val_crt, dim_loc );
     992        1429 :     dim_loc = sub( dim_loc, no_vals_ind[idx_lead][1] );
     993        1429 :     index = extract_l( L_mult0( index, C_VQ[dim_loc][no_vals_ind[idx_lead][2]] ) );
     994             : 
     995        1429 :     val_crt = vals_fx[idx_lead][2];
     996        1429 :     move16(); /*Q13 */
     997        1429 :     nr = find_pos_fx( cv_copy, dim_loc, val_crt, p );
     998        1429 :     move16();
     999        1429 :     index = add( index, c2idx_fx( dim_loc, p, nr ) );
    1000             :     /* maximum 4 values */
    1001             : 
    1002        1429 :     return index;
    1003             : }
    1004             : 
    1005             : /*-----------------------------------------------------------------*
    1006             :  * find_pos()
    1007             :  *
    1008             :  * Finds the positions in vector c for which the vector components are equal to 'arg'.
    1009             :  * It returns the number of such positions and their values in the array 'p'.
    1010             :  *-----------------------------------------------------------------*/
    1011             : 
    1012      805924 : Word16 find_pos_fx(             /* o  : number of positions             */
    1013             :                     Word16 *c,  /* i  : input vector                 Q13*/
    1014             :                     Word16 len, /* i  : input vector dim                */
    1015             :                     Word16 arg, /* i  : argument to be compared with Q13*/
    1016             :                     Word16 *p   /* o  : vector of positions             */
    1017             : )
    1018             : {
    1019      805924 :     Word16 i = 0, j = 0;
    1020             : 
    1021             :     /* how many (j) and which (p) positions are in the relation pred(arg,c[i]) */
    1022     7013578 :     FOR( i = 0; i < len; i++ )
    1023             :     {
    1024     6207654 :         IF( EQ_16( arg, c[i] ) )
    1025             :         {
    1026     2152693 :             p[j++] = i;
    1027     2152693 :             move16();
    1028             :         }
    1029             :     }
    1030             : 
    1031      805924 :     return j;
    1032             : }
    1033             : /*-----------------------------------------------------------------*
    1034             :  * encode_sign_pc1()
    1035             :  *
    1036             :  * Creates an index for signs of the significant codevector components
    1037             :  * Gives the index of the signs - binary representation where negative sign stands for 1
    1038             :  * and positive sign stands for 1.
    1039             :  *-----------------------------------------------------------------*/
    1040      686600 : static Word16 encode_sign_pc1_fx(                /* o  : index of signs                                             */
    1041             :                                   Word16 parity, /* i  : parity of the leader class to which the codevector belongs */
    1042             :                                   Word16 *cv     /* i  : input codevector                                        Q13*/
    1043             : )
    1044             : {
    1045             :     Word16 idx_sign;
    1046      686600 :     Word16 cnt, i, len = LATTICE_DIM;
    1047             : 
    1048      686600 :     idx_sign = 0;
    1049      686600 :     move16();
    1050      686600 :     cnt = 0;
    1051      686600 :     move16();
    1052             : 
    1053      686600 :     if ( parity )
    1054             :     {
    1055      289202 :         len = sub( len, 1 );
    1056             :     }
    1057             : 
    1058     5890198 :     FOR( i = 0; i < len; i++ )
    1059             :     {
    1060     5203598 :         IF( cv[i] < 0 )
    1061             :         {
    1062     1813650 :             idx_sign = add( idx_sign, ( shl( 1, cnt ) ) );
    1063     1813650 :             cnt = add( cnt, 1 );
    1064             :         }
    1065             : 
    1066     5203598 :         if ( cv[i] > 0 )
    1067             :         {
    1068     1944164 :             cnt = add( cnt, 1 );
    1069             :         }
    1070             :     }
    1071             : 
    1072      686600 :     return idx_sign;
    1073             : }
    1074             : 
    1075             : /*-----------------------------------------------------------------*
    1076             :  * take_out_val()
    1077             :  *
    1078             :  * removes the value val from the vector v
    1079             :  *-----------------------------------------------------------------*/
    1080             : 
    1081      190910 : static void take_out_val_fx(
    1082             :     Word16 *v,     /* i  : input vector                          x2.56*/
    1083             :     Word16 *v_out, /* o  : output vector without the value val        */
    1084             :     Word16 val,    /* i  : value to be removed                   x2.56*/
    1085             :     Word16 len     /* i  : input vector length                        */
    1086             : )
    1087             : {
    1088             :     Word16 i, cnt;
    1089             : 
    1090      190910 :     cnt = 0;
    1091      190910 :     move16();
    1092             : 
    1093     1716761 :     FOR( i = 0; i < len; i++ )
    1094             :     {
    1095     1525851 :         if ( NE_16( v[i], val ) )
    1096             :         {
    1097     1287542 :             v_out[cnt++] = v[i];
    1098     1287542 :             move16();
    1099             :         }
    1100             :     }
    1101             : 
    1102      190910 :     return;
    1103             : }
    1104             : 
    1105             : /*-----------------------------------------------------------------------*
    1106             :  * c2idx()
    1107             :  * Indexing of vectors having k non-nul positions located in the positions
    1108             :  * given by the array p.
    1109             :  *-----------------------------------------------------------------------*/
    1110     2152693 : Word16 c2idx_fx(            /* o: index                    */
    1111             :                  Word16 n,  /* i: vector lenght            */
    1112             :                  Word16 *p, /* i: non null value positions */
    1113             :                  Word16 k   /* i: non-nullnumber of values */
    1114             : )
    1115             : {
    1116             :     Word16 skip, i, p0;
    1117             :     Word16 tmp;
    1118             : 
    1119     2152693 :     IF( EQ_16( k, 1 ) )
    1120             :     {
    1121      805924 :         return p[0];
    1122             :     }
    1123             :     ELSE
    1124             :     {
    1125     1346769 :         skip = 0;
    1126     1346769 :         move16();
    1127     2416631 :         FOR( i = 1; i <= p[0]; i++ )
    1128             :         {
    1129     1069862 :             skip = add( skip, C_VQ[( n - i )][( k - 1 )] ); // Q0
    1130             :         }
    1131             : 
    1132     1346769 :         p0 = p[0];
    1133     1346769 :         move16();
    1134     4085336 :         FOR( i = 1; i < k; i++ )
    1135             :         {
    1136     2738567 :             p[i] = sub( p[i], add( p0, 1 ) );
    1137             :         }
    1138     1346769 :         tmp = add( skip, c2idx_fx( sub( n, add( p0, 1 ) ), p + 1, sub( k, 1 ) ) );
    1139             : 
    1140     1346769 :         return tmp;
    1141             :     }
    1142             : }
    1143             : 
    1144             : /*-----------------------------------------------------------------*
    1145             :  * mslvq()
    1146             :  *
    1147             :  * Encodes the LSF residual
    1148             :  *-----------------------------------------------------------------*/
    1149             : 
    1150      694437 : Word32 mslvq_ivas_16(
    1151             :     Word16 *pTmp,          /* i  : M-dimensional input vector */
    1152             :     Word16 *quant,         /* o  : quantized vector */
    1153             :     Word16 *cv_out,        /* o  : corresponding 8-dim lattice codevectors (without the scaling) */
    1154             :     Word16 *idx_lead,      /* o  : leader index for each 8-dim subvector  */
    1155             :     Word16 *idx_scale,     /* o  : scale index for each subvector */
    1156             :     const Word16 *w,       /* i  : weights for LSF quantization */
    1157             :     const Word16 mode,     /* i  : number indicating the coding type (V/UV/G...)*/
    1158             :     const Word16 mode_glb, /* i  : LVQ coding mode */
    1159             :     const Word16 pred_flag /* i  : prediction flag (0: safety net, 1,2 - predictive  )*/
    1160             :                            /*Retunr dist in q 22*/
    1161             : )
    1162             : {
    1163             :     Word32 dist, L_tmp;
    1164             :     const Word16 *p_scales, *p_sigma, *p_inv_sigma;
    1165             :     Word16 i, tmp, tmp1;
    1166             :     Word16 p_no_lead[MAX_NO_SCALES * 2];
    1167      694437 :     dist = L_deposit_l( 0 );
    1168      694437 :     IF( pred_flag == 0 )
    1169             :     {
    1170      182016 :         p_sigma = sigma_MSLVQ_fx[mode];
    1171             :         /* inverse sigma is precomputed to save complexity */
    1172      182016 :         p_inv_sigma = inv_sigma_MSLVQ_fx[mode];
    1173      182016 :         p_scales = scales_ivas_fx[mode_glb];
    1174             : 
    1175      182016 :         tmp = no_lead_idx[mode_glb][0];
    1176      182016 :         move16();
    1177      182016 :         tmp1 = no_lead_idx[mode_glb][1];
    1178      182016 :         move16();
    1179      182016 :         test();
    1180      182016 :         if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) )
    1181             :         {
    1182           0 :             tmp = add( tmp, DELTA_LEADER );
    1183             :         }
    1184      728064 :         FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1185             :         {
    1186      546048 :             p_no_lead[i] = (Word16) leaders_short[tmp][i];
    1187      546048 :             move16();
    1188      546048 :             p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i];
    1189      546048 :             move16();
    1190             :         }
    1191             :     }
    1192             :     ELSE
    1193             :     {
    1194      512421 :         IF( GE_16( pred_flag, 5 ) )
    1195             :         {
    1196             :             /* assert( pred_flag >= 12 && pred_flag <= 15 ); */
    1197             :             /* pred_flag is here the number of bits for MSLVQ */
    1198             : 
    1199        3363 :             p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM];
    1200             : 
    1201             :             /* inverse sigma is precomputed to save complexity */
    1202        3363 :             p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM];
    1203        3363 :             IF( mode_glb == 0 )
    1204             :             {
    1205        3363 :                 p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )];
    1206             : 
    1207       13452 :                 FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1208             :                 {
    1209       10089 :                     p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
    1210       10089 :                     move16();
    1211             :                 }
    1212             :             }
    1213             :             ELSE
    1214             :             {
    1215           0 :                 p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )];
    1216           0 :                 FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1217             :                 {
    1218           0 :                     p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
    1219           0 :                     move16();
    1220             :                 }
    1221             :             }
    1222             :         }
    1223             :         ELSE
    1224             :         {
    1225      509058 :             p_sigma = sigma_p_ivas_fx[mode];
    1226             : 
    1227             :             /* inverse sigma is precomputed to save complexity */
    1228      509058 :             p_inv_sigma = inv_sigma_p_ivas_fx[mode];
    1229             : 
    1230      509058 :             p_scales = scales_p_ivas_fx[mode_glb];
    1231             : 
    1232      509058 :             tmp = no_lead_p_idx[mode_glb][0];
    1233      509058 :             move16();
    1234      509058 :             tmp1 = no_lead_p_idx[mode_glb][1];
    1235      509058 :             move16();
    1236             : 
    1237      509058 :             test();
    1238      509058 :             IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) )
    1239             :             {
    1240       10866 :                 tmp = add( tmp, DELTA_LEADER );
    1241             :             }
    1242             : 
    1243      509058 :             test();
    1244      509058 :             IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) )
    1245             :             {
    1246           0 :                 tmp = add( tmp, DELTA_LEADER );
    1247           0 :                 tmp1 = add( tmp1, DELTA_LEADER );
    1248             :             }
    1249             : 
    1250     2036232 :             FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1251             :             {
    1252     1527174 :                 p_no_lead[i] = (Word16) leaders_short[tmp][i];
    1253     1527174 :                 move16();
    1254     1527174 :                 p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i];
    1255     1527174 :                 move16();
    1256             :             }
    1257             :         }
    1258             :     }
    1259             : 
    1260             :     /* first subvector */
    1261      694437 :     dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale,
    1262             :                                   p_sigma, p_inv_sigma, p_scales, p_no_lead );
    1263             : 
    1264      694437 :     IF( LT_16( pred_flag, 5 ) )
    1265             :     {
    1266             :         /* second subvector */
    1267      691074 :         L_tmp = quantize_data_ivas_fx( 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 );
    1268             : 
    1269      691074 :         dist = L_add( dist, L_tmp );
    1270             :     }
    1271             : 
    1272      694437 :     return dist;
    1273             : }
    1274             : 
    1275             : 
    1276        3363 : UWord32 index_lvq_SHB_fx(
    1277             :     const Word16 idx_lead,
    1278             :     const Word16 idx_scale,
    1279             :     const Word16 nbits,
    1280             :     Word16 *lat_cv,
    1281             :     const Word16 mode )
    1282             : {
    1283             :     UWord16 i;
    1284             :     const Word8 *p_no_lead;
    1285             :     UWord32 index;
    1286             : 
    1287        3363 :     IF( mode == 0 )
    1288             :     {
    1289        3363 :         p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3];
    1290             :     }
    1291             :     ELSE
    1292             :     {
    1293           0 :         p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3];
    1294             :     }
    1295             : 
    1296        3363 :     index = 0;
    1297        3363 :     move32();
    1298        3363 :     IF( GT_16( idx_lead, -1 ) )
    1299             :     {
    1300        3363 :         index = 1;
    1301        3363 :         move32();
    1302        4479 :         FOR( i = 0; i < idx_scale; i++ )
    1303             :         {
    1304        1116 :             index = index + table_no_cv[p_no_lead[i]];
    1305        1116 :             move32();
    1306             :         }
    1307             : 
    1308        3363 :         IF( idx_lead > 0 )
    1309             :         {
    1310        3314 :             index = index + table_no_cv[idx_lead];
    1311        3314 :             move32();
    1312             :         }
    1313             : 
    1314        3363 :         index = index + encode_comb_fx( lat_cv, idx_lead );
    1315        3363 :         move32();
    1316             :     }
    1317             : 
    1318        3363 :     return index;
    1319             : }

Generated by: LCOV version 1.14