LCOV - code coverage report
Current view: top level - lib_com - mslvq_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 545 619 88.0 %
Date: 2025-09-13 03:17:37 Functions: 21 22 95.5 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "cnst.h"
      36             : #include "prot_fx.h"
      37             : #include "ivas_cnst.h"
      38             : #include "stl.h"
      39             : #include "rom_com.h"
      40             : #include "ivas_prot_fx.h"
      41             : #include "wmc_auto.h"
      42             : 
      43             : 
      44             : /*-----------------------------------------------------------------*
      45             :  * Local functions
      46             :  *-----------------------------------------------------------------*/
      47             : 
      48             : static void make_offset_scale_fx( Word16 j, const Word32 tab_no_cv[], const Word16 no_ld[], Word16 no_scl, Word32 offset_scale[][MAX_NO_SCALES + 1] );
      49             : static void init_offset_fx( Word32 offset_scale1[][MAX_NO_SCALES + 1], Word32 offset_scale2[][MAX_NO_SCALES + 1], Word32 offset_scale1_p[][MAX_NO_SCALES + 1], Word32 offset_scale2_p[][MAX_NO_SCALES + 1], Word16 no_scales[][2], Word16 no_scales_p[][2] );
      50             : static void decode_comb_fx( Word32 index, Word16 *cv, Word16 idx_lead );
      51             : static void decode_sign_pc1_fx( Word16 *c, Word16 idx_sign, Word16 parity );
      52             : static void put_value_fx( Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16 no_new_val );
      53             : static void decode_leaders_fx( Word16 index, Word16 idx_lead, Word16 *cv );
      54             : static void idx2c_fx( Word16 n, Word16 *p, Word16 k, Word16 val );
      55             : static void divide_64_32_fx( Word16 *xs, Word32 y, Word32 *result, Word32 *rem );
      56             : static Word16
      57             : decode_indexes_fx( Word16 *index, Word16 no_bits, const Word16 *p_scales, Word16 *p_no_scales, Word32 *p_offset_scale1, Word32 *p_offset_scale2, Word16 *x_lvq, Word16 mode_glb, Word16 *scales );
      58             : static Word16 decode_indexes_ivas_fx(
      59             :     Word16 *index,
      60             :     const Word16 no_bits,
      61             :     const Word16 *p_scales, // Q11
      62             :     const Word16 prediction_flag,
      63             :     Word16 *x_lvq, // Q0
      64             :     const Word16 mode_glb,
      65             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
      66             : );
      67             : static Word32 divide_32_32_fx( Word32 y, Word32 x, Word32 *rem );
      68             : static Word16 divide_16_16_fx( Word16 y, Word16 x, Word16 *rem );
      69             : static Word16 decode_indexes_ivas_fx(
      70             :     Word16 *index,
      71             :     const Word16 no_bits,
      72             :     const Word16 *p_scales, // Q11
      73             :     const Word16 prediction_flag,
      74             :     Word16 *x_lvq, // Q0
      75             :     const Word16 mode_glb,
      76             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
      77             : );
      78             : 
      79             : /* used in CNG-LP coding */
      80        1744 : void permute_fx(
      81             :     Word16 *pTmp1,     /* i/o: vector whose components are to be permuted */
      82             :     const Word16 *perm /* i  : permutation info (indexes that should be interchanged), max two perms */
      83             : )
      84             : {
      85             :     Word16 p1, p2;
      86             :     Word16 tmp;
      87             : 
      88        1744 :     p1 = perm[0];
      89        1744 :     move16();
      90        1744 :     p2 = perm[1];
      91        1744 :     move16();
      92        1744 :     tmp = pTmp1[p1];
      93        1744 :     move16();
      94        1744 :     pTmp1[p1] = pTmp1[p2];
      95        1744 :     move16();
      96        1744 :     move16();
      97        1744 :     pTmp1[p2] = tmp;
      98        1744 :     move16();
      99        1744 :     p1 = perm[2];
     100        1744 :     move16();
     101             : 
     102        1744 :     IF( GT_16( p1, -1 ) )
     103             :     {
     104         268 :         p2 = perm[3];
     105         268 :         move16();
     106         268 :         tmp = pTmp1[p1];
     107         268 :         move16();
     108         268 :         pTmp1[p1] = pTmp1[p2];
     109         268 :         move16();
     110         268 :         move16();
     111         268 :         pTmp1[p2] = tmp;
     112         268 :         move16();
     113             :     }
     114             : 
     115        1744 :     return;
     116             : }
     117             : 
     118             : 
     119        8163 : void init_lvq_fx(
     120             :     Word32 offset_scale1[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
     121             :     Word32 offset_scale2[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
     122             :     Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
     123             :     Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
     124             :     Word16 no_scales[][2],                       /* o: number of truncations for each LSF subvector at each MSLVQ structure - safety net  */
     125             :     Word16 no_scales_p[][2]                      /* o: number of truncations for each LSF subvector at each MSLVQ structure - predictive  */
     126             : )
     127             : {
     128             :     Word16 i, j;
     129             :     Word16 k;
     130             :     /* safety-net mode */
     131     1053027 :     FOR( i = 0; i < MAX_NO_MODES; i++ )
     132             :     {
     133     4097826 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     134             :         {
     135     3052962 :             if ( no_lead_fx[i][j] > 0 )
     136             :             {
     137     2791746 :                 k = add( k, 1 );
     138             :             }
     139     3052962 :             if ( no_lead_fx[i][j] <= 0 )
     140             :             {
     141      261216 :                 j = MAX_NO_SCALES - 1;
     142      261216 :                 move16();
     143             :             }
     144             :         }
     145     1044864 :         no_scales[i][0] = k;
     146     1044864 :         move16();
     147             : 
     148     3918240 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     149             :         {
     150     2873376 :             if ( no_lead_fx[i][j] > 0 )
     151             :             {
     152     2334618 :                 k = add( k, 1 );
     153             :             }
     154     2873376 :             if ( no_lead_fx[i][j] <= 0 )
     155             :             {
     156      538758 :                 j = MAX_NO_SCALES << 1;
     157      538758 :                 move16();
     158             :             }
     159             :         }
     160     1044864 :         no_scales[i][1] = k;
     161     1044864 :         move16();
     162             :     }
     163             :     /* predictive mode */
     164     1191798 :     FOR( i = 0; i < MAX_NO_MODES_p; i++ )
     165             :     {
     166     4677399 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     167             :         {
     168     3493764 :             if ( no_lead_p_fx[i][j] > 0 )
     169             :             {
     170     3354993 :                 k = add( k, 1 );
     171             :             }
     172     3493764 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     173             :             {
     174      138771 :                 j = MAX_NO_SCALES - 1;
     175      138771 :                 move16();
     176             :             }
     177             :         }
     178     1183635 :         no_scales_p[i][0] = k;
     179     1183635 :         move16();
     180             : 
     181     4440672 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     182             :         {
     183     3257037 :             if ( no_lead_p_fx[i][j] > 0 )
     184             :             {
     185     2661138 :                 k = add( k, 1 );
     186             :             }
     187             : 
     188     3257037 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     189             :             {
     190      595899 :                 j = MAX_NO_SCALES << 1;
     191      595899 :                 move16();
     192             :             }
     193             :         }
     194             : 
     195     1183635 :         no_scales_p[i][1] = k;
     196     1183635 :         move16();
     197             :     }
     198             :     /* index offsets for each truncation */
     199        8163 :     init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
     200        8163 : }
     201             : 
     202             : /* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure  */
     203     4456998 : static void make_offset_scale_fx(
     204             :     Word16 j,                                /* i: MSLVQ structure index */
     205             :     const Word32 tab_no_cv[],                /* i: cummulated number of codevectors in each leader class */
     206             :     const Word16 no_ld[],                    /* i: number of leaders in each truncation for the MSLVQ structure j*/
     207             :     Word16 no_scl,                           /* i: number of truncations in the MSLVQ structure j */
     208             :     Word32 offset_scale[][MAX_NO_SCALES + 1] /* o: offset values */
     209             : )
     210             : {
     211             :     Word16 i;
     212             : 
     213     4456998 :     offset_scale[j][0] = L_deposit_l( 1 );
     214     4456998 :     move32();
     215    15599493 :     FOR( i = 1; i <= no_scl; i++ )
     216             :     {
     217    11142495 :         offset_scale[j][i] = L_add( offset_scale[j][sub( i, 1 )], tab_no_cv[no_ld[sub( i, 1 )]] );
     218    11142495 :         move32();
     219             :     }
     220             : 
     221     4456998 :     return;
     222             : }
     223             : 
     224     2740158 : static void make_offset_scale(
     225             :     const UWord32 tab_no_cv[],
     226             :     const Word8 *no_ld,
     227             :     const Word16 no_scl,
     228             :     UWord32 *offset_scale )
     229             : {
     230             :     Word16 i;
     231             : 
     232     2740158 :     offset_scale[0] = 1;
     233     2740158 :     move32();
     234    10960632 :     FOR( i = 1; i <= no_scl; i++ )
     235             :     {
     236     8220474 :         offset_scale[i] = UL_addNsD( offset_scale[i - 1], tab_no_cv[(Word16) no_ld[i - 1]] );
     237     8220474 :         move32();
     238             :     }
     239             : 
     240     2740158 :     return;
     241             : }
     242             : 
     243        8163 : void init_offset_fx(
     244             :     Word32 offset_scale1[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
     245             :     Word32 offset_scale2[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
     246             :     Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
     247             :     Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
     248             :     Word16 no_scales[][2],                       /* i: number of truncations for each LSF subvector at each MSLVQ structure - safety net  */
     249             :     Word16 no_scales_p[][2]                      /* i: number of truncations for each LSF subvector at each MSLVQ structure - predictive  */
     250             : )
     251             : {
     252             :     Word16 j;
     253             :     /* safety-net */
     254     1053027 :     FOR( j = 0; j < MAX_NO_MODES; j++ )
     255             :     {
     256     1044864 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
     257     1044864 :         make_offset_scale_fx( j, table_no_cv_fx, &no_lead_fx[j][MAX_NO_SCALES], no_scales[j][1], offset_scale2 );
     258             :     }
     259             :     /* predictive modes AR and MA */
     260     1191798 :     FOR( j = 0; j < MAX_NO_MODES_p; j++ )
     261             :     {
     262     1183635 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p );
     263     1183635 :         make_offset_scale_fx( j, table_no_cv_fx, &no_lead_p_fx[j][MAX_NO_SCALES], no_scales_p[j][1], offset_scale2_p );
     264             :     }
     265             : 
     266        8163 :     offset_scale1[MAX_NO_MODES][0] = 1;
     267        8163 :     move32();
     268        8163 :     offset_scale2[MAX_NO_MODES][0] = 1;
     269        8163 :     move32();
     270        8163 :     offset_scale1_p[MAX_NO_MODES_p][0] = 1;
     271        8163 :     move32();
     272        8163 :     offset_scale2_p[MAX_NO_MODES_p][0] = 1;
     273        8163 :     move32();
     274             : 
     275        8163 :     return;
     276             : }
     277             : 
     278             : static Word16
     279        4080 : decode_indexes_fx(
     280             :     Word16 *index,           /* i: LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
     281             :     Word16 no_bits,          /* i: number of bits for the index */
     282             :     const Word16 *p_scales,  /* i: scale values for the MSLVQ structures */
     283             :     Word16 *p_no_scales,     /* i: number of truncations for each MSLVQ structure */
     284             :     Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
     285             :     Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
     286             :     Word16 *x_lvq,           /* o: decoded LSF vector in Q1 */
     287             :     Word16 mode_glb,         /* i: index of LSLVQ structure */
     288             :     // note_ : renamed from scales
     289             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector */
     290             : )
     291             : {
     292        4080 :     Word32 index1 = 0, index2 = 0;
     293        4080 :     move32();
     294        4080 :     move32();
     295        4080 :     Word16 len_scales = MAX_NO_SCALES * 2, no_modes;
     296        4080 :     move16();
     297             :     Word16 i, im1, idx_scale;
     298             :     Word16 tmp;
     299             : 
     300        4080 :     no_modes = MAX_NO_SCALES + 1;
     301        4080 :     move16();
     302             : 
     303        4080 :     IF( LE_16( no_bits, shl( LEN_INDICE, 1 ) ) ) /* the third short is not used */
     304             :     {
     305        2392 :         index[2] = 0;
     306        2392 :         move16();
     307        2392 :         if ( LE_16( no_bits, LEN_INDICE ) )
     308             :         {
     309           0 :             index[1] = 0;
     310           0 :             move16();
     311             :         }
     312             :     }
     313             : 
     314             :     /* safety check in case of bit errors */
     315       16320 :     FOR( i = 0; i < 3; i++ )
     316             :     {
     317       12240 :         IF( index[i] < 0 )
     318             :         {
     319           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     320           0 :             scales_mslvq[0] = 0;
     321           0 :             move16();
     322           0 :             scales_mslvq[1] = 0;
     323           0 :             move16();
     324           0 :             index[i] = 0;
     325           0 :             move16();
     326           0 :             return 1;
     327             :         }
     328             :     }
     329             : 
     330             :     /* first subvector */
     331        4080 :     tmp = i_mult2( mode_glb, no_modes );
     332             : 
     333        4080 :     IF( p_offset_scale2[add( tmp, p_no_scales[add( shl( mode_glb, 1 ), 1 )] )] > 0 )
     334             :     {
     335        4080 :         divide_64_32_fx( index, p_offset_scale2[tmp + p_no_scales[add( shl( mode_glb, 1 ), 1 )]], &index1, &index2 );
     336             :     }
     337             :     ELSE
     338             :     {
     339           0 :         index1 = L_deposit_l( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
     340           0 :         index2 = L_deposit_l( 0 );
     341             :     }
     342        4080 :     IF( index1 == 0 )
     343             :     {
     344           0 :         FOR( i = 0; i < LATTICE_DIM; i++ )
     345             :         {
     346           0 :             x_lvq[i] = 0;
     347           0 :             move16();
     348             :         }
     349           0 :         scales_mslvq[0] = 0;
     350           0 :         move16();
     351             :     }
     352             :     ELSE
     353             :     {
     354        4080 :         IF( GE_32( index1, p_offset_scale1[mode_glb * no_modes + p_no_scales[mode_glb * 2]] ) )
     355             :         {
     356             :             /* safety check in case of bit errors */
     357           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     358           0 :             scales_mslvq[0] = 0;
     359           0 :             move16();
     360           0 :             scales_mslvq[1] = 0;
     361           0 :             move16();
     362           0 :             return 1;
     363             :         }
     364             : 
     365             :         /* find idx_scale */
     366        4080 :         i = 1;
     367        4080 :         move16();
     368        6674 :         WHILE( LE_16( i, p_no_scales[mode_glb * 2] ) && GE_32( index1, p_offset_scale1[mode_glb * no_modes + i] ) )
     369             :         {
     370        2594 :             i = add( i, 1 );
     371             :         }
     372        4080 :         idx_scale = sub( i, 1 );
     373        4080 :         move16();
     374        4080 :         index1 = L_sub( index1, p_offset_scale1[tmp + idx_scale] );
     375             : 
     376             :         /* find idx_leader */
     377        4080 :         i = 1;
     378        4080 :         move16();
     379             : 
     380       47264 :         WHILE( GE_32( index1, table_no_cv_fx[i] ) )
     381             :         {
     382       43184 :             i = add( i, 1 );
     383             :         }
     384        4080 :         im1 = sub( i, 1 );
     385        4080 :         decode_comb_fx( L_sub( index1, table_no_cv_fx[im1] ), x_lvq, im1 );
     386        4080 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     387        4080 :         move16();
     388             :     }
     389             : 
     390             :     /* second subvector */
     391        4080 :     IF( index2 == 0 )
     392             :     {
     393         252 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     394             :         {
     395         224 :             x_lvq[i] = 0;
     396         224 :             move16();
     397             :         }
     398          28 :         scales_mslvq[1] = 0;
     399          28 :         move16();
     400             :     }
     401             :     ELSE
     402             :     {
     403             :         /* find the index for the scale/truncation */
     404        4052 :         i = 1;
     405        4052 :         move16();
     406        6018 :         WHILE( GE_32( index2, p_offset_scale2[tmp + i] ) )
     407             :         {
     408        1966 :             i = add( i, 1 );
     409             :         }
     410             : 
     411        4052 :         idx_scale = sub( i, 1 );
     412        4052 :         index2 = L_sub( index2, p_offset_scale2[add( tmp, idx_scale )] );
     413             :         /* find the index of the leader vector */
     414        4052 :         i = 1;
     415        4052 :         move16();
     416       17406 :         WHILE( GE_32( index2, table_no_cv_fx[i] ) )
     417             :         {
     418       13354 :             i = add( i, 1 );
     419             :         }
     420        4052 :         im1 = sub( i, 1 );
     421        4052 :         decode_comb_fx( index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
     422        4052 :         scales_mslvq[1] = p_scales[add( i_mult2( mode_glb, len_scales ), add( MAX_NO_SCALES, idx_scale ) )];
     423        4052 :         move16();
     424             :     }
     425             : 
     426        4080 :     return 0;
     427             : }
     428             : 
     429      512262 : static Word16 decode_indexes_ivas_fx(
     430             :     Word16 *index,
     431             :     const Word16 no_bits,
     432             :     const Word16 *p_scales, // Q11
     433             :     const Word16 prediction_flag,
     434             :     Word16 *x_lvq, // Q1
     435             :     const Word16 mode_glb,
     436             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
     437             : )
     438             : {
     439      512262 :     Word32 index1 = 0, index2, idx_scale;
     440      512262 :     move32();
     441             :     Word16 i;
     442             : 
     443      512262 :     Word16 len_scales = i_mult( MAX_NO_SCALES, 2 );
     444             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     445             : 
     446      512262 :     IF( LE_16( no_bits, 2 * LEN_INDICE ) ) /* the third short is not used */
     447             :     {
     448      281915 :         index[2] = 0;
     449      281915 :         move16();
     450      281915 :         if ( LE_16( no_bits, LEN_INDICE ) )
     451             :         {
     452        1170 :             index[1] = 0;
     453        1170 :             move16();
     454             :         }
     455             :     }
     456             : 
     457             :     /* safety check in case of bit errors */
     458     2049048 :     FOR( i = 0; i < 3; i++ )
     459             :     {
     460     1536786 :         IF( index[i] < 0 )
     461             :         {
     462           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     463           0 :             scales_mslvq[0] = 0;
     464           0 :             move16();
     465           0 :             scales_mslvq[1] = 0;
     466           0 :             move16();
     467           0 :             index[i] = 0;
     468           0 :             return 1;
     469             :         }
     470             :     }
     471             : 
     472      512262 :     create_offset( offset_scale1, offset_scale2, mode_glb, prediction_flag );
     473             :     /* first subvector */
     474      512262 :     IF( offset_scale2[MAX_NO_SCALES - 1] > 0 )
     475             :     {
     476      512262 :         divide_64_32_fx( index, offset_scale2[MAX_NO_SCALES], &index1, &index2 );
     477             :     }
     478             :     ELSE
     479             :     {
     480           0 :         index1 = (UWord32) ( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
     481           0 :         move32();
     482           0 :         index2 = 0;
     483           0 :         move32();
     484             :     }
     485             : 
     486      512262 :     IF( index1 == 0 )
     487             :     {
     488        1602 :         FOR( i = 0; i < LATTICE_DIM; i++ )
     489             :         {
     490        1424 :             x_lvq[i] = 0;
     491        1424 :             scales_mslvq[0] = 0;
     492        1424 :             move16();
     493             :         }
     494             :     }
     495             :     ELSE
     496             :     {
     497      512084 :         IF( GE_32( index1, (Word32) offset_scale1[MAX_NO_SCALES] ) )
     498             :         {
     499             :             /* safety check in case of bit errors */
     500           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     501           0 :             scales_mslvq[0] = 0;
     502           0 :             move16();
     503           0 :             scales_mslvq[1] = 0;
     504           0 :             move16();
     505           0 :             return 1;
     506             :         }
     507             : 
     508             :         /* find idx_scale */
     509      512084 :         i = 1;
     510      512084 :         test();
     511      793513 :         WHILE( LE_16( (Word16) i, MAX_NO_SCALES ) && GE_32( index1, (Word32) offset_scale1[i] ) )
     512             :         {
     513      281429 :             i++;
     514             :         }
     515             : 
     516      512084 :         idx_scale = i - 1;
     517      512084 :         index1 = L_sub( index1, offset_scale1[idx_scale] );
     518             : 
     519             :         /* find idx_leader */
     520      512084 :         i = 1;
     521      512084 :         move16();
     522     6241373 :         WHILE( GE_32( index1, (Word32) table_no_cv[i] ) )
     523             :         {
     524     5729289 :             i++;
     525             :         }
     526      512084 :         decode_comb_fx( (Word32) ( index1 - table_no_cv[i - 1] ), x_lvq, i - 1 );
     527      512084 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     528      512084 :         move16();
     529             :         // for (i = 0; i < LATTICE_DIM; i++)
     530             :         //{
     531             :         //     //x_lvq[i] *= scale;
     532             :         //     x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
     533             :         // }
     534             :     }
     535             : 
     536             :     /* second subvector */
     537      512262 :     IF( index2 == 0 )
     538             :     {
     539      192222 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     540             :         {
     541             :             // x_lvq[i] = 0.0;
     542      170864 :             x_lvq[i] = 0;
     543      170864 :             move16();
     544             :         }
     545       21358 :         scales_mslvq[1] = 0;
     546       21358 :         move16();
     547             :     }
     548             :     ELSE
     549             :     {
     550             : 
     551             :         /* find the index for the scale/truncation */
     552      490904 :         i = 1;
     553      490904 :         move16();
     554      732097 :         WHILE( GE_32( index2, (Word32) offset_scale2[i] ) )
     555             :         {
     556      241193 :             i++;
     557             :         }
     558             : 
     559      490904 :         idx_scale = i - 1;
     560      490904 :         move16();
     561      490904 :         index2 = L_sub( index2, offset_scale2[idx_scale] );
     562             :         /* find the index of the leader vector */
     563      490904 :         i = 1;
     564      490904 :         move16();
     565     2180728 :         WHILE( GE_32( index2, (Word32) table_no_cv[i] ) )
     566             :         {
     567     1689824 :             i++;
     568             :         }
     569      490904 :         decode_comb_fx( (Word32) ( index2 - table_no_cv[i - 1] ), &x_lvq[LATTICE_DIM], i - 1 );
     570             : 
     571      490904 :         scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
     572      490904 :         move16();
     573             :         // for (i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++)
     574             :         //{
     575             :         //     //x_lvq[i] *= scale;
     576             :         //     x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
     577             :         // }
     578             :     }
     579             : 
     580      512262 :     return 0;
     581             : }
     582             : 
     583        4080 : Word16 deindex_lvq_fx(
     584             :     Word16 *index,           /* i  : index to be decoded, as an array of 3 Word16             */
     585             :     Word16 *x_lvq,           /* o  : decoded codevector                             Q(x2.56)  */
     586             :     Word16 mode,             /* i  : LVQ  coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
     587             :     Word16 sf_flag,          /* i  : safety net flag                                          */
     588             :     Word16 no_bits,          /* i  : number of bits for lattice                               */
     589             :     Word32 *p_offset_scale1, /* i  : offset for first subvector                               */
     590             :     Word32 *p_offset_scale2, /* i  : offset for the second subvector                          */
     591             :     Word16 *p_no_scales      /* i  : number of scales for each truncation and each MSLVQ structure */
     592             : )
     593             : {
     594             :     Word16 i;
     595             :     const Word16 *p_scales;
     596             :     Word16 mode_glb;
     597             :     Word32 L_tmp;
     598             :     // note_ : renamed from scales
     599             :     Word16 scales_mslvq[2];
     600             :     Word16 ber_flag;
     601             : 
     602        4080 :     IF( EQ_16( sf_flag, 1 ) )
     603             :     {
     604         580 :         mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub( no_bits, min_lat_bits_SN_fx[mode] )] );
     605         580 :         p_scales = &scales_fx[0][0];
     606         580 :         move16();
     607             :     }
     608             :     ELSE
     609             :     {
     610        3500 :         mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub( no_bits, min_lat_bits_pred_fx[mode] )] );
     611        3500 :         p_scales = &scales_p_fx[0][0];
     612        3500 :         move16();
     613             :     }
     614             : 
     615             :     /* decode the lattice index into the lattice codevectors for the two subvectors */
     616             :     ber_flag =
     617        4080 :         decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
     618             :                            p_offset_scale2, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
     619             : 
     620             : 
     621        4080 :     IF( EQ_16( sf_flag, 1 ) )
     622             :     {
     623             :         /* safety-net case*/
     624         580 :         IF( scales_mslvq[0] )
     625             :         {
     626        5220 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     627             :             {
     628        4640 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1  = Q13 */
     629             :                 /* Increase calculation accuracy  by shifting more to the left and using rounding instead of truncation*/
     630        4640 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     631        4640 :                 x_lvq[i] = round_fx( L_tmp );
     632        4640 :                 move16();
     633             :             }
     634             :         }
     635         580 :         IF( scales_mslvq[1] )
     636             :         {
     637        5112 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     638             :             {
     639        4544 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     640        4544 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     641        4544 :                 x_lvq[i] = round_fx( L_tmp );
     642        4544 :                 move16();
     643             :             }
     644             :         }
     645             :     }
     646             :     ELSE
     647             :     {
     648             :         /* predictive mode AR or MA */
     649        3500 :         IF( scales_mslvq[0] )
     650             :         {
     651       31500 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     652             :             {
     653       28000 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                             /* Q1+Q11+Q1  = Q13 */
     654       28000 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     655       28000 :                 x_lvq[i] = round_fx( L_tmp );
     656       28000 :                 move16();
     657             :             }
     658             :         }
     659        3500 :         IF( scales_mslvq[1] )
     660             :         {
     661       31356 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     662             :             {
     663       27872 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                             /* Q1+Q11+Q1  = Q13 */
     664       27872 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     665       27872 :                 x_lvq[i] = round_fx( L_tmp );
     666       27872 :                 move16();
     667             :             }
     668             :         }
     669             :     }
     670             : 
     671        4080 :     return ber_flag;
     672             : }
     673             : 
     674      511831 : Word16 deindex_lvq_ivas_fx(
     675             :     Word16 *index,  /* i  : index to be decoded, as an array of 3 Word16             */
     676             :     Word16 *x_lvq,  /* o  : decoded codevector                             Q(x2.56)  */
     677             :     Word16 mode,    /* i  : LVQ  coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
     678             :     Word16 sf_flag, /* i  : safety net flag                                          */
     679             :     Word16 no_bits  /* i  : number of bits for lattice                               */
     680             : )
     681             : {
     682             :     Word16 i;
     683             :     const Word16 *p_scales;
     684             :     Word16 mode_glb;
     685             :     Word32 L_tmp;
     686             :     // note_ : renamed from scales
     687             :     Word16 scales_mslvq[2];
     688             :     Word16 ber_flag;
     689             : 
     690      511831 :     IF( EQ_16( sf_flag, 1 ) )
     691             :     {
     692       71782 :         IF( LT_16( mode, 6 ) ) /* for NB */
     693             :         {
     694           0 :             mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( no_bits, min_lat_bits_SN[mode] )] );
     695             :         }
     696             :         ELSE
     697             :         {
     698       71782 :             mode_glb = add( offset_lvq_modes_SN[mode], sub( no_bits, min_lat_bits_SN[mode] ) ); /* there is granularity of 1 bit */
     699             :         }
     700       71782 :         p_scales = &scales_ivas_fx[0][0]; // Q11
     701       71782 :         move16();
     702             :     }
     703             :     ELSE
     704             :     {
     705      440049 :         test();
     706      440049 :         IF( ( LT_16( mode, 6 ) ) || ( EQ_16( mode, 12 ) ) ) /* for NB */
     707             :         {
     708        9752 :             mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( no_bits, min_lat_bits_pred[mode] )] );
     709             :         }
     710             :         ELSE
     711             :         {
     712      430297 :             mode_glb = add( offset_lvq_modes_pred[mode], sub( no_bits, min_lat_bits_pred[mode] ) );
     713             :         }
     714      440049 :         p_scales = &scales_p_ivas_fx[0][0]; // Q11
     715      440049 :         move16();
     716             :     }
     717             : 
     718             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     719      511831 :     create_offset( offset_scale1, offset_scale2, mode_glb, 1 - sf_flag );
     720             : 
     721             :     /* decode the lattice index into the lattice codevectors for the two subvectors */
     722             :     // ber_flag =
     723             :     //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, offset_scale1,
     724             :     //         offset_scale2, x_lvq, mode_glb, scales_mslvq); /* x_lvq is here Q1 */
     725             :     ber_flag =
     726      511831 :         decode_indexes_ivas_fx( index, no_bits, p_scales, 1 - sf_flag, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
     727             : 
     728             : 
     729      511831 :     IF( EQ_16( sf_flag, 1 ) )
     730             :     {
     731             :         /* safety-net case*/
     732       71782 :         IF( scales_mslvq[0] )
     733             :         {
     734      645282 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     735             :             {
     736      573584 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1  = Q13 */
     737             :                 /* Increase calculation accuracy  by shifting more to the left and using rounding instead of truncation*/
     738      573584 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     739      573584 :                 x_lvq[i] = round_fx( L_tmp );
     740      573584 :                 move16();
     741             :             }
     742             :         }
     743       71782 :         IF( scales_mslvq[1] )
     744             :         {
     745      602487 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     746             :             {
     747      535544 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     748      535544 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     749      535544 :                 x_lvq[i] = round_fx( L_tmp );
     750      535544 :                 move16();
     751             :             }
     752             :         }
     753             :     }
     754             :     ELSE
     755             :     {
     756             :         /* predictive mode AR or MA */
     757      440049 :         IF( scales_mslvq[0] )
     758             :         {
     759     3959703 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     760             :             {
     761     3519736 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                  /* Q1+Q11+Q1  = Q13 */
     762     3519736 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     763     3519736 :                 x_lvq[i] = round_fx( L_tmp );
     764     3519736 :                 move16();
     765             :             }
     766             :         }
     767      440049 :         IF( scales_mslvq[1] )
     768             :         {
     769     3811779 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     770             :             {
     771     3388248 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                  /* Q1+Q11+Q1  = Q13 */
     772     3388248 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     773     3388248 :                 x_lvq[i] = round_fx( L_tmp );
     774     3388248 :                 move16();
     775             :             }
     776             :         }
     777             :     }
     778             : 
     779      511831 :     return ber_flag;
     780             : }
     781             : 
     782             : /*----------------------------------------------------------------------------------------------------*
     783             :  * deindex_lvq_cng()
     784             :  * Note:
     785             :  * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
     786             :  * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
     787             :  * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
     788             :  *----------------------------------------------------------------------------------------------------*/
     789             : 
     790           0 : Word16 deindex_lvq_cng_fx(
     791             :     Word16 *index,           /* i: index to be decoded, as an array of 3 short */
     792             :     Word16 *x_lvq,           /* o: decoded codevector  Q9 */
     793             :     Word16 idx_cv,           /* i: relative mode_lvq, wrt START_CNG */
     794             :     Word16 no_bits,          /* i: number of bits for lattice */
     795             :     Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
     796             :     Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
     797             :     Word16 *p_no_scales      /* i: number of scales for each MSLVQ structure and each subvector */
     798             : )
     799             : {
     800             :     Word16 i;
     801             :     Word32 L_tmp;
     802             :     const Word16 *p_scales;
     803             :     Word16 mode_glb, mode;
     804             :     // note_ : renamed from scales as global declaration of scales is causing warning
     805             :     Word16 scales_mslvq[2];
     806             :     Word16 ber_flag;
     807             : 
     808             :     /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
     809           0 :     mode_glb = add( START_CNG, idx_cv );
     810             : 
     811           0 :     mode = add( LVQ_COD_MODES, idx_cv );
     812             : 
     813           0 :     p_scales = &scales_fx[0][0];
     814           0 :     move16();
     815             :     ber_flag =
     816           0 :         decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq );
     817             : 
     818           0 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     819             :     {
     820           0 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                 /* Q1+Q11+Q1  = Q13 */
     821           0 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     822           0 :         x_lvq[i] = round_fx( L_tmp );
     823           0 :         move16();
     824             :     }
     825           0 :     FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     826             :     {
     827           0 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     828           0 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     829           0 :         x_lvq[i] = round_fx( L_tmp );
     830           0 :         move16();
     831             :     }
     832             : 
     833             :     /* check if permutting needed */
     834           0 :     IF( cng_sort[idx_cv] )
     835             :     {
     836           0 :         permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
     837             :     }
     838             : 
     839           0 :     return ber_flag;
     840             : }
     841             : 
     842             : 
     843             : /*----------------------------------------------------------------------------------------------------*
     844             :  * deindex_lvq_cng()
     845             :  * Note:
     846             :  * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
     847             :  * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
     848             :  * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
     849             :  *----------------------------------------------------------------------------------------------------*/
     850             : 
     851         431 : Word16 deindex_lvq_cng_ivas_fx(
     852             :     Word16 *index, /* i: index to be decoded, as an array of 3 short */
     853             :     Word16 *x_lvq, /* o: decoded codevector  Q9 */
     854             :     Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
     855             :     Word16 no_bits /* i: number of bits for lattice */
     856             : )
     857             : {
     858             :     Word16 i;
     859             :     Word32 L_tmp;
     860             :     const Word16 *p_scales;
     861             :     Word16 mode_glb, mode;
     862             :     // note_ : renamed from scales as global declaration of scales is causing warning
     863             :     Word16 scales_mslvq[2];
     864             :     Word16 ber_flag;
     865             : 
     866             :     /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
     867         431 :     mode_glb = add( START_CNG_IVAS, idx_cv );
     868             : 
     869         431 :     mode = add( LVQ_COD_MODES, idx_cv );
     870             : 
     871         431 :     p_scales = &scales_ivas_fx[0][0];
     872         431 :     move16();
     873             :     // ber_flag =
     874             :     //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq);
     875             :     ber_flag =
     876         431 :         decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
     877             : 
     878        3879 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     879             :     {
     880        3448 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                 /* Q1+Q11+Q1  = Q13 */
     881        3448 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     882        3448 :         x_lvq[i] = round_fx( L_tmp );
     883        3448 :         move16();
     884             :     }
     885        3879 :     FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     886             :     {
     887        3448 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     888        3448 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     889        3448 :         x_lvq[i] = round_fx( L_tmp );
     890        3448 :         move16();
     891             :     }
     892             : 
     893             :     /* check if permutting needed */
     894         431 :     IF( cng_sort[idx_cv] )
     895             :     {
     896         424 :         permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
     897             :     }
     898             : 
     899         431 :     return ber_flag;
     900             : }
     901             : 
     902             : /* combinatorial indexing */
     903     3249075 : static void idx2c_fx(
     904             :     Word16 n,  /* i  : total number of positions (components)*/
     905             :     Word16 *p, /* o  : array with positions of the k components */
     906             :     Word16 k,  /* i  : number of components whose position is to be determined */
     907             :     Word16 val /* i  : index to be decoded  */
     908             : )
     909             : {
     910             :     Word16 i, skip, pos, k1;
     911             : 
     912     3249075 :     skip = 0;
     913     3249075 :     move16();
     914     3249075 :     pos = 0;
     915     3249075 :     move16();
     916     3249075 :     k1 = sub( k, 1 );
     917     3249075 :     move16();
     918     6863315 :     WHILE( LT_16( add( skip, sub( C_VQ[n - pos - 1][k1], 1 ) ), val ) )
     919             :     {
     920     3614240 :         skip = add( skip, C_VQ[n - pos - 1][k1] );
     921     3614240 :         move16();
     922     3614240 :         pos++;
     923     3614240 :         move16();
     924             :     }
     925             : 
     926     3249075 :     p[0] = pos;
     927     3249075 :     move16();
     928     3249075 :     n = sub( n, add( pos, 1 ) );
     929     3249075 :     val = sub( val, skip );
     930     3249075 :     IF( EQ_16( k, 1 ) )
     931             :     {
     932     1219393 :         return;
     933             :     }
     934             : 
     935     2029682 :     idx2c_fx( n, p + 1, k1, val );
     936             : 
     937             :     /* pos+1 */
     938     6149747 :     FOR( i = 1; i < k; i++ )
     939             :     {
     940     4120065 :         p[i] = add( p[i], add( pos, 1 ) );
     941     4120065 :         move16();
     942             :     }
     943             : 
     944     2029682 :     return;
     945             : }
     946             : /* combinatorial deindexing */
     947     1014317 : static void decode_comb_fx(
     948             :     Word32 index,   /* i  : index to be decoded */
     949             :     Word16 *cv,     /* o  : decoded codevector Q1*/
     950             :     Word16 idx_lead /* i  : leader class index */
     951             : )
     952             : {
     953             :     Word16 idx_sign;
     954     1014317 :     IF( LT_32( L_shl( index, 1 ), pi0[idx_lead] ) )
     955             :     {
     956       74279 :         idx_sign = 0;
     957       74279 :         move16();
     958             :     }
     959             :     ELSE
     960             :     {
     961      940038 :         idx_sign = extract_l( div_l( L_shl( index, 1 ), pi0[idx_lead] ) ); /*(index/pi0_fx[idx_lead]); */
     962             :     }
     963     1014317 :     index = L_sub( index, L_mult0( idx_sign, pi0[idx_lead] ) );
     964     1014317 :     decode_leaders_fx( extract_l( index ), idx_lead, cv );
     965     1014317 :     decode_sign_pc1_fx( cv, idx_sign, pl_par[idx_lead] );
     966             : 
     967     1014317 :     return;
     968             : }
     969     1014317 : void decode_sign_pc1_fx(
     970             :     Word16 *c,       /* o  : decoded codevector  Q1*/
     971             :     Word16 idx_sign, /* i  : sign index */
     972             :     Word16 parity    /* i  : parity flag (+1/-1/0) */
     973             : )
     974             : {
     975     1014317 :     Word16 i, len = LATTICE_DIM, cnt_neg = 1;
     976             : 
     977     1014317 :     if ( parity )
     978             :     {
     979      427258 :         len = sub( len, 1 );
     980             :     }
     981             : 
     982     8701595 :     FOR( i = 0; i < len; i++ )
     983             :     {
     984     7687278 :         IF( c[i] > 0 )
     985             :         {
     986             :             /*if (idx_sign % 2) */
     987     5584853 :             IF( s_and( idx_sign, 1 ) )
     988             :             {
     989     2700017 :                 c[i] = negate( c[i] );
     990     2700017 :                 move16();
     991     2700017 :                 cnt_neg = negate( cnt_neg );
     992     2700017 :                 move16();
     993             :             }
     994     5584853 :             idx_sign = shr( idx_sign, 1 ); /*  >>= 1; */
     995             :         }
     996             :     }
     997             : 
     998     1014317 :     IF( LT_16( len, LATTICE_DIM ) )
     999             :     {
    1000      427258 :         IF( NE_16( cnt_neg, parity ) )
    1001             :         {
    1002      193924 :             c[len] = negate( c[len] );
    1003      193924 :             move16();
    1004             :         }
    1005             :     }
    1006             : 
    1007     1014317 :     return;
    1008             : }
    1009             : 
    1010             : 
    1011     1014317 : static void decode_leaders_fx(
    1012             :     Word16 index,    /* i  : index to be decoded    */
    1013             :     Word16 idx_lead, /* i  : leader class index     */
    1014             :     Word16 *cv       /* o  : decoded codevector   Q1*/
    1015             : )
    1016             : {
    1017             :     Word16 i, no_vals_loc, no_vals_last, p[LATTICE_DIM], dim_loc, n_crt;
    1018             :     Word16 index1;
    1019             :     Word16 val_crt;
    1020             : 
    1021     1014317 :     no_vals_loc = no_vals[idx_lead];
    1022     1014317 :     move16();
    1023     1014317 :     val_crt = vals_fx[idx_lead][no_vals_loc - 1];
    1024     1014317 :     move16(); /*Q1  */
    1025     1014317 :     no_vals_last = no_vals_ind[idx_lead][no_vals_loc - 1];
    1026     1014317 :     move16();
    1027             : 
    1028     5879778 :     FOR( i = 0; i < no_vals_last; i++ )
    1029             :     {
    1030     4865461 :         cv[i] = val_crt;
    1031     4865461 :         move16(); /*Q1 */
    1032             :     }
    1033             : 
    1034     1014317 :     val_crt = 1;
    1035     1014317 :     move16();
    1036     1014317 :     dim_loc = no_vals_last;
    1037     1014317 :     move16();
    1038             : 
    1039     1014317 :     SWITCH( no_vals_loc )
    1040             :     {
    1041      101629 :         case 1:
    1042      101629 :             BREAK;
    1043      608563 :         case 2:
    1044      608563 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index );
    1045      608563 :             put_value_fx( cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind[idx_lead][0] );
    1046      608563 :             BREAK;
    1047        2580 :         case 4:
    1048        2580 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][2] );
    1049        2580 :             n_crt = no_vals_ind[idx_lead][2];
    1050        2580 :             move16();
    1051        2580 :             index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index ); /*  index1 = index/C_VQ_fx[dim_loc][n_crt]; */
    1052        2580 :             /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
    1053        2580 :             idx2c_fx( dim_loc, p, n_crt, index );
    1054        2580 :             put_value_fx( cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind[idx_lead][2] ); /* Q1 */
    1055        2580 :             index = index1;
    1056        2580 :             move16();
    1057             :             /* no break */
    1058      304125 :         case 3:
    1059      304125 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][1] );
    1060      304125 :             n_crt = no_vals_ind[idx_lead][1];
    1061      304125 :             move16();
    1062      304125 :             index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index );
    1063             :             /*index  = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]));move16(); */
    1064      304125 :             idx2c_fx( dim_loc, p, n_crt, index );
    1065      304125 :             put_value_fx( cv, p, vals_fx[idx_lead][1], sub( dim_loc, n_crt ), n_crt );
    1066      304125 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index1 );
    1067      304125 :             move16();
    1068      304125 :             put_value_fx( cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind[idx_lead][0] );
    1069      304125 :             BREAK;
    1070             :     }
    1071             : 
    1072     1014317 :     return;
    1073             : }
    1074             : 
    1075             : /* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x.  */
    1076      636380 : static Word32 divide_32_32_fx( Word32 y,   /* i */
    1077             :                                Word32 x,   /* i */
    1078             :                                Word32 *rem /* o */
    1079             : )
    1080             : {
    1081             :     Word32 result, t, L_tmp;
    1082             :     Word16 i, ny, nx, nyx;
    1083             : 
    1084             : 
    1085      636380 :     IF( LT_32( y, x ) )
    1086             :     {
    1087       27079 :         result = L_deposit_l( 0 );
    1088       27079 :         *rem = y;
    1089       27079 :         move32();
    1090             :     }
    1091             :     ELSE
    1092             :     {
    1093             : 
    1094      609301 :         result = L_deposit_l( 0 );
    1095      609301 :         IF( y == 0 )
    1096             :         {
    1097           0 :             ny = 0;
    1098           0 :             move16();
    1099             :         }
    1100             :         ELSE
    1101             :         {
    1102      609301 :             ny = sub( 31, norm_l( y ) );
    1103             :         }
    1104      609301 :         IF( x == 0 )
    1105             :         {
    1106           0 :             nx = 0;
    1107           0 :             move16();
    1108             :         }
    1109             :         ELSE
    1110             :         {
    1111      609301 :             nx = sub( 31, norm_l( x ) );
    1112             :         }
    1113             : 
    1114      609301 :         nyx = sub( ny, nx );
    1115             : 
    1116             :         /*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
    1117      609301 :         t = L_shr( y, add( nyx, 1 ) );
    1118     8841738 :         FOR( i = 0; i <= nyx; i++ )
    1119             :         {
    1120     8232437 :             t = L_add( L_shl( t, 1 ), L_and( L_shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
    1121     8232437 :             result = L_shl( result, 1 );
    1122     8232437 :             L_tmp = L_sub( t, x );
    1123     8232437 :             IF( L_tmp >= 0 )
    1124             :             {
    1125     4110385 :                 result = L_add( result, 1 );
    1126     4110385 :                 t = L_add( L_tmp, 0 );
    1127             :             }
    1128             :         }
    1129      609301 :         *rem = t;
    1130      609301 :         move32();
    1131             :     }
    1132      636380 :     return result;
    1133             : }
    1134             : 
    1135             : /* divide_32_32_fx() :Division reminder for Word16 - rem is the reminder of the division between y and x.  */
    1136      306705 : static Word16 divide_16_16_fx( Word16 y,   /* i */
    1137             :                                Word16 x,   /* i */
    1138             :                                Word16 *rem /* o */
    1139             : )
    1140             : {
    1141             :     Word16 result, t, tmp;
    1142             :     Word16 i, ny, nx, nyx;
    1143             : 
    1144             : 
    1145      306705 :     IF( LT_32( y, x ) )
    1146             :     {
    1147       37565 :         result = 0;
    1148       37565 :         move16();
    1149       37565 :         *rem = y;
    1150       37565 :         move16();
    1151             :     }
    1152             :     ELSE
    1153             :     {
    1154             : 
    1155      269140 :         result = 0;
    1156      269140 :         move16();
    1157      269140 :         IF( y == 0 )
    1158             :         {
    1159           0 :             ny = 0;
    1160           0 :             move16();
    1161             :         }
    1162             :         ELSE
    1163             :         {
    1164      269140 :             ny = sub( 15, norm_s( y ) );
    1165             :         }
    1166      269140 :         IF( x == 0 )
    1167             :         {
    1168           0 :             nx = 0;
    1169           0 :             move16();
    1170             :         }
    1171             :         ELSE
    1172             :         {
    1173      269140 :             nx = sub( 15, norm_s( x ) );
    1174             :         }
    1175             : 
    1176      269140 :         nyx = sub( ny, nx );
    1177             : 
    1178      269140 :         t = s_and( shr( y, add( nyx, 1 ) ), sub( shl( 1, sub( nx, 1 ) ), 1 ) );
    1179     1131102 :         FOR( i = 0; i <= nyx; i++ )
    1180             :         {
    1181      861962 :             t = add( shl( t, 1 ), s_and( shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
    1182      861962 :             result = shl( result, 1 );
    1183      861962 :             tmp = sub( t, x );
    1184      861962 :             IF( tmp >= 0 )
    1185             :             {
    1186      498571 :                 result = add( result, 1 );
    1187      498571 :                 t = tmp;
    1188      498571 :                 move16();
    1189             :             }
    1190             :         }
    1191      269140 :         *rem = t;
    1192      269140 :         move16();
    1193             :     }
    1194      306705 :     return result;
    1195             : }
    1196             : 
    1197      516342 : static void divide_64_32_fx(
    1198             :     Word16 *xs,     /* i  : denominator as array of two int32  */
    1199             :     Word32 y,       /* i  : nominator on 32 bits               */
    1200             :     Word32 *result, /* o  : integer division result on 32 bits */
    1201             :     Word32 *rem     /* o  : integer division reminder on 32 bits */
    1202             : )
    1203             : {
    1204             :     Word16 nb_x1;
    1205             :     Word32 r, x_tmp, x[2], q, q1;
    1206             : 
    1207      516342 :     x[0] = L_add( L_add( L_shl( L_deposit_l( s_and( xs[2], 1 ) ), 2 * LEN_INDICE ), L_shl( L_deposit_l( xs[1] ), LEN_INDICE ) ), L_deposit_l( xs[0] ) );
    1208      516342 :     move32();
    1209      516342 :     x[1] = L_shr( L_deposit_l( xs[2] ), 1 );
    1210      516342 :     move32();
    1211             : 
    1212             :     /*x[0] = (((xs[2])&(1)<<(LEN_INDICE*2)) + (xs[1]<<LEN_INDICE) + xs[0];
    1213             :     x[1] = xs[2]>>1;                                                              */
    1214             : 
    1215      516342 :     IF( x[1] == 0 )
    1216             :     {
    1217      396304 :         nb_x1 = 0;
    1218      396304 :         move16();
    1219             :     }
    1220             :     ELSE
    1221             :     {
    1222      120038 :         nb_x1 = sub( 31, norm_l( x[1] ) ); /*get_no_bits_fx(x[1]); */
    1223             :     }
    1224             :     /* take the first 31 bits */
    1225      516342 :     IF( nb_x1 > 0 )
    1226             :     {
    1227      120038 :         x_tmp = L_add( L_shl( x[1], sub( 31, nb_x1 ) ), L_shr( x[0], nb_x1 ) );
    1228             :         /* x_tmp = (x[1]<<(32-nb_x1)) + (x[0]>>nb_x1);        */
    1229             : 
    1230      120038 :         q = divide_32_32_fx( x_tmp, y, &r );                                                     /* q = x_tmp/y, reminder r */
    1231      120038 :         r = L_add( L_shl( r, nb_x1 ), L_and( x[0], L_deposit_l( sub( shl( 1, nb_x1 ), 1 ) ) ) ); /* this is the first reminder */
    1232             :         /* r = (r<<nb_x1)+(x[0]&((1<<nb_x1) - 1));         */
    1233             : 
    1234      120038 :         q1 = divide_32_32_fx( r, y, rem );
    1235      120038 :         *result = L_add( L_shl( q, nb_x1 ), q1 );
    1236      120038 :         move32();
    1237             :     }
    1238             :     ELSE
    1239             :     {
    1240      396304 :         *result = divide_32_32_fx( x[0], y, rem );
    1241      396304 :         move32();
    1242             :     }
    1243             : 
    1244      516342 :     return;
    1245             : }
    1246             : 
    1247     1219393 : static void put_value_fx(
    1248             :     Word16 *cv,       /* i/o  : input codevector            Q1*/
    1249             :     Word16 *p,        /* i  : array with positions            */
    1250             :     Word16 val,       /* i  : value to be inserted          Q1*/
    1251             :     Word16 dim,       /* i  : vector dimension                */
    1252             :     Word16 no_new_val /* i  : number of values to be inserted */
    1253             : )
    1254             : {
    1255             :     Word16 cv_out[LATTICE_DIM];
    1256             :     Word16 i, occ[LATTICE_DIM], cnt, limit;
    1257             : 
    1258     1219393 :     limit = add( dim, no_new_val );
    1259    10587003 :     FOR( i = 0; i < limit; i++ )
    1260             :     {
    1261     9367610 :         occ[i] = 0;
    1262     9367610 :         move16();
    1263             :     }
    1264             : 
    1265     4468468 :     FOR( i = 0; i < no_new_val; i++ )
    1266             :     {
    1267     3249075 :         cv_out[p[i]] = val;
    1268     3249075 :         move16();
    1269     3249075 :         occ[p[i]] = 1;
    1270     3249075 :         move16();
    1271             :     }
    1272             : 
    1273     1219393 :     cnt = 0;
    1274     1219393 :     move16();
    1275    10587003 :     FOR( i = 0; i < limit; i++ )
    1276             :     {
    1277     9367610 :         if ( occ[i] == 0 )
    1278             :         {
    1279     6118535 :             cv_out[i] = cv[cnt++];
    1280     6118535 :             move16();
    1281             :         }
    1282             :     }
    1283             : 
    1284    10587003 :     FOR( i = 0; i < limit; i++ )
    1285             :     {
    1286     9367610 :         cv[i] = cv_out[i];
    1287     9367610 :         move16();
    1288             :     }
    1289             : 
    1290     1219393 :     return;
    1291             : }
    1292             : 
    1293             : /*-----------------------------------------------------------------*
    1294             :  * create_offset()
    1295             :  *
    1296             :  *
    1297             :  *-----------------------------------------------------------------*/
    1298             : 
    1299     1370079 : void create_offset(
    1300             :     UWord32 *offset_scale1,
    1301             :     UWord32 *offset_scale2,
    1302             :     const Word16 mode,
    1303             :     const Word16 prediction_flag )
    1304             : {
    1305             :     Word16 tmp, tmp1;
    1306             : 
    1307     1370079 :     if ( prediction_flag == 0 )
    1308             :     {
    1309             :         /* safety_net */
    1310      235469 :         tmp = no_lead_idx[mode][0];
    1311      235469 :         if ( ( tmp <= LIMIT_LEADER ) && ( tmp < no_lead_idx[mode][1] - 2 ) )
    1312             :         {
    1313           0 :             tmp += DELTA_LEADER;
    1314             :         }
    1315      235469 :         make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
    1316      235469 :         make_offset_scale( table_no_cv, leaders_short[no_lead_idx[mode][1]], MAX_NO_SCALES, offset_scale2 );
    1317             :     }
    1318             :     else
    1319             :     {
    1320     1134610 :         tmp = no_lead_p_idx[mode][0];
    1321     1134610 :         tmp1 = no_lead_p_idx[mode][1];
    1322     1134610 :         if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
    1323             :         {
    1324       25546 :             tmp += DELTA_LEADER;
    1325             :         }
    1326             : 
    1327     1134610 :         if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
    1328             :         {
    1329           0 :             tmp += DELTA_LEADER;
    1330           0 :             tmp1 = DELTA_LEADER;
    1331             :         }
    1332             : 
    1333     1134610 :         make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
    1334     1134610 :         make_offset_scale( table_no_cv, leaders_short[tmp1], MAX_NO_SCALES, offset_scale2 );
    1335             :     }
    1336             : 
    1337     1370079 :     return;
    1338             : }
    1339             : 
    1340             : /*-----------------------------------------------------------------*
    1341             :  * sort_desc_ind()
    1342             :  *
    1343             :  * sorts in descending order and computes indices in the sorted vector
    1344             :  *-----------------------------------------------------------------*/
    1345             : 
    1346        4525 : void sort_desc_ind_32_fx(
    1347             :     Word32 *s,        /* i/o: vector to be sorted Qx*/
    1348             :     const Word16 len, /* i  : vector length       */
    1349             :     Word16 *ind       /* o  : array of indices    */
    1350             : )
    1351             : {
    1352             :     Word16 i, k, sorted, a;
    1353             :     Word32 t;
    1354             : 
    1355       22370 :     FOR( i = 0; i < len; i++ )
    1356             :     {
    1357       17845 :         ind[i] = i;
    1358       17845 :         move16();
    1359             :     }
    1360        4525 :     sorted = 0;
    1361        4525 :     move16();
    1362       15302 :     FOR( k = len - 1; k && !sorted; k-- )
    1363             :     {
    1364       10777 :         sorted = 1;
    1365       10777 :         move16();
    1366       34221 :         FOR( i = 0; i < k; i++ )
    1367             :         {
    1368       23444 :             IF( LT_32( s[i], s[i + 1] ) )
    1369             :             {
    1370       10980 :                 sorted = 0;
    1371       10980 :                 move16();
    1372       10980 :                 t = s[i];
    1373       10980 :                 move16();
    1374       10980 :                 s[i] = s[i + 1];
    1375       10980 :                 move16();
    1376       10980 :                 s[i + 1] = t;
    1377       10980 :                 move16();
    1378       10980 :                 a = ind[i];
    1379       10980 :                 move16();
    1380       10980 :                 ind[i] = ind[i + 1];
    1381       10980 :                 move16();
    1382       10980 :                 ind[i + 1] = a;
    1383       10980 :                 move16();
    1384             :             }
    1385             :         }
    1386             :     }
    1387             : 
    1388        4525 :     return;
    1389             : }
    1390             : 
    1391        3197 : void deindex_lvq_SHB_fx(
    1392             :     UWord32 index,
    1393             :     Word16 *out,
    1394             :     const Word16 nbits,
    1395             :     const Word16 mode )
    1396             : {
    1397             :     UWord16 i;
    1398             :     const Word8 *p_no_lead;
    1399             :     const Word16 *p_scales;
    1400             :     Word16 scale;
    1401             :     Word16 idx_scale;
    1402             :     UWord32 offsets[MAX_NO_SCALES + 1];
    1403             : 
    1404        3197 :     IF( mode == 0 )
    1405             :     {
    1406        3197 :         p_no_lead = &no_lead_BWE[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
    1407        3197 :         p_scales = &scales_BWE_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
    1408             :     }
    1409             :     ELSE
    1410             :     {
    1411           0 :         p_no_lead = &no_lead_BWE_3b[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
    1412           0 :         p_scales = &scales_BWE_3b_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
    1413             :     }
    1414             : 
    1415             : 
    1416        3197 :     IF( index == 0 )
    1417             :     {
    1418           0 :         set16_fx( out, 0, LATTICE_DIM );
    1419             :     }
    1420             :     ELSE
    1421             :     {
    1422             :         /* create offsets */
    1423        3197 :         offsets[0] = 0;
    1424        3197 :         move32();
    1425       12788 :         FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1426             :         {
    1427        9591 :             offsets[i + 1] = UL_addNsD( table_no_cv[p_no_lead[i]], offsets[i] );
    1428        9591 :             move32();
    1429             :         }
    1430             : 
    1431             :         /* find idx_scale */
    1432        3197 :         idx_scale = 0;
    1433        3197 :         test();
    1434        7439 :         WHILE( LE_32( i, MAX_NO_SCALES ) && index >= offsets[idx_scale] )
    1435             :         {
    1436        4242 :             test();
    1437        4242 :             idx_scale = add( idx_scale, 1 );
    1438             :         }
    1439        3197 :         idx_scale = sub( idx_scale, 1 );
    1440        3197 :         index = L_sub( index, offsets[idx_scale] );
    1441             : 
    1442             :         /* find idx_leader */
    1443        3197 :         i = 1;
    1444        3197 :         move16();
    1445       21751 :         WHILE( GT_32( index, table_no_cv[i] ) )
    1446             :         {
    1447       18554 :             i = add( i, 1 );
    1448             :         }
    1449        3197 :         i = sub( i, 1 );
    1450             : 
    1451        3197 :         decode_comb_fx( (Word32) ( L_sub( L_sub( index, table_no_cv[i] ), 1 ) ), out, i );
    1452             : 
    1453        3197 :         scale = p_scales[idx_scale];
    1454        3197 :         move16();
    1455       28773 :         FOR( i = 0; i < LATTICE_DIM; i++ )
    1456             :         {
    1457       25576 :             Word32 temp = Mpy_32_16_1( sigma_BWE_fx[add( i_mult( mode, LATTICE_DIM ), i )], scale );
    1458       25576 :             temp = Mpy_32_16_1( temp, out[i] );
    1459       25576 :             out[i] = extract_l( temp ); /* Q15 output*/
    1460       25576 :             move16();
    1461             :             // out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i];
    1462             :         }
    1463             :     }
    1464             : 
    1465        3197 :     return;
    1466             : }

Generated by: LCOV version 1.14