LCOV - code coverage report
Current view: top level - lib_com - mslvq_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 545 619 88.0 %
Date: 2025-06-27 02:59:36 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        1730 : 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        1730 :     p1 = perm[0];
      89        1730 :     move16();
      90        1730 :     p2 = perm[1];
      91        1730 :     move16();
      92        1730 :     tmp = pTmp1[p1];
      93        1730 :     move16();
      94        1730 :     pTmp1[p1] = pTmp1[p2];
      95        1730 :     move16();
      96        1730 :     move16();
      97        1730 :     pTmp1[p2] = tmp;
      98        1730 :     move16();
      99        1730 :     p1 = perm[2];
     100        1730 :     move16();
     101             : 
     102        1730 :     IF( GT_16( p1, -1 ) )
     103             :     {
     104         270 :         p2 = perm[3];
     105         270 :         move16();
     106         270 :         tmp = pTmp1[p1];
     107         270 :         move16();
     108         270 :         pTmp1[p1] = pTmp1[p2];
     109         270 :         move16();
     110         270 :         move16();
     111         270 :         pTmp1[p2] = tmp;
     112         270 :         move16();
     113             :     }
     114             : 
     115        1730 :     return;
     116             : }
     117             : 
     118             : 
     119        7239 : 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      933831 :     FOR( i = 0; i < MAX_NO_MODES; i++ )
     132             :     {
     133     3633978 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     134             :         {
     135     2707386 :             if ( no_lead_fx[i][j] > 0 )
     136             :             {
     137     2475738 :                 k = add( k, 1 );
     138             :             }
     139     2707386 :             if ( no_lead_fx[i][j] <= 0 )
     140             :             {
     141      231648 :                 j = MAX_NO_SCALES - 1;
     142      231648 :                 move16();
     143             :             }
     144             :         }
     145      926592 :         no_scales[i][0] = k;
     146      926592 :         move16();
     147             : 
     148     3474720 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     149             :         {
     150     2548128 :             if ( no_lead_fx[i][j] > 0 )
     151             :             {
     152     2070354 :                 k = add( k, 1 );
     153             :             }
     154     2548128 :             if ( no_lead_fx[i][j] <= 0 )
     155             :             {
     156      477774 :                 j = MAX_NO_SCALES << 1;
     157      477774 :                 move16();
     158             :             }
     159             :         }
     160      926592 :         no_scales[i][1] = k;
     161      926592 :         move16();
     162             :     }
     163             :     /* predictive mode */
     164     1056894 :     FOR( i = 0; i < MAX_NO_MODES_p; i++ )
     165             :     {
     166     4147947 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     167             :         {
     168     3098292 :             if ( no_lead_p_fx[i][j] > 0 )
     169             :             {
     170     2975229 :                 k = add( k, 1 );
     171             :             }
     172     3098292 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     173             :             {
     174      123063 :                 j = MAX_NO_SCALES - 1;
     175      123063 :                 move16();
     176             :             }
     177             :         }
     178     1049655 :         no_scales_p[i][0] = k;
     179     1049655 :         move16();
     180             : 
     181     3938016 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     182             :         {
     183     2888361 :             if ( no_lead_p_fx[i][j] > 0 )
     184             :             {
     185     2359914 :                 k = add( k, 1 );
     186             :             }
     187             : 
     188     2888361 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     189             :             {
     190      528447 :                 j = MAX_NO_SCALES << 1;
     191      528447 :                 move16();
     192             :             }
     193             :         }
     194             : 
     195     1049655 :         no_scales_p[i][1] = k;
     196     1049655 :         move16();
     197             :     }
     198             :     /* index offsets for each truncation */
     199        7239 :     init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
     200        7239 : }
     201             : 
     202             : /* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure  */
     203     3952494 : 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     3952494 :     offset_scale[j][0] = L_deposit_l( 1 );
     214     3952494 :     move32();
     215    13833729 :     FOR( i = 1; i <= no_scl; i++ )
     216             :     {
     217     9881235 :         offset_scale[j][i] = L_add( offset_scale[j][sub( i, 1 )], tab_no_cv[no_ld[sub( i, 1 )]] );
     218     9881235 :         move32();
     219             :     }
     220             : 
     221     3952494 :     return;
     222             : }
     223             : 
     224     2707384 : 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     2707384 :     offset_scale[0] = 1;
     233     2707384 :     move32();
     234    10829536 :     FOR( i = 1; i <= no_scl; i++ )
     235             :     {
     236     8122152 :         offset_scale[i] = UL_addNsD( offset_scale[i - 1], tab_no_cv[(Word16) no_ld[i - 1]] );
     237     8122152 :         move32();
     238             :     }
     239             : 
     240     2707384 :     return;
     241             : }
     242             : 
     243        7239 : 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      933831 :     FOR( j = 0; j < MAX_NO_MODES; j++ )
     255             :     {
     256      926592 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
     257      926592 :         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     1056894 :     FOR( j = 0; j < MAX_NO_MODES_p; j++ )
     261             :     {
     262     1049655 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p );
     263     1049655 :         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        7239 :     offset_scale1[MAX_NO_MODES][0] = 1;
     267        7239 :     move32();
     268        7239 :     offset_scale2[MAX_NO_MODES][0] = 1;
     269        7239 :     move32();
     270        7239 :     offset_scale1_p[MAX_NO_MODES_p][0] = 1;
     271        7239 :     move32();
     272        7239 :     offset_scale2_p[MAX_NO_MODES_p][0] = 1;
     273        7239 :     move32();
     274             : 
     275        7239 :     return;
     276             : }
     277             : 
     278             : static Word16
     279        4144 : 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        4144 :     Word32 index1 = 0, index2 = 0;
     293        4144 :     move32();
     294        4144 :     move32();
     295        4144 :     Word16 len_scales = MAX_NO_SCALES * 2, no_modes;
     296        4144 :     move16();
     297             :     Word16 i, im1, idx_scale;
     298             :     Word16 tmp;
     299             : 
     300        4144 :     no_modes = MAX_NO_SCALES + 1;
     301        4144 :     move16();
     302             : 
     303        4144 :     IF( LE_16( no_bits, shl( LEN_INDICE, 1 ) ) ) /* the third short is not used */
     304             :     {
     305        2402 :         index[2] = 0;
     306        2402 :         move16();
     307        2402 :         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       16576 :     FOR( i = 0; i < 3; i++ )
     316             :     {
     317       12432 :         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        4144 :     tmp = i_mult2( mode_glb, no_modes );
     332             : 
     333        4144 :     IF( p_offset_scale2[add( tmp, p_no_scales[add( shl( mode_glb, 1 ), 1 )] )] > 0 )
     334             :     {
     335        4144 :         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        4144 :     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        4144 :         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        4144 :         i = 1;
     367        4144 :         move16();
     368        6734 :         WHILE( LE_16( i, p_no_scales[mode_glb * 2] ) && GE_32( index1, p_offset_scale1[mode_glb * no_modes + i] ) )
     369             :         {
     370        2590 :             i = add( i, 1 );
     371             :         }
     372        4144 :         idx_scale = sub( i, 1 );
     373        4144 :         move16();
     374        4144 :         index1 = L_sub( index1, p_offset_scale1[tmp + idx_scale] );
     375             : 
     376             :         /* find idx_leader */
     377        4144 :         i = 1;
     378        4144 :         move16();
     379             : 
     380       48269 :         WHILE( GE_32( index1, table_no_cv_fx[i] ) )
     381             :         {
     382       44125 :             i = add( i, 1 );
     383             :         }
     384        4144 :         im1 = sub( i, 1 );
     385        4144 :         decode_comb_fx( L_sub( index1, table_no_cv_fx[im1] ), x_lvq, im1 );
     386        4144 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     387        4144 :         move16();
     388             :     }
     389             : 
     390             :     /* second subvector */
     391        4144 :     IF( index2 == 0 )
     392             :     {
     393         270 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     394             :         {
     395         240 :             x_lvq[i] = 0;
     396         240 :             move16();
     397             :         }
     398          30 :         scales_mslvq[1] = 0;
     399          30 :         move16();
     400             :     }
     401             :     ELSE
     402             :     {
     403             :         /* find the index for the scale/truncation */
     404        4114 :         i = 1;
     405        4114 :         move16();
     406        6163 :         WHILE( GE_32( index2, p_offset_scale2[tmp + i] ) )
     407             :         {
     408        2049 :             i = add( i, 1 );
     409             :         }
     410             : 
     411        4114 :         idx_scale = sub( i, 1 );
     412        4114 :         index2 = L_sub( index2, p_offset_scale2[add( tmp, idx_scale )] );
     413             :         /* find the index of the leader vector */
     414        4114 :         i = 1;
     415        4114 :         move16();
     416       17900 :         WHILE( GE_32( index2, table_no_cv_fx[i] ) )
     417             :         {
     418       13786 :             i = add( i, 1 );
     419             :         }
     420        4114 :         im1 = sub( i, 1 );
     421        4114 :         decode_comb_fx( index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
     422        4114 :         scales_mslvq[1] = p_scales[add( i_mult2( mode_glb, len_scales ), add( MAX_NO_SCALES, idx_scale ) )];
     423        4114 :         move16();
     424             :     }
     425             : 
     426        4144 :     return 0;
     427             : }
     428             : 
     429      504351 : 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      504351 :     Word32 index1 = 0, index2, idx_scale;
     440      504351 :     move32();
     441             :     Word16 i;
     442             : 
     443      504351 :     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      504351 :     IF( LE_16( no_bits, 2 * LEN_INDICE ) ) /* the third short is not used */
     447             :     {
     448      276397 :         index[2] = 0;
     449      276397 :         move16();
     450      276397 :         if ( LE_16( no_bits, LEN_INDICE ) )
     451             :         {
     452        1140 :             index[1] = 0;
     453        1140 :             move16();
     454             :         }
     455             :     }
     456             : 
     457             :     /* safety check in case of bit errors */
     458     2017404 :     FOR( i = 0; i < 3; i++ )
     459             :     {
     460     1513053 :         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      504351 :     create_offset( offset_scale1, offset_scale2, mode_glb, prediction_flag );
     473             :     /* first subvector */
     474      504351 :     IF( offset_scale2[MAX_NO_SCALES - 1] > 0 )
     475             :     {
     476      504351 :         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      504351 :     IF( index1 == 0 )
     487             :     {
     488        1584 :         FOR( i = 0; i < LATTICE_DIM; i++ )
     489             :         {
     490        1408 :             x_lvq[i] = 0;
     491        1408 :             scales_mslvq[0] = 0;
     492        1408 :             move16();
     493             :         }
     494             :     }
     495             :     ELSE
     496             :     {
     497      504175 :         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      504175 :         i = 1;
     510      504175 :         test();
     511      780492 :         WHILE( LE_16( (Word16) i, MAX_NO_SCALES ) && GE_32( index1, (Word32) offset_scale1[i] ) )
     512             :         {
     513      276317 :             i++;
     514             :         }
     515             : 
     516      504175 :         idx_scale = i - 1;
     517      504175 :         index1 = L_sub( index1, offset_scale1[idx_scale] );
     518             : 
     519             :         /* find idx_leader */
     520      504175 :         i = 1;
     521      504175 :         move16();
     522     6138221 :         WHILE( GE_32( index1, (Word32) table_no_cv[i] ) )
     523             :         {
     524     5634046 :             i++;
     525             :         }
     526      504175 :         decode_comb_fx( (Word32) ( index1 - table_no_cv[i - 1] ), x_lvq, i - 1 );
     527      504175 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     528      504175 :         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      504351 :     IF( index2 == 0 )
     538             :     {
     539      190341 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     540             :         {
     541             :             // x_lvq[i] = 0.0;
     542      169192 :             x_lvq[i] = 0;
     543      169192 :             move16();
     544             :         }
     545       21149 :         scales_mslvq[1] = 0;
     546       21149 :         move16();
     547             :     }
     548             :     ELSE
     549             :     {
     550             : 
     551             :         /* find the index for the scale/truncation */
     552      483202 :         i = 1;
     553      483202 :         move16();
     554      722512 :         WHILE( GE_32( index2, (Word32) offset_scale2[i] ) )
     555             :         {
     556      239310 :             i++;
     557             :         }
     558             : 
     559      483202 :         idx_scale = i - 1;
     560      483202 :         move16();
     561      483202 :         index2 = L_sub( index2, offset_scale2[idx_scale] );
     562             :         /* find the index of the leader vector */
     563      483202 :         i = 1;
     564      483202 :         move16();
     565     2149073 :         WHILE( GE_32( index2, (Word32) table_no_cv[i] ) )
     566             :         {
     567     1665871 :             i++;
     568             :         }
     569      483202 :         decode_comb_fx( (Word32) ( index2 - table_no_cv[i - 1] ), &x_lvq[LATTICE_DIM], i - 1 );
     570             : 
     571      483202 :         scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
     572      483202 :         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      504351 :     return 0;
     581             : }
     582             : 
     583        4144 : 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        4144 :     IF( EQ_16( sf_flag, 1 ) )
     603             :     {
     604         523 :         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         523 :         p_scales = &scales_fx[0][0];
     606         523 :         move16();
     607             :     }
     608             :     ELSE
     609             :     {
     610        3621 :         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        3621 :         p_scales = &scales_p_fx[0][0];
     612        3621 :         move16();
     613             :     }
     614             : 
     615             :     /* decode the lattice index into the lattice codevectors for the two subvectors */
     616             :     ber_flag =
     617        4144 :         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        4144 :     IF( EQ_16( sf_flag, 1 ) )
     622             :     {
     623             :         /* safety-net case*/
     624         523 :         IF( scales_mslvq[0] )
     625             :         {
     626        4707 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     627             :             {
     628        4184 :                 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        4184 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     631        4184 :                 x_lvq[i] = round_fx( L_tmp );
     632        4184 :                 move16();
     633             :             }
     634             :         }
     635         523 :         IF( scales_mslvq[1] )
     636             :         {
     637        4599 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     638             :             {
     639        4088 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     640        4088 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     641        4088 :                 x_lvq[i] = round_fx( L_tmp );
     642        4088 :                 move16();
     643             :             }
     644             :         }
     645             :     }
     646             :     ELSE
     647             :     {
     648             :         /* predictive mode AR or MA */
     649        3621 :         IF( scales_mslvq[0] )
     650             :         {
     651       32589 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     652             :             {
     653       28968 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                             /* Q1+Q11+Q1  = Q13 */
     654       28968 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     655       28968 :                 x_lvq[i] = round_fx( L_tmp );
     656       28968 :                 move16();
     657             :             }
     658             :         }
     659        3621 :         IF( scales_mslvq[1] )
     660             :         {
     661       32427 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     662             :             {
     663       28824 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                             /* Q1+Q11+Q1  = Q13 */
     664       28824 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     665       28824 :                 x_lvq[i] = round_fx( L_tmp );
     666       28824 :                 move16();
     667             :             }
     668             :         }
     669             :     }
     670             : 
     671        4144 :     return ber_flag;
     672             : }
     673             : 
     674      503934 : 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      503934 :     IF( EQ_16( sf_flag, 1 ) )
     691             :     {
     692       71079 :         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       71079 :             mode_glb = add( offset_lvq_modes_SN[mode], sub( no_bits, min_lat_bits_SN[mode] ) ); /* there is granularity of 1 bit */
     699             :         }
     700       71079 :         p_scales = &scales_ivas_fx[0][0]; // Q11
     701       71079 :         move16();
     702             :     }
     703             :     ELSE
     704             :     {
     705      432855 :         test();
     706      432855 :         IF( ( LT_16( mode, 6 ) ) || ( EQ_16( mode, 12 ) ) ) /* for NB */
     707             :         {
     708        9595 :             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      423260 :             mode_glb = add( offset_lvq_modes_pred[mode], sub( no_bits, min_lat_bits_pred[mode] ) );
     713             :         }
     714      432855 :         p_scales = &scales_p_ivas_fx[0][0]; // Q11
     715      432855 :         move16();
     716             :     }
     717             : 
     718             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     719      503934 :     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      503934 :         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      503934 :     IF( EQ_16( sf_flag, 1 ) )
     730             :     {
     731             :         /* safety-net case*/
     732       71079 :         IF( scales_mslvq[0] )
     733             :         {
     734      638937 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     735             :             {
     736      567944 :                 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      567944 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     739      567944 :                 x_lvq[i] = round_fx( L_tmp );
     740      567944 :                 move16();
     741             :             }
     742             :         }
     743       71079 :         IF( scales_mslvq[1] )
     744             :         {
     745      596772 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     746             :             {
     747      530464 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     748      530464 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     749      530464 :                 x_lvq[i] = round_fx( L_tmp );
     750      530464 :                 move16();
     751             :             }
     752             :         }
     753             :     }
     754             :     ELSE
     755             :     {
     756             :         /* predictive mode AR or MA */
     757      432855 :         IF( scales_mslvq[0] )
     758             :         {
     759     3894948 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     760             :             {
     761     3462176 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                  /* Q1+Q11+Q1  = Q13 */
     762     3462176 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     763     3462176 :                 x_lvq[i] = round_fx( L_tmp );
     764     3462176 :                 move16();
     765             :             }
     766             :         }
     767      432855 :         IF( scales_mslvq[1] )
     768             :         {
     769     3748302 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     770             :             {
     771     3331824 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                  /* Q1+Q11+Q1  = Q13 */
     772     3331824 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     773     3331824 :                 x_lvq[i] = round_fx( L_tmp );
     774     3331824 :                 move16();
     775             :             }
     776             :         }
     777             :     }
     778             : 
     779      503934 :     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         417 : 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         417 :     mode_glb = add( START_CNG_IVAS, idx_cv );
     868             : 
     869         417 :     mode = add( LVQ_COD_MODES, idx_cv );
     870             : 
     871         417 :     p_scales = &scales_ivas_fx[0][0];
     872         417 :     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         417 :         decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
     877             : 
     878        3753 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     879             :     {
     880        3336 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                 /* Q1+Q11+Q1  = Q13 */
     881        3336 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     882        3336 :         x_lvq[i] = round_fx( L_tmp );
     883        3336 :         move16();
     884             :     }
     885        3753 :     FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     886             :     {
     887        3336 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     888        3336 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     889        3336 :         x_lvq[i] = round_fx( L_tmp );
     890        3336 :         move16();
     891             :     }
     892             : 
     893             :     /* check if permutting needed */
     894         417 :     IF( cng_sort[idx_cv] )
     895             :     {
     896         410 :         permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
     897             :     }
     898             : 
     899         417 :     return ber_flag;
     900             : }
     901             : 
     902             : /* combinatorial indexing */
     903     3199786 : 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     3199786 :     skip = 0;
     913     3199786 :     move16();
     914     3199786 :     pos = 0;
     915     3199786 :     move16();
     916     3199786 :     k1 = sub( k, 1 );
     917     3199786 :     move16();
     918     6766122 :     WHILE( LT_16( add( skip, sub( C_VQ[n - pos - 1][k1], 1 ) ), val ) )
     919             :     {
     920     3566336 :         skip = add( skip, C_VQ[n - pos - 1][k1] );
     921     3566336 :         move16();
     922     3566336 :         pos++;
     923     3566336 :         move16();
     924             :     }
     925             : 
     926     3199786 :     p[0] = pos;
     927     3199786 :     move16();
     928     3199786 :     n = sub( n, add( pos, 1 ) );
     929     3199786 :     val = sub( val, skip );
     930     3199786 :     IF( EQ_16( k, 1 ) )
     931             :     {
     932     1200719 :         return;
     933             :     }
     934             : 
     935     1999067 :     idx2c_fx( n, p + 1, k1, val );
     936             : 
     937             :     /* pos+1 */
     938     6058999 :     FOR( i = 1; i < k; i++ )
     939             :     {
     940     4059932 :         p[i] = add( p[i], add( pos, 1 ) );
     941     4059932 :         move16();
     942             :     }
     943             : 
     944     1999067 :     return;
     945             : }
     946             : /* combinatorial deindexing */
     947      998807 : 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      998807 :     IF( LT_32( L_shl( index, 1 ), pi0[idx_lead] ) )
     955             :     {
     956       73859 :         idx_sign = 0;
     957       73859 :         move16();
     958             :     }
     959             :     ELSE
     960             :     {
     961      924948 :         idx_sign = extract_l( div_l( L_shl( index, 1 ), pi0[idx_lead] ) ); /*(index/pi0_fx[idx_lead]); */
     962             :     }
     963      998807 :     index = L_sub( index, L_mult0( idx_sign, pi0[idx_lead] ) );
     964      998807 :     decode_leaders_fx( extract_l( index ), idx_lead, cv );
     965      998807 :     decode_sign_pc1_fx( cv, idx_sign, pl_par[idx_lead] );
     966             : 
     967      998807 :     return;
     968             : }
     969      998807 : 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      998807 :     Word16 i, len = LATTICE_DIM, cnt_neg = 1;
     976             : 
     977      998807 :     if ( parity )
     978             :     {
     979      421122 :         len = sub( len, 1 );
     980             :     }
     981             : 
     982     8568141 :     FOR( i = 0; i < len; i++ )
     983             :     {
     984     7569334 :         IF( c[i] > 0 )
     985             :         {
     986             :             /*if (idx_sign % 2) */
     987     5498772 :             IF( s_and( idx_sign, 1 ) )
     988             :             {
     989     2657370 :                 c[i] = negate( c[i] );
     990     2657370 :                 move16();
     991     2657370 :                 cnt_neg = negate( cnt_neg );
     992     2657370 :                 move16();
     993             :             }
     994     5498772 :             idx_sign = shr( idx_sign, 1 ); /*  >>= 1; */
     995             :         }
     996             :     }
     997             : 
     998      998807 :     IF( LT_16( len, LATTICE_DIM ) )
     999             :     {
    1000      421122 :         IF( NE_16( cnt_neg, parity ) )
    1001             :         {
    1002      190921 :             c[len] = negate( c[len] );
    1003      190921 :             move16();
    1004             :         }
    1005             :     }
    1006             : 
    1007      998807 :     return;
    1008             : }
    1009             : 
    1010             : 
    1011      998807 : 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      998807 :     no_vals_loc = no_vals[idx_lead];
    1022      998807 :     move16();
    1023      998807 :     val_crt = vals_fx[idx_lead][no_vals_loc - 1];
    1024      998807 :     move16(); /*Q1  */
    1025      998807 :     no_vals_last = no_vals_ind[idx_lead][no_vals_loc - 1];
    1026      998807 :     move16();
    1027             : 
    1028     5789477 :     FOR( i = 0; i < no_vals_last; i++ )
    1029             :     {
    1030     4790670 :         cv[i] = val_crt;
    1031     4790670 :         move16(); /*Q1 */
    1032             :     }
    1033             : 
    1034      998807 :     val_crt = 1;
    1035      998807 :     move16();
    1036      998807 :     dim_loc = no_vals_last;
    1037      998807 :     move16();
    1038             : 
    1039      998807 :     SWITCH( no_vals_loc )
    1040             :     {
    1041       99849 :         case 1:
    1042       99849 :             BREAK;
    1043      599708 :         case 2:
    1044      599708 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index );
    1045      599708 :             put_value_fx( cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind[idx_lead][0] );
    1046      599708 :             BREAK;
    1047        2511 :         case 4:
    1048        2511 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][2] );
    1049        2511 :             n_crt = no_vals_ind[idx_lead][2];
    1050        2511 :             move16();
    1051        2511 :             index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index ); /*  index1 = index/C_VQ_fx[dim_loc][n_crt]; */
    1052        2511 :             /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
    1053        2511 :             idx2c_fx( dim_loc, p, n_crt, index );
    1054        2511 :             put_value_fx( cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind[idx_lead][2] ); /* Q1 */
    1055        2511 :             index = index1;
    1056        2511 :             move16();
    1057             :             /* no break */
    1058      299250 :         case 3:
    1059      299250 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][1] );
    1060      299250 :             n_crt = no_vals_ind[idx_lead][1];
    1061      299250 :             move16();
    1062      299250 :             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      299250 :             idx2c_fx( dim_loc, p, n_crt, index );
    1065      299250 :             put_value_fx( cv, p, vals_fx[idx_lead][1], sub( dim_loc, n_crt ), n_crt );
    1066      299250 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index1 );
    1067      299250 :             move16();
    1068      299250 :             put_value_fx( cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind[idx_lead][0] );
    1069      299250 :             BREAK;
    1070             :     }
    1071             : 
    1072      998807 :     return;
    1073             : }
    1074             : 
    1075             : /* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x.  */
    1076      626881 : 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      626881 :     IF( LT_32( y, x ) )
    1086             :     {
    1087       26748 :         result = L_deposit_l( 0 );
    1088       26748 :         *rem = y;
    1089       26748 :         move32();
    1090             :     }
    1091             :     ELSE
    1092             :     {
    1093             : 
    1094      600133 :         result = L_deposit_l( 0 );
    1095      600133 :         IF( y == 0 )
    1096             :         {
    1097           0 :             ny = 0;
    1098           0 :             move16();
    1099             :         }
    1100             :         ELSE
    1101             :         {
    1102      600133 :             ny = sub( 31, norm_l( y ) );
    1103             :         }
    1104      600133 :         IF( x == 0 )
    1105             :         {
    1106           0 :             nx = 0;
    1107           0 :             move16();
    1108             :         }
    1109             :         ELSE
    1110             :         {
    1111      600133 :             nx = sub( 31, norm_l( x ) );
    1112             :         }
    1113             : 
    1114      600133 :         nyx = sub( ny, nx );
    1115             : 
    1116             :         /*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
    1117      600133 :         t = L_shr( y, add( nyx, 1 ) );
    1118     8706113 :         FOR( i = 0; i <= nyx; i++ )
    1119             :         {
    1120     8105980 :             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     8105980 :             result = L_shl( result, 1 );
    1122     8105980 :             L_tmp = L_sub( t, x );
    1123     8105980 :             IF( L_tmp >= 0 )
    1124             :             {
    1125     4044245 :                 result = L_add( result, 1 );
    1126     4044245 :                 t = L_add( L_tmp, 0 );
    1127             :             }
    1128             :         }
    1129      600133 :         *rem = t;
    1130      600133 :         move32();
    1131             :     }
    1132      626881 :     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      301761 : 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      301761 :     IF( LT_32( y, x ) )
    1146             :     {
    1147       36819 :         result = 0;
    1148       36819 :         move16();
    1149       36819 :         *rem = y;
    1150       36819 :         move16();
    1151             :     }
    1152             :     ELSE
    1153             :     {
    1154             : 
    1155      264942 :         result = 0;
    1156      264942 :         move16();
    1157      264942 :         IF( y == 0 )
    1158             :         {
    1159           0 :             ny = 0;
    1160           0 :             move16();
    1161             :         }
    1162             :         ELSE
    1163             :         {
    1164      264942 :             ny = sub( 15, norm_s( y ) );
    1165             :         }
    1166      264942 :         IF( x == 0 )
    1167             :         {
    1168           0 :             nx = 0;
    1169           0 :             move16();
    1170             :         }
    1171             :         ELSE
    1172             :         {
    1173      264942 :             nx = sub( 15, norm_s( x ) );
    1174             :         }
    1175             : 
    1176      264942 :         nyx = sub( ny, nx );
    1177             : 
    1178      264942 :         t = s_and( shr( y, add( nyx, 1 ) ), sub( shl( 1, sub( nx, 1 ) ), 1 ) );
    1179     1115074 :         FOR( i = 0; i <= nyx; i++ )
    1180             :         {
    1181      850132 :             t = add( shl( t, 1 ), s_and( shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
    1182      850132 :             result = shl( result, 1 );
    1183      850132 :             tmp = sub( t, x );
    1184      850132 :             IF( tmp >= 0 )
    1185             :             {
    1186      490521 :                 result = add( result, 1 );
    1187      490521 :                 t = tmp;
    1188      490521 :                 move16();
    1189             :             }
    1190             :         }
    1191      264942 :         *rem = t;
    1192      264942 :         move16();
    1193             :     }
    1194      301761 :     return result;
    1195             : }
    1196             : 
    1197      508495 : 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      508495 :     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      508495 :     move32();
    1209      508495 :     x[1] = L_shr( L_deposit_l( xs[2] ), 1 );
    1210      508495 :     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      508495 :     IF( x[1] == 0 )
    1216             :     {
    1217      390109 :         nb_x1 = 0;
    1218      390109 :         move16();
    1219             :     }
    1220             :     ELSE
    1221             :     {
    1222      118386 :         nb_x1 = sub( 31, norm_l( x[1] ) ); /*get_no_bits_fx(x[1]); */
    1223             :     }
    1224             :     /* take the first 31 bits */
    1225      508495 :     IF( nb_x1 > 0 )
    1226             :     {
    1227      118386 :         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      118386 :         q = divide_32_32_fx( x_tmp, y, &r );                                                     /* q = x_tmp/y, reminder r */
    1231      118386 :         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      118386 :         q1 = divide_32_32_fx( r, y, rem );
    1235      118386 :         *result = L_add( L_shl( q, nb_x1 ), q1 );
    1236      118386 :         move32();
    1237             :     }
    1238             :     ELSE
    1239             :     {
    1240      390109 :         *result = divide_32_32_fx( x[0], y, rem );
    1241      390109 :         move32();
    1242             :     }
    1243             : 
    1244      508495 :     return;
    1245             : }
    1246             : 
    1247     1200719 : 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     1200719 :     limit = add( dim, no_new_val );
    1259    10425239 :     FOR( i = 0; i < limit; i++ )
    1260             :     {
    1261     9224520 :         occ[i] = 0;
    1262     9224520 :         move16();
    1263             :     }
    1264             : 
    1265     4400505 :     FOR( i = 0; i < no_new_val; i++ )
    1266             :     {
    1267     3199786 :         cv_out[p[i]] = val;
    1268     3199786 :         move16();
    1269     3199786 :         occ[p[i]] = 1;
    1270     3199786 :         move16();
    1271             :     }
    1272             : 
    1273     1200719 :     cnt = 0;
    1274     1200719 :     move16();
    1275    10425239 :     FOR( i = 0; i < limit; i++ )
    1276             :     {
    1277     9224520 :         if ( occ[i] == 0 )
    1278             :         {
    1279     6024734 :             cv_out[i] = cv[cnt++];
    1280     6024734 :             move16();
    1281             :         }
    1282             :     }
    1283             : 
    1284    10425239 :     FOR( i = 0; i < limit; i++ )
    1285             :     {
    1286     9224520 :         cv[i] = cv_out[i];
    1287     9224520 :         move16();
    1288             :     }
    1289             : 
    1290     1200719 :     return;
    1291             : }
    1292             : 
    1293             : /*-----------------------------------------------------------------*
    1294             :  * create_offset()
    1295             :  *
    1296             :  *
    1297             :  *-----------------------------------------------------------------*/
    1298             : 
    1299     1353692 : 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     1353692 :     if ( prediction_flag == 0 )
    1308             :     {
    1309             :         /* safety_net */
    1310      233856 :         tmp = no_lead_idx[mode][0];
    1311      233856 :         if ( ( tmp <= LIMIT_LEADER ) && ( tmp < no_lead_idx[mode][1] - 2 ) )
    1312             :         {
    1313           0 :             tmp += DELTA_LEADER;
    1314             :         }
    1315      233856 :         make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
    1316      233856 :         make_offset_scale( table_no_cv, leaders_short[no_lead_idx[mode][1]], MAX_NO_SCALES, offset_scale2 );
    1317             :     }
    1318             :     else
    1319             :     {
    1320     1119836 :         tmp = no_lead_p_idx[mode][0];
    1321     1119836 :         tmp1 = no_lead_p_idx[mode][1];
    1322     1119836 :         if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
    1323             :         {
    1324       25763 :             tmp += DELTA_LEADER;
    1325             :         }
    1326             : 
    1327     1119836 :         if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
    1328             :         {
    1329           0 :             tmp += DELTA_LEADER;
    1330           0 :             tmp1 = DELTA_LEADER;
    1331             :         }
    1332             : 
    1333     1119836 :         make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
    1334     1119836 :         make_offset_scale( table_no_cv, leaders_short[tmp1], MAX_NO_SCALES, offset_scale2 );
    1335             :     }
    1336             : 
    1337     1353692 :     return;
    1338             : }
    1339             : 
    1340             : /*-----------------------------------------------------------------*
    1341             :  * sort_desc_ind()
    1342             :  *
    1343             :  * sorts in descending order and computes indices in the sorted vector
    1344             :  *-----------------------------------------------------------------*/
    1345             : 
    1346        4355 : 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       21520 :     FOR( i = 0; i < len; i++ )
    1356             :     {
    1357       17165 :         ind[i] = i;
    1358       17165 :         move16();
    1359             :     }
    1360        4355 :     sorted = 0;
    1361        4355 :     move16();
    1362       14684 :     FOR( k = len - 1; k && !sorted; k-- )
    1363             :     {
    1364       10329 :         sorted = 1;
    1365       10329 :         move16();
    1366       32826 :         FOR( i = 0; i < k; i++ )
    1367             :         {
    1368       22497 :             IF( LT_32( s[i], s[i + 1] ) )
    1369             :             {
    1370       10458 :                 sorted = 0;
    1371       10458 :                 move16();
    1372       10458 :                 t = s[i];
    1373       10458 :                 move16();
    1374       10458 :                 s[i] = s[i + 1];
    1375       10458 :                 move16();
    1376       10458 :                 s[i + 1] = t;
    1377       10458 :                 move16();
    1378       10458 :                 a = ind[i];
    1379       10458 :                 move16();
    1380       10458 :                 ind[i] = ind[i + 1];
    1381       10458 :                 move16();
    1382       10458 :                 ind[i + 1] = a;
    1383       10458 :                 move16();
    1384             :             }
    1385             :         }
    1386             :     }
    1387             : 
    1388        4355 :     return;
    1389             : }
    1390             : 
    1391        3172 : 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        3172 :     IF( mode == 0 )
    1405             :     {
    1406        3172 :         p_no_lead = &no_lead_BWE[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
    1407        3172 :         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        3172 :     IF( index == 0 )
    1417             :     {
    1418           0 :         set16_fx( out, 0, LATTICE_DIM );
    1419             :     }
    1420             :     ELSE
    1421             :     {
    1422             :         /* create offsets */
    1423        3172 :         offsets[0] = 0;
    1424        3172 :         move32();
    1425       12688 :         FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1426             :         {
    1427        9516 :             offsets[i + 1] = UL_addNsD( table_no_cv[p_no_lead[i]], offsets[i] );
    1428        9516 :             move32();
    1429             :         }
    1430             : 
    1431             :         /* find idx_scale */
    1432        3172 :         idx_scale = 0;
    1433        3172 :         test();
    1434        7331 :         WHILE( LE_32( i, MAX_NO_SCALES ) && index >= offsets[idx_scale] )
    1435             :         {
    1436        4159 :             test();
    1437        4159 :             idx_scale = add( idx_scale, 1 );
    1438             :         }
    1439        3172 :         idx_scale = sub( idx_scale, 1 );
    1440        3172 :         index = L_sub( index, offsets[idx_scale] );
    1441             : 
    1442             :         /* find idx_leader */
    1443        3172 :         i = 1;
    1444        3172 :         move16();
    1445       21605 :         WHILE( GT_32( index, table_no_cv[i] ) )
    1446             :         {
    1447       18433 :             i = add( i, 1 );
    1448             :         }
    1449        3172 :         i = sub( i, 1 );
    1450             : 
    1451        3172 :         decode_comb_fx( (Word32) ( L_sub( L_sub( index, table_no_cv[i] ), 1 ) ), out, i );
    1452             : 
    1453        3172 :         scale = p_scales[idx_scale];
    1454        3172 :         move16();
    1455       28548 :         FOR( i = 0; i < LATTICE_DIM; i++ )
    1456             :         {
    1457       25376 :             Word32 temp = Mpy_32_16_1( sigma_BWE_fx[add( i_mult( mode, LATTICE_DIM ), i )], scale );
    1458       25376 :             temp = Mpy_32_16_1( temp, out[i] );
    1459       25376 :             out[i] = extract_l( temp ); /* Q15 output*/
    1460       25376 :             move16();
    1461             :             // out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i];
    1462             :         }
    1463             :     }
    1464             : 
    1465        3172 :     return;
    1466             : }

Generated by: LCOV version 1.14