LCOV - code coverage report
Current view: top level - lib_enc - lsf_msvq_ma_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 624 885 70.5 %
Date: 2025-09-14 03:13:15 Functions: 13 21 61.9 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <assert.h>
       7             : #include "options.h"
       8             : //#include "prot_fx.h"
       9             : #include "cnst.h"
      10             : #include "rom_com_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_enc.h"
      13             : #include "basop_util.h"
      14             : #include "prot_fx.h"     /* Function prototypes                    */
      15             : #include "prot_fx_enc.h" /* Function prototypes                    */
      16             : #include "basop_proto_func.h"
      17             : #include "wmc_auto.h"
      18             : 
      19             : 
      20             : /*-------------------------------------------------------------------*
      21             :  * Local constants
      22             :  *-------------------------------------------------------------------*/
      23             : 
      24             : #define kMaxC 8
      25             : 
      26             : #define MAXINT32 2147483647
      27             : #ifndef swap
      28             : #define swap( x, y, type ) \
      29             :     {                      \
      30             :         type u__p;         \
      31             :         u__p = x;          \
      32             :         x = y;             \
      33             :         y = u__p;          \
      34             :     }
      35             : #endif
      36             : 
      37             : #define depack_4_values( cbp, val0, val1, val2, val3 ) \
      38             :     val0 = shr( ( cbp )[0], 4 );                       \
      39             :     val1 = shr( ( cbp )[1], 4 );                       \
      40             :     val2 = shr( ( cbp )[2], 4 );                       \
      41             :     val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) );
      42             : 
      43             : /*--------------------------------------------------------------------------*
      44             :  * msvq_encmsvq_stage1_dct_search()
      45             :  *
      46             :  *  stage1 search in a segmentwise  truncated dct N  domain without  weights
      47             :  *--------------------------------------------------------------------------*/
      48             : 
      49             : /*! r: (p_max , best candidate sofar ) */
      50        2742 : Word16 msvq_stage1_dct_search_fx(
      51             :     const Word32 *u_fx,                       /* i  : target                                        exp : u_e */
      52             :     const Word16 u_e,                         /* i  : exp for target                                       Q0 */
      53             :     const Word16 N,                           /* i  : target length and  IDCT synthesis length                */
      54             :     const Word16 maxC_st1,                    /* i  : number of final stage 1 candidates to provide           */
      55             :     const DCTTYPE dcttype,                    /* e.g. DCT_T2_16_XX, DCT_T2_24_XX;                             */
      56             :     const Word16 max_dct_trunc,               /* i  :  maximum of truncation lenghts                          */
      57             :     Word32 *invTrfMatrix_fx,                  /* i  : IDCT synthesis matrix for dim N                     Q31 */
      58             :     const Word16 *midQ_truncQ_fx,             /* i  : midQ  vector                                            */
      59             :     const Word32 *dct_scaleF_fx,              /* i  : global scale factors                                Q10 */
      60             :     const Word16 n_segm,                      /* i  : number of segments                                      */
      61             :     const Word16 *cols_per_segment,           /* i  : remaining length per segment                            */
      62             :     const Word16 *trunc_dct_cols_per_segment, /* i  : trunc length per segment                                */
      63             :     const Word16 *entries_per_segment,        /* i  : number of rows per segment                              */
      64             :     const Word16 *cum_entries_per_segment,    /* i  : number of cumulative entries                            */
      65             :     const Word8 *const W8Qx_dct_sections[],   /* i  : Word8(byte) segment  table ptrs                         */
      66             :     const Word16 *col_syn_shift[],            /* i  : columnwise  syn shift tables                            */
      67             :     const Word8 *segm_neighbour_fwd,          /* i  : circular neighbour list fwd                             */
      68             :     const Word8 *segm_neighbour_rev,          /* i  : circular neighbour list reverse                         */
      69             :     const Word16 npost_check,                 /* i  : number of neigbours to check , should be even           */
      70             :     Word32 *st1_mse_ptr_fx,                   /* i  : dynRAM buffer for MSEs                        exp : u_e */
      71             :     Word16 *indices_st1_local,                /* o  :  selected cand indices                                  */
      72             :     Word32 *st1_syn_vec_ptr_fx,               /* i/o:  buffer for IDCT24 synthesis               i :exp : u_e */
      73             :     Word32 *dist1_ptr_fx,                     /* o  :  resulting stage 1 MSEs in DCT-N domain                 */
      74             :     Word16 *dist1_ptr_e )
      75             : {
      76             :     Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; // Q20
      77             :     Word32 u_mr_fx[FDCNG_VQ_MAX_LEN];
      78             :     Word16 dist1_ptr_e_buf[2 * LSFMBEST_MAX];
      79             :     Word64 mse_trunc_segm_fx[FDCNG_VQ_DCT_NSEGM];
      80             :     Word32 tmp_fx, check_mse;
      81             :     Word16 tmp_e, check_mse_e;
      82             :     Word64 mse_fx; /* Word64 in BASOP */
      83             : 
      84             :     Word16 p_max, c, c2, segm, j_full, j, i;
      85             :     Word16 n_ana, p_mins[2], idx_min[2];
      86             : 
      87             :     Word16 st1_mse_ptr_e[128];
      88             : 
      89             :     const Word8 *cbpW8;
      90             :     const Word16 *dct_col_shift_tab;
      91             : 
      92             :     Word32 *st1_mse_pair_fx;
      93             :     Word16 *st1_mse_pair_e;
      94             :     Word16 *st1_idx_pair;
      95             : 
      96             :     Word32 tmp2_fx;
      97             :     Word16 check_ind[FDCNG_VQ_DCT_NPOST];
      98        2742 :     assert( ( npost_check % 2 == 0 ) && ( npost_check <= FDCNG_VQ_DCT_NPOST ) );
      99             : 
     100        2742 :     assert( n_segm <= FDCNG_VQ_DCT_NSEGM );
     101             : 
     102        2742 :     n_ana = N; /*  VQ stage#1 core is currently always using stored DCT N coeffs */
     103        2742 :     move16();
     104        2742 :     assert( n_ana >= max_dct_trunc ); /* check for  FDCNGVQ  WB , SWB, FB operation  */
     105             : 
     106             :     /* remove  mid  stage#1 vector,  in original  input  domain */
     107        2742 :     tmp_e = s_max( 12, u_e );
     108       68550 :     FOR( i = 0; i < n_ana; i++ )
     109             :     {
     110       65808 :         u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e
     111       65808 :         move32();
     112             :     }
     113             : 
     114        2742 :     dctT2_N_apply_matrix_fx( (const Word32 *) u_mr_fx, dct_target_fx, s_min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix_fx, max_dct_trunc, dcttype ); // exp : tmp_e
     115             : 
     116             :     /* init search state  ptr's  at the top */
     117        2742 :     set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 );
     118        2742 :     set16_fx( dist1_ptr_e_buf, 32, maxC_st1 );
     119        2742 :     st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e
     120        2742 :     st1_mse_pair_e = &( dist1_ptr_e_buf[0] );                           /* req. ptr post upd +=2 */
     121        2742 :     st1_idx_pair = &( indices_st1_local[0] );                           /* req. ptr post upd +=2 */
     122        2742 :     set64_fx( mse_trunc_segm_fx, 0, n_segm );
     123             : 
     124             :     // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM );
     125             : 
     126       13710 :     FOR( segm = 0; segm < n_segm; segm++ )
     127             :     {              /*  point to a  new paired location for each segment  */
     128       10968 :         p_max = 0; /* req. to point to one of 1 or 0, this init  can potentially be omitted here,as p_max is always 1 or 0 */
     129       10968 :         move16();
     130             : 
     131             :         /* compute segment common trunction error in dctN domain */
     132             : 
     133       65808 :         FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ )
     134             :         {
     135       54840 :             mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41
     136       54840 :             move64();
     137             :         }
     138             : 
     139       10968 :         cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */
     140             : 
     141      361944 :         FOR( j = 0; j < entries_per_segment[segm]; j++ )
     142             :         {
     143             :             /* unweighted segmented search DCT domain loop */
     144      350976 :             j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */
     145             : 
     146      350976 :             mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in  BASOP a move32() */ // Q41
     147      350976 :             move64();
     148             : 
     149      350976 :             dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */
     150             : 
     151     5763684 :             FOR( c2 = 0; c2 < cols_per_segment[segm]; c2++ )
     152             :             {
     153             : #define WMC_TOOL_SKIP
     154     5412708 :                 tmp_fx = L_sub( dct_target_fx[c2], Mpy_32_32( L_shl( cbpW8[c2], add( sub( Q31, tmp_e ), dct_col_shift_tab[c2] ) ), dct_scaleF_fx[1] ) ); /*   note:  BASOP shift left defined for signed integers      */
     155             :                 LOGIC( 1 );
     156             :                 SHIFT( 1 );
     157             :                 ADD( 1 ); /* in BASOP:    s_and(for W8->W16), shl(), sub()*/
     158             : #undef WMC_TOOL_SKIP
     159     5412708 :                 mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /*  L_mac or L_mac0()   square Word16 -> Word32*/ // Q41
     160             :             }
     161      350976 :             Word16 L_tmp = W_norm( mse_fx );
     162      350976 :             st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM,  move32() in BASOP */ // st1_mse_ptr_e
     163      350976 :             move32();
     164      350976 :             st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp );
     165      350976 :             move16();
     166             : 
     167             : #define WMC_TOOL_SKIP
     168      350976 :             cbpW8 += cols_per_segment[segm]; /*   fixed  pointer increment for each segment  */
     169             : #undef WMC_TOOL_SKIP
     170             : 
     171             :             /* overwrite with a new worst index at p_max  */
     172             : 
     173             :             /* Note: The three inner loop if's below are not 100% properly instrumented by WMC tool */
     174             :             // if ( st1_mse_ptr_fx[j_full] < st1_mse_pair_fx[p_max] ) /* L_sub  */
     175      350976 :             IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_ptr_fx[j_full], st1_mse_ptr_e[j_full], st1_mse_pair_fx[p_max], st1_mse_pair_e[p_max] ), -1 ) ) /* L_sub  */
     176             :             {
     177      154542 :                 st1_idx_pair[p_max] = j_full; /* move16, single BASOP */
     178      154542 :                 move16();
     179             :             } /* BASOP 2 ops */
     180             : 
     181      350976 :             IF( EQ_16( st1_idx_pair[p_max], j_full ) )
     182             :             {                                                    /* idx updated  -->  also update mse */
     183      154542 :                 st1_mse_pair_fx[p_max] = st1_mse_ptr_fx[j_full]; /* move32(), single BASOP  */
     184      154542 :                 move32();
     185      154542 :                 st1_mse_pair_e[p_max] = st1_mse_ptr_e[j_full]; /* move32(), single BASOP  */
     186      154542 :                 move16();
     187             :             } /* BASOP 3 ops */
     188             : 
     189             :             /* avoid WC costly candidate list management by always updating p_max,
     190             :                as we have only a pair in each segment to maintain */
     191      350976 :             p_max = 0;
     192      350976 :             move16();
     193      350976 :             if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_pair_fx[0], st1_mse_pair_e[0], st1_mse_pair_fx[1], st1_mse_pair_e[1] ), -1 ) ) /* L_sub()*/
     194             :             {
     195      187763 :                 p_max = 1; /*  move16() */
     196      187763 :                 move16();
     197             :             } /* BASOP 3 ops  ,Note  2 ops possible in BASOP with L_sub and  L_lshr  */
     198             : 
     199             :             /* Note: logical shift right not available in ANSI-C */
     200             :             /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */
     201             :             /* in java logical shift right is available as  >>> ,  in BASOP  it is available as L_lshr */
     202             : 
     203             :             /* Cost: weighted sum with cond moves ('if') => 8 in float ,   7 in BASOP with L_lshr  */
     204             :         } /* j in section */
     205             : 
     206       10968 :         st1_mse_pair_fx += 2; /* req. ptr init  */
     207       10968 :         st1_mse_pair_e += 2;  /* req. ptr init  */
     208       10968 :         st1_idx_pair += 2;    /* req.  ptr init */
     209             : 
     210             :     } /* next segment */
     211             : 
     212        2742 :     tmp_e = 0;
     213        2742 :     move16();
     214       24678 :     FOR( j = 0; j < maxC_st1; j++ )
     215             :     {
     216             :         /* compute_full mse using stored DCT24 domain  MSE's   */
     217             :         /* calculate MSE  from stage1 inner using existing  inner  DCT domain variables */
     218       21936 :         tmp_e = s_max( dist1_ptr_e_buf[j], tmp_e );
     219             :     }
     220             : 
     221       24678 :     FOR( j = 0; j < maxC_st1; j++ )
     222             :     {
     223             :         /* compute_full mse using stored DCT24 domain  MSE's   */
     224             :         /* calculate MSE  from stage1 inner using existing  inner  DCT domain variables */
     225       21936 :         dist1_ptr_fx[j] = L_shr( dist1_ptr_fx[j], sub( tmp_e, dist1_ptr_e_buf[j] ) );
     226       21936 :         move32();
     227       21936 :         *dist1_ptr_e = tmp_e;
     228       21936 :         move16();
     229             :     }
     230             : 
     231             : 
     232        2742 :     assert( ( maxC_st1 >= 3 ) );
     233        2742 :     assert( ( maxC_st1 <= 8 ) );
     234             : 
     235        2742 :     p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish  current worst candidate for MSVQ stage#2  among all  maxC_st1 candidates so far */
     236             : 
     237        2742 :     p_mins[0] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find best  entry among all maxC_pre   */
     238        2742 :     move16();
     239        2742 :     tmp_fx = dist1_ptr_fx[p_mins[0]];
     240        2742 :     move32();
     241        2742 :     dist1_ptr_fx[p_mins[0]] = MAX_32; /* exclude 1st */
     242        2742 :     move32();
     243             : 
     244        2742 :     p_mins[1] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find 2nd best entry  */
     245        2742 :     move16();
     246        2742 :     tmp2_fx = dist1_ptr_fx[p_mins[1]];
     247        2742 :     move32();
     248        2742 :     dist1_ptr_fx[p_mins[1]] = MAX_32; /* exclude 2nd */
     249        2742 :     move32();
     250             : 
     251        2742 :     dist1_ptr_fx[p_mins[0]] = tmp_fx; /* restore 1st */
     252        2742 :     move32();
     253        2742 :     dist1_ptr_fx[p_mins[1]] = tmp2_fx; /* restore 2nd */
     254        2742 :     move32();
     255             : 
     256        2742 :     idx_min[0] = indices_st1_local[p_mins[0]];
     257        2742 :     move16();
     258        2742 :     idx_min[1] = indices_st1_local[p_mins[1]];
     259        2742 :     move16();
     260             : 
     261             : 
     262             :     /* use global exclusion list to never reselect  the two  (best) global  MSE values sofar  */
     263        2742 :     st1_mse_ptr_fx[idx_min[0]] = MAX_32; /* move32() */
     264        2742 :     move32();
     265        2742 :     st1_mse_ptr_e[idx_min[0]] = MAX_16;
     266        2742 :     move16();
     267        2742 :     st1_mse_ptr_fx[idx_min[1]] = MAX_32; /* move32() */
     268        2742 :     move32();
     269        2742 :     st1_mse_ptr_e[idx_min[1]] = MAX_16;
     270        2742 :     move16();
     271             : 
     272             :     /* circular MSE-neigbour list in use to potentially replace some segment search candidates */
     273             :     /* using both 1st and 2nd best neighbours   in fwd and rev directions */
     274        2742 :     check_ind[0] = segm_neighbour_fwd[idx_min[0]];
     275        2742 :     move16();
     276        2742 :     check_ind[1] = segm_neighbour_rev[idx_min[0]];
     277        2742 :     move16();
     278             : 
     279        2742 :     check_ind[2] = segm_neighbour_fwd[idx_min[1]];
     280        2742 :     move16();
     281        2742 :     check_ind[3] = segm_neighbour_rev[idx_min[1]];
     282        2742 :     move16();
     283             : 
     284        2742 :     check_ind[4] = segm_neighbour_fwd[check_ind[0]];
     285        2742 :     move16();
     286        2742 :     check_ind[5] = segm_neighbour_rev[check_ind[1]];
     287        2742 :     move16();
     288             : 
     289        2742 :     check_ind[6] = segm_neighbour_fwd[check_ind[2]];
     290        2742 :     move16();
     291        2742 :     check_ind[FDCNG_VQ_DCT_NPOST - 1] = segm_neighbour_rev[check_ind[3]];
     292        2742 :     move16();
     293             : 
     294       24678 :     FOR( i = 0; i < npost_check; i++ )
     295             :     {
     296             :         /*   move MSE from DCT-inner loop search  to  input synthesis domain */
     297             :         /*   multiplication by fdcng_dct_scaleF[2]   to get the float outer loop scale correct in IDCT synthesis domain  */
     298       21936 :         check_mse = st1_mse_ptr_fx[check_ind[i]];
     299       21936 :         move32();
     300       21936 :         check_mse_e = st1_mse_ptr_e[check_ind[i]];
     301       21936 :         move16();
     302             : 
     303       21936 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( check_mse, check_mse_e, dist1_ptr_fx[p_max], *dist1_ptr_e ), -1 ) )
     304             :         { /* new winner , replace worst */
     305       10454 :             dist1_ptr_fx[p_max] = L_shl( check_mse, sub( check_mse_e, *dist1_ptr_e ) );
     306       10454 :             move32();
     307       10454 :             indices_st1_local[p_max] = check_ind[i];
     308       10454 :             move16();
     309       10454 :             st1_mse_ptr_fx[check_ind[i]] = MAX_32; /* exclude,   BASOP: move32() */
     310       10454 :             move32();
     311       10454 :             st1_mse_ptr_e[check_ind[i]] = MAX_16;
     312       10454 :             move16();
     313       10454 :             p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish a new  current worst candidate   among all maxC */
     314             :         }
     315             :     }
     316             : 
     317             :     /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */
     318             :     /* always extract full length signal(e.g. 24) to be able to update WB(e.g.  N_in==21) candidate MSE values */
     319             :     /* in the case that only a part of the IDCT N  vector is in final use    */
     320             : 
     321             :     /* note: synthesis not yet fully parameterized/generalized for other IDCT lengths */
     322        2742 :     assert( N == 24 );
     323             :     {
     324       24678 :         FOR( c = 0; c < maxC_st1; c++ )
     325             :         {
     326       21936 :             dec_FDCNG_MSVQ_stage1_fx( indices_st1_local[c], N, invTrfMatrix_fx, dcttype + 1, &( st1_syn_vec_ptr_fx[c * N] ), NULL ); // Q11 : output
     327       21936 :             scale_sig32( &( st1_syn_vec_ptr_fx[c * N] ), N, sub( 11, s_max( u_e, 12 ) ) );
     328             :         }
     329             :     }
     330             : 
     331        2742 :     return p_max; /*ptr to worst performing candidate */
     332             : }
     333             : 
     334             : 
     335             : /*--------------------------------------------------------------------------*
     336             :  * msvq_stage1_dct_recalc_candidates_fdcng_wb()
     337             :  *
     338             :  * recalc MSE for fdcng WB(0..20) coeffs ,
     339             :            essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1  MSE in the DCT24 domain truncated search,
     340             :            excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep the WB MSEs update for the subsequent stages
     341             :  *--------------------------------------------------------------------------*/
     342             : 
     343             : /*! r: (updated p_max) */
     344         725 : Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx(
     345             :     const Word32 *st1_syn_vec_ptr_fx, /* i  : IDCT24 synthesis vectors               st1_syn_vec_e*/
     346             :     const Word16 st1_syn_vec_e,       /* i  : exp for IDCT24 synthesis vectors       */
     347             :     const Word32 *u_fx,               /* i  : target   signal                        u_e*/
     348             :     const Word16 u_e,                 /* i  : exp for target   signal                */
     349             :     const Word16 maxC_st1,            /* i  : number of candidates in stage1         */
     350             :     Word32 *dist_ptr_fx,              /* i/o: updated  MSE vector for stage1         */
     351             :     Word16 *dist_ptr_e                /* i/o: exp for updated  MSE vector for stage1 */
     352             : )
     353             : {
     354             :     Word16 i;
     355             :     Word16 p_max_local, c;
     356             :     const Word32 *p2_fx;
     357             :     Word16 tmp_e;
     358             :     Word32 res24_fx, high_diff_fx[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB];
     359             :     Word64 acc;
     360             :     Word16 res24_e[FD_CNG_maxC_37bits];
     361             :     Word16 dist_e;
     362             : 
     363         725 :     dist_e = *dist_ptr_e;
     364         725 :     move16();
     365        6525 :     FOR( c = 0; c < maxC_st1; c++ )
     366             :     {                                                                                                 /* point to extended  synthesis part */
     367        5800 :         p2_fx = (const Word32 *) &( st1_syn_vec_ptr_fx[c * FDCNG_VQ_MAX_LEN + FDCNG_VQ_MAX_LEN_WB] ); /* ptr init to synthesis candidate c */
     368        5800 :         tmp_e = s_max( st1_syn_vec_e, u_e );
     369        5800 :         tmp_e = add( tmp_e, 1 );
     370             :         /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated  input target */
     371       23200 :         FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
     372             :         {
     373       17400 :             high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e
     374       17400 :             move32();
     375             :         }
     376        5800 :         acc = 0;
     377        5800 :         move64();
     378       23200 :         FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
     379             :         {
     380       17400 :             acc = W_mac_32_32( acc, high_diff_fx[i], high_diff_fx[i] );
     381             :         }
     382        5800 :         res24_e[c] = tmp_e;
     383        5800 :         move16();
     384        5800 :         tmp_e = W_norm( acc );
     385        5800 :         res24_fx = W_extract_h( W_shl( acc, tmp_e ) );
     386             : 
     387        5800 :         res24_e[c] = sub( shl( res24_e[c], 1 ), tmp_e );
     388        5800 :         move16();
     389             : 
     390        5800 :         dist_ptr_fx[c] = BASOP_Util_Add_Mant32Exp( dist_ptr_fx[c], *dist_ptr_e, L_negate( res24_fx ), res24_e[c], &res24_e[c] ); /* remove DCT24 high band error contribution */
     391        5800 :         move32();
     392        5800 :         dist_e = s_max( dist_e, res24_e[c] );
     393        5800 :         move16();
     394             :     }
     395             : 
     396             : 
     397        6525 :     FOR( c = 0; c < maxC_st1; c++ )
     398             :     {
     399        5800 :         dist_ptr_fx[c] = L_shl( dist_ptr_fx[c], sub( res24_e[c], dist_e ) );
     400        5800 :         move32();
     401             :     }
     402         725 :     *dist_ptr_e = dist_e;
     403         725 :     move16();
     404             :     /* finally update p_max,  as it may potentially change,
     405             :        due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */
     406         725 :     p_max_local = maximum_32_fx( dist_ptr_fx, maxC_st1, NULL );
     407             : 
     408         725 :     return p_max_local;
     409             : }
     410             : 
     411             : 
     412             : /*--------------------------------------------------------------------------*
     413             :  * depack_mul_values_fx()
     414             :  *
     415             :  *--------------------------------------------------------------------------*/
     416             : 
     417           0 : static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N )
     418             : {
     419             :     Word16 i, val0, val1, val2, val3;
     420             :     Word32 en;
     421             : 
     422           0 :     en = 0;
     423           0 :     move32();
     424           0 :     FOR( i = 0; i < N; i += 4 )
     425             :     {
     426           0 :         depack_4_values( cbp + i_mult( shr( i, 2 ), 3 ), val0, val1, val2, val3 )
     427           0 :             Tmp[i + 0] = mult_r( shl_sat( w[i + 0], 2 ), val0 );
     428           0 :         move16();
     429           0 :         en = L_mac_sat( en, val0, Tmp[i + 0] );
     430           0 :         Tmp[i + 1] = mult_r( shl_sat( w[i + 1], 2 ), val1 );
     431           0 :         move16();
     432           0 :         en = L_mac_sat( en, val1, Tmp[i + 1] );
     433           0 :         Tmp[i + 2] = mult_r( shl_sat( w[i + 2], 2 ), val2 );
     434           0 :         move16();
     435           0 :         en = L_mac_sat( en, val2, Tmp[i + 2] );
     436           0 :         Tmp[i + 3] = mult_r( shl_sat( w[i + 3], 2 ), val3 );
     437           0 :         move16();
     438           0 :         en = L_mac_sat( en, val3, Tmp[i + 3] );
     439             :     }
     440             : 
     441           0 :     return en;
     442             : }
     443             : 
     444             : 
     445             : /*--------------------------------------------------------------------------*
     446             :  * depack_sub_values()
     447             :  *
     448             :  *--------------------------------------------------------------------------*/
     449             : 
     450      557600 : static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N )
     451             : {
     452             :     Word16 j, val0, val1, val2, val3;
     453             : 
     454     1951600 :     FOR( j = 0; j < N; j += 4 )
     455             :     {
     456     1394000 :         depack_4_values( cbp + i_mult( 3, shr( j, 2 ) ), val0, val1, val2, val3 )
     457             : 
     458             :             /*pTmp[i] = (p1[i] - cbp[i]);*/
     459     1394000 :             pTmp[j + 0] = sub( p1[j + 0], val0 );
     460     1394000 :         move16(); /*3Q12*1.28*/
     461     1394000 :         pTmp[j + 1] = sub( p1[j + 1], val1 );
     462     1394000 :         move16(); /*3Q12*1.28*/
     463     1394000 :         pTmp[j + 2] = sub( p1[j + 2], val2 );
     464     1394000 :         move16(); /*3Q12*1.28*/
     465     1394000 :         pTmp[j + 3] = sub( p1[j + 3], val3 );
     466     1394000 :         move16(); /*3Q12*1.28*/
     467             :     }
     468      557600 : }
     469             : 
     470             : 
     471     1184900 : static Word64 depack_mul_values_fx64( Word32 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N )
     472             : {
     473             :     Word16 i, val0, val1, val2, val3;
     474             :     Word64 en;
     475             : 
     476     1184900 :     en = 0;
     477     1184900 :     move32();
     478     4879000 :     FOR( i = 0; i < N; i += 4 )
     479             :     {
     480     3694100 :         depack_4_values( cbp + i_mult( shr( i, 2 ), 3 ), val0, val1, val2, val3 )
     481     3694100 :             Tmp[i + 0] = L_mult0( w[i + 0], val0 ); // Q8 * Q2.56
     482     3694100 :         move16();
     483     3694100 :         en = W_mac_32_16( en, Tmp[i + 0], val0 ); // Q8 * Q2.56 * 2.56 * Q1
     484     3694100 :         Tmp[i + 1] = L_mult0( w[i + 1], val1 );
     485     3694100 :         move16();
     486     3694100 :         en = W_mac_32_16( en, Tmp[i + 1], val1 );
     487     3694100 :         Tmp[i + 2] = L_mult0( w[i + 2], val2 );
     488     3694100 :         move16();
     489     3694100 :         en = W_mac_32_16( en, Tmp[i + 2], val2 );
     490     3694100 :         Tmp[i + 3] = L_mult0( w[i + 3], val3 );
     491     3694100 :         move16();
     492     3694100 :         en = W_mac_32_16( en, Tmp[i + 3], val3 );
     493             :     }
     494             : 
     495     1184900 :     return en; // Q8 * Q2.56 * 2.56 * Q1
     496             : }
     497             : 
     498             : /*--------------------------------------------------------------------------*
     499             :  * msvq_enc_find_p_max_8()
     500             :  *
     501             :  * Unroll of inner search loop for maxC == 8
     502             :  *--------------------------------------------------------------------------*/
     503             : 
     504           0 : static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] )
     505             : {
     506             :     Word16 p_max;
     507             : 
     508           0 :     p_max = 0;
     509           0 :     move16();
     510             : 
     511             :     BASOP_SATURATE_WARNING_OFF_EVS
     512           0 :     if ( GT_32( dist[1], dist[p_max] ) )
     513             :     {
     514           0 :         p_max = 1;
     515           0 :         move16();
     516             :     }
     517           0 :     if ( GT_32( dist[2], dist[p_max] ) )
     518             :     {
     519           0 :         p_max = 2;
     520           0 :         move16();
     521             :     }
     522           0 :     if ( GT_32( dist[3], dist[p_max] ) )
     523             :     {
     524           0 :         p_max = 3;
     525           0 :         move16();
     526             :     }
     527           0 :     if ( GT_32( dist[4], dist[p_max] ) )
     528             :     {
     529           0 :         p_max = 4;
     530           0 :         move16();
     531             :     }
     532           0 :     if ( GT_32( dist[5], dist[p_max] ) )
     533             :     {
     534           0 :         p_max = 5;
     535           0 :         move16();
     536             :     }
     537           0 :     if ( GT_32( dist[6], dist[p_max] ) )
     538             :     {
     539           0 :         p_max = 6;
     540           0 :         move16();
     541             :     }
     542           0 :     if ( GT_32( dist[7], dist[p_max] ) )
     543             :     {
     544           0 :         p_max = 7;
     545           0 :         move16();
     546             :     }
     547             :     BASOP_SATURATE_WARNING_ON_EVS
     548           0 :     return p_max;
     549             : }
     550             : 
     551             : 
     552     1480737 : static Word16 msvq_enc_find_p_max_8_fx64( Word64 dist[] )
     553             : {
     554             :     Word16 p_max;
     555             : 
     556     1480737 :     p_max = 0;
     557     1480737 :     move16();
     558             : 
     559             :     BASOP_SATURATE_WARNING_OFF_EVS
     560     1480737 :     if ( GT_64( dist[1], dist[p_max] ) )
     561             :     {
     562      701609 :         p_max = 1;
     563      701609 :         move16();
     564             :     }
     565     1480737 :     if ( GT_64( dist[2], dist[p_max] ) )
     566             :     {
     567      496986 :         p_max = 2;
     568      496986 :         move16();
     569             :     }
     570     1480737 :     if ( GT_64( dist[3], dist[p_max] ) )
     571             :     {
     572      394427 :         p_max = 3;
     573      394427 :         move16();
     574             :     }
     575     1480737 :     if ( GT_64( dist[4], dist[p_max] ) )
     576             :     {
     577      301622 :         p_max = 4;
     578      301622 :         move16();
     579             :     }
     580     1480737 :     if ( GT_64( dist[5], dist[p_max] ) )
     581             :     {
     582      238182 :         p_max = 5;
     583      238182 :         move16();
     584             :     }
     585     1480737 :     if ( GT_64( dist[6], dist[p_max] ) )
     586             :     {
     587      217845 :         p_max = 6;
     588      217845 :         move16();
     589             :     }
     590     1480737 :     if ( GT_64( dist[7], dist[p_max] ) )
     591             :     {
     592      185700 :         p_max = 7;
     593      185700 :         move16();
     594             :     }
     595             :     BASOP_SATURATE_WARNING_ON_EVS
     596     1480737 :     return p_max;
     597             : }
     598             : 
     599             : 
     600             : /*--------------------------------------------------------------------------*
     601             :  * msvq_enc_find_p_max_6()
     602             :  *
     603             :  * Unroll of inner search loop for maxC == 6
     604             :  *--------------------------------------------------------------------------*/
     605             : 
     606           0 : static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] )
     607             : {
     608             :     Word16 p_max;
     609             : 
     610           0 :     p_max = 0;
     611           0 :     move16();
     612             : 
     613             :     BASOP_SATURATE_WARNING_OFF_EVS
     614           0 :     if ( GT_32( dist[1], dist[p_max] ) )
     615             :     {
     616           0 :         p_max = 1;
     617           0 :         move16();
     618             :     }
     619           0 :     if ( GT_32( dist[2], dist[p_max] ) )
     620             :     {
     621           0 :         p_max = 2;
     622           0 :         move16();
     623             :     }
     624           0 :     if ( GT_32( dist[3], dist[p_max] ) )
     625             :     {
     626           0 :         p_max = 3;
     627           0 :         move16();
     628             :     }
     629           0 :     if ( GT_32( dist[4], dist[p_max] ) )
     630             :     {
     631           0 :         p_max = 4;
     632           0 :         move16();
     633             :     }
     634           0 :     if ( GT_32( dist[5], dist[p_max] ) )
     635             :     {
     636           0 :         p_max = 5;
     637           0 :         move16();
     638             :     }
     639             :     BASOP_SATURATE_WARNING_ON_EVS
     640           0 :     return p_max;
     641             : }
     642             : 
     643           0 : static Word16 msvq_enc_find_p_max_6_fx64( Word64 dist[] )
     644             : {
     645             :     Word16 p_max;
     646             : 
     647           0 :     p_max = 0;
     648           0 :     move16();
     649             : 
     650             :     BASOP_SATURATE_WARNING_OFF_EVS
     651           0 :     if ( GT_64( dist[1], dist[p_max] ) )
     652             :     {
     653           0 :         p_max = 1;
     654           0 :         move16();
     655             :     }
     656           0 :     if ( GT_64( dist[2], dist[p_max] ) )
     657             :     {
     658           0 :         p_max = 2;
     659           0 :         move16();
     660             :     }
     661           0 :     if ( GT_64( dist[3], dist[p_max] ) )
     662             :     {
     663           0 :         p_max = 3;
     664           0 :         move16();
     665             :     }
     666           0 :     if ( GT_64( dist[4], dist[p_max] ) )
     667             :     {
     668           0 :         p_max = 4;
     669           0 :         move16();
     670             :     }
     671           0 :     if ( GT_64( dist[5], dist[p_max] ) )
     672             :     {
     673           0 :         p_max = 5;
     674           0 :         move16();
     675             :     }
     676             :     BASOP_SATURATE_WARNING_ON_EVS
     677           0 :     return p_max;
     678             : }
     679             : 
     680             : 
     681             : /*--------------------------------------------------------------------------*
     682             :  * msvq_enc_fx()
     683             :  *
     684             :  * MSVQ encoder
     685             :  *--------------------------------------------------------------------------*/
     686             : 
     687           0 : void msvq_enc_fx(
     688             :     const Word16 *const *cb, /* i  : Codebook (indexed cb[*stages][levels][p])         (0Q15) */
     689             :     const Word16 dims[],     /* i  : Dimension of each codebook stage (NULL: full dim.)       */
     690             :     const Word16 offs[],     /* i  : Starting dimension of each codebook stage (NULL: 0)      */
     691             :     const Word16 u[],        /* i  : Vector to be encoded (prediction and mean removed)(3Q12) */
     692             :     const Word16 *levels,    /* i  : Number of levels in each stage                           */
     693             :     const Word16 maxC,       /* i  : Tree search size (number of candidates kept from         */
     694             :     /*      one stage to the next == M-best)                         */
     695             :     const Word16 stages, /* i  : Number of stages                                         */
     696             :     const Word16 w[],    /* i  : Weights                                                  Q8*/
     697             :     const Word16 N,      /* i  : Vector dimension                                         */
     698             :     const Word16 maxN,   /* i  : Codebook dimension                                       */
     699             :     Word16 Idx[]         /* o  : Indices                                                  */
     700             : )
     701             : {
     702             :     Word16 j;
     703             :     const Word16 *cbp;
     704             :     Word16 p2i;
     705             :     Word16 resid_buf[2 * LSFMBEST_MAX * M_MAX], *resid[2];
     706             :     Word16 *pTmp, *p1;
     707             :     Word16 *indices[2], m, s, c, c2, p_max, i, Tmp[M_MAX];
     708             :     Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
     709             :     Word32 dist_buf[2 * LSFMBEST_MAX], *dist[2], t1, tmp, en, ss2;
     710             :     Word16 ( *func_ptr )( Word32 * );
     711             :     Word16 N34;
     712             :     Word16 n, maxn, start;
     713             : 
     714             :     /*----------------------------------------------------------------*
     715             :      * Allocate memory for previous (parent) and current nodes.
     716             :      *   Parent node is indexed [0], current node is indexed [1].
     717             :      *----------------------------------------------------------------*/
     718           0 :     indices[0] = idx_buf;
     719           0 :     indices[1] = idx_buf + maxC * stages; /*move16();*/
     720             :     /*vr_iset(0, idx_buf, 2*stages*maxC);*/
     721           0 :     set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
     722             : 
     723           0 :     resid[0] = resid_buf;
     724           0 :     resid[1] = resid_buf + maxC * N; /*move16();*/
     725             : 
     726           0 :     dist[0] = dist_buf;
     727           0 :     dist[1] = dist_buf + maxC; /*move16();*/
     728             : 
     729             :     /*vr_iset(0, parents, maxC);*/
     730           0 :     set16_fx( parents, 0, maxC );
     731             : 
     732             : 
     733           0 :     func_ptr = msvq_enc_find_p_max_6_fx;
     734           0 :     move16();
     735           0 :     if ( EQ_16( maxC, 8 ) )
     736             :     {
     737           0 :         func_ptr = msvq_enc_find_p_max_8_fx;
     738           0 :         move16();
     739             :     }
     740             : 
     741             :     /*----------------------------------------------------------------*
     742             :      * LSF weights are normalized, so it is always better to multiply it first
     743             :      * Set up inital distance vector
     744             :      *----------------------------------------------------------------*/
     745             :     /* Q0/16 * Qw_norm/16 << 1 >> 16 => Qwnorm-15/16 * Q0/16 << 1 => Qwnorm-14/32 * 6.5536 */
     746           0 :     ss2 = L_mult( mult( u[0], shl( w[0], 2 ) ), u[0] );
     747           0 :     move16();
     748           0 :     FOR( j = 1; j < N; j++ )
     749             :     {
     750           0 :         ss2 = L_mac_sat( ss2, mult( u[j], shl_sat( w[j], 2 ) ), u[j] );
     751             :     }
     752             : 
     753             :     /* Set up inital error (residual) vectors */
     754           0 :     pTmp = resid[1]; /*move16();*/
     755           0 :     FOR( c = 0; c < maxC; c++ )
     756             :     {
     757           0 :         Copy( u, pTmp + c * N, N );
     758           0 :         dist[1][c] = ss2;
     759           0 :         move32();
     760             :     }
     761             : 
     762             :     /* Loop over all stages */
     763           0 :     m = 1;
     764           0 :     move16();
     765           0 :     FOR( s = 0; s < stages; s++ )
     766             :     {
     767             :         /* codebook pointer is set to point to first stage */
     768           0 :         cbp = cb[s]; /*3Q12*1.28*/
     769           0 :         move16();
     770             : 
     771             :         /* Set up pointers to parent and current nodes */
     772           0 :         swap( indices[0], indices[1], Word16 * );
     773           0 :         move16();
     774           0 :         move16();
     775           0 :         move16();
     776           0 :         swap( resid[0], resid[1], Word16 * );
     777           0 :         move16();
     778           0 :         move16();
     779           0 :         move16();
     780           0 :         swap( dist[0], dist[1], Word32 * );
     781           0 :         move32();
     782           0 :         move32();
     783           0 :         move32();
     784             : 
     785             :         /* p_max points to maximum distortion node (worst of best) */
     786           0 :         p_max = 0;
     787           0 :         move16();
     788             : 
     789           0 :         n = N;
     790           0 :         move16();
     791           0 :         maxn = maxN;
     792           0 :         move16();
     793           0 :         if ( dims )
     794             :         {
     795           0 :             n = dims[s];
     796           0 :             move16();
     797             :         }
     798           0 :         if ( dims )
     799             :         {
     800           0 :             maxn = n;
     801           0 :             move16();
     802             :         }
     803             : 
     804           0 :         assert( ( maxn % 4 ) == 0 );
     805           0 :         N34 = mult( maxn, 24576 /*0.75f Q15*/ );
     806             : 
     807           0 :         start = 0;
     808           0 :         move16();
     809           0 :         if ( offs )
     810             :         {
     811           0 :             start = offs[s];
     812           0 :             move16();
     813             :         }
     814             : 
     815           0 :         set16_fx( Tmp, 0, start );
     816           0 :         set16_fx( Tmp + start + n, 0, sub( N, add( start, n ) ) );
     817             : 
     818             :         /* Set distortions to a large value */
     819           0 :         FOR( j = 0; j < maxC; j++ )
     820             :         {
     821           0 :             dist[1][j] = MAXINT32;
     822           0 :             move32();
     823             :         }
     824             : 
     825           0 :         FOR( j = 0; j < levels[s]; j++ )
     826             :         {
     827             :             /* Compute weighted codebook element and its energy */
     828           0 :             en = depack_mul_values_fx( Tmp + start, w + start, cbp, n );
     829             : 
     830           0 :             cbp += N34; /* pointer is incremented */
     831             : 
     832             :             /* Iterate over all parent nodes */
     833           0 :             FOR( c = 0; c < m; c++ )
     834             :             {
     835           0 :                 pTmp = &resid[0][c * N];
     836             :                 /*tmp = (*pTmp++) * Tmp[0];*/
     837           0 :                 t1 = L_mult( pTmp[0], Tmp[0] );
     838             : 
     839           0 :                 FOR( i = 1; i < N; i++ )
     840             :                 {
     841           0 :                     t1 = L_mac( t1, pTmp[i], Tmp[i] );
     842             :                 }
     843             : 
     844             :                 BASOP_SATURATE_WARNING_OFF_EVS
     845             :                 /*NOTE: as long as a shorter distance is found, saturation can be accepted.*/
     846           0 :                 tmp = L_add_sat( dist[0][c], L_sub_sat( en, L_shl( t1, 1 ) ) );
     847           0 :                 t1 = L_sub_sat( tmp, dist[1][p_max] );
     848             :                 BASOP_SATURATE_WARNING_ON_EVS
     849             : 
     850           0 :                 IF( t1 <= 0 )
     851             :                 {
     852             :                     /* Replace worst */
     853           0 :                     dist[1][p_max] = tmp;
     854           0 :                     move32();
     855           0 :                     indices[1][p_max * stages + s] = j;
     856           0 :                     move16();
     857           0 :                     add( 0, 0 );
     858           0 :                     mult( 0, 0 );
     859           0 :                     parents[p_max] = c;
     860           0 :                     move16();
     861             : 
     862           0 :                     p_max = ( *func_ptr )( dist[1] );
     863             : 
     864             :                 } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
     865             :             }     /* FOR (c=0; c<m; c++) */
     866             :         }         /* FOR (j=0; j<levels[s]; j++) */
     867             : 
     868             :         /*------------------------------------------------------------*
     869             :          * Compute error vectors for each node
     870             :          *------------------------------------------------------------*/
     871           0 :         pTmp = resid[1];
     872           0 :         FOR( c = 0; c < maxC; c++ )
     873             :         {
     874             :             /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
     875           0 :             p1 = resid[0] + parents[c] * N;
     876           0 :             p2i = indices[1][c * stages + s];
     877           0 :             move16();
     878             : 
     879           0 :             Copy( p1, pTmp, start );
     880           0 :             depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n );
     881           0 :             Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) );
     882             : 
     883           0 :             pTmp += N;
     884             : 
     885             :             /* Get indices that were used for parent node */
     886             :             /*mvs2s(indices[0]+parents[c]*stages, indices[1]+c*stages, s);*/
     887           0 :             Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s );
     888             :         } /* for (c=0; c<maxC; c++) */
     889           0 :         m = maxC;
     890           0 :         move16();
     891             :     } /* for (m=1, s=0; s<stages; s++) */
     892             : 
     893             :     /* Find the optimum candidate */
     894           0 :     c2 = findIndexOfMinWord32( dist[1], maxC );
     895             :     /*mvi2i (indices[1]+c2*stages, Idx, stages);*/
     896           0 :     Copy( indices[1] + c2 * stages, Idx, stages );
     897             : 
     898             : 
     899           0 :     return;
     900             : }
     901             : 
     902       34850 : void msvq_enc_lsf_fx64(
     903             :     const Word16 *const *cb, /* i  : Codebook (indexed cb[*stages][levels][p])         (10Q5 * 1.28) */
     904             :     const Word16 dims[],     /* i  : Dimension of each codebook stage (NULL: full dim.)       */
     905             :     const Word16 offs[],     /* i  : Starting dimension of each codebook stage (NULL: 0)      */
     906             :     const Word16 u[],        /* i  : Vector to be encoded (prediction and mean removed)(Q14Q1*1.28) */
     907             :     const Word16 *levels,    /* i  : Number of levels in each stage                           */
     908             :     const Word16 maxC,       /* i  : Tree search size (number of candidates kept from         */
     909             :     /*      one stage to the next == M-best)                         */
     910             :     const Word16 stages, /* i  : Number of stages                                         */
     911             :     const Word16 w[],    /* i  : Weights                                                  Q8*/
     912             :     const Word16 N,      /* i  : Vector dimension                                         */
     913             :     const Word16 maxN,   /* i  : Codebook dimension                                       */
     914             :     Word16 Idx[]         /* o  : Indices                                                  */
     915             : )
     916             : {
     917             :     Word16 j;
     918             :     const Word16 *cbp;
     919             :     Word16 p2i;
     920             :     Word16 resid_buf[2 * LSFMBEST_MAX * M_MAX], *resid[2];
     921             :     Word16 *pTmp, *p1;
     922             :     Word16 *indices[2], m, s, c, c2, p_max, i;
     923             :     Word32 Tmp32[M_MAX];
     924             :     Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
     925             :     Word64 *dist_64[2], en64, tmp64;
     926             :     Word64 dist_buf_64[2 * LSFMBEST_MAX];
     927             :     Word16 ( *func_ptr64 )( Word64 * );
     928             :     Word16 N34;
     929             :     Word16 n, maxn, start;
     930             : 
     931             :     /*----------------------------------------------------------------*
     932             :      * Allocate memory for previous (parent) and current nodes.
     933             :      *   Parent node is indexed [0], current node is indexed [1].
     934             :      *----------------------------------------------------------------*/
     935       34850 :     indices[0] = idx_buf;
     936       34850 :     indices[1] = idx_buf + maxC * stages; /*move16();*/
     937             :     /*vr_iset(0, idx_buf, 2*stages*maxC);*/
     938       34850 :     set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
     939             : 
     940       34850 :     resid[0] = resid_buf;
     941       34850 :     resid[1] = resid_buf + maxC * N; /*move16();*/
     942             : 
     943       34850 :     dist_64[0] = dist_buf_64;
     944       34850 :     dist_64[1] = dist_buf_64 + maxC; /*move16();*/
     945             : 
     946             :     /*vr_iset(0, parents, maxC);*/
     947       34850 :     set16_fx( parents, 0, maxC );
     948             : 
     949             : 
     950       34850 :     func_ptr64 = msvq_enc_find_p_max_6_fx64;
     951       34850 :     move16();
     952       34850 :     if ( EQ_16( maxC, 8 ) )
     953             :     {
     954       34850 :         func_ptr64 = msvq_enc_find_p_max_8_fx64;
     955       34850 :         move16();
     956             :     }
     957             : 
     958             :     /*----------------------------------------------------------------*
     959             :      * LSF weights are normalized, so it is always better to multiply it first
     960             :      * Set up inital distance vector
     961             :      *----------------------------------------------------------------*/
     962             :     /* Q0/16 * Qw_norm/16 << 1 >> 16 => Qwnorm-15/16 * Q0/16 << 1 => Qwnorm-14/32 * 6.5536 */
     963             :     Word64 ss2_64;
     964       34850 :     ss2_64 = W_mult_32_16( L_mult0( u[0], w[0] ), u[0] );
     965             :     // Q8 * Q2.56 * 2.56 * Q1
     966      557600 :     FOR( j = 1; j < N; j++ )
     967             :     {
     968      522750 :         ss2_64 = W_mac_32_16( ss2_64, L_mult0( u[j], w[j] ), u[j] );
     969             :     }
     970             : 
     971             :     /* Set up inital error (residual) vectors */
     972       34850 :     pTmp = resid[1]; /*move16();*/
     973      313650 :     FOR( c = 0; c < maxC; c++ )
     974             :     {
     975      278800 :         Copy( u, pTmp + c * N, N );
     976      278800 :         dist_64[1][c] = ss2_64;
     977      278800 :         move64();
     978             :     }
     979             : 
     980             :     /* Loop over all stages */
     981       34850 :     m = 1;
     982       34850 :     move16();
     983      104550 :     FOR( s = 0; s < stages; s++ )
     984             :     {
     985             :         /* codebook pointer is set to point to first stage */
     986       69700 :         cbp = cb[s]; /*3Q12*1.28*/
     987       69700 :         move16();
     988             : 
     989             :         /* Set up pointers to parent and current nodes */
     990       69700 :         swap( indices[0], indices[1], Word16 * );
     991       69700 :         move16();
     992       69700 :         move16();
     993       69700 :         move16();
     994       69700 :         move16();
     995       69700 :         swap( resid[0], resid[1], Word16 * );
     996       69700 :         move16();
     997       69700 :         move16();
     998       69700 :         move16();
     999       69700 :         swap( dist_64[0], dist_64[1], Word64 * );
    1000       69700 :         move64();
    1001       69700 :         move64();
    1002       69700 :         move64();
    1003             : 
    1004             :         /* p_max points to maximum distortion node (worst of best) */
    1005       69700 :         p_max = 0;
    1006       69700 :         move16();
    1007             : 
    1008       69700 :         n = N;
    1009       69700 :         move16();
    1010       69700 :         maxn = maxN;
    1011       69700 :         move16();
    1012       69700 :         if ( dims )
    1013             :         {
    1014       69700 :             n = dims[s];
    1015       69700 :             move16();
    1016             :         }
    1017       69700 :         if ( dims )
    1018             :         {
    1019       69700 :             maxn = n;
    1020       69700 :             move16();
    1021             :         }
    1022             : 
    1023       69700 :         assert( ( maxn % 4 ) == 0 );
    1024       69700 :         N34 = mult( maxn, 24576 /*0.75f Q15*/ );
    1025             : 
    1026       69700 :         start = 0;
    1027       69700 :         move16();
    1028       69700 :         if ( offs )
    1029             :         {
    1030       69700 :             start = offs[s];
    1031       69700 :             move16();
    1032             :         }
    1033             : 
    1034       69700 :         set32_fx( Tmp32, 0, start );
    1035       69700 :         set32_fx( Tmp32 + start + n, 0, sub( N, add( start, n ) ) );
    1036             : 
    1037             :         /* Set distortions to a large value */
    1038      627300 :         FOR( j = 0; j < maxC; j++ )
    1039             :         {
    1040      557600 :             dist_64[1][j] = LLONG_MAX;
    1041      557600 :             move64();
    1042             :         }
    1043             : 
    1044     1254600 :         FOR( j = 0; j < levels[s]; j++ )
    1045             :         {
    1046             :             /* Compute weighted codebook element and its energy */
    1047     1184900 :             en64 = depack_mul_values_fx64( Tmp32 + start, w + start, cbp, n ); // Q8
    1048             :             // en64: Q8 * Q2.56 * Q2.56 * q1
    1049             :             // Tmp: 2.56 * Q8
    1050             : 
    1051     1184900 :             cbp += N34; /* pointer is incremented */
    1052             : 
    1053             :             /* Iterate over all parent nodes */
    1054     6273000 :             FOR( c = 0; c < m; c++ )
    1055             :             {
    1056     5088100 :                 pTmp = &resid[0][c * N]; // this resid buffer is initial lsf values
    1057             :                 /*tmp = (*pTmp++) * Tmp[0];*/
    1058     5088100 :                 Word64 t164 = 0;
    1059     5088100 :                 move64();
    1060     5088100 :                 t164 = W_mult_32_16( Tmp32[0], pTmp[0] ); // 2.56 * Q8 * Q2.56 * Q1
    1061             :                 // Tmp32: Q8 * Q2.56
    1062    81409600 :                 FOR( i = 1; i < N; i++ )
    1063             :                 {
    1064    76321500 :                     t164 = W_mac_32_16( t164, Tmp32[i], pTmp[i] ); // 2.56 * Q8 * Q2.56 * Q1
    1065             :                 }
    1066             : 
    1067     5088100 :                 tmp64 = W_add( dist_64[0][c], W_sub( en64, W_shl( t164, 1 ) ) );
    1068     5088100 :                 t164 = W_sub( tmp64, dist_64[1][p_max] );
    1069     5088100 :                 IF( t164 <= 0 )
    1070             :                 {
    1071             :                     /* Replace worst */
    1072     1480737 :                     dist_64[1][p_max] = tmp64;
    1073     1480737 :                     move64();
    1074     1480737 :                     indices[1][p_max * stages + s] = j;
    1075     1480737 :                     move16();
    1076     1480737 :                     parents[p_max] = c;
    1077     1480737 :                     move16();
    1078             : 
    1079     1480737 :                     p_max = ( *func_ptr64 )( dist_64[1] );
    1080             : 
    1081             :                 } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
    1082             :             }     /* FOR (c=0; c<m; c++) */
    1083             :         }         /* FOR (j=0; j<levels[s]; j++) */
    1084             : 
    1085             :         /*------------------------------------------------------------*
    1086             :          * Compute error vectors for each node
    1087             :          *------------------------------------------------------------*/
    1088       69700 :         pTmp = resid[1];
    1089      627300 :         FOR( c = 0; c < maxC; c++ )
    1090             :         {
    1091             :             /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
    1092      557600 :             p1 = resid[0] + parents[c] * N;
    1093      557600 :             p2i = indices[1][c * stages + s];
    1094      557600 :             move16();
    1095             : 
    1096      557600 :             Copy( p1, pTmp, start );
    1097      557600 :             depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n );
    1098      557600 :             Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) );
    1099             : 
    1100      557600 :             pTmp += N;
    1101             : 
    1102             :             /* Get indices that were used for parent node */
    1103             :             /*mvs2s(indices[0]+parents[c]*stages, indices[1]+c*stages, s);*/
    1104      557600 :             Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s );
    1105             :         } /* for (c=0; c<maxC; c++) */
    1106       69700 :         m = maxC;
    1107       69700 :         move16();
    1108             :     } /* for (m=1, s=0; s<stages; s++) */
    1109             : 
    1110             :     /* Find the optimum candidate */
    1111       34850 :     c2 = findIndexOfMinWord64( dist_64[1], maxC );
    1112             :     /*mvi2i (indices[1]+c2*stages, Idx, stages);*/
    1113       34850 :     Copy( indices[1] + c2 * stages, Idx, stages );
    1114             : 
    1115             : 
    1116       34850 :     return;
    1117             : }
    1118             : /*--------------------------------------------------------------------------*
    1119             :  * msvq_enc_ivas_fx()
    1120             :  *
    1121             :  * MSVQ encoder
    1122             :  *--------------------------------------------------------------------------*/
    1123             : 
    1124       93939 : void msvq_enc_ivas_fx(
    1125             :     const Word16 *const *cb,    /* i  : Codebook (indexed cb[*stages][levels][p])                 Q_cb  */
    1126             :     const Word16 Q_cb,          /* i  : Codebook Q                                                      */
    1127             :     const Word16 dims[],        /* i  : Dimension of each codebook stage (NULL: full dim.)              */
    1128             :     const Word16 offs[],        /* i  : Starting dimension of each codebook stage (NULL: 0)             */
    1129             :     const Word32 u_fx[],        /* i  : Vector to be encoded (prediction and mean removed)  (exp : u_e) */
    1130             :     const Word16 u_e,           /* i  : Exponent for Vector to be encoded                               */
    1131             :     const Word16 *levels,       /* i  : Number of levels in each stage                                  */
    1132             :     const Word16 maxC,          /* i  : Tree search size (number of candidates kept from from one stage to the next == M-best) */
    1133             :     const Word16 stages,        /* i  : Number of stages                                                */
    1134             :     const Word16 w[],           /* i  : Weights                                                     Q8  */
    1135             :     const Word16 N,             /* i  : Vector dimension                                                */
    1136             :     const Word16 maxN,          /* i  : Codebook dimension                                              */
    1137             :     const Word16 applyDCT_flag, /* i  : applyDCT flag                                                   */
    1138             :     Word32 *invTrfMatrix_fx,    /* i/o: synthesis matrix                                            Q31 */
    1139             :     Word16 Idx[]                /* o  : Indices                                                         */
    1140             : )
    1141             : {
    1142             :     Word16 j;
    1143             :     const Word16 *cbp, *cb_stage;
    1144             :     Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2];
    1145             :     Word32 *pTmp, *p1, *p2; // pTmp_e
    1146             :     Word16 pTmp_e;
    1147             :     Word16 *indices[2], m, s, c, c2, p_max, i;
    1148             :     Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
    1149             :     Word32 dist_buf_fx[2 * LSFMBEST_MAX], *dist_fx[2], tmp, en, ss2, Tmp[M_MAX];
    1150             :     Word16 dist_buf_e[2 * LSFMBEST_MAX], *dist_e[2];
    1151             :     Word16 tmp_e, tmp_n, en_e;
    1152             :     Word16 resid_e;
    1153             :     Word16 n, maxn, start;
    1154             :     Word64 W_acc; /*64 bit accumulator*/
    1155             : 
    1156       93939 :     Word32 *st1_syn_vec_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC;
    1157       93939 :     Word32 *st1_mse_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] );
    1158             :     Word16 indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2];
    1159             : 
    1160             :     /*----------------------------------------------------------------*
    1161             :      * Allocate memory for previous (parent) and current nodes.
    1162             :      *   Parent node is indexed [0], current node is indexed [1].
    1163             :      *----------------------------------------------------------------*/
    1164       93939 :     indices[0] = idx_buf;
    1165       93939 :     indices[1] = idx_buf + maxC * stages; /*move16();*/
    1166             :     /*vr_iset(0, idx_buf, 2*stages*maxC);*/
    1167       93939 :     set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
    1168             : 
    1169       93939 :     resid_fx[0] = resid_buf_fx;
    1170       93939 :     resid_fx[1] = resid_buf_fx + maxC * N; /*move16();*/
    1171             : 
    1172       93939 :     dist_fx[0] = dist_buf_fx;
    1173       93939 :     dist_e[0] = dist_buf_e;
    1174       93939 :     dist_fx[1] = dist_buf_fx + maxC;
    1175       93939 :     dist_e[1] = dist_buf_e + maxC;
    1176             : 
    1177             :     /*vr_iset(0, parents, maxC);*/
    1178       93939 :     set16_fx( parents, 0, maxC );
    1179             : 
    1180             :     /*----------------------------------------------------------------*
    1181             :      * LSF weights are normalized, so it is always better to multiply it first
    1182             :      * Set up inital distance vector
    1183             :      *----------------------------------------------------------------*/
    1184       93939 :     W_acc = W_mult_32_32( Mpy_32_16_1( u_fx[0], shl( w[0], 2 ) ), u_fx[0] ); // 2*Qu - 6 + 1
    1185     1522785 :     FOR( j = 1; j < N; j++ )
    1186             :     {
    1187     1428846 :         W_acc = W_mac_32_32( W_acc, Mpy_32_16_1( u_fx[j], shl( w[j], 2 ) ), u_fx[j] ); // 2*Qu - 6 + 1
    1188             :     }
    1189             : 
    1190       93939 :     tmp_n = W_norm( W_acc );
    1191       93939 :     ss2 = W_extract_h( W_shl( W_acc, tmp_n ) );
    1192       93939 :     tmp_e = sub( add( shl( u_e, 1 ), 5 ), tmp_n );
    1193             : 
    1194             :     /* Set up inital error (residual) vectors */
    1195       93939 :     pTmp = resid_fx[1]; /*move16();*/
    1196       93939 :     resid_e = u_e;
    1197       93939 :     move16();
    1198       93939 :     IF( applyDCT_flag != 0 )
    1199             :     {
    1200        2742 :         resid_e = s_max( u_e, 12 );
    1201             :     }
    1202      389466 :     FOR( c = 0; c < maxC; c++ )
    1203             :     {
    1204      295527 :         Copy32( u_fx, pTmp + c * N, N );
    1205      295527 :         test();
    1206      295527 :         IF( applyDCT_flag != 0 && LT_16( u_e, 12 ) )
    1207             :         {
    1208       21448 :             scale_sig32( pTmp + c * N, N, sub( u_e, resid_e ) );
    1209             :         }
    1210      295527 :         dist_fx[1][c] = ss2;
    1211      295527 :         move32();
    1212      295527 :         dist_e[1][c] = tmp_e;
    1213      295527 :         move16();
    1214             :     }
    1215             : 
    1216             :     /* Loop over all stages */
    1217       93939 :     m = 1;
    1218       93939 :     move16();
    1219      397525 :     FOR( s = 0; s < stages; s++ )
    1220             :     {
    1221             :         /* codebook pointer is set to point to first stage */
    1222      303586 :         cbp = cb[s]; /*Q_cb*/
    1223      303586 :         cb_stage = cbp;
    1224             : 
    1225             :         /* Set up pointers to parent and current nodes */
    1226      303586 :         swap( indices[0], indices[1], Word16 * );
    1227      303586 :         move16();
    1228      303586 :         move16();
    1229      303586 :         move16();
    1230      303586 :         swap( resid_fx[0], resid_fx[1], Word32 * );
    1231      303586 :         move32();
    1232      303586 :         move32();
    1233      303586 :         move32();
    1234      303586 :         swap( dist_fx[0], dist_fx[1], Word32 * );
    1235      303586 :         swap( dist_e[0], dist_e[1], Word16 * );
    1236      303586 :         move32();
    1237      303586 :         move32();
    1238      303586 :         move32();
    1239      303586 :         move16();
    1240      303586 :         move16();
    1241      303586 :         move16();
    1242             : 
    1243             :         /* p_max points to maximum distortion node (worst of best) */
    1244      303586 :         p_max = 0;
    1245      303586 :         move16();
    1246             : 
    1247      303586 :         n = N;
    1248      303586 :         move16();
    1249      303586 :         maxn = maxN;
    1250      303586 :         move16();
    1251      303586 :         if ( dims )
    1252             :         {
    1253           0 :             n = dims[s];
    1254           0 :             move16();
    1255             :         }
    1256      303586 :         if ( dims )
    1257             :         {
    1258           0 :             maxn = n;
    1259           0 :             move16();
    1260             :         }
    1261             : 
    1262      303586 :         assert( ( maxn % 4 ) == 0 );
    1263             : 
    1264      303586 :         start = 0;
    1265      303586 :         move16();
    1266      303586 :         if ( offs )
    1267             :         {
    1268           0 :             start = offs[s];
    1269           0 :             move16();
    1270             :         }
    1271             : 
    1272      303586 :         set32_fx( Tmp, 0, start );
    1273      303586 :         set32_fx( Tmp + start + n, 0, sub( N, add( start, n ) ) );
    1274             : 
    1275             :         /* Set distortions to a large value */
    1276     1292444 :         FOR( j = 0; j < maxC; j++ )
    1277             :         {
    1278      988858 :             dist_fx[1][j] = MAX_32;
    1279      988858 :             move32();
    1280      988858 :             dist_e[1][j] = MAX_16 / 2;
    1281      988858 :             move16();
    1282             :         }
    1283             : 
    1284      303586 :         test();
    1285      303586 :         IF( !s && applyDCT_flag != 0 ) /* means: m==1 */
    1286             :         {
    1287             :             /* stage 1 candidates search in truncated dct24  domain without any weights  */
    1288        2742 :             assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */
    1289        2742 :             assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM );
    1290        2742 :             p_max = msvq_stage1_dct_search_fx( u_fx, u_e, FDCNG_VQ_MAX_LEN, maxC, DCT_T2_24_XX, FDCNG_VQ_DCT_MAXTRUNC, (Word32 *) invTrfMatrix_fx, cdk1r_tr_midQ_truncQ_fx, fdcng_dct_scaleF_fx, FDCNG_VQ_DCT_NSEGM,
    1291             :                                                cdk1_ivas_cols_per_segment, cdk1_ivas_trunc_dct_cols_per_segment, cdk1_ivas_entries_per_segment, cdk1_ivas_cum_entries_per_segment, cdk_37bits_ivas_stage1_W8Qx_dct_sections,
    1292             :                                                stage1_dct_col_syn_shift, cdk1_ivas_segm_neighbour_fwd, cdk1_ivas_segm_neighbour_rev, FDCNG_VQ_DCT_NPOST, st1_mse_ptr_fx, indices_st1_local, st1_syn_vec_ptr_fx, dist_fx[1], &dist_e[1][0] );
    1293             : 
    1294             :             /*    move established stage#1  indices  to the global MSVQ list structure */
    1295        2742 :             set16_fx( dist_e[1], dist_e[1][0], maxC );
    1296       24678 :             FOR( c = 0; c < maxC; c++ )
    1297             :             {
    1298       21936 :                 indices[1][c * stages] = indices_st1_local[c];
    1299       21936 :                 move16();
    1300             :             }
    1301             :         }
    1302             :         ELSE
    1303             :         {
    1304    17081612 :             FOR( j = 0; j < levels[s]; j++ )
    1305             :             {
    1306             :                 /* Compute weighted codebook element and its energy */
    1307    16780768 :                 en = 0;
    1308    16780768 :                 move32();
    1309    16780768 :                 en_e = 0;
    1310    16780768 :                 move16();
    1311    16780768 :                 W_acc = 0;
    1312    16780768 :                 move64();
    1313   291233952 :                 FOR( c2 = 0; c2 < n; c2++ )
    1314             :                 {
    1315   274453184 :                     Tmp[start + c2] = L_mult0( shl( w[start + c2], 2 ), cbp[c2] );
    1316   274453184 :                     move32();
    1317   274453184 :                     W_acc = W_mac_32_16( W_acc, Tmp[start + c2], cbp[c2] );
    1318             :                 }
    1319             : 
    1320    16780768 :                 tmp_n = W_norm( W_acc );
    1321             : 
    1322    16780768 :                 en = W_extract_h( W_shl( W_acc, tmp_n ) );
    1323    16780768 :                 en_e = sub( sub( 52, shl( Q_cb, 1 ) ), tmp_n );
    1324             : 
    1325    16780768 :                 cbp += maxn; /* pointer is incremented */
    1326             : 
    1327             :                 /* Iterate over all parent nodes */
    1328    54993344 :                 FOR( c = 0; c < m; c++ )
    1329             :                 {
    1330    38212576 :                     pTmp = &resid_fx[0][c * N];
    1331    38212576 :                     pTmp_e = resid_e;
    1332    38212576 :                     move16();
    1333             :                     /*tmp = (*pTmp++) * Tmp[0];*/
    1334    38212576 :                     W_acc = W_mult_32_32( pTmp[0], Tmp[0] );
    1335             : 
    1336   659088384 :                     FOR( i = 1; i < N; i++ )
    1337             :                     {
    1338   620875808 :                         W_acc = W_mac_32_32( W_acc, pTmp[i], Tmp[i] );
    1339             :                     }
    1340    38212576 :                     tmp_n = W_norm( W_acc );
    1341    38212576 :                     tmp = W_extract_h( W_shl( W_acc, tmp_n ) );
    1342    38212576 :                     tmp_e = sub( add( pTmp_e, sub( Q31 - Q10, Q_cb ) ), tmp_n );
    1343             : 
    1344             : 
    1345    38212576 :                     tmp_n = s_max( tmp_e, en_e );
    1346    38212576 :                     tmp_n = s_max( dist_e[0][c], tmp_n );
    1347             : 
    1348    38212576 :                     IF( NE_16( dist_e[0][c], MAX_16 / 2 ) )
    1349             :                     {
    1350    38212576 :                         tmp_n = add( tmp_n, 2 );
    1351    38212576 :                         tmp = L_sub( L_shl( en, sub( en_e, tmp_n ) ), L_shl( tmp, add( sub( tmp_e, tmp_n ), 1 ) ) );
    1352    38212576 :                         tmp = L_add( tmp, L_shl( dist_fx[0][c], sub( dist_e[0][c], tmp_n ) ) );
    1353             :                     }
    1354             :                     ELSE
    1355             :                     {
    1356           0 :                         tmp = MAX_32 - 1;
    1357           0 :                         move32();
    1358           0 :                         tmp_n = MAX_16 / 2;
    1359           0 :                         move32();
    1360             :                     }
    1361             : 
    1362    38212576 :                     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp, tmp_n, dist_fx[1][p_max], dist_e[1][p_max] ), -1 ) )
    1363             :                     {
    1364             :                         /* Replace worst */
    1365     4551800 :                         dist_fx[1][p_max] = tmp;
    1366     4551800 :                         move32();
    1367     4551800 :                         dist_e[1][p_max] = tmp_n;
    1368     4551800 :                         move16();
    1369     4551800 :                         indices[1][p_max * stages + s] = j;
    1370     4551800 :                         move16();
    1371     4551800 :                         parents[p_max] = c;
    1372     4551800 :                         move16();
    1373             : 
    1374     4551800 :                         p_max = 0;
    1375     4551800 :                         move16();
    1376     4551800 :                         tmp_e = p_max;
    1377     4551800 :                         move16();
    1378             : 
    1379     4551800 :                         tmp_n = dist_e[1][0];
    1380     4551800 :                         move16();
    1381    16522940 :                         FOR( c2 = 1; c2 < maxC; c2++ )
    1382             :                         {
    1383    11971140 :                             if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx[1][c2], dist_e[1][c2], dist_fx[1][p_max], dist_e[1][p_max] ), 1 ) )
    1384             :                             {
    1385     4535470 :                                 p_max = c2;
    1386     4535470 :                                 move16();
    1387             :                             }
    1388    11971140 :                             test();
    1389    11971140 :                             if ( GT_16( dist_e[1][c2], tmp_n ) && NE_16( dist_e[1][c2], MAX_16 / 2 ) )
    1390             :                             {
    1391      206778 :                                 tmp_n = dist_e[1][c2];
    1392      206778 :                                 move16();
    1393             :                             }
    1394             :                         }
    1395    21074740 :                         FOR( c2 = 0; c2 < maxC; c2++ )
    1396             :                         {
    1397    16522940 :                             IF( NE_16( dist_e[1][c2], MAX_16 / 2 ) )
    1398             :                             {
    1399    15298458 :                                 dist_fx[1][c2] = L_shl( dist_fx[1][c2], sub( dist_e[1][c2], tmp_n ) );
    1400    15298458 :                                 move32();
    1401    15298458 :                                 dist_e[1][c2] = tmp_n;
    1402    15298458 :                                 move16();
    1403             :                             }
    1404             :                         }
    1405             :                     } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
    1406             :                 }     /* FOR (c=0; c<m; c++) */
    1407             :             }         /* FOR (j=0; j<levels[s]; j++) */
    1408             :         }
    1409             : 
    1410             : 
    1411             :         /*------------------------------------------------------------*
    1412             :          * Compute error vectors for each node
    1413             :          *------------------------------------------------------------*/
    1414      303586 :         pTmp = resid_fx[1];
    1415     1292444 :         FOR( c = 0; c < maxC; c++ )
    1416             :         {
    1417             : 
    1418             :             /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
    1419      988858 :             p1 = resid_fx[0] + parents[c] * N;
    1420      988858 :             p2 = NULL;
    1421      988858 :             IF( cb_stage != NULL )
    1422             :             {
    1423             :                 // p2 = cb_stage + ( indices[1][c * stages + s] ) * maxn; /* regular ptr init */
    1424      966922 :                 Copy_Scale_sig_16_32_DEPREC( cb_stage + ( indices[1][c * stages + s] ) * maxn, Tmp, N, 0 );
    1425      966922 :                 scale_sig32( Tmp, N, sub( sub( Q31, Q_cb ), resid_e ) );
    1426      966922 :                 p2 = Tmp;
    1427             :             }
    1428      988858 :             test();
    1429      988858 :             IF( s == 0 && applyDCT_flag != 0 )
    1430             :             {
    1431       21936 :                 p2 = (Word32 *) &( st1_syn_vec_ptr_fx[c * FDCNG_VQ_MAX_LEN] ); /*ptr init of stage 1 */
    1432             :             }
    1433             : 
    1434      988858 :             Copy32( p1, pTmp, start );
    1435    17713786 :             FOR( j = 0; j < n; j++ )
    1436             :             {
    1437    16724928 :                 pTmp[start + j] = L_sub( p1[start + j], p2[j] );
    1438    16724928 :                 move32();
    1439             :             }
    1440      988858 :             Copy32( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) );
    1441             : 
    1442      988858 :             pTmp += N;
    1443             : 
    1444             :             /* Get indices that were used for parent node */
    1445             :             /*mvs2s(indices[0]+parents[c]*stages, indices[1]+c*stages, s);*/
    1446      988858 :             Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s );
    1447             :         } /* for (c=0; c<maxC; c++) */
    1448             :           /* recalc MSE for WB(0..20) coeffs ,
    1449             : essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1  MSE in the DCT24 domain truncated search,
    1450             : excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep WB MSEs update for the subsequent stages
    1451             : */
    1452             :           /* recalc MSE for WB(0..20) coeffs ,
    1453             :              essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1  MSE in the DCT24 domain truncated search,
    1454             :              excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep WB MSEs update for the subsequent stages
    1455             :                */
    1456      303586 :         test();
    1457      303586 :         IF( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB )
    1458             :         {
    1459         725 :             p_max = msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( st1_syn_vec_ptr_fx, resid_e, u_fx, u_e, maxC, dist_fx[1], &dist_e[1][0] );
    1460         725 :             set16_fx( dist_e[1], dist_e[1][0], maxC );
    1461             :         }
    1462      303586 :         m = maxC;
    1463      303586 :         move16();
    1464             :     } /* for (m=1, s=0; s<stages; s++) */
    1465             : 
    1466             :     /* Find the optimum candidate */
    1467       93939 :     c2 = minimum_32_fx( dist_fx[1], maxC, NULL );
    1468             :     /*mvi2i (indices[1]+c2*stages, Idx, stages);*/
    1469       93939 :     Copy( indices[1] + c2 * stages, Idx, stages );
    1470             : 
    1471             : 
    1472       93939 :     return;
    1473             : }
    1474             : 
    1475             : 
    1476             : /*--------------------------------------------------------------------------*
    1477             :  * lsf_msvq_ma_encprm_fx()
    1478             :  *
    1479             :  *
    1480             :  *--------------------------------------------------------------------------*/
    1481             : 
    1482         976 : Word16 lsf_msvq_ma_encprm_fx(
    1483             :     BSTR_ENC_HANDLE hBstr,
    1484             :     Word16 *param_lpc, // Q0
    1485             :     Word16 core,
    1486             :     Word16 acelp_mode,
    1487             :     Word16 acelp_midLpc,
    1488             :     Word16 *bits_param_lpc,
    1489             :     Word16 no_indices )
    1490             : {
    1491             :     Word16 i, nbits_lpc;
    1492             :     Word16 bits_midlpc;
    1493             : 
    1494         976 :     bits_midlpc = MIDLSF_NBITS;
    1495         976 :     move16();
    1496         976 :     nbits_lpc = 0;
    1497         976 :     move16();
    1498             : 
    1499        3989 :     FOR( i = 0; i < no_indices; i++ )
    1500             :     {
    1501             : 
    1502        3013 :         push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
    1503        3013 :         param_lpc++;
    1504        3013 :         nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
    1505             :     }
    1506         976 :     IF( NE_16( acelp_mode, VOICED ) )
    1507             :     {
    1508         722 :         test();
    1509         722 :         IF( ( core == ACELP_CORE ) && acelp_midLpc )
    1510             :         {
    1511             : 
    1512         342 :             push_next_indice( hBstr, *param_lpc, bits_midlpc );
    1513         342 :             nbits_lpc = add( nbits_lpc, bits_midlpc );
    1514             :         }
    1515             :     }
    1516             : 
    1517         976 :     return nbits_lpc;
    1518             : }
    1519             : 
    1520             : 
    1521      112117 : Word16 lsf_msvq_ma_encprm_ivas_fx(
    1522             :     BSTR_ENC_HANDLE hBstr,
    1523             :     const Word16 *param_lpc, // Q0
    1524             :     const Word16 core,
    1525             :     const Word16 acelp_mode,
    1526             :     const Word16 acelp_midLpc,
    1527             :     const Word16 *bits_param_lpc,
    1528             :     const Word16 no_indices )
    1529             : {
    1530             :     Word16 i, nbits_lpc;
    1531             :     Word16 bits_midlpc;
    1532             : 
    1533      112117 :     bits_midlpc = MIDLSF_NBITS;
    1534      112117 :     move16();
    1535      112117 :     nbits_lpc = 0;
    1536      112117 :     move16();
    1537             : 
    1538      461037 :     FOR( i = 0; i < no_indices; i++ )
    1539             :     {
    1540             : 
    1541      348920 :         push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
    1542      348920 :         param_lpc++;
    1543      348920 :         nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
    1544             :     }
    1545      112117 :     IF( NE_16( acelp_mode, VOICED ) )
    1546             :     {
    1547       88359 :         test();
    1548       88359 :         IF( ( core == ACELP_CORE ) && acelp_midLpc )
    1549             :         {
    1550             : 
    1551           0 :             push_next_indice( hBstr, *param_lpc, bits_midlpc );
    1552           0 :             nbits_lpc = add( nbits_lpc, bits_midlpc );
    1553             :         }
    1554             :     }
    1555             : 
    1556      112117 :     return nbits_lpc;
    1557             : }
    1558             : 
    1559             : 
    1560             : /*--------------------------------------------------------------------------*
    1561             :  * midlsf_enc_fx()
    1562             :  *
    1563             :  *
    1564             :  *--------------------------------------------------------------------------*/
    1565             : 
    1566         708 : void midlsf_enc_fx(
    1567             :     const Word16 qlsf0[],          /* i: quantized lsf coefficients (3Q12)      */
    1568             :     const Word16 qlsf1[],          /* i: quantized lsf coefficients (3Q12)      */
    1569             :     const Word16 lsf[],            /* i: lsf coefficients           (3Q12)      */
    1570             :     Word16 *idx,                   /* o: codebook index                                 */
    1571             :     const Word16 lpcorder,         /* i: order of the lpc                                       */
    1572             :     const Word32 *Bin_Ener_128_fx, // Q_ener
    1573             :     const Word16 Q_ener,
    1574             :     const Word8 narrowBand,
    1575             :     const Word32 sr_core,
    1576             :     const Word16 coder_type )
    1577             : {
    1578             :     Word32 err, err_min, L_tmp;
    1579             :     Word16 k, k1, j, tmp, size, qlsf[M], wghts[M];
    1580             :     const Word16 *ratio;
    1581             : #ifndef ISSUE_1867_replace_overflow_libenc
    1582             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1583             :     Flag Overflow = 0;
    1584             : #endif
    1585             : #endif
    1586             : 
    1587         708 :     IF( EQ_16( coder_type, UNVOICED ) )
    1588             :     {
    1589          27 :         ratio = tbl_mid_unv_wb_5b_fx;
    1590             :     }
    1591             :     ELSE
    1592             :     {
    1593         681 :         ratio = tbl_mid_gen_wb_5b_fx;
    1594             :     }
    1595         708 :     size = 32;
    1596         708 :     move16();
    1597             : 
    1598             :     /* Weights */
    1599         708 :     Unified_weighting_fx(
    1600             :         Bin_Ener_128_fx, /* i  : FFT Bin energy 128 bins in two sets    Q_ener */
    1601             :         Q_ener,
    1602             :         lsf,                              /* i  : LSF vector                             x2.56 */
    1603             :         wghts,                            /* o  : LP weighting filter (numerator)         Q8 */
    1604             :         narrowBand,                       /* i  : flag for Narrowband                     */
    1605         708 :         sub( coder_type, UNVOICED ) == 0, /* i  : flag for Unvoiced frame                 */
    1606             :         sr_core,                          /* i  : sampling rate of core-coder             */
    1607             :         lpcorder                          /* i  : LP order                                */
    1608             :     );
    1609         708 :     err_min = MAXINT32;
    1610         708 :     move16();
    1611         708 :     *idx = 0;
    1612         708 :     move16();
    1613         708 :     k1 = 0;
    1614         708 :     move16();
    1615       23364 :     FOR( k = 0; k < size; k++ )
    1616             :     {
    1617       22656 :         err = L_deposit_l( 0 );
    1618             : 
    1619      385152 :         FOR( j = 0; j < M; j++ )
    1620             :         {
    1621             :             /*      qlsf[j] = (1.0f - ratio[k*M+j]) * qlsf0[j] + ratio[k*M+j] * qlsf1[j]; */
    1622      362496 :             L_tmp = L_mult( sub( 0x2000, ratio[k1 + j] ), qlsf0[j] );
    1623      362496 :             L_tmp = L_mac( L_tmp, ratio[k1 + j], qlsf1[j] );
    1624      362496 :             qlsf[j] = round_fx( L_shl( L_tmp, 2 ) );
    1625      362496 :             test();
    1626      362496 :             test();
    1627      362496 :             IF( j > 0 && LT_16( j, M ) && LT_16( qlsf[j], add( qlsf[j - 1], LSF_GAP_MID_FX ) ) )
    1628             :             {
    1629        1949 :                 qlsf[j] = add( qlsf[j - 1], LSF_GAP_MID_FX );
    1630             :             }
    1631             : 
    1632      362496 :             tmp = sub( lsf[j], qlsf[j] );
    1633             :             /*        err +=  wghts[j] * ftemp * ftemp; */
    1634             :             /* tmp is usually very small, we can have some extra precision with very rare saturation */
    1635      362496 :             tmp = shl_sat( tmp, 4 );
    1636             : #ifdef ISSUE_1867_replace_overflow_libenc
    1637      362496 :             tmp = mult_r_sat( tmp, tmp );
    1638             : #else
    1639             :             tmp = mult_ro( tmp, tmp, &Overflow );
    1640             : #endif
    1641      362496 :             err = L_mac( err, tmp, wghts[j] );
    1642             :         }
    1643             : #ifdef ISSUE_1867_replace_overflow_libenc
    1644       22656 :         err = L_shl_sat( err, 2 );
    1645             : #else
    1646             :         err = L_shl_o( err, 2, &Overflow );
    1647             : #endif
    1648             : 
    1649             :         /*        err = L_shl(err,Wscale); */
    1650       22656 :         err = Mult_32_16( err, LSF_1_OVER_256SQ );
    1651             :         /*        err = Mult_32_16(err,Wmult); */
    1652             : 
    1653       22656 :         IF( LT_32( err, err_min ) )
    1654             :         {
    1655        2854 :             err_min = L_add( err, 0 );
    1656        2854 :             *idx = k;
    1657        2854 :             move16();
    1658             :         }
    1659       22656 :         k1 += M;
    1660       22656 :         move16();
    1661             :     }
    1662             : 
    1663         708 :     return;
    1664             : }
    1665             : 
    1666             : 
    1667             : /*--------------------------------------------------------------------------*
    1668             :  * Q_lsf_tcxlpc_fx()
    1669             :  *
    1670             :  * Returns: number of indices
    1671             :  *--------------------------------------------------------------------------*/
    1672             : 
    1673           0 : Word16 Q_lsf_tcxlpc_fx(
    1674             :     /* const */ Word16 lsf[], /* i  : original lsf      14Q1 * 1.28 */
    1675             :     Word16 lsf_q[],           /* o  : quantized lsf     (14Q1*1.28)*/
    1676             :     Word16 lsp_q_ind[],       /* o  : quantized lsp (w/o MA prediction) */
    1677             :     Word16 indices[],         /* o  : VQ indices        */
    1678             :     const Word16 lpcorder,    /* i  : LPC order         */
    1679             :     const Word16 narrowband,  /* i  : narrowband flag   */
    1680             :     const Word16 cdk,         /* i  : codebook selector */
    1681             :     const Word16 mem_MA[],    /* i  : MA memory         */
    1682             :     const Word16 coder_type,
    1683             :     const Word32 *Bin_Ener, // Q_ener
    1684             :     const Word16 Q_ener )
    1685             : {
    1686             :     Word16 weights[M + 1];
    1687             :     Word16 pred[M16k];
    1688             :     Word16 i;
    1689             :     Word16 NumIndices;
    1690             :     Word16 lsf_q_ind[M16k];
    1691             :     const Word16 *means;
    1692             :     Word16 lsf_rem[M];
    1693             :     Word16 lsf_rem_q_ind[M];
    1694             : 
    1695           0 :     Unified_weighting_fx( Bin_Ener, Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M );
    1696             : 
    1697           0 :     move16();
    1698           0 :     NumIndices = 0;
    1699             : 
    1700             :     /* Put disabled flag */
    1701           0 :     indices[NumIndices] = 0;
    1702           0 :     move16();
    1703           0 :     NumIndices = add( NumIndices, 1 );
    1704             : 
    1705             :     /* Inter-frame prediction */
    1706             : 
    1707           0 :     means = lsf_means[narrowband]; /* 14Q1 * 1.28 */
    1708             : 
    1709           0 :     FOR( i = 0; i < lpcorder; ++i )
    1710             :     {
    1711           0 :         pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28  + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/
    1712             :     }
    1713             : 
    1714             :     /* Subtract prediction */
    1715             : 
    1716           0 :     FOR( i = 0; i < lpcorder; ++i )
    1717             :     {
    1718           0 :         lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */
    1719             :     }
    1720             : 
    1721             : 
    1722           0 :     msvq_enc_fx(
    1723           0 :         lsf_codebook[narrowband][cdk],
    1724             :         lsf_dims,
    1725             :         lsf_offs,
    1726             :         lsf,
    1727             :         lsf_numlevels,
    1728             :         kMaxC,
    1729             :         TCXLPC_NUMSTAGES,
    1730             :         weights,
    1731             :         lpcorder,
    1732             :         lpcorder,
    1733           0 :         indices + NumIndices );
    1734           0 :     msvq_dec(
    1735           0 :         lsf_codebook[narrowband][cdk],
    1736             :         lsf_dims,
    1737             :         lsf_offs,
    1738             :         TCXLPC_NUMSTAGES,
    1739             :         lpcorder,
    1740             :         lpcorder,
    1741           0 :         indices + NumIndices,
    1742             :         lsf_q );
    1743           0 :     NumIndices = add( NumIndices, TCXLPC_NUMSTAGES );
    1744             : 
    1745           0 :     FOR( i = 0; i < lpcorder; ++i )
    1746             :     {
    1747           0 :         lsf_q_ind[i] = lsf_q[i]; /*(14Q1*1.28)*/
    1748           0 :         move16();
    1749             :     }
    1750             : 
    1751             :     /* Update flag */
    1752           0 :     indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk );
    1753           0 :     move16();
    1754             : 
    1755             :     /* Get residual vector */
    1756           0 :     FOR( i = 0; i < lpcorder; ++i )
    1757             :     {
    1758           0 :         lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) );
    1759             :     }
    1760             : 
    1761             :     /* Quantize using extra stage(s) */
    1762           0 :     msvq_enc_fx(
    1763           0 :         lsf_ind_codebook[narrowband][cdk],
    1764             :         lsf_ind_dims,
    1765             :         lsf_ind_offs,
    1766             :         lsf_rem,
    1767             :         lsf_ind_numlevels,
    1768             :         kMaxC,
    1769             :         TCXLPC_IND_NUMSTAGES,
    1770             :         weights,
    1771             :         lpcorder,
    1772             :         lpcorder,
    1773           0 :         indices + NumIndices );
    1774             :     /* Only add contribution if flag is enabled */
    1775           0 :     IF( indices[0] )
    1776             :     {
    1777             :         /* Decode */
    1778           0 :         msvq_dec(
    1779           0 :             lsf_ind_codebook[narrowband][cdk],
    1780             :             lsf_ind_dims,
    1781             :             lsf_ind_offs,
    1782             :             TCXLPC_IND_NUMSTAGES,
    1783             :             lpcorder,
    1784             :             lpcorder,
    1785           0 :             indices + NumIndices,
    1786             :             lsf_rem_q_ind );
    1787           0 :         NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES );
    1788             : 
    1789             :         /* Add to MA-removed vector */
    1790           0 :         FOR( i = 0; i < lpcorder; ++i )
    1791             :         {
    1792           0 :             lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] );
    1793             :         }
    1794             :     }
    1795             : 
    1796             :     /* Add inter-frame prediction */
    1797           0 :     FOR( i = 0; i < lpcorder; ++i )
    1798             :     {
    1799           0 :         lsf_q[i] = add( lsf_q[i], pred[i] );
    1800           0 :         lsf[i] = add( lsf[i], pred[i] );
    1801             :     }
    1802             : 
    1803           0 :     reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
    1804             : 
    1805           0 :     FOR( i = 0; i < lpcorder; ++i )
    1806             :     {
    1807           0 :         lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] );
    1808             :     }
    1809           0 :     reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
    1810             : 
    1811           0 :     IF( lsp_q_ind )
    1812             :     {
    1813           0 :         E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder );
    1814             :     }
    1815             : 
    1816           0 :     return NumIndices;
    1817             : }
    1818             : 
    1819             : 
    1820       17425 : Word16 Q_lsf_tcxlpc_ivas_fx(
    1821             :     /* const */ Word16 lsf[], /* i  : original lsf      */
    1822             :     Word16 lsf_q[],           /* o  : quantized lsf     */
    1823             :     Word16 lsp_q_ind[],       /* o  : quantized lsp (w/o MA prediction) */
    1824             :     Word16 indices[],         /* o  : VQ indices        */
    1825             :     const Word16 lpcorder,    /* i  : LPC order         */
    1826             :     const Word16 narrowband,  /* i  : narrowband flag   */
    1827             :     const Word16 cdk,         /* i  : codebook selector */
    1828             :     const Word16 mem_MA[],    /* i  : MA memory         */
    1829             :     const Word16 coder_type,
    1830             :     const Word32 *Bin_Ener,
    1831             :     const Word16 Q_ener )
    1832             : {
    1833             :     Word16 weights[M + 1];
    1834             :     Word16 pred[M16k];
    1835             :     Word16 i;
    1836             :     Word16 NumIndices;
    1837             :     Word16 lsf_q_ind[M16k];
    1838             :     const Word16 *means;
    1839             :     Word16 lsf_rem[M];
    1840             :     Word16 lsf_rem_q_ind[M];
    1841             : 
    1842       17425 :     Unified_weighting_fx( &Bin_Ener[L_FFT / 2], Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M );
    1843             : 
    1844       17425 :     move16();
    1845       17425 :     NumIndices = 0;
    1846             : 
    1847             :     /* Put disabled flag */
    1848       17425 :     indices[NumIndices] = 0;
    1849       17425 :     move16();
    1850       17425 :     NumIndices = add( NumIndices, 1 );
    1851             : 
    1852             :     /* Inter-frame prediction */
    1853             : 
    1854       17425 :     means = lsf_means[narrowband]; /* 14Q1 * 1.28 */
    1855             : 
    1856      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1857             :     {
    1858      278800 :         pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28  + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/
    1859      278800 :         move16();
    1860             :     }
    1861             : 
    1862             :     /* Subtract prediction */
    1863             : 
    1864      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1865             :     {
    1866      278800 :         lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */
    1867      278800 :         move16();
    1868             :     }
    1869             : 
    1870       17425 :     msvq_enc_lsf_fx64(
    1871       17425 :         lsf_codebook[narrowband][cdk],
    1872             :         lsf_dims,
    1873             :         lsf_offs,
    1874             :         lsf,
    1875             :         lsf_numlevels,
    1876             :         kMaxC,
    1877             :         TCXLPC_NUMSTAGES,
    1878             :         weights,
    1879             :         lpcorder,
    1880             :         lpcorder,
    1881       17425 :         indices + NumIndices );
    1882       17425 :     msvq_dec(
    1883       17425 :         lsf_codebook[narrowband][cdk],
    1884             :         lsf_dims,
    1885             :         lsf_offs,
    1886             :         TCXLPC_NUMSTAGES,
    1887             :         lpcorder,
    1888             :         lpcorder,
    1889       17425 :         indices + NumIndices,
    1890             :         lsf_q );
    1891       17425 :     NumIndices = add( NumIndices, TCXLPC_NUMSTAGES );
    1892             : 
    1893      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1894             :     {
    1895      278800 :         lsf_q_ind[i] = lsf_q[i];
    1896      278800 :         move16();
    1897             :     }
    1898             : 
    1899             :     /* Update flag */
    1900       17425 :     indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk );
    1901       17425 :     move16();
    1902             : 
    1903             :     /* Get residual vector */
    1904      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1905             :     {
    1906      278800 :         lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) );
    1907      278800 :         move16();
    1908             :     }
    1909             : 
    1910             :     /* Quantize using extra stage(s) */
    1911       17425 :     msvq_enc_lsf_fx64(
    1912       17425 :         lsf_ind_codebook[narrowband][cdk],
    1913             :         lsf_ind_dims,
    1914             :         lsf_ind_offs,
    1915             :         lsf_rem,
    1916             :         lsf_ind_numlevels,
    1917             :         kMaxC,
    1918             :         TCXLPC_IND_NUMSTAGES,
    1919             :         weights,
    1920             :         lpcorder,
    1921             :         lpcorder,
    1922       17425 :         indices + NumIndices );
    1923             :     /* Only add contribution if flag is enabled */
    1924       17425 :     IF( indices[0] )
    1925             :     {
    1926             :         /* Decode */
    1927        4883 :         msvq_dec(
    1928        4883 :             lsf_ind_codebook[narrowband][cdk],
    1929             :             lsf_ind_dims,
    1930             :             lsf_ind_offs,
    1931             :             TCXLPC_IND_NUMSTAGES,
    1932             :             lpcorder,
    1933             :             lpcorder,
    1934        4883 :             indices + NumIndices,
    1935             :             lsf_rem_q_ind );
    1936        4883 :         NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES );
    1937             : 
    1938             :         /* Add to MA-removed vector */
    1939       83011 :         FOR( i = 0; i < lpcorder; ++i )
    1940             :         {
    1941       78128 :             lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] );
    1942       78128 :             move16();
    1943             :         }
    1944             :     }
    1945             : 
    1946             :     /* Add inter-frame prediction */
    1947      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1948             :     {
    1949      278800 :         lsf_q[i] = add( lsf_q[i], pred[i] );
    1950      278800 :         lsf[i] = add( lsf[i], pred[i] );
    1951      278800 :         move16();
    1952      278800 :         move16();
    1953             :     }
    1954             : 
    1955       17425 :     reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
    1956             : 
    1957      296225 :     FOR( i = 0; i < lpcorder; ++i )
    1958             :     {
    1959      278800 :         lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] );
    1960      278800 :         move16();
    1961             :     }
    1962       17425 :     reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
    1963             : 
    1964       17425 :     IF( lsp_q_ind )
    1965             :     {
    1966       17425 :         E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder );
    1967             :     }
    1968             : 
    1969       17425 :     return NumIndices;
    1970             : }
    1971             : 
    1972             : 
    1973             : /*--------------------------------------------------------------------------*
    1974             :  * enc_lsf_tcxlpc_fx()
    1975             :  *
    1976             :  * Returns: number of bits written
    1977             :  *--------------------------------------------------------------------------*/
    1978             : 
    1979           0 : Word16 enc_lsf_tcxlpc_fx(
    1980             :     Word16 **indices,     /* i  : Ptr to VQ indices  */
    1981             :     BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle    */
    1982             : )
    1983             : {
    1984             :     Word16 i, NumBits;
    1985             : 
    1986             :     Word16 flag;
    1987             : 
    1988             :     /* Read flag */
    1989           0 :     flag = ( *indices )[0];
    1990           0 :     move16();
    1991           0 :     ++*indices;
    1992             : 
    1993           0 :     NumBits = TCXLPC_NUMBITS;
    1994           0 :     move16();
    1995           0 :     FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i )
    1996             :     {
    1997           0 :         push_next_indice( hBstr, **indices, lsf_numbits[i] );
    1998           0 :         ++*indices;
    1999             :     }
    2000             : 
    2001           0 :     IF( flag )
    2002             :     {
    2003           0 :         NumBits = add( NumBits, TCXLPC_IND_NUMBITS );
    2004           0 :         FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i )
    2005             :         {
    2006           0 :             push_next_indice( hBstr, **indices, lsf_ind_numbits[i] );
    2007           0 :             ++*indices;
    2008             :         }
    2009             :     }
    2010           0 :     return NumBits;
    2011             : }
    2012             : 
    2013             : 
    2014       17425 : Word16 enc_lsf_tcxlpc_ivas_fx(
    2015             :     const Word16 **indices, /* i  : Ptr to VQ indices  */
    2016             :     BSTR_ENC_HANDLE hBstr   /* i/o: encoder bitstream handle    */
    2017             : )
    2018             : {
    2019             :     Word16 i, NumBits;
    2020             : 
    2021             :     Word16 flag;
    2022             : 
    2023             :     /* Read flag */
    2024       17425 :     flag = ( *indices )[0];
    2025       17425 :     move16();
    2026       17425 :     ++*indices;
    2027             : 
    2028       17425 :     NumBits = TCXLPC_NUMBITS;
    2029       17425 :     move16();
    2030       69700 :     FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i )
    2031             :     {
    2032       52275 :         push_next_indice( hBstr, **indices, lsf_numbits[i] );
    2033       52275 :         ++*indices;
    2034             :     }
    2035             : 
    2036       17425 :     IF( flag )
    2037             :     {
    2038        4883 :         NumBits = add( NumBits, TCXLPC_IND_NUMBITS );
    2039        9766 :         FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i )
    2040             :         {
    2041        4883 :             push_next_indice( hBstr, **indices, lsf_ind_numbits[i] );
    2042        4883 :             ++*indices;
    2043             :         }
    2044             :     }
    2045       17425 :     return NumBits;
    2046             : }
    2047             : 
    2048             : 
    2049             : /*--------------------------------------------------------------------------*
    2050             :  * lsf_bctcvq_encprm_fx()
    2051             :  *
    2052             :  *
    2053             :  *--------------------------------------------------------------------------*/
    2054             : 
    2055         270 : Word16 lsf_bctcvq_encprm_fx(
    2056             :     BSTR_ENC_HANDLE hBstr,
    2057             :     Word16 *param_lpc, // Q0
    2058             :     Word16 *bits_param_lpc,
    2059             :     Word16 no_indices )
    2060             : {
    2061             :     Word16 i, nbits_lpc;
    2062             : 
    2063         270 :     nbits_lpc = 0;
    2064             : 
    2065        2970 :     FOR( i = 0; i < no_indices; i++ )
    2066             :     {
    2067        2700 :         push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
    2068        2700 :         param_lpc++;
    2069        2700 :         nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
    2070             :     }
    2071             : 
    2072         270 :     return nbits_lpc;
    2073             : }
    2074             : 
    2075             : 
    2076           0 : Word16 lsf_bctcvq_encprm_ivas_fx(
    2077             :     BSTR_ENC_HANDLE hBstr,
    2078             :     const Word16 *param_lpc, // Q0
    2079             :     const Word16 *bits_param_lpc,
    2080             :     const Word16 no_indices )
    2081             : {
    2082             :     Word16 i, nbits_lpc;
    2083             : 
    2084           0 :     nbits_lpc = 0;
    2085           0 :     move16();
    2086             : 
    2087           0 :     FOR( i = 0; i < no_indices; i++ )
    2088             :     {
    2089           0 :         push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
    2090           0 :         param_lpc++;
    2091           0 :         nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
    2092             :     }
    2093             : 
    2094           0 :     return nbits_lpc;
    2095             : }

Generated by: LCOV version 1.14