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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 498 569 87.5 %
Date: 2025-05-03 01:55:50 Functions: 18 19 94.7 %

          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 "options.h"
      34             : #include "prot_fx.h"
      35             : #include "ivas_cnst.h"
      36             : #include "stl.h"
      37             : #include "rom_com.h"
      38             : 
      39             : /*-----------------------------------------------------------------*
      40             :  * Local functions
      41             :  *-----------------------------------------------------------------*/
      42             : 
      43             : 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] );
      44             : 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] );
      45             : static void decode_comb_fx( Word32 index, Word16 *cv, Word16 idx_lead );
      46             : static void decode_sign_pc1_fx( Word16 *c, Word16 idx_sign, Word16 parity );
      47             : static void put_value_fx( Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16 no_new_val );
      48             : static void decode_leaders_fx( Word16 index, Word16 idx_lead, Word16 *cv );
      49             : static void idx2c_fx( Word16 n, Word16 *p, Word16 k, Word16 val );
      50             : static void divide_64_32_fx( Word16 *xs, Word32 y, Word32 *result, Word32 *rem );
      51             : static Word16
      52             : 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 );
      53             : static Word16 decode_indexes_ivas_fx(
      54             :     Word16 *index,
      55             :     const Word16 no_bits,
      56             :     const Word16 *p_scales, // Q11
      57             :     const Word16 prediction_flag,
      58             :     Word16 *x_lvq, // Q0
      59             :     const Word16 mode_glb,
      60             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
      61             : );
      62             : static Word32 divide_32_32_fx( Word32 y, Word32 x, Word32 *rem );
      63             : static Word16 divide_16_16_fx( Word16 y, Word16 x, Word16 *rem );
      64             : static Word16 decode_indexes_ivas_fx(
      65             :     Word16 *index,
      66             :     const Word16 no_bits,
      67             :     const Word16 *p_scales, // Q11
      68             :     const Word16 prediction_flag,
      69             :     Word16 *x_lvq, // Q0
      70             :     const Word16 mode_glb,
      71             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
      72             : );
      73             : 
      74             : /* used in CNG-LP coding */
      75        1733 : void permute_fx(
      76             :     Word16 *pTmp1,     /* i/o: vector whose components are to be permuted */
      77             :     const Word16 *perm /* i  : permutation info (indexes that should be interchanged), max two perms */
      78             : )
      79             : {
      80             :     Word16 p1, p2;
      81             :     Word16 tmp;
      82             : 
      83        1733 :     p1 = perm[0];
      84        1733 :     move16();
      85        1733 :     p2 = perm[1];
      86        1733 :     move16();
      87        1733 :     tmp = pTmp1[p1];
      88        1733 :     move16();
      89        1733 :     pTmp1[p1] = pTmp1[p2];
      90        1733 :     move16();
      91        1733 :     move16();
      92        1733 :     pTmp1[p2] = tmp;
      93        1733 :     move16();
      94        1733 :     p1 = perm[2];
      95        1733 :     move16();
      96             : 
      97        1733 :     IF( GT_16( p1, -1 ) )
      98             :     {
      99         270 :         p2 = perm[3];
     100         270 :         move16();
     101         270 :         tmp = pTmp1[p1];
     102         270 :         move16();
     103         270 :         pTmp1[p1] = pTmp1[p2];
     104         270 :         move16();
     105         270 :         move16();
     106         270 :         pTmp1[p2] = tmp;
     107         270 :         move16();
     108             :     }
     109             : 
     110        1733 :     return;
     111             : }
     112             : 
     113             : 
     114        7239 : void init_lvq_fx(
     115             :     Word32 offset_scale1[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
     116             :     Word32 offset_scale2[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
     117             :     Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
     118             :     Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
     119             :     Word16 no_scales[][2],                       /* o: number of truncations for each LSF subvector at each MSLVQ structure - safety net  */
     120             :     Word16 no_scales_p[][2]                      /* o: number of truncations for each LSF subvector at each MSLVQ structure - predictive  */
     121             : )
     122             : {
     123             :     Word16 i, j;
     124             : #ifdef OPT_STEREO_32KBPS_V1
     125             :     Word16 k;
     126             : #endif /* OPT_STEREO_32KBPS_V1 */
     127             :     /* safety-net mode */
     128      933831 :     FOR( i = 0; i < MAX_NO_MODES; i++ )
     129             :     {
     130             : #ifdef OPT_STEREO_32KBPS_V1
     131     3633978 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     132             :         {
     133     2707386 :             if ( no_lead_fx[i][j] > 0 )
     134             :             {
     135     2475738 :                 k = add( k, 1 );
     136             :             }
     137     2707386 :             if ( no_lead_fx[i][j] <= 0 )
     138             :             {
     139      231648 :                 j = MAX_NO_SCALES - 1;
     140      231648 :                 move16();
     141             :             }
     142             :         }
     143      926592 :         no_scales[i][0] = k;
     144      926592 :         move16();
     145             : 
     146     3474720 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     147             :         {
     148     2548128 :             if ( no_lead_fx[i][j] > 0 )
     149             :             {
     150     2070354 :                 k = add( k, 1 );
     151             :             }
     152     2548128 :             if ( no_lead_fx[i][j] <= 0 )
     153             :             {
     154      477774 :                 j = MAX_NO_SCALES << 1;
     155      477774 :                 move16();
     156             :             }
     157             :         }
     158      926592 :         no_scales[i][1] = k;
     159      926592 :         move16();
     160             : #else  /* OPT_STEREO_32KBPS_V1 */
     161             :         j = 0;
     162             :         move16();
     163             :         test();
     164             :         WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_fx[i][j] > 0 ) )
     165             :         {
     166             :             j++;
     167             :         }
     168             :         no_scales[i][0] = j;
     169             :         move16();
     170             :         j = MAX_NO_SCALES;
     171             :         move16();
     172             :         test();
     173             :         WHILE( ( LT_16( j, shl( MAX_NO_SCALES, 1 ) ) ) && ( no_lead_fx[i][j] > 0 ) )
     174             :         {
     175             :             j++;
     176             :         }
     177             :         no_scales[i][1] = sub( j, MAX_NO_SCALES );
     178             :         move16();
     179             : #endif /* OPT_STEREO_32KBPS_V1 */
     180             :     }
     181             :     /* predictive mode */
     182     1056894 :     FOR( i = 0; i < MAX_NO_MODES_p; i++ )
     183             :     {
     184             : #ifdef OPT_STEREO_32KBPS_V1
     185     4147947 :         FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
     186             :         {
     187     3098292 :             if ( no_lead_p_fx[i][j] > 0 )
     188             :             {
     189     2975229 :                 k = add( k, 1 );
     190             :             }
     191     3098292 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     192             :             {
     193      123063 :                 j = MAX_NO_SCALES - 1;
     194      123063 :                 move16();
     195             :             }
     196             :         }
     197     1049655 :         no_scales_p[i][0] = k;
     198     1049655 :         move16();
     199             : 
     200     3938016 :         FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
     201             :         {
     202     2888361 :             if ( no_lead_p_fx[i][j] > 0 )
     203             :             {
     204     2359914 :                 k = add( k, 1 );
     205             :             }
     206             : 
     207     2888361 :             if ( ( no_lead_p_fx[i][j] <= 0 ) )
     208             :             {
     209      528447 :                 j = MAX_NO_SCALES << 1;
     210      528447 :                 move16();
     211             :             }
     212             :         }
     213             : 
     214     1049655 :         no_scales_p[i][1] = k;
     215     1049655 :         move16();
     216             : #else  /* OPT_STEREO_32KBPS_V1 */
     217             :         j = 0;
     218             :         move16();
     219             :         WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_p_fx[i][j] > 0 ) )
     220             :         {
     221             :             test();
     222             :             j++;
     223             :         }
     224             :         no_scales_p[i][0] = j;
     225             :         move16();
     226             :         j = MAX_NO_SCALES;
     227             :         move16();
     228             :         WHILE( ( LT_16( j, shl( MAX_NO_SCALES, 1 ) ) ) && ( no_lead_p_fx[i][j] > 0 ) )
     229             :         {
     230             :             test();
     231             :             j++;
     232             :         }
     233             :         no_scales_p[i][1] = sub( j, MAX_NO_SCALES );
     234             :         move16();
     235             : #endif /* OPT_STEREO_32KBPS_V1 */
     236             :     }
     237             :     /* index offsets for each truncation */
     238        7239 :     init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
     239        7239 : }
     240             : 
     241             : /* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure  */
     242     3952494 : static void make_offset_scale_fx(
     243             :     Word16 j,                                /* i: MSLVQ structure index */
     244             :     const Word32 tab_no_cv[],                /* i: cummulated number of codevectors in each leader class */
     245             :     const Word16 no_ld[],                    /* i: number of leaders in each truncation for the MSLVQ structure j*/
     246             :     Word16 no_scl,                           /* i: number of truncations in the MSLVQ structure j */
     247             :     Word32 offset_scale[][MAX_NO_SCALES + 1] /* o: offset values */
     248             : )
     249             : {
     250             :     Word16 i;
     251             : 
     252     3952494 :     offset_scale[j][0] = L_deposit_l( 1 );
     253     3952494 :     move32();
     254    13833729 :     FOR( i = 1; i <= no_scl; i++ )
     255             :     {
     256     9881235 :         offset_scale[j][i] = L_add( offset_scale[j][sub( i, 1 )], tab_no_cv[no_ld[sub( i, 1 )]] );
     257     9881235 :         move32();
     258             :     }
     259             : 
     260     3952494 :     return;
     261             : }
     262             : 
     263        7239 : void init_offset_fx(
     264             :     Word32 offset_scale1[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
     265             :     Word32 offset_scale2[][MAX_NO_SCALES + 1],   /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
     266             :     Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
     267             :     Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
     268             :     Word16 no_scales[][2],                       /* i: number of truncations for each LSF subvector at each MSLVQ structure - safety net  */
     269             :     Word16 no_scales_p[][2]                      /* i: number of truncations for each LSF subvector at each MSLVQ structure - predictive  */
     270             : )
     271             : {
     272             :     Word16 j;
     273             :     /* safety-net */
     274      933831 :     FOR( j = 0; j < MAX_NO_MODES; j++ )
     275             :     {
     276      926592 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
     277      926592 :         make_offset_scale_fx( j, table_no_cv_fx, &no_lead_fx[j][MAX_NO_SCALES], no_scales[j][1], offset_scale2 );
     278             :     }
     279             :     /* predictive modes AR and MA */
     280     1056894 :     FOR( j = 0; j < MAX_NO_MODES_p; j++ )
     281             :     {
     282     1049655 :         make_offset_scale_fx( j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p );
     283     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 );
     284             :     }
     285             : 
     286        7239 :     offset_scale1[MAX_NO_MODES][0] = 1;
     287        7239 :     move32();
     288        7239 :     offset_scale2[MAX_NO_MODES][0] = 1;
     289        7239 :     move32();
     290        7239 :     offset_scale1_p[MAX_NO_MODES_p][0] = 1;
     291        7239 :     move32();
     292        7239 :     offset_scale2_p[MAX_NO_MODES_p][0] = 1;
     293        7239 :     move32();
     294             : 
     295        7239 :     return;
     296             : }
     297             : 
     298             : static Word16
     299        4165 : decode_indexes_fx(
     300             :     Word16 *index,           /* i: LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
     301             :     Word16 no_bits,          /* i: number of bits for the index */
     302             :     const Word16 *p_scales,  /* i: scale values for the MSLVQ structures */
     303             :     Word16 *p_no_scales,     /* i: number of truncations for each MSLVQ structure */
     304             :     Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
     305             :     Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
     306             :     Word16 *x_lvq,           /* o: decoded LSF vector in Q1 */
     307             :     Word16 mode_glb,         /* i: index of LSLVQ structure */
     308             :     // note_ : renamed from scales
     309             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector */
     310             : )
     311             : {
     312        4165 :     Word32 index1 = 0, index2 = 0;
     313        4165 :     move32();
     314        4165 :     move32();
     315        4165 :     Word16 len_scales = MAX_NO_SCALES * 2, no_modes;
     316        4165 :     move16();
     317             :     Word16 i, im1, idx_scale;
     318             :     Word16 tmp;
     319             : 
     320        4165 :     no_modes = MAX_NO_SCALES + 1;
     321        4165 :     move16();
     322             : 
     323        4165 :     IF( LE_16( no_bits, shl( LEN_INDICE, 1 ) ) ) /* the third short is not used */
     324             :     {
     325        2422 :         index[2] = 0;
     326        2422 :         move16();
     327        2422 :         if ( LE_16( no_bits, LEN_INDICE ) )
     328             :         {
     329           0 :             index[1] = 0;
     330           0 :             move16();
     331             :         }
     332             :     }
     333             : 
     334             :     /* safety check in case of bit errors */
     335       16660 :     FOR( i = 0; i < 3; i++ )
     336             :     {
     337       12495 :         IF( index[i] < 0 )
     338             :         {
     339           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     340           0 :             scales_mslvq[0] = 0;
     341           0 :             move16();
     342           0 :             scales_mslvq[1] = 0;
     343           0 :             move16();
     344           0 :             index[i] = 0;
     345           0 :             move16();
     346           0 :             return 1;
     347             :         }
     348             :     }
     349             : 
     350             :     /* first subvector */
     351        4165 :     tmp = i_mult2( mode_glb, no_modes );
     352             : 
     353        4165 :     IF( p_offset_scale2[add( tmp, p_no_scales[add( shl( mode_glb, 1 ), 1 )] )] > 0 )
     354             :     {
     355        4165 :         divide_64_32_fx( index, p_offset_scale2[tmp + p_no_scales[add( shl( mode_glb, 1 ), 1 )]], &index1, &index2 );
     356             :     }
     357             :     ELSE
     358             :     {
     359           0 :         index1 = L_deposit_l( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
     360           0 :         index2 = L_deposit_l( 0 );
     361             :     }
     362        4165 :     IF( index1 == 0 )
     363             :     {
     364           0 :         FOR( i = 0; i < LATTICE_DIM; i++ )
     365             :         {
     366           0 :             x_lvq[i] = 0;
     367           0 :             move16();
     368             :         }
     369           0 :         scales_mslvq[0] = 0;
     370           0 :         move16();
     371             :     }
     372             :     ELSE
     373             :     {
     374        4165 :         IF( GE_32( index1, p_offset_scale1[mode_glb * no_modes + p_no_scales[mode_glb * 2]] ) )
     375             :         {
     376             :             /* safety check in case of bit errors */
     377           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     378           0 :             scales_mslvq[0] = 0;
     379           0 :             move16();
     380           0 :             scales_mslvq[1] = 0;
     381           0 :             move16();
     382           0 :             return 1;
     383             :         }
     384             : 
     385             :         /* find idx_scale */
     386        4165 :         i = 1;
     387        4165 :         move16();
     388        6782 :         WHILE( LE_16( i, p_no_scales[mode_glb * 2] ) && GE_32( index1, p_offset_scale1[mode_glb * no_modes + i] ) )
     389             :         {
     390        2617 :             i = add( i, 1 );
     391             :         }
     392        4165 :         idx_scale = sub( i, 1 );
     393        4165 :         move16();
     394        4165 :         index1 = L_sub( index1, p_offset_scale1[tmp + idx_scale] );
     395             : 
     396             :         /* find idx_leader */
     397        4165 :         i = 1;
     398        4165 :         move16();
     399             : 
     400       48437 :         WHILE( GE_32( index1, table_no_cv_fx[i] ) )
     401             :         {
     402       44272 :             i = add( i, 1 );
     403             :         }
     404        4165 :         im1 = sub( i, 1 );
     405        4165 :         decode_comb_fx( L_sub( index1, table_no_cv_fx[im1] ), x_lvq, im1 );
     406        4165 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     407        4165 :         move16();
     408             :     }
     409             : 
     410             :     /* second subvector */
     411        4165 :     IF( index2 == 0 )
     412             :     {
     413         270 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     414             :         {
     415         240 :             x_lvq[i] = 0;
     416         240 :             move16();
     417             :         }
     418          30 :         scales_mslvq[1] = 0;
     419          30 :         move16();
     420             :     }
     421             :     ELSE
     422             :     {
     423             :         /* find the index for the scale/truncation */
     424        4135 :         i = 1;
     425        4135 :         move16();
     426        6188 :         WHILE( GE_32( index2, p_offset_scale2[tmp + i] ) )
     427             :         {
     428        2053 :             i = add( i, 1 );
     429             :         }
     430             : 
     431        4135 :         idx_scale = sub( i, 1 );
     432        4135 :         index2 = L_sub( index2, p_offset_scale2[add( tmp, idx_scale )] );
     433             :         /* find the index of the leader vector */
     434        4135 :         i = 1;
     435        4135 :         move16();
     436       17905 :         WHILE( GE_32( index2, table_no_cv_fx[i] ) )
     437             :         {
     438       13770 :             i = add( i, 1 );
     439             :         }
     440        4135 :         im1 = sub( i, 1 );
     441        4135 :         decode_comb_fx( index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
     442        4135 :         scales_mslvq[1] = p_scales[add( i_mult2( mode_glb, len_scales ), add( MAX_NO_SCALES, idx_scale ) )];
     443        4135 :         move16();
     444             :     }
     445             : 
     446        4165 :     return 0;
     447             : }
     448             : 
     449      503384 : static Word16 decode_indexes_ivas_fx(
     450             :     Word16 *index,
     451             :     const Word16 no_bits,
     452             :     const Word16 *p_scales, // Q11
     453             :     const Word16 prediction_flag,
     454             :     Word16 *x_lvq, // Q1
     455             :     const Word16 mode_glb,
     456             :     Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
     457             : )
     458             : {
     459      503384 :     Word32 index1 = 0, index2, idx_scale;
     460      503384 :     move32();
     461             :     Word16 i;
     462             : 
     463      503384 :     Word16 len_scales = i_mult( MAX_NO_SCALES, 2 );
     464             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     465             : 
     466      503384 :     IF( LE_16( no_bits, 2 * LEN_INDICE ) ) /* the third short is not used */
     467             :     {
     468      275744 :         index[2] = 0;
     469      275744 :         move16();
     470      275744 :         if ( LE_16( no_bits, LEN_INDICE ) )
     471             :         {
     472        1133 :             index[1] = 0;
     473        1133 :             move16();
     474             :         }
     475             :     }
     476             : 
     477             :     /* safety check in case of bit errors */
     478     2013536 :     FOR( i = 0; i < 3; i++ )
     479             :     {
     480     1510152 :         IF( index[i] < 0 )
     481             :         {
     482           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     483           0 :             scales_mslvq[0] = 0;
     484           0 :             move16();
     485           0 :             scales_mslvq[1] = 0;
     486           0 :             move16();
     487           0 :             index[i] = 0;
     488           0 :             return 1;
     489             :         }
     490             :     }
     491             : 
     492      503384 :     create_offset( offset_scale1, offset_scale2, mode_glb, prediction_flag );
     493             :     /* first subvector */
     494      503384 :     IF( offset_scale2[MAX_NO_SCALES - 1] > 0 )
     495             :     {
     496      503384 :         divide_64_32_fx( index, offset_scale2[MAX_NO_SCALES], &index1, &index2 );
     497             :     }
     498             :     ELSE
     499             :     {
     500           0 :         index1 = (UWord32) ( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
     501           0 :         move32();
     502           0 :         index2 = 0;
     503           0 :         move32();
     504             :     }
     505             : 
     506      503384 :     IF( index1 == 0 )
     507             :     {
     508        1611 :         FOR( i = 0; i < LATTICE_DIM; i++ )
     509             :         {
     510        1432 :             x_lvq[i] = 0;
     511        1432 :             scales_mslvq[0] = 0;
     512        1432 :             move16();
     513             :         }
     514             :     }
     515             :     ELSE
     516             :     {
     517      503205 :         IF( GE_32( index1, (Word32) offset_scale1[MAX_NO_SCALES] ) )
     518             :         {
     519             :             /* safety check in case of bit errors */
     520           0 :             set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
     521           0 :             scales_mslvq[0] = 0;
     522           0 :             move16();
     523           0 :             scales_mslvq[1] = 0;
     524           0 :             move16();
     525           0 :             return 1;
     526             :         }
     527             : 
     528             :         /* find idx_scale */
     529      503205 :         i = 1;
     530      503205 :         test();
     531      778334 :         WHILE( LE_16( (Word16) i, MAX_NO_SCALES ) && GE_32( index1, (Word32) offset_scale1[i] ) )
     532             :         {
     533      275129 :             i++;
     534             :         }
     535             : 
     536      503205 :         idx_scale = i - 1;
     537      503205 :         index1 = L_sub( index1, offset_scale1[idx_scale] );
     538             : 
     539             :         /* find idx_leader */
     540      503205 :         i = 1;
     541      503205 :         move16();
     542     6094900 :         WHILE( GE_32( index1, (Word32) table_no_cv[i] ) )
     543             :         {
     544     5591695 :             i++;
     545             :         }
     546      503205 :         decode_comb_fx( (Word32) ( index1 - table_no_cv[i - 1] ), x_lvq, i - 1 );
     547      503205 :         scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
     548      503205 :         move16();
     549             :         // for (i = 0; i < LATTICE_DIM; i++)
     550             :         //{
     551             :         //     //x_lvq[i] *= scale;
     552             :         //     x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
     553             :         // }
     554             :     }
     555             : 
     556             :     /* second subvector */
     557      503384 :     IF( index2 == 0 )
     558             :     {
     559      190188 :         FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     560             :         {
     561             :             // x_lvq[i] = 0.0;
     562      169056 :             x_lvq[i] = 0;
     563      169056 :             move16();
     564             :         }
     565       21132 :         scales_mslvq[1] = 0;
     566       21132 :         move16();
     567             :     }
     568             :     ELSE
     569             :     {
     570             : 
     571             :         /* find the index for the scale/truncation */
     572      482252 :         i = 1;
     573      482252 :         move16();
     574      719766 :         WHILE( GE_32( index2, (Word32) offset_scale2[i] ) )
     575             :         {
     576      237514 :             i++;
     577             :         }
     578             : 
     579      482252 :         idx_scale = i - 1;
     580      482252 :         move16();
     581      482252 :         index2 = L_sub( index2, offset_scale2[idx_scale] );
     582             :         /* find the index of the leader vector */
     583      482252 :         i = 1;
     584      482252 :         move16();
     585     2129488 :         WHILE( GE_32( index2, (Word32) table_no_cv[i] ) )
     586             :         {
     587     1647236 :             i++;
     588             :         }
     589      482252 :         decode_comb_fx( (Word32) ( index2 - table_no_cv[i - 1] ), &x_lvq[LATTICE_DIM], i - 1 );
     590             : 
     591      482252 :         scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
     592      482252 :         move16();
     593             :         // for (i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++)
     594             :         //{
     595             :         //     //x_lvq[i] *= scale;
     596             :         //     x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
     597             :         // }
     598             :     }
     599             : 
     600      503384 :     return 0;
     601             : }
     602             : 
     603        4165 : Word16 deindex_lvq_fx(
     604             :     Word16 *index,           /* i  : index to be decoded, as an array of 3 Word16             */
     605             :     Word16 *x_lvq,           /* o  : decoded codevector                             Q(x2.56)  */
     606             :     Word16 mode,             /* i  : LVQ  coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
     607             :     Word16 sf_flag,          /* i  : safety net flag                                          */
     608             :     Word16 no_bits,          /* i  : number of bits for lattice                               */
     609             :     Word32 *p_offset_scale1, /* i  : offset for first subvector                               */
     610             :     Word32 *p_offset_scale2, /* i  : offset for the second subvector                          */
     611             :     Word16 *p_no_scales      /* i  : number of scales for each truncation and each MSLVQ structure */
     612             : )
     613             : {
     614             :     Word16 i;
     615             :     const Word16 *p_scales;
     616             :     Word16 mode_glb;
     617             :     Word32 L_tmp;
     618             :     // note_ : renamed from scales
     619             :     Word16 scales_mslvq[2];
     620             :     Word16 ber_flag;
     621             : 
     622        4165 :     IF( EQ_16( sf_flag, 1 ) )
     623             :     {
     624         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] )] );
     625         523 :         p_scales = &scales_fx[0][0];
     626         523 :         move16();
     627             :     }
     628             :     ELSE
     629             :     {
     630        3642 :         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] )] );
     631        3642 :         p_scales = &scales_p_fx[0][0];
     632        3642 :         move16();
     633             :     }
     634             : 
     635             :     /* decode the lattice index into the lattice codevectors for the two subvectors */
     636             :     ber_flag =
     637        4165 :         decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
     638             :                            p_offset_scale2, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
     639             : 
     640             : 
     641        4165 :     IF( EQ_16( sf_flag, 1 ) )
     642             :     {
     643             :         /* safety-net case*/
     644         523 :         IF( scales_mslvq[0] )
     645             :         {
     646        4707 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     647             :             {
     648        4184 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1  = Q13 */
     649             :                 /* Increase calculation accuracy  by shifting more to the left and using rounding instead of truncation*/
     650        4184 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     651        4184 :                 x_lvq[i] = round_fx( L_tmp );
     652        4184 :                 move16();
     653             :             }
     654             :         }
     655         523 :         IF( scales_mslvq[1] )
     656             :         {
     657        4608 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     658             :             {
     659        4096 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     660        4096 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     661        4096 :                 x_lvq[i] = round_fx( L_tmp );
     662        4096 :                 move16();
     663             :             }
     664             :         }
     665             :     }
     666             :     ELSE
     667             :     {
     668             :         /* predictive mode AR or MA */
     669        3642 :         IF( scales_mslvq[0] )
     670             :         {
     671       32778 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     672             :             {
     673       29136 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                             /* Q1+Q11+Q1  = Q13 */
     674       29136 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     675       29136 :                 x_lvq[i] = round_fx( L_tmp );
     676       29136 :                 move16();
     677             :             }
     678             :         }
     679        3642 :         IF( scales_mslvq[1] )
     680             :         {
     681       32607 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     682             :             {
     683       28984 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                             /* Q1+Q11+Q1  = Q13 */
     684       28984 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     685       28984 :                 x_lvq[i] = round_fx( L_tmp );
     686       28984 :                 move16();
     687             :             }
     688             :         }
     689             :     }
     690             : 
     691        4165 :     return ber_flag;
     692             : }
     693             : 
     694      502967 : Word16 deindex_lvq_ivas_fx(
     695             :     Word16 *index,  /* i  : index to be decoded, as an array of 3 Word16             */
     696             :     Word16 *x_lvq,  /* o  : decoded codevector                             Q(x2.56)  */
     697             :     Word16 mode,    /* i  : LVQ  coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
     698             :     Word16 sf_flag, /* i  : safety net flag                                          */
     699             :     Word16 no_bits  /* i  : number of bits for lattice                               */
     700             : )
     701             : {
     702             :     Word16 i;
     703             :     const Word16 *p_scales;
     704             :     Word16 mode_glb;
     705             :     Word32 L_tmp;
     706             :     // note_ : renamed from scales
     707             :     Word16 scales_mslvq[2];
     708             :     Word16 ber_flag;
     709             : 
     710      502967 :     IF( EQ_16( sf_flag, 1 ) )
     711             :     {
     712       70759 :         IF( LT_16( mode, 6 ) ) /* for NB */
     713             :         {
     714           0 :             mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( no_bits, min_lat_bits_SN[mode] )] );
     715             :         }
     716             :         ELSE
     717             :         {
     718       70759 :             mode_glb = add( offset_lvq_modes_SN[mode], sub( no_bits, min_lat_bits_SN[mode] ) ); /* there is granularity of 1 bit */
     719             :         }
     720       70759 :         p_scales = &scales_ivas_fx[0][0]; // Q11
     721       70759 :         move16();
     722             :     }
     723             :     ELSE
     724             :     {
     725      432208 :         test();
     726      432208 :         IF( ( LT_16( mode, 6 ) ) || ( EQ_16( mode, 12 ) ) ) /* for NB */
     727             :         {
     728        9583 :             mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( no_bits, min_lat_bits_pred[mode] )] );
     729             :         }
     730             :         ELSE
     731             :         {
     732      422625 :             mode_glb = add( offset_lvq_modes_pred[mode], sub( no_bits, min_lat_bits_pred[mode] ) );
     733             :         }
     734      432208 :         p_scales = &scales_p_ivas_fx[0][0]; // Q11
     735      432208 :         move16();
     736             :     }
     737             : 
     738             :     UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
     739      502967 :     create_offset( offset_scale1, offset_scale2, mode_glb, 1 - sf_flag );
     740             : 
     741             :     /* decode the lattice index into the lattice codevectors for the two subvectors */
     742             :     // ber_flag =
     743             :     //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, offset_scale1,
     744             :     //         offset_scale2, x_lvq, mode_glb, scales_mslvq); /* x_lvq is here Q1 */
     745             :     ber_flag =
     746      502967 :         decode_indexes_ivas_fx( index, no_bits, p_scales, 1 - sf_flag, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
     747             : 
     748             : 
     749      502967 :     IF( EQ_16( sf_flag, 1 ) )
     750             :     {
     751             :         /* safety-net case*/
     752       70759 :         IF( scales_mslvq[0] )
     753             :         {
     754      636057 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     755             :             {
     756      565384 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1  = Q13 */
     757             :                 /* Increase calculation accuracy  by shifting more to the left and using rounding instead of truncation*/
     758      565384 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     759      565384 :                 x_lvq[i] = round_fx( L_tmp );
     760      565384 :                 move16();
     761             :             }
     762             :         }
     763       70759 :         IF( scales_mslvq[1] )
     764             :         {
     765      594045 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     766             :             {
     767      528040 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     768      528040 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     769      528040 :                 x_lvq[i] = round_fx( L_tmp );
     770      528040 :                 move16();
     771             :             }
     772             :         }
     773             :     }
     774             :     ELSE
     775             :     {
     776             :         /* predictive mode AR or MA */
     777      432208 :         IF( scales_mslvq[0] )
     778             :         {
     779     3889098 :             FOR( i = 0; i < LATTICE_DIM; i++ )
     780             :             {
     781     3456976 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                  /* Q1+Q11+Q1  = Q13 */
     782     3456976 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     783     3456976 :                 x_lvq[i] = round_fx( L_tmp );
     784     3456976 :                 move16();
     785             :             }
     786             :         }
     787      432208 :         IF( scales_mslvq[1] )
     788             :         {
     789     3742479 :             FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     790             :             {
     791     3326648 :                 L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                  /* Q1+Q11+Q1  = Q13 */
     792     3326648 :                 L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     793     3326648 :                 x_lvq[i] = round_fx( L_tmp );
     794     3326648 :                 move16();
     795             :             }
     796             :         }
     797             :     }
     798             : 
     799      502967 :     return ber_flag;
     800             : }
     801             : 
     802             : /*----------------------------------------------------------------------------------------------------*
     803             :  * deindex_lvq_cng()
     804             :  * Note:
     805             :  * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
     806             :  * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
     807             :  * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
     808             :  *----------------------------------------------------------------------------------------------------*/
     809             : 
     810           0 : Word16 deindex_lvq_cng_fx(
     811             :     Word16 *index,           /* i: index to be decoded, as an array of 3 short */
     812             :     Word16 *x_lvq,           /* o: decoded codevector  Q9 */
     813             :     Word16 idx_cv,           /* i: relative mode_lvq, wrt START_CNG */
     814             :     Word16 no_bits,          /* i: number of bits for lattice */
     815             :     Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
     816             :     Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
     817             :     Word16 *p_no_scales      /* i: number of scales for each MSLVQ structure and each subvector */
     818             : )
     819             : {
     820             :     Word16 i;
     821             :     Word32 L_tmp;
     822             :     const Word16 *p_scales;
     823             :     Word16 mode_glb, mode;
     824             :     // note_ : renamed from scales as global declaration of scales is causing warning
     825             :     Word16 scales_mslvq[2];
     826             :     Word16 ber_flag;
     827             : 
     828             :     /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
     829           0 :     mode_glb = add( START_CNG, idx_cv );
     830             : 
     831           0 :     mode = add( LVQ_COD_MODES, idx_cv );
     832             : 
     833           0 :     p_scales = &scales_fx[0][0];
     834           0 :     move16();
     835             :     ber_flag =
     836           0 :         decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq );
     837             : 
     838           0 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     839             :     {
     840           0 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                 /* Q1+Q11+Q1  = Q13 */
     841           0 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     842           0 :         x_lvq[i] = round_fx( L_tmp );
     843           0 :         move16();
     844             :     }
     845           0 :     FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     846             :     {
     847           0 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     848           0 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     849           0 :         x_lvq[i] = round_fx( L_tmp );
     850           0 :         move16();
     851             :     }
     852             : 
     853             :     /* check if permutting needed */
     854           0 :     IF( cng_sort[idx_cv] )
     855             :     {
     856           0 :         permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
     857             :     }
     858             : 
     859           0 :     return ber_flag;
     860             : }
     861             : 
     862             : 
     863             : /*----------------------------------------------------------------------------------------------------*
     864             :  * deindex_lvq_cng()
     865             :  * Note:
     866             :  * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
     867             :  * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
     868             :  * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
     869             :  *----------------------------------------------------------------------------------------------------*/
     870             : 
     871         417 : Word16 deindex_lvq_cng_ivas_fx(
     872             :     Word16 *index, /* i: index to be decoded, as an array of 3 short */
     873             :     Word16 *x_lvq, /* o: decoded codevector  Q9 */
     874             :     Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
     875             :     Word16 no_bits /* i: number of bits for lattice */
     876             : )
     877             : {
     878             :     Word16 i;
     879             :     Word32 L_tmp;
     880             :     const Word16 *p_scales;
     881             :     Word16 mode_glb, mode;
     882             :     // note_ : renamed from scales as global declaration of scales is causing warning
     883             :     Word16 scales_mslvq[2];
     884             :     Word16 ber_flag;
     885             : 
     886             :     /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
     887         417 :     mode_glb = add( START_CNG_IVAS, idx_cv );
     888             : 
     889         417 :     mode = add( LVQ_COD_MODES, idx_cv );
     890             : 
     891         417 :     p_scales = &scales_ivas_fx[0][0];
     892         417 :     move16();
     893             :     // ber_flag =
     894             :     //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq);
     895             :     ber_flag =
     896         417 :         decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
     897             : 
     898        3753 :     FOR( i = 0; i < LATTICE_DIM; i++ )
     899             :     {
     900        3336 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[0] );                                 /* Q1+Q11+Q1  = Q13 */
     901        3336 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     902        3336 :         x_lvq[i] = round_fx( L_tmp );
     903        3336 :         move16();
     904             :     }
     905        3753 :     FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
     906             :     {
     907        3336 :         L_tmp = L_mult( x_lvq[i], scales_mslvq[1] );                                 /* Q1+Q11+Q1  = Q13 */
     908        3336 :         L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
     909        3336 :         x_lvq[i] = round_fx( L_tmp );
     910        3336 :         move16();
     911             :     }
     912             : 
     913             :     /* check if permutting needed */
     914         417 :     IF( cng_sort[idx_cv] )
     915             :     {
     916         410 :         permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
     917             :     }
     918             : 
     919         417 :     return ber_flag;
     920             : }
     921             : 
     922             : /* combinatorial indexing */
     923     3189609 : static void idx2c_fx(
     924             :     Word16 n,  /* i  : total number of positions (components)*/
     925             :     Word16 *p, /* o  : array with positions of the k components */
     926             :     Word16 k,  /* i  : number of components whose position is to be determined */
     927             :     Word16 val /* i  : index to be decoded  */
     928             : )
     929             : {
     930             :     Word16 i, skip, pos, k1;
     931             : 
     932     3189609 :     skip = 0;
     933     3189609 :     move16();
     934     3189609 :     pos = 0;
     935     3189609 :     move16();
     936     3189609 :     k1 = sub( k, 1 );
     937     3189609 :     move16();
     938     6738038 :     WHILE( LT_16( add( skip, sub( C_VQ[n - pos - 1][k1], 1 ) ), val ) )
     939             :     {
     940     3548429 :         skip = add( skip, C_VQ[n - pos - 1][k1] );
     941     3548429 :         move16();
     942     3548429 :         pos++;
     943     3548429 :         move16();
     944             :     }
     945             : 
     946     3189609 :     p[0] = pos;
     947     3189609 :     move16();
     948     3189609 :     n = sub( n, add( pos, 1 ) );
     949     3189609 :     val = sub( val, skip );
     950     3189609 :     IF( EQ_16( k, 1 ) )
     951             :     {
     952     1196127 :         return;
     953             :     }
     954             : 
     955     1993482 :     idx2c_fx( n, p + 1, k1, val );
     956             : 
     957             :     /* pos+1 */
     958     6044689 :     FOR( i = 1; i < k; i++ )
     959             :     {
     960     4051207 :         p[i] = add( p[i], add( pos, 1 ) );
     961     4051207 :         move16();
     962             :     }
     963             : 
     964     1993482 :     return;
     965             : }
     966             : /* combinatorial deindexing */
     967      996929 : static void decode_comb_fx(
     968             :     Word32 index,   /* i  : index to be decoded */
     969             :     Word16 *cv,     /* o  : decoded codevector Q1*/
     970             :     Word16 idx_lead /* i  : leader class index */
     971             : )
     972             : {
     973             :     Word16 idx_sign;
     974      996929 :     IF( LT_32( L_shl( index, 1 ), pi0[idx_lead] ) )
     975             :     {
     976       73941 :         idx_sign = 0;
     977       73941 :         move16();
     978             :     }
     979             :     ELSE
     980             :     {
     981      922988 :         idx_sign = extract_l( div_l( L_shl( index, 1 ), pi0[idx_lead] ) ); /*(index/pi0_fx[idx_lead]); */
     982             :     }
     983      996929 :     index = L_sub( index, L_mult0( idx_sign, pi0[idx_lead] ) );
     984      996929 :     decode_leaders_fx( extract_l( index ), idx_lead, cv );
     985      996929 :     decode_sign_pc1_fx( cv, idx_sign, pl_par[idx_lead] );
     986             : 
     987      996929 :     return;
     988             : }
     989      996929 : void decode_sign_pc1_fx(
     990             :     Word16 *c,       /* o  : decoded codevector  Q1*/
     991             :     Word16 idx_sign, /* i  : sign index */
     992             :     Word16 parity    /* i  : parity flag (+1/-1/0) */
     993             : )
     994             : {
     995      996929 :     Word16 i, len = LATTICE_DIM, cnt_neg = 1;
     996             : 
     997      996929 :     if ( parity )
     998             :     {
     999      419102 :         len = sub( len, 1 );
    1000             :     }
    1001             : 
    1002     8553259 :     FOR( i = 0; i < len; i++ )
    1003             :     {
    1004     7556330 :         IF( c[i] > 0 )
    1005             :         {
    1006             :             /*if (idx_sign % 2) */
    1007     5481733 :             IF( s_and( idx_sign, 1 ) )
    1008             :             {
    1009     2649785 :                 c[i] = negate( c[i] );
    1010     2649785 :                 move16();
    1011     2649785 :                 cnt_neg = negate( cnt_neg );
    1012     2649785 :                 move16();
    1013             :             }
    1014     5481733 :             idx_sign = shr( idx_sign, 1 ); /*  >>= 1; */
    1015             :         }
    1016             :     }
    1017             : 
    1018      996929 :     IF( LT_16( len, LATTICE_DIM ) )
    1019             :     {
    1020      419102 :         IF( NE_16( cnt_neg, parity ) )
    1021             :         {
    1022      190130 :             c[len] = negate( c[len] );
    1023      190130 :             move16();
    1024             :         }
    1025             :     }
    1026             : 
    1027      996929 :     return;
    1028             : }
    1029             : 
    1030             : 
    1031      996929 : static void decode_leaders_fx(
    1032             :     Word16 index,    /* i  : index to be decoded    */
    1033             :     Word16 idx_lead, /* i  : leader class index     */
    1034             :     Word16 *cv       /* o  : decoded codevector   Q1*/
    1035             : )
    1036             : {
    1037             :     Word16 i, no_vals_loc, no_vals_last, p[LATTICE_DIM], dim_loc, n_crt;
    1038             :     Word16 index1;
    1039             :     Word16 val_crt;
    1040             : 
    1041      996929 :     no_vals_loc = no_vals[idx_lead];
    1042      996929 :     move16();
    1043      996929 :     val_crt = vals_fx[idx_lead][no_vals_loc - 1];
    1044      996929 :     move16(); /*Q1  */
    1045      996929 :     no_vals_last = no_vals_ind[idx_lead][no_vals_loc - 1];
    1046      996929 :     move16();
    1047             : 
    1048     5782752 :     FOR( i = 0; i < no_vals_last; i++ )
    1049             :     {
    1050     4785823 :         cv[i] = val_crt;
    1051     4785823 :         move16(); /*Q1 */
    1052             :     }
    1053             : 
    1054      996929 :     val_crt = 1;
    1055      996929 :     move16();
    1056      996929 :     dim_loc = no_vals_last;
    1057      996929 :     move16();
    1058             : 
    1059      996929 :     SWITCH( no_vals_loc )
    1060             :     {
    1061      100111 :         case 1:
    1062      100111 :             BREAK;
    1063      600049 :         case 2:
    1064      600049 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index );
    1065      600049 :             put_value_fx( cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind[idx_lead][0] );
    1066      600049 :             BREAK;
    1067        2540 :         case 4:
    1068        2540 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][2] );
    1069        2540 :             n_crt = no_vals_ind[idx_lead][2];
    1070        2540 :             move16();
    1071        2540 :             index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index ); /*  index1 = index/C_VQ_fx[dim_loc][n_crt]; */
    1072        2540 :             /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
    1073        2540 :             idx2c_fx( dim_loc, p, n_crt, index );
    1074        2540 :             put_value_fx( cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind[idx_lead][2] ); /* Q1 */
    1075        2540 :             index = index1;
    1076        2540 :             move16();
    1077             :             /* no break */
    1078      296769 :         case 3:
    1079      296769 :             dim_loc = add( dim_loc, no_vals_ind[idx_lead][1] );
    1080      296769 :             n_crt = no_vals_ind[idx_lead][1];
    1081      296769 :             move16();
    1082      296769 :             index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index );
    1083             :             /*index  = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]));move16(); */
    1084      296769 :             idx2c_fx( dim_loc, p, n_crt, index );
    1085      296769 :             put_value_fx( cv, p, vals_fx[idx_lead][1], sub( dim_loc, n_crt ), n_crt );
    1086      296769 :             idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index1 );
    1087      296769 :             move16();
    1088      296769 :             put_value_fx( cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind[idx_lead][0] );
    1089      296769 :             BREAK;
    1090             :     }
    1091             : 
    1092      996929 :     return;
    1093             : }
    1094             : 
    1095             : /* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x.  */
    1096      624090 : static Word32 divide_32_32_fx( Word32 y,   /* i */
    1097             :                                Word32 x,   /* i */
    1098             :                                Word32 *rem /* o */
    1099             : )
    1100             : {
    1101             :     Word32 result, t, L_tmp;
    1102             :     Word16 i, ny, nx, nyx;
    1103             : 
    1104             : 
    1105      624090 :     IF( LT_32( y, x ) )
    1106             :     {
    1107       25952 :         result = L_deposit_l( 0 );
    1108       25952 :         *rem = y;
    1109       25952 :         move32();
    1110             :     }
    1111             :     ELSE
    1112             :     {
    1113             : 
    1114      598138 :         result = L_deposit_l( 0 );
    1115      598138 :         IF( y == 0 )
    1116             :         {
    1117           0 :             ny = 0;
    1118           0 :             move16();
    1119             :         }
    1120             :         ELSE
    1121             :         {
    1122      598138 :             ny = sub( 31, norm_l( y ) );
    1123             :         }
    1124      598138 :         IF( x == 0 )
    1125             :         {
    1126           0 :             nx = 0;
    1127           0 :             move16();
    1128             :         }
    1129             :         ELSE
    1130             :         {
    1131      598138 :             nx = sub( 31, norm_l( x ) );
    1132             :         }
    1133             : 
    1134      598138 :         nyx = sub( ny, nx );
    1135             : 
    1136             :         /*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
    1137      598138 :         t = L_shr( y, add( nyx, 1 ) );
    1138     8677040 :         FOR( i = 0; i <= nyx; i++ )
    1139             :         {
    1140     8078902 :             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)))); */
    1141     8078902 :             result = L_shl( result, 1 );
    1142     8078902 :             L_tmp = L_sub( t, x );
    1143     8078902 :             IF( L_tmp >= 0 )
    1144             :             {
    1145     4030400 :                 result = L_add( result, 1 );
    1146     4030400 :                 t = L_add( L_tmp, 0 );
    1147             :             }
    1148             :         }
    1149      598138 :         *rem = t;
    1150      598138 :         move32();
    1151             :     }
    1152      624090 :     return result;
    1153             : }
    1154             : 
    1155             : /* divide_32_32_fx() :Division reminder for Word16 - rem is the reminder of the division between y and x.  */
    1156      299309 : static Word16 divide_16_16_fx( Word16 y,   /* i */
    1157             :                                Word16 x,   /* i */
    1158             :                                Word16 *rem /* o */
    1159             : )
    1160             : {
    1161             :     Word16 result, t, tmp;
    1162             :     Word16 i, ny, nx, nyx;
    1163             : 
    1164             : 
    1165      299309 :     IF( LT_32( y, x ) )
    1166             :     {
    1167       36771 :         result = 0;
    1168       36771 :         move16();
    1169       36771 :         *rem = y;
    1170       36771 :         move16();
    1171             :     }
    1172             :     ELSE
    1173             :     {
    1174             : 
    1175      262538 :         result = 0;
    1176      262538 :         move16();
    1177      262538 :         IF( y == 0 )
    1178             :         {
    1179           0 :             ny = 0;
    1180           0 :             move16();
    1181             :         }
    1182             :         ELSE
    1183             :         {
    1184      262538 :             ny = sub( 15, norm_s( y ) );
    1185             :         }
    1186      262538 :         IF( x == 0 )
    1187             :         {
    1188           0 :             nx = 0;
    1189           0 :             move16();
    1190             :         }
    1191             :         ELSE
    1192             :         {
    1193      262538 :             nx = sub( 15, norm_s( x ) );
    1194             :         }
    1195             : 
    1196      262538 :         nyx = sub( ny, nx );
    1197             : 
    1198      262538 :         t = s_and( shr( y, add( nyx, 1 ) ), sub( shl( 1, sub( nx, 1 ) ), 1 ) );
    1199     1103921 :         FOR( i = 0; i <= nyx; i++ )
    1200             :         {
    1201      841383 :             t = add( shl( t, 1 ), s_and( shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
    1202      841383 :             result = shl( result, 1 );
    1203      841383 :             tmp = sub( t, x );
    1204      841383 :             IF( tmp >= 0 )
    1205             :             {
    1206      485308 :                 result = add( result, 1 );
    1207      485308 :                 t = tmp;
    1208      485308 :                 move16();
    1209             :             }
    1210             :         }
    1211      262538 :         *rem = t;
    1212      262538 :         move16();
    1213             :     }
    1214      299309 :     return result;
    1215             : }
    1216             : 
    1217      507549 : static void divide_64_32_fx(
    1218             :     Word16 *xs,     /* i  : denominator as array of two int32  */
    1219             :     Word32 y,       /* i  : nominator on 32 bits               */
    1220             :     Word32 *result, /* o  : integer division result on 32 bits */
    1221             :     Word32 *rem     /* o  : integer division reminder on 32 bits */
    1222             : )
    1223             : {
    1224             :     Word16 nb_x1;
    1225             :     Word32 r, x_tmp, x[2], q, q1;
    1226             : 
    1227      507549 :     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] ) );
    1228      507549 :     move32();
    1229      507549 :     x[1] = L_shr( L_deposit_l( xs[2] ), 1 );
    1230      507549 :     move32();
    1231             : 
    1232             :     /*x[0] = (((xs[2])&(1)<<(LEN_INDICE*2)) + (xs[1]<<LEN_INDICE) + xs[0];
    1233             :     x[1] = xs[2]>>1;                                                              */
    1234             : 
    1235      507549 :     IF( x[1] == 0 )
    1236             :     {
    1237      391008 :         nb_x1 = 0;
    1238      391008 :         move16();
    1239             :     }
    1240             :     ELSE
    1241             :     {
    1242      116541 :         nb_x1 = sub( 31, norm_l( x[1] ) ); /*get_no_bits_fx(x[1]); */
    1243             :     }
    1244             :     /* take the first 31 bits */
    1245      507549 :     IF( nb_x1 > 0 )
    1246             :     {
    1247      116541 :         x_tmp = L_add( L_shl( x[1], sub( 31, nb_x1 ) ), L_shr( x[0], nb_x1 ) );
    1248             :         /* x_tmp = (x[1]<<(32-nb_x1)) + (x[0]>>nb_x1);        */
    1249             : 
    1250      116541 :         q = divide_32_32_fx( x_tmp, y, &r );                                                     /* q = x_tmp/y, reminder r */
    1251      116541 :         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 */
    1252             :         /* r = (r<<nb_x1)+(x[0]&((1<<nb_x1) - 1));         */
    1253             : 
    1254      116541 :         q1 = divide_32_32_fx( r, y, rem );
    1255      116541 :         *result = L_add( L_shl( q, nb_x1 ), q1 );
    1256      116541 :         move32();
    1257             :     }
    1258             :     ELSE
    1259             :     {
    1260      391008 :         *result = divide_32_32_fx( x[0], y, rem );
    1261      391008 :         move32();
    1262             :     }
    1263             : 
    1264      507549 :     return;
    1265             : }
    1266             : 
    1267     1196127 : static void put_value_fx(
    1268             :     Word16 *cv,       /* i/o  : input codevector            Q1*/
    1269             :     Word16 *p,        /* i  : array with positions            */
    1270             :     Word16 val,       /* i  : value to be inserted          Q1*/
    1271             :     Word16 dim,       /* i  : vector dimension                */
    1272             :     Word16 no_new_val /* i  : number of values to be inserted */
    1273             : )
    1274             : {
    1275             :     Word16 cv_out[LATTICE_DIM];
    1276             :     Word16 i, occ[LATTICE_DIM], cnt, limit;
    1277             : 
    1278     1196127 :     limit = add( dim, no_new_val );
    1279    10387064 :     FOR( i = 0; i < limit; i++ )
    1280             :     {
    1281     9190937 :         occ[i] = 0;
    1282     9190937 :         move16();
    1283             :     }
    1284             : 
    1285     4385736 :     FOR( i = 0; i < no_new_val; i++ )
    1286             :     {
    1287     3189609 :         cv_out[p[i]] = val;
    1288     3189609 :         move16();
    1289     3189609 :         occ[p[i]] = 1;
    1290     3189609 :         move16();
    1291             :     }
    1292             : 
    1293     1196127 :     cnt = 0;
    1294     1196127 :     move16();
    1295    10387064 :     FOR( i = 0; i < limit; i++ )
    1296             :     {
    1297     9190937 :         if ( occ[i] == 0 )
    1298             :         {
    1299     6001328 :             cv_out[i] = cv[cnt++];
    1300     6001328 :             move16();
    1301             :         }
    1302             :     }
    1303             : 
    1304    10387064 :     FOR( i = 0; i < limit; i++ )
    1305             :     {
    1306     9190937 :         cv[i] = cv_out[i];
    1307     9190937 :         move16();
    1308             :     }
    1309             : 
    1310     1196127 :     return;
    1311             : }
    1312             : 
    1313        3172 : void deindex_lvq_SHB_fx(
    1314             :     UWord32 index,
    1315             :     Word16 *out,
    1316             :     const Word16 nbits,
    1317             :     const Word16 mode )
    1318             : {
    1319             :     UWord16 i;
    1320             :     const Word8 *p_no_lead;
    1321             :     const Word16 *p_scales;
    1322             :     Word16 scale;
    1323             :     Word16 idx_scale;
    1324             :     UWord32 offsets[MAX_NO_SCALES + 1];
    1325             : 
    1326        3172 :     IF( mode == 0 )
    1327             :     {
    1328        3172 :         p_no_lead = &no_lead_BWE[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
    1329        3172 :         p_scales = &scales_BWE_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
    1330             :     }
    1331             :     ELSE
    1332             :     {
    1333           0 :         p_no_lead = &no_lead_BWE_3b[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
    1334           0 :         p_scales = &scales_BWE_3b_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
    1335             :     }
    1336             : 
    1337             : 
    1338        3172 :     IF( index == 0 )
    1339             :     {
    1340           0 :         set16_fx( out, 0, LATTICE_DIM );
    1341             :     }
    1342             :     ELSE
    1343             :     {
    1344             :         /* create offsets */
    1345        3172 :         offsets[0] = 0;
    1346        3172 :         move32();
    1347       12688 :         FOR( i = 0; i < MAX_NO_SCALES; i++ )
    1348             :         {
    1349        9516 :             offsets[i + 1] = UL_addNsD( table_no_cv[p_no_lead[i]], offsets[i] );
    1350        9516 :             move32();
    1351             :         }
    1352             : 
    1353             :         /* find idx_scale */
    1354        3172 :         idx_scale = 0;
    1355        3172 :         test();
    1356        7331 :         WHILE( LE_32( i, MAX_NO_SCALES ) && index >= offsets[idx_scale] )
    1357             :         {
    1358        4159 :             test();
    1359        4159 :             idx_scale = add( idx_scale, 1 );
    1360             :         }
    1361        3172 :         idx_scale = sub( idx_scale, 1 );
    1362        3172 :         index = L_sub( index, offsets[idx_scale] );
    1363             : 
    1364             :         /* find idx_leader */
    1365        3172 :         i = 1;
    1366        3172 :         move16();
    1367       21605 :         WHILE( GT_32( index, table_no_cv[i] ) )
    1368             :         {
    1369       18433 :             i = add( i, 1 );
    1370             :         }
    1371        3172 :         i = sub( i, 1 );
    1372             : 
    1373        3172 :         decode_comb_fx( (Word32) ( L_sub( L_sub( index, table_no_cv[i] ), 1 ) ), out, i );
    1374             : 
    1375        3172 :         scale = p_scales[idx_scale];
    1376        3172 :         move16();
    1377       28548 :         FOR( i = 0; i < LATTICE_DIM; i++ )
    1378             :         {
    1379       25376 :             Word32 temp = Mpy_32_16_1( sigma_BWE_fx[add( i_mult( mode, LATTICE_DIM ), i )], scale );
    1380       25376 :             temp = Mpy_32_16_1( temp, out[i] );
    1381       25376 :             out[i] = extract_l( temp ); /* Q15 output*/
    1382       25376 :             move16();
    1383             :             // out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i];
    1384             :         }
    1385             :     }
    1386             : 
    1387        3172 :     return;
    1388             : }

Generated by: LCOV version 1.14