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

Generated by: LCOV version 1.14