LCOV - code coverage report
Current view: top level - lib_com - tools_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 1543 1896 81.4 %
Date: 2025-11-14 01:07:58 Functions: 154 171 90.1 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdlib.h>
      38             : #include <assert.h>
      39             : #include <stdint.h>
      40             : #include "options.h"
      41             : #include "stl.h"
      42             : #include <math.h>
      43             : #include "cnst.h"
      44             : #include "prot_fx.h"
      45             : #include "basop_util.h"
      46             : #include "basop32.h"
      47             : #include "wmc_auto.h"
      48             : #include "prot_fx_enc.h"
      49             : #include "ivas_prot_fx.h"
      50             : 
      51             : 
      52             : #define INV_BANDS10 3277                                   /* 1/10 in Q15 */
      53             : #define INV_BANDS9  3641                                   /* 1/9  in Q15 */
      54             : #define INV_BANDS3  10923                                  /* 1/9  in Q15 */
      55             : static const Word16 b_hp400_fx[3] = { 3660, -7320, 3660 }; /* Q12 (/4) */
      56             : static const Word16 a_hp400_fx[3] = { 16384, 29280, -14160 };
      57             : static const Word16 a_hp400_ivas_fx[3] = { 4096, 7320, -3540 }; /*Q12*/
      58             : 
      59             : /*------------------------------------------------------------------*
      60             :  * own_random()
      61             :  *
      62             :  * Random generator
      63             :  *------------------------------------------------------------------*/
      64             : 
      65             : /*! r: output random value */
      66   338481421 : Word16 own_random(
      67             :     Word16 *seed /* i/o: random seed         */
      68             : )
      69             : {
      70   338481421 :     *seed = (Word16) ( *seed * 31821L + 13849L );
      71             : 
      72   338481421 :     return ( *seed );
      73             : }
      74             : 
      75             : 
      76             : /*---------------------------------------------------------------------
      77             :  * sum_s()
      78             :  * sum_l()
      79             :  *
      80             :  *---------------------------------------------------------------------*/
      81             : 
      82             : /*! r: sum of all vector elements */
      83      509350 : Word16 sum_s(
      84             :     const Word16 *vec, /* i  : input vector                          */
      85             :     const Word16 lvec  /* i  : length of input vector                */
      86             : )
      87             : {
      88             :     Word16 i;
      89             :     Word16 tmp;
      90             : 
      91      509350 :     tmp = 0;
      92    10929385 :     for ( i = 0; i < lvec; i++ )
      93             :     {
      94    10420035 :         tmp += vec[i];
      95             :     }
      96             : 
      97      509350 :     return tmp;
      98             : }
      99             : 
     100             : /*! r: sum of all vector elements */
     101        7837 : Word32 sum_l_fx(
     102             :     const Word32 *vec, /* i  : input vector                          */
     103             :     const Word16 lvec  /* i  : length of input vector                */
     104             : )
     105             : {
     106             :     Word16 i;
     107             :     Word32 tmpL;
     108             : 
     109        7837 :     tmpL = 0;
     110        7837 :     move32();
     111       94044 :     FOR( i = 0; i < lvec; i++ )
     112             :     {
     113       86207 :         tmpL = L_add( tmpL, vec[i] );
     114             :     }
     115             : 
     116        7837 :     return tmpL;
     117             : }
     118             : 
     119             : /*----------------------------------------------------------------------
     120             :  * sum2_f()
     121             :  *
     122             :  *---------------------------------------------------------------------*/
     123             : 
     124             : /*! r: sum of all squared vector elements */
     125        2044 : Word32 sum2_f_16_fx(
     126             :     const Word16 *vec, /* i  : input vector                          */
     127             :     const Word16 lvec  /* i  : length of input vector                */
     128             : )
     129             : {
     130             :     Word16 i;
     131             :     Word32 tmp;
     132             : 
     133        2044 :     tmp = 0;
     134        2044 :     move32();
     135       34748 :     FOR( i = 0; i < lvec; i++ )
     136             :     {
     137       32704 :         tmp = L_add( tmp, L_mult0( vec[i], vec[i] ) );
     138             :     }
     139             : 
     140        2044 :     return tmp;
     141             : }
     142         200 : Word32 sum2_f_16_gb_fx(
     143             :     const Word16 *vec, /* i  : input vector                          */
     144             :     const Word16 lvec, /* i  : length of input vector                */
     145             :     Word16 gb )
     146             : {
     147             :     Word16 i;
     148             :     Word32 tmp;
     149             : 
     150         200 :     tmp = 0;
     151      146120 :     FOR( i = 0; i < lvec; i++ )
     152             :     {
     153      145920 :         tmp = L_add( tmp, L_shr( L_mult0( vec[i], vec[i] ), gb ) );
     154             :     }
     155             : 
     156         200 :     return tmp;
     157             : }
     158             : 
     159             : 
     160       38920 : Word32 sum2_16_exp_fx(
     161             :     const Word16 *vec, /* i  : input vector           Q(15 - exp) */
     162             :     const Word16 lvec, /* i  : length of input vector             */
     163             :     Word16 *exp,       /* i/o: exponent of vector                 */
     164             :     Word16 gb          /* i  : guard bits                         */
     165             : )
     166             : {
     167             :     Word16 i, s;
     168             :     Word32 L_tmp, var_a;
     169             : 
     170       38920 :     L_tmp = 0;
     171       38920 :     move32();
     172       38920 :     var_a = 0;
     173       38920 :     move32();
     174     7361796 :     FOR( i = 0; i < lvec; i++ )
     175             :     {
     176     7322876 :         var_a = L_mult0( vec[i], vec[i] );          /* 2 * Q(15 - exp) */
     177     7322876 :         L_tmp = L_add( L_tmp, L_shr( var_a, gb ) ); /* 2 * Q(15 - exp) - gb */
     178             :     }
     179             : 
     180       38920 :     s = norm_l( L_tmp );
     181       38920 :     L_tmp = L_shl( L_tmp, s ); /* 2 * Q(15 - exp) - gb + s */
     182             : 
     183       38920 :     *exp = add( sub( add( shl( *exp, 1 ), gb ), s ), 1 );
     184       38920 :     move16();
     185             : 
     186       38920 :     return L_tmp;
     187             : }
     188             : 
     189             : 
     190     9342141 : Word32 sum2_32_exp_fx(
     191             :     const Word32 *vec, /* i  : input vector, Qx                     */
     192             :     const Word16 lvec, /* i  : length of input vector               */
     193             :     Word16 *exp,       /* i/o: exponent of vector                   */
     194             :     Word16 gb          /* i  : guard bits                           */
     195             : )
     196             : {
     197             :     Word16 i, s, norm;
     198             :     Word64 W_tmp;
     199             : 
     200     9342141 :     W_tmp = 0;
     201     9342141 :     Word64 var_a = 0;
     202     9342141 :     move64();
     203     9342141 :     move64();
     204             : 
     205     9342141 :     norm = L_norm_arr( vec, lvec );
     206             : 
     207     9342141 :     gb = sub( gb, norm );
     208             : 
     209  1897809761 :     FOR( i = 0; i < lvec; i++ )
     210             :     {
     211  1888467620 :         var_a = W_mult0_32_32( vec[i], vec[i] );    // 2x
     212  1888467620 :         W_tmp = W_add( W_tmp, W_shr( var_a, gb ) ); // 2x-gb
     213             :     }
     214             : 
     215     9342141 :     s = W_norm( W_tmp );
     216     9342141 :     W_tmp = W_shl( W_tmp, s ); // 2x - gb + s
     217             : 
     218             :     //*exp = 31 - (2*(31 - *exp) - gb + s) + 32;
     219     9342141 :     *exp = add( sub( add( shl( *exp, 1 ), gb ), s ), 1 );
     220     9342141 :     move16();
     221             : 
     222     9342141 :     return W_extract_h( W_tmp );
     223             : }
     224             : 
     225             : 
     226             : /* o  : Q(2x - 31 - gb)                      */
     227     9377866 : Word32 sum2_f_32_fx(
     228             :     const Word32 *vec, /* i  : input vector, Qx                     */
     229             :     const Word16 lvec, /* i  : length of input vector               */
     230             :     Word16 gb          /* i  : guard bits                           */
     231             : )
     232             : {
     233             :     Word16 i;
     234             :     Word32 tmp;
     235             : 
     236     9377866 :     tmp = 0;
     237     9377866 :     Word32 var_a = 0;
     238     9377866 :     move32();
     239     9377866 :     move32();
     240    92923669 :     FOR( i = 0; i < lvec; i++ )
     241             :     {
     242    83545803 :         var_a = Mpy_32_32( vec[i], vec[i] );    // 2x-31
     243    83545803 :         tmp = L_add( tmp, L_shr( var_a, gb ) ); // 2x-31-gb
     244             :     }
     245             : 
     246     9377866 :     return tmp;
     247             : }
     248             : 
     249     2776761 : Word32 sum2_32_fx(
     250             :     const Word32 *vec, /* i  : input vector                          */
     251             :     const Word16 lvec, /* i  : length of input vector                */
     252             :     Word16 *e )
     253             : {
     254             :     Word16 i;
     255             :     Word32 tmp;
     256             : 
     257     2776761 :     tmp = 0;
     258     2776761 :     Word32 var_a = 0;
     259     2776761 :     Word16 exp = 0, exp_tmp;
     260     2776761 :     move32();
     261     2776761 :     move32();
     262     2776761 :     move16();
     263   198721181 :     FOR( i = 0; i < lvec; i++ )
     264             :     {
     265   195944420 :         exp_tmp = norm_l( vec[i] );
     266   195944420 :         var_a = L_shl( vec[i], exp_tmp );
     267   195944420 :         var_a = Mpy_32_32( var_a, var_a );
     268   195944420 :         exp_tmp = shl( sub( *e, exp_tmp ), 1 );
     269   195944420 :         tmp = BASOP_Util_Add_Mant32Exp( tmp, exp, var_a, exp_tmp, &exp );
     270             :     }
     271     2776761 :     *e = exp;
     272     2776761 :     move16();
     273             : 
     274     2776761 :     return tmp;
     275             : }
     276             : 
     277             : 
     278             : /*-------------------------------------------------------------------*
     279             :  * set_c()
     280             :  * set_s()
     281             :  * set_l()
     282             :  * set_d()
     283             :  *
     284             :  * Set the vector elements to a value
     285             :  *-------------------------------------------------------------------*/
     286             : 
     287      937364 : void set_c(
     288             :     Word8 y[],     /* i/o: Vector to set                       */
     289             :     const Word8 a, /* i  : Value to set the vector to          */
     290             :     const Word32 N /* i  : Length of the vector                */
     291             : )
     292             : {
     293             :     Word16 i;
     294             : 
     295     5197590 :     for ( i = 0; i < N; i++ )
     296             :     {
     297     4260226 :         y[i] = a;
     298             :     }
     299             : 
     300      937364 :     return;
     301             : }
     302             : 
     303             : 
     304     2810624 : void set_s(
     305             :     Word16 y[],     /* i/o: Vector to set                       */
     306             :     const Word16 a, /* i  : Value to set the vector to          */
     307             :     const Word16 N  /* i  : Length of the vector                */
     308             : )
     309             : {
     310             :     Word16 i;
     311             : 
     312    31680025 :     for ( i = 0; i < N; i++ )
     313             :     {
     314    28869401 :         y[i] = a;
     315             :     }
     316             : 
     317     2810624 :     return;
     318             : }
     319             : 
     320             : 
     321       44544 : void set_l(
     322             :     Word32 y[],     /* i/o: Vector to set                       */
     323             :     const Word32 a, /* i  : Value to set the vector to          */
     324             :     const Word16 N  /* i  : Length of the vector                */
     325             : )
     326             : {
     327             :     Word16 i;
     328             : 
     329     2717184 :     for ( i = 0; i < N; i++ )
     330             :     {
     331     2672640 :         y[i] = a;
     332             :     }
     333             : 
     334       44544 :     return;
     335             : }
     336             : 
     337             : 
     338     1324124 : void mvs2s(
     339             :     const Word16 x[], /* i  : input vector  */
     340             :     Word16 y[],       /* o  : output vector */
     341             :     const Word16 n    /* i  : vector size   */
     342             : )
     343             : {
     344             :     Word16 i;
     345             : 
     346     1324124 :     if ( n <= 0 )
     347             :     {
     348             :         /* cannot transfer vectors with size 0 */
     349           0 :         return;
     350             :     }
     351             : 
     352     1324124 :     if ( y < x )
     353             :     {
     354           0 :         for ( i = 0; i < n; i++ )
     355             :         {
     356           0 :             y[i] = x[i];
     357             :         }
     358             :     }
     359             :     else
     360             :     {
     361     9268550 :         for ( i = n - 1; i >= 0; i-- )
     362             :         {
     363     7944426 :             y[i] = x[i];
     364             :         }
     365             :     }
     366             : 
     367     1324124 :     return;
     368             : }
     369             : 
     370     1871259 : void mvl2l(
     371             :     const Word32 x[], /* i  : input vector  */
     372             :     Word32 y[],       /* o  : output vector */
     373             :     const Word16 n    /* i  : vector size   */
     374             : )
     375             : {
     376             :     Word16 i;
     377             : 
     378     1871259 :     if ( n <= 0 )
     379             :     {
     380             :         /* no need to transfer vectors with size 0 */
     381           0 :         return;
     382             :     }
     383             : 
     384     1871259 :     if ( y < x )
     385             :     {
     386  2599235007 :         for ( i = 0; i < n; i++ )
     387             :         {
     388  2597364000 :             y[i] = x[i];
     389             :         }
     390             :     }
     391             :     else
     392             :     {
     393      242172 :         for ( i = n - 1; i >= 0; i-- )
     394             :         {
     395      241920 :             y[i] = x[i];
     396             :         }
     397             :     }
     398             : 
     399     1871259 :     return;
     400             : }
     401             : 
     402             : /*! r: index of the maximum value in the input vector */
     403      980562 : Word16 maximum_s(
     404             :     const Word16 *vec, /* i  : input vector                                   */
     405             :     const Word16 lvec, /* i  : length of input vector                         */
     406             :     Word16 *max        /* o  : maximum value in the input vector              */
     407             : )
     408             : {
     409             :     Word16 i, ind;
     410             :     Word16 tmp;
     411             : 
     412      980562 :     ind = 0;
     413      980562 :     move16();
     414      980562 :     tmp = vec[0];
     415      980562 :     move16();
     416             : 
     417    14187981 :     FOR( i = 1; i < lvec; i++ )
     418             :     {
     419    13207419 :         IF( GT_16( vec[i], tmp ) )
     420             :         {
     421      287646 :             ind = i;
     422      287646 :             move16();
     423      287646 :             tmp = vec[i];
     424      287646 :             move16();
     425             :         }
     426             :     }
     427             : 
     428      980562 :     if ( max != NULL )
     429             :     {
     430      973948 :         *max = tmp;
     431      973948 :         move16();
     432             :     }
     433             : 
     434      980562 :     return ind;
     435             : }
     436             : 
     437             : /*! r: index of the maximum value in the input vector */
     438      333350 : Word16 maximum_l(
     439             :     const Word32 *vec, /* i  : input vector                                   */
     440             :     const Word16 lvec, /* i  : length of input vector                         */
     441             :     Word32 *max_val    /* o  : maximum value in the input vector              */
     442             : )
     443             : {
     444             :     Word16 i, ind;
     445             :     Word32 tmp;
     446             : 
     447      333350 :     ind = 0;
     448      333350 :     tmp = vec[0];
     449      333350 :     move16();
     450      333350 :     move32();
     451    91043997 :     FOR( i = 1; i < lvec; i++ )
     452             :     {
     453    90710647 :         IF( GT_32( vec[i], tmp ) )
     454             :         {
     455     1691675 :             ind = i;
     456     1691675 :             tmp = vec[i];
     457     1691675 :             move16();
     458     1691675 :             move32();
     459             :         }
     460             :     }
     461             : 
     462      333350 :     if ( max_val != NULL )
     463             :     {
     464      333350 :         *max_val = tmp;
     465      333350 :         move32();
     466             :     }
     467             : 
     468      333350 :     return ind;
     469             : }
     470             : 
     471             : /*! r: index of the maximum value in the input vector */
     472     2201344 : Word16 maximumAbs_l(
     473             :     const Word32 *vec, /* i  : input vector                                   */
     474             :     const Word16 lvec, /* i  : length of input vector                         */
     475             :     Word32 *max_val    /* o  : maximum value in the input vector              */
     476             : )
     477             : {
     478             :     Word16 j, ind;
     479             :     Word32 tmp;
     480             : 
     481     2201344 :     ind = 0;
     482     2201344 :     move16();
     483     2201344 :     tmp = L_abs( vec[0] );
     484             : 
     485    80228025 :     FOR( j = 1; j < lvec; j++ )
     486             :     {
     487    78026681 :         IF( GT_32( L_abs( vec[j] ), tmp ) )
     488             :         {
     489     7331065 :             ind = j;
     490     7331065 :             move16();
     491     7331065 :             tmp = L_abs( vec[j] );
     492             :         }
     493             :     }
     494             : 
     495     2201344 :     IF( max_val != NULL )
     496             :     {
     497     2201344 :         *max_val = tmp;
     498     2201344 :         move32();
     499             :     }
     500             : 
     501     2201344 :     return ind;
     502             : }
     503             : 
     504             : /*-------------------------------------------------------------------*
     505             :  * minimum_s()
     506             :  *
     507             :  * Finds minimum 16-bit signed integer value in the array and returns it.
     508             :  *-------------------------------------------------------------------*/
     509             : 
     510             : /*! r: index of the minimum value in the input vector */
     511   143916246 : Word16 minimum_s(
     512             :     const Word16 *vec, /* i  : Input vector                      */
     513             :     const Word16 lvec, /* i  : Vector length                     */
     514             :     Word16 *min_val    /* o  : minimum value in the input vector */
     515             : )
     516             : {
     517             :     Word16 i, ind;
     518             : 
     519   143916246 :     ind = 0;
     520   143916246 :     move16();
     521             : 
     522   686089200 :     FOR( i = 1; i < lvec; i++ )
     523             :     {
     524   542172954 :         if ( LT_16( vec[i], vec[ind] ) )
     525             :         {
     526    53539971 :             ind = i;
     527    53539971 :             move16();
     528             :         }
     529             :     }
     530             : 
     531   143916246 :     if ( min_val != NULL )
     532             :     {
     533   143916246 :         *min_val = vec[ind];
     534   143916246 :         move16();
     535             :     }
     536             : 
     537   143916246 :     return ind;
     538             : }
     539             : 
     540             : /*-------------------------------------------------------------------*
     541             :  * minimum_l()
     542             :  *
     543             :  * Finds minimum 16-bit signed integer value in the array and returns it.
     544             :  *-------------------------------------------------------------------*/
     545             : 
     546             : /*! r: index of the minimum value in the input vector */
     547      235547 : Word16 minimum_l(
     548             :     const Word32 *vec, /* i  : Input vector                      */
     549             :     const Word16 lvec, /* i  : Vector length                     */
     550             :     Word32 *min_val    /* o  : minimum value in the input vector */
     551             : )
     552             : {
     553             :     Word16 i, ind;
     554             : 
     555      235547 :     ind = 0;
     556      235547 :     move16();
     557             : 
     558     3344938 :     FOR( i = 1; i < lvec; i++ )
     559             :     {
     560     3109391 :         if ( LT_32( vec[i], vec[ind] ) )
     561             :         {
     562      699404 :             ind = i;
     563      699404 :             move16();
     564             :         }
     565             :     }
     566             : 
     567      235547 :     if ( min_val != NULL )
     568             :     {
     569      235547 :         *min_val = vec[ind];
     570      235547 :         move32();
     571             :     }
     572             : 
     573      235547 :     return ind;
     574             : }
     575             : 
     576             : /*---------------------------------------------------------------------*
     577             :  * dotp()
     578             :  *
     579             :  * Dot product of vector x[] and vector y[]
     580             :  *---------------------------------------------------------------------*/
     581             : 
     582             : /*! r: dot product of x[] and y[] */
     583    14696353 : Word32 dotp_fx32(
     584             :     const Word32 x[], /* i  : vector x[]                Qx */
     585             :     const Word32 y[], /* i  : vector y[]                Qy */
     586             :     const Word16 n    /* i  : vector length                */
     587             : )
     588             : {
     589             :     Word16 i;
     590             :     Word32 suma;
     591             : 
     592    14696353 :     suma = Mpy_32_32( x[0], y[0] );
     593             : 
     594    38835827 :     FOR( i = 1; i < n; i++ )
     595             :     {
     596    24139474 :         suma = L_add( suma, Mpy_32_32( x[i], y[i] ) );
     597             :     }
     598             : 
     599    14696353 :     return suma;
     600             : }
     601             : 
     602             : /*To calculate dot product of two 32 bit arrays in case of overflow*/
     603     3767611 : Word32 dotp_fx32_o(
     604             :     const Word32 x[],     /* i  : vector x[]                    */
     605             :     const Word32 y[],     /* i  : vector y[]                    */
     606             :     const Word16 n,       /* i  : vector length                 */
     607             :     const Word16 log_len, /* i  : max factor added to result q after dot product (equal to log2(n))                 */
     608             :     Word16 *res_q         /*stores resultant Q*/
     609             : )
     610             : {
     611             :     Word16 i;
     612             :     Word64 suma; /*resultant q= q(x)+q(y)-9-x such that q<=31*/
     613             : 
     614     3767611 :     suma = W_shr( W_mult_32_32( x[0], y[0] ), log_len );
     615             : 
     616   193474242 :     FOR( i = 1; i < n; i++ )
     617             :     {
     618   189706631 :         suma = W_add( suma, W_shr( W_mult_32_32( x[i], y[i] ), log_len ) );
     619             :     }
     620     3767611 :     *res_q = add( sub( *res_q, log_len ), 1 );
     621     3767611 :     move16();
     622     3767611 :     test();
     623     3767611 :     test();
     624    48928068 :     FOR( ; ( suma > MAX_32 ) || ( suma < MIN_32 ) || ( *res_q > 31 ); )
     625             :     {
     626    45160457 :         suma = W_shr( suma, 1 );
     627    45160457 :         *res_q = sub( *res_q, 1 );
     628    45160457 :         move16();
     629             :     }
     630             : 
     631     3767611 :     return W_extract_l( suma );
     632             : }
     633             : 
     634             : 
     635     1521635 : Word32 dotp_fx32_fac(
     636             :     const Word32 x[],     /* i  : vector x[]                    */
     637             :     const Word32 y[],     /* i  : vector y[]                    */
     638             :     const Word16 n,       /* i  : vector length                 */
     639             :     const Word16 log_len, /* i  : max factor added to result q after dot product (equal to log2(n))                 */
     640             :     Word16 *res_q         /*stores resultant Q*/
     641             : )
     642             : {
     643             :     Word16 i;
     644             :     Word64 suma; /*resultant q= q(x)+q(y)-9-x such that q<=31*/
     645             : 
     646     1521635 :     suma = W_shr( W_mult_32_32( x[0], y[0] ), log_len );
     647             : 
     648  1311180480 :     FOR( i = 1; i < n; i++ )
     649             :     {
     650  1309658845 :         suma = W_add( suma, W_shr( W_mult_32_32( x[i], y[i] ), log_len ) );
     651             :     }
     652     1521635 :     *res_q = add( *res_q, add( sub( *res_q, log_len ), 1 ) );
     653     1521635 :     move16();
     654     1521635 :     test();
     655     1521635 :     test();
     656    31594798 :     FOR( ; ( suma > MAX_32 ) || ( suma < MIN_32 ) || ( *res_q > 31 ); )
     657             :     {
     658    30073163 :         suma = W_shr( suma, 1 );
     659    30073163 :         *res_q = sub( *res_q, 1 );
     660    30073163 :         move16();
     661             :     }
     662     1521635 :     return W_extract_l( suma );
     663             : }
     664             : 
     665             : 
     666             : /*-------------------------------------------------------------------*
     667             :  * v_add_w64()
     668             :  *
     669             :  * Subtraction of two vectors sample by sample
     670             :  *-------------------------------------------------------------------*/
     671             : 
     672           0 : void v_add_w64(
     673             :     const Word64 x1[], /* i  : Input vector 1                                   */
     674             :     const Word64 x2[], /* i  : Input vector 2                                   */
     675             :     Word64 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
     676             :     const Word16 N,    /* i  : Vector length                                    */
     677             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
     678             : )
     679             : {
     680             :     Word16 i;
     681             : 
     682           0 :     FOR( i = 0; i < N; i++ )
     683             :     {
     684           0 :         y[i] = W_add( W_shr( x1[i], hdrm ), W_shr( x2[i], hdrm ) );
     685           0 :         move64();
     686             :     }
     687             : 
     688           0 :     return;
     689             : }
     690             : 
     691             : 
     692             : /*-------------------------------------------------------------------*
     693             :  * v_sub_fx()
     694             :  *
     695             :  * Subtraction of two vectors sample by sample
     696             :  *-------------------------------------------------------------------*/
     697             : 
     698     7089325 : void v_sub_fx(
     699             :     const Word32 x1[], /* i  : Input vector 1                                   */
     700             :     const Word32 x2[], /* i  : Input vector 2                                   */
     701             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
     702             :     const Word16 N,    /* i  : Vector length                                    */
     703             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
     704             : )
     705             : {
     706             :     Word16 i;
     707             : 
     708    28357300 :     FOR( i = 0; i < N; i++ )
     709             :     {
     710    21267975 :         y[i] = L_sub( L_shr( x1[i], hdrm ), L_shr( x2[i], hdrm ) );
     711    21267975 :         move32();
     712             :     }
     713             : 
     714     7089325 :     return;
     715             : }
     716             : 
     717   576109274 : void v_sub_fx_no_hdrm(
     718             :     const Word32 x1[], /* i  : Input vector 1                                   */
     719             :     const Word32 x2[], /* i  : Input vector 2                                   */
     720             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
     721             :     const Word16 N     /* i  : Vector length                                    */
     722             : )
     723             : {
     724             :     Word16 i;
     725             : 
     726  2812560431 :     FOR( i = 0; i < N; i++ )
     727             :     {
     728  2236451157 :         y[i] = L_sub( x1[i], x2[i] );
     729  2236451157 :         move32();
     730             :     }
     731             : 
     732   576109274 :     return;
     733             : }
     734             : 
     735             : /*-------------------------------------------------------------------*
     736             :  * v_multc()
     737             :  *
     738             :  * Multiplication of vector by constant
     739             :  *-------------------------------------------------------------------*/
     740             : 
     741    67362230 : void v_multc_fx(
     742             :     const Word32 x[], /* i  : Input vector                                     */
     743             :     const Word32 c,   /* i  : Constant                                         */
     744             :     Word32 y[],       /* o  : Output vector that contains c*x                  */
     745             :     const Word16 N    /* i  : Vector length                                    */
     746             : )
     747             : {
     748             :     Word16 i;
     749             : 
     750  7165715755 :     FOR( i = 0; i < N; i++ )
     751             :     {
     752  7098353525 :         y[i] = Mpy_32_32( c, x[i] );
     753  7098353525 :         move32();
     754             :     }
     755             : 
     756    67362230 :     return;
     757             : }
     758             : 
     759     1989841 : void v_multc_fx_16(
     760             :     const Word32 x[], /* i  : Input vector                                     */
     761             :     const Word16 c,   /* i  : Constant                                         */
     762             :     Word32 y[],       /* o  : Output vector that contains c*x                  */
     763             :     const Word16 N    /* i  : Vector length                                    */
     764             : )
     765             : {
     766             :     Word16 i;
     767             : 
     768   260153679 :     FOR( i = 0; i < N; i++ )
     769             :     {
     770   258163838 :         y[i] = Mpy_32_16_1( x[i], c );
     771   258163838 :         move32();
     772             :     }
     773             : 
     774     1989841 :     return;
     775             : }
     776             : 
     777       16169 : void v_multc_fx_16_16(
     778             :     const Word16 x[], /* i  : Input vector                                     */
     779             :     const Word16 c,   /* i  : Constant                                         */
     780             :     Word16 y[],       /* o  : Output vector that contains c*x                  */
     781             :     const Word16 N    /* i  : Vector length                                    */
     782             : )
     783             : {
     784             :     Word16 i;
     785             : 
     786     7921737 :     FOR( i = 0; i < N; i++ )
     787             :     {
     788     7905568 :         y[i] = mult_r( x[i], c );
     789     7905568 :         move16();
     790             :     }
     791             : 
     792       16169 :     return;
     793             : }
     794             : 
     795             : 
     796        1492 : void sort(
     797             :     UWord16 *x, /* i/o: Vector to be sorted     */
     798             :     UWord16 len /* i/o: vector length           */
     799             : )
     800             : {
     801             :     Word16 i;
     802             :     UWord16 j, tempr;
     803             : 
     804        9278 :     FOR( i = len - 2; i >= 0; i-- )
     805             :     {
     806        7786 :         tempr = x[i];
     807        7786 :         move16();
     808       17391 :         FOR( j = i + 1; ( j < len ) && ( tempr > x[j] ); j++ )
     809             :         {
     810        9605 :             test();
     811        9605 :             x[j - 1] = x[j];
     812        9605 :             move16();
     813             :         }
     814        7786 :         x[j - 1] = tempr;
     815        7786 :         move16();
     816             :     }
     817             : 
     818        1492 :     return;
     819             : }
     820             : 
     821             : 
     822             : /*-------------------------------------------------------------------*
     823             :  * usdequant_fx()
     824             :  *
     825             :  * Uniform scalar de-quantizer routine
     826             :  *
     827             :  * Applies de-quantization based on scale and round operations.
     828             :  *-------------------------------------------------------------------*/
     829             : 
     830             : /* Qx*/
     831      398102 : Word16 usdequant_fx(
     832             :     const Word16 idx,  /* i: quantizer index Q0*/
     833             :     const Word16 qlow, /* i: lowest codebook entry (index 0) Qx*/
     834             :     const Word16 delta /* i: quantization step Qx-1*/
     835             : )
     836             : {
     837             :     Word16 g;
     838             :     Word32 L_tmp;
     839             : 
     840             :     /*g = idx * delta + qlow;*/
     841      398102 :     L_tmp = L_deposit_l( qlow );                /*Qx */
     842      398102 :     L_tmp = L_mac( L_tmp, idx, delta );         /*Qx */
     843      398102 :     g = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
     844      398102 :     return ( g );
     845             : }
     846             : 
     847             : /* Qx*/
     848      230958 : Word32 usdequant32_fx(
     849             :     const Word16 idx,  /* i: quantizer index Q0*/
     850             :     const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/
     851             :     const Word32 delta /* i: quantization step Qx-1*/
     852             : )
     853             : {
     854             :     Word32 g;
     855             :     Word64 L_tmp;
     856             : 
     857             :     /*g = idx * delta + qlow;*/
     858      230958 :     L_tmp = W_deposit32_l( qlow ); /*Qx */
     859      230958 :     L_tmp = W_mac_32_16( L_tmp, delta, idx );
     860      230958 :     IF( GE_64( L_tmp, MAX_32 ) )
     861             :     {
     862       42147 :         g = MAX_32;
     863       42147 :         move32();
     864             :     }
     865             :     ELSE
     866             :     {
     867      188811 :         g = W_extract_l( L_tmp ); /*Qx */
     868             :     }
     869      230958 :     return ( g );
     870             : }
     871             : 
     872             : 
     873             : /*-------------------------------------------------------------------*
     874             :  * usquant()
     875             :  *
     876             :  * Uniform scalar quantizer according to MMSE criterion
     877             :  * (nearest neighbour in Euclidean space)
     878             :  *
     879             :  * Applies quantization based on scale and round operations.
     880             :  * Index of the winning codeword and the winning codeword itself are returned.
     881             :  *-------------------------------------------------------------------*/
     882             : 
     883             : /* o: index of the winning codeword   */
     884     1547310 : Word16 usquant_fx(
     885             :     const Word16 x,     /* i: scalar value to quantize        Qx*/
     886             :     Word16 *xq,         /* o: quantized value                 Qx*/
     887             :     const Word16 qlow,  /* i: lowest codebook entry (index 0) Qx*/
     888             :     const Word16 delta, /* i: quantization step               Qx-1*/
     889             :     const Word16 cbsize /* i: codebook size                   */
     890             : )
     891             : {
     892             :     Word16 idx;
     893             :     Word16 tmp, exp;
     894             :     Word32 L_tmp;
     895             : 
     896             :     /*    idx = (short)( (x - qlow)/delta + 0.5f); */
     897     1547310 :     exp = norm_s( delta );
     898     1547310 :     tmp = div_s( shl( 1, sub( 14, exp ) ), delta );                                             /*Q(29-exp-(Qx-1))->Q(30-exp-Qx) */
     899     1547310 :     L_tmp = L_mult( sub_sat( x, qlow ), tmp );                                                  /*Q(31-exp) */
     900     1547310 :     idx = extract_l( L_shr_r( L_add( L_tmp, shl_sat( 1, sub( 30, exp ) ) ), sub( 31, exp ) ) ); /*Q0 */
     901             : 
     902     1547310 :     idx = s_min( idx, sub( cbsize, 1 ) );
     903     1547310 :     idx = s_max( idx, 0 );
     904             : 
     905             :     /*    *xq = idx*delta + qlow; */
     906     1547310 :     L_tmp = L_deposit_l( qlow );                  /*Qx */
     907     1547310 :     L_tmp = L_mac( L_tmp, idx, delta );           /*Qx */
     908     1547310 :     *xq = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
     909             : 
     910     1547310 :     return idx;
     911             : }
     912             : 
     913             : 
     914             : /*-------------------------------------------------------------------*
     915             :  * Dot_product:
     916             :  *
     917             :  * Compute scalar product of <x[],y[]> using accumulator.
     918             :  * Performs no normalization, as opposed to Dot_product12()
     919             :  *-------------------------------------------------------------------*/
     920             : /* o  : Sum  */
     921    62034832 : Word32 Dot_product(
     922             :     const Word16 x[], /* i  : 12bits: x vector */
     923             :     const Word16 y[], /* i  : 12bits: y vector */
     924             :     const Word16 lg   /* i  : vector length    */
     925             : )
     926             : {
     927             :     Word16 i;
     928             :     Word32 L_sum;
     929             :     Word64 L64_sum;
     930             : 
     931    62034832 :     L64_sum = 1;
     932    62034832 :     move64();
     933  3789002478 :     FOR( i = 0; i < lg; i++ )
     934             :     {
     935  3726967646 :         L64_sum = W_mac_16_16( L64_sum, x[i], y[i] );
     936             :     }
     937    62034832 :     L_sum = W_sat_l( L64_sum );
     938             : 
     939    62034832 :     return L_sum;
     940             : }
     941             : 
     942             : 
     943             : /*---------------------------------------------------------------------*
     944             :  * dotp_fx()
     945             :  *
     946             :  * Dot product of vector x[] and vector y[]
     947             :  *---------------------------------------------------------------------*/
     948             : 
     949             : /* o  : dot product of x[] and y[]    */
     950     1661396 : Word32 dotp_fx(
     951             :     const Word16 x[], /* i  : vector x[]                    */
     952             :     const Word16 y[], /* i  : vector y[]                    */
     953             :     const Word16 n,   /* i  : vector length                 */
     954             :     Word16 *exp       /* o  : exponent of result (0..+30)   */
     955             : )
     956             : {
     957             :     Word16 sft;
     958             :     Word32 L_sum;
     959             : 
     960     1661396 :     assert( *exp == 0 );
     961             : 
     962     1661396 :     L_sum = L_add( L_shr( Dot_product( x, y, n ), 1 ), 1 );
     963             : 
     964             :     /* Normalize acc in Q31 */
     965             : 
     966     1661396 :     sft = norm_l( L_sum );
     967     1661396 :     L_sum = L_shl( L_sum, sft );
     968             : 
     969     1661396 :     *exp = sub( 30, sft );
     970     1661396 :     move16(); /* exponent = 0..30 */
     971             : 
     972     1661396 :     return L_sum;
     973             : }
     974             : 
     975             : /* o  : sum of all squared vector elements    Q(2x+1)*/
     976      513129 : Word32 sum2_fx(
     977             :     const Word16 *vec, /* i  : input vector           Qx*/
     978             :     const Word16 lvec  /* i  : length of input vector   */
     979             : )
     980             : {
     981             :     Word16 i;
     982             :     Word32 L_tmp;
     983             : 
     984      513129 :     L_tmp = L_deposit_l( 0 );
     985    40405209 :     FOR( i = 0; i < lvec; i++ )
     986             :     {
     987    39892080 :         L_tmp = L_mac_sat( L_tmp, vec[i], vec[i] ); /*Q(2x+1) */
     988             :     }
     989             : 
     990      513129 :     return L_tmp;
     991             : }
     992             : 
     993             : 
     994             : /* o  : sum of all squared vector elements    Q(2*Qx)*/
     995      185151 : Word64 sum2_fx_no_sat(
     996             :     const Word16 *vec, /* i  : input vector                          Qx*/
     997             :     const Word16 lvec  /* i  : length of input vector                */
     998             : )
     999             : {
    1000             :     Word16 i;
    1001             :     Word64 sum;
    1002             : 
    1003      185151 :     sum = 0;
    1004      185151 :     move64();
    1005    79182911 :     FOR( i = 0; i < lvec; i++ )
    1006             :     {
    1007    78997760 :         sum = W_mac0_16_16( sum, vec[i], vec[i] ); // 2*Qx
    1008             :     }
    1009             : 
    1010      185151 :     return sum;
    1011             : }
    1012             : 
    1013      127566 : Word32 sum_32_fx(
    1014             :     const Word32 *vec, /* i  : input vector                          */
    1015             :     const Word16 lvec, /* i  : length of input vector                */
    1016             :     Word16 *e )
    1017             : {
    1018             :     Word16 i, shift;
    1019      127566 :     Word64 tmp = 0;
    1020      127566 :     move64();
    1021             :     Word32 ans;
    1022             : 
    1023      404350 :     FOR( i = 0; i < lvec; i++ )
    1024             :     {
    1025      276784 :         tmp = W_add( tmp, vec[i] ); // e
    1026             :     }
    1027      127566 :     shift = W_norm( tmp );
    1028      127566 :     tmp = W_shl( tmp, shift ); // shift + (31 - e)
    1029      127566 :     ans = W_extract_h( tmp );  // shift + (31 - e) - 32
    1030      127566 :     *e = add( sub( *e, shift ), 32 );
    1031      127566 :     move16();
    1032             : 
    1033      127566 :     return ans;
    1034             : }
    1035             : 
    1036             : /* o  : sum of all squared vector elements    Q(2x+1 -5)*/
    1037      108694 : Word32 sum2_fx_mod(
    1038             :     const Word16 *vec, /* i  : input vector                          Qx*/
    1039             :     const Word16 lvec  /* i  : length of input vector                */
    1040             : )
    1041             : {
    1042             :     Word16 i;
    1043             :     Word32 L_tmp;
    1044             : 
    1045      108694 :     L_tmp = L_deposit_l( 0 );
    1046    69672854 :     FOR( i = 0; i < lvec; i++ )
    1047             :     {
    1048    69564160 :         L_tmp = L_add_sat( L_tmp, L_shr( L_mult_sat( vec[i], vec[i] ), 9 ) );
    1049             :     }
    1050             : 
    1051      108694 :     return L_tmp;
    1052             : }
    1053             : 
    1054             : 
    1055             : /*-------------------------------------------------------------------*
    1056             :  * Copy:
    1057             :  *
    1058             :  * Copy vector x[] to y[]
    1059             :  *
    1060             :  *-------------------------------------------------------------------*/
    1061             : 
    1062   209430290 : void Copy(
    1063             :     const Word16 x[], /* i  : input vector  */
    1064             :     Word16 y[],       /* o  : output vector */
    1065             :     const Word16 L    /* i  : vector length */
    1066             : )
    1067             : {
    1068             :     Word16 i;
    1069             : 
    1070   209430290 :     IF( y < x )
    1071             :     {
    1072 20942958404 :         FOR( i = 0; i < L; i++ )
    1073             :         {
    1074 20835758163 :             y[i] = x[i];
    1075 20835758163 :             move16();
    1076             :         }
    1077             : 
    1078             :         /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
    1079   107200241 :         return;
    1080             :     }
    1081             : 
    1082 20481740492 :     FOR( i = L - 1; i >= 0; i-- )
    1083             :     {
    1084 20379510443 :         y[i] = x[i];
    1085 20379510443 :         move16();
    1086             :     }
    1087             : 
    1088   102230049 :     return;
    1089             : }
    1090             : 
    1091             : 
    1092             : /*-------------------------------------------------------------------*
    1093             :  * Copy64:
    1094             :  *
    1095             :  * Copy vector x[] to y[] (64 bits)
    1096             :  *-------------------------------------------------------------------*/
    1097             : 
    1098       12780 : void Copy64(
    1099             :     const Word64 x[], /* i  : input vector  */
    1100             :     Word64 y[],       /* o  : output vector */
    1101             :     const Word16 L    /* i  : vector length */
    1102             : )
    1103             : {
    1104             :     Word16 i;
    1105       12780 :     IF( y < x )
    1106             :     {
    1107           0 :         FOR( i = 0; i < L; i++ )
    1108             :         {
    1109           0 :             y[i] = x[i];
    1110           0 :             move64();
    1111             :         }
    1112             : 
    1113             :         /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
    1114           0 :         return;
    1115             :     }
    1116             : 
    1117       45864 :     FOR( i = L - 1; i >= 0; i-- )
    1118             :     {
    1119       33084 :         y[i] = x[i];
    1120       33084 :         move64();
    1121             :     }
    1122             : 
    1123       12780 :     return;
    1124             : }
    1125             : 
    1126    11453183 : void set64_fx(
    1127             :     Word64 y[],     /* i/o: Vector to set                       */
    1128             :     const Word64 a, /* i  : Value to set the vector to          */
    1129             :     const Word16 N  /* i  : Lenght of the vector                */
    1130             : )
    1131             : {
    1132             :     Word16 i;
    1133   511162770 :     FOR( i = 0; i < N; i++ )
    1134             :     {
    1135   499709587 :         y[i] = a;
    1136   499709587 :         move64();
    1137             :     }
    1138             : 
    1139    11453183 :     return;
    1140             : }
    1141             : 
    1142      235781 : void Copy_pword(
    1143             :     const PWord16 x[], /* i  : input vector  */
    1144             :     PWord16 y[],       /* o  : output vector */
    1145             :     const Word16 L     /* i  : vector length */
    1146             : )
    1147             : {
    1148             :     Word16 i;
    1149             : 
    1150      235781 :     IF( y < x )
    1151             :     {
    1152     4785702 :         FOR( i = 0; i < L; i++ )
    1153             :         {
    1154     4564504 :             y[i].v.im = x[i].v.im;
    1155     4564504 :             y[i].v.re = x[i].v.re;
    1156     4564504 :             move16();
    1157     4564504 :             move16();
    1158             :         }
    1159             : 
    1160             :         /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
    1161      221198 :         return;
    1162             :     }
    1163             : 
    1164      895133 :     FOR( i = L - 1; i >= 0; i-- )
    1165             :     {
    1166      880550 :         y[i].v.im = x[i].v.im;
    1167      880550 :         y[i].v.re = x[i].v.re;
    1168      880550 :         move16();
    1169      880550 :         move16();
    1170             :     }
    1171             : 
    1172       14583 :     return;
    1173             : }
    1174             : /*-------------------------------------------------------------------*
    1175             :  * Copy32:
    1176             :  *
    1177             :  * Copy vector x[] to y[] (32 bits)
    1178             :  *-------------------------------------------------------------------*/
    1179   401359323 : void Copy32(
    1180             :     const Word32 x[], /* i  : input vector  */
    1181             :     Word32 y[],       /* o  : output vector */
    1182             :     const Word16 L    /* i  : vector length */
    1183             : )
    1184             : {
    1185             :     Word16 i;
    1186   401359323 :     IF( y < x )
    1187             :     {
    1188 42163148412 :         FOR( i = 0; i < L; i++ )
    1189             :         {
    1190 41963501626 :             y[i] = x[i];
    1191 41963501626 :             move32();
    1192             :         }
    1193             : 
    1194   199646786 :         return;
    1195             :     }
    1196             : 
    1197 40332075060 :     FOR( i = L - 1; i >= 0; i-- )
    1198             :     {
    1199 40130362523 :         y[i] = x[i];
    1200 40130362523 :         move32();
    1201             :     }
    1202             : }
    1203             : 
    1204      343313 : void set8_fx(
    1205             :     Word8 y[],     /* i/o: Vector to set                       */
    1206             :     const Word8 a, /* i  : Value to set the vector to          */
    1207             :     const Word16 N /* i  : Lenght of the vector                */
    1208             : )
    1209             : {
    1210             :     Word16 i;
    1211             : 
    1212    76894106 :     FOR( i = 0; i < N; i++ )
    1213             :     {
    1214    76550793 :         y[i] = a;
    1215    76550793 :         move16();
    1216             :     }
    1217             : 
    1218      343313 :     return;
    1219             : }
    1220             : 
    1221             : 
    1222             : /*-------------------------------------------------------------------*
    1223             :  * set16_fx()
    1224             :  * set32_fx()
    1225             :  *
    1226             :  * Set the vector elements to a value
    1227             :  *-------------------------------------------------------------------*/
    1228             : 
    1229   357645212 : void set16_fx(
    1230             :     Word16 y[],     /* i/o: Vector to set                       */
    1231             :     const Word16 a, /* i  : Value to set the vector to          */
    1232             :     const Word16 N  /* i  : Lenght of the vector                */
    1233             : )
    1234             : {
    1235             :     Word16 i;
    1236             : 
    1237 41594274463 :     FOR( i = 0; i < N; i++ )
    1238             :     {
    1239 41236629251 :         y[i] = a;
    1240 41236629251 :         move16();
    1241             :     }
    1242             : 
    1243   357645212 :     return;
    1244             : }
    1245             : 
    1246   775018744 : void set32_fx(
    1247             :     Word32 y[],     /* i/o: Vector to set                       */
    1248             :     const Word32 a, /* i  : Value to set the vector to          */
    1249             :     const Word16 N  /* i  : Lenght of the vector                */
    1250             : )
    1251             : {
    1252             :     Word16 i;
    1253             : 
    1254 79396049740 :     FOR( i = 0; i < N; i++ )
    1255             :     {
    1256 78621030996 :         y[i] = a;
    1257 78621030996 :         move32();
    1258             :     }
    1259             : 
    1260   775018744 :     return;
    1261             : }
    1262             : 
    1263             : 
    1264             : /*-------------------------------------------------------------------*
    1265             :  * Copy_Scale_sig
    1266             :  *
    1267             :  * Up/down scale a 16 bits vector x and move it into y
    1268             :  *-------------------------------------------------------------------*/
    1269             : 
    1270    24013586 : void Copy_Scale_sig(
    1271             :     const Word16 x[], /* i  : signal to scale input           Qx        */
    1272             :     Word16 y[],       /* o  : scaled signal output            Qx        */
    1273             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1274             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1275             : )
    1276             : {
    1277             :     Word16 i;
    1278             :     Word16 tmp;
    1279             : 
    1280    24013586 :     IF( exp0 == 0 )
    1281             :     {
    1282  2401243073 :         FOR( i = 0; i < lg; i++ )
    1283             :         {
    1284  2396806366 :             y[i] = x[i];
    1285  2396806366 :             move16();
    1286             :         }
    1287     4436707 :         return;
    1288             :     }
    1289    19576879 :     IF( exp0 < 0 )
    1290             :     {
    1291    14964571 :         tmp = shl( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
    1292  6480073832 :         FOR( i = 0; i < lg; i++ )
    1293             :         {
    1294  6465109261 :             y[i] = msu_r( 0, x[i], tmp );
    1295  6465109261 :             move16();
    1296             :         }
    1297    14964571 :         return;
    1298             :     }
    1299  2414448126 :     FOR( i = 0; i < lg; i++ )
    1300             :     {
    1301  2409835818 :         y[i] = shl_sat( x[i], exp0 );
    1302  2409835818 :         move16(); /* saturation can occur here */
    1303             :     }
    1304             : 
    1305     4612308 :     return;
    1306             : }
    1307             : 
    1308             : 
    1309             : /*-------------------------------------------------------------------*
    1310             :  * Copy_Scale_sig
    1311             :  *
    1312             :  * Up/down scale a 16 bits vector x and move it into y
    1313             :  *-------------------------------------------------------------------*/
    1314             : 
    1315     4446355 : void Copy_Scale_sig_16_32_DEPREC(
    1316             :     const Word16 x[], /* i  : signal to scale input           Qx        */
    1317             :     Word32 y[],       /* o  : scaled signal output            Qx        */
    1318             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1319             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1320             : )
    1321             : {
    1322             :     Word16 i;
    1323             :     Word16 tmp;
    1324             : 
    1325     4446355 :     IF( exp0 == 0 )
    1326             :     {
    1327  1319966073 :         FOR( i = 0; i < lg; i++ )
    1328             :         {
    1329  1317371506 :             y[i] = L_deposit_l( x[i] );
    1330  1317371506 :             move32();
    1331             :         }
    1332     2594567 :         return;
    1333             :     }
    1334     1851788 :     IF( exp0 < 0 )
    1335             :     {
    1336             :         /*Should not happen */
    1337    77502172 :         FOR( i = 0; i < lg; i++ )
    1338             :         {
    1339    77277708 :             y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
    1340    77277708 :             move32();
    1341             :         }
    1342      224464 :         return;
    1343             :     }
    1344             : #ifdef DEBUGGING
    1345             :     if ( exp0 >= 16 )
    1346             :     {
    1347             :         printf( "Issue in Copy_Scale_sig_16_32_DEPREC\n" );
    1348             :     }
    1349             : #else
    1350     1627324 :     assert( exp0 < 16 );
    1351             : #endif
    1352     1627324 :     tmp = shl_sat( 1, exp0 );
    1353   572350978 :     FOR( i = 0; i < lg; i++ )
    1354             :     {
    1355   570723654 :         y[i] = L_mult0( x[i], tmp );
    1356   570723654 :         move32(); /* saturation can occur here */
    1357             :     }
    1358             : 
    1359     1627324 :     return;
    1360             : }
    1361             : 
    1362      162476 : void Copy_Scale_sig_16_32_r(
    1363             :     const Word16 x[], /* i  : signal to scale input           Qx        */
    1364             :     Word32 y[],       /* o  : scaled signal output            Qx        */
    1365             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1366             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1367             : )
    1368             : {
    1369             :     Word16 i;
    1370             : 
    1371   125567048 :     FOR( i = 0; i < lg; i++ )
    1372             :     {
    1373   125404572 :         y[i] = L_shl_r( L_deposit_l( x[i] ), exp0 );
    1374             :     }
    1375             : 
    1376      162476 :     return;
    1377             : }
    1378             : 
    1379    20607291 : void Copy_Scale_sig_16_32_no_sat(
    1380             :     const Word16 x[], /* i  : signal to scale input           Qx        */
    1381             :     Word32 y[],       /* o  : scaled signal output            Qx        */
    1382             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1383             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1384             : )
    1385             : {
    1386             :     Word16 i;
    1387             :     Word32 L_tmp;
    1388             : 
    1389    20607291 :     IF( exp0 == 0 )
    1390             :     {
    1391   643759305 :         FOR( i = 0; i < lg; i++ )
    1392             :         {
    1393   641253539 :             y[i] = L_deposit_l( x[i] );
    1394   641253539 :             move32();
    1395             :         }
    1396     2505766 :         return;
    1397             :     }
    1398    18101525 :     IF( exp0 < 0 )
    1399             :     {
    1400             :         /*Should not happen */
    1401   292634670 :         FOR( i = 0; i < lg; i++ )
    1402             :         {
    1403   291910029 :             y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
    1404   291910029 :             move32();
    1405             :         }
    1406      724641 :         return;
    1407             :     }
    1408             : 
    1409    17376884 :     L_tmp = L_shl_sat( 1, exp0 - 1 );
    1410             : 
    1411    17376884 :     IF( L_tmp >= 0x7FFF )
    1412             :     {
    1413  1786551701 :         FOR( i = 0; i < lg; i++ )
    1414             :         {
    1415             :             // y[i] = L_mult0(x[i], L_tmp);
    1416  1783477918 :             y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) );
    1417  1783477918 :             move32(); /* Overflow can occur here */
    1418             :         }
    1419     3073783 :         return;
    1420             :     }
    1421             :     // ELSE
    1422             :     {
    1423    14303101 :         Word16 tmp = extract_l( L_tmp );
    1424  6591807059 :         FOR( i = 0; i < lg; i++ )
    1425             :         {
    1426  6577503958 :             y[i] = L_mult( x[i], tmp );
    1427  6577503958 :             move32();
    1428             :         }
    1429             :     }
    1430             : 
    1431    14303101 :     return;
    1432             : }
    1433             : 
    1434             : 
    1435    12821282 : void Copy_Scale_sig_32_16(
    1436             :     const Word32 x[], /* i  : signal to scale input           Qx        */
    1437             :     Word16 y[],       /* o  : scaled signal output            Qx        */
    1438             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1439             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1440             : )
    1441             : {
    1442             :     Word16 i;
    1443             :     Word16 tmp;
    1444             : 
    1445    12821282 :     tmp = add( 16, exp0 );
    1446    12821282 :     IF( tmp != 0 )
    1447             :     {
    1448  8287090245 :         FOR( i = 0; i < lg; i++ )
    1449             :         {
    1450  8274858121 :             y[i] = round_fx_sat( L_shl_sat( x[i], tmp ) );
    1451  8274858121 :             move16();
    1452             :         }
    1453             :     }
    1454             :     ELSE
    1455             :     {
    1456   132825759 :         FOR( i = 0; i < lg; i++ )
    1457             :         {
    1458   132236601 :             y[i] = round_fx_sat( x[i] );
    1459   132236601 :             move16();
    1460             :         }
    1461             :     }
    1462             : 
    1463    12821282 :     return;
    1464             : }
    1465             : 
    1466             : 
    1467             : /*-------------------------------------------------------------------*
    1468             :  * Scale_sig32
    1469             :  *
    1470             :  * Up/down scale a 32 bits vector
    1471             :  *-------------------------------------------------------------------*/
    1472             : 
    1473   135528247 : void Scale_sig32(
    1474             :     Word32 x[],       /* i/o: signal to scale                 Qx        */
    1475             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1476             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1477             : )
    1478             : {
    1479             :     Word16 i;
    1480             : 
    1481   135528247 :     IF( 0 == exp0 )
    1482             :     {
    1483    35948313 :         return;
    1484             :     }
    1485             : 
    1486 34322126665 :     FOR( i = 0; i < lg; i++ )
    1487             :     {
    1488 34222546731 :         x[i] = L_shl_sat( x[i], exp0 );
    1489 34222546731 :         move32(); /* saturation can occur here */
    1490             :     }
    1491             : 
    1492    99579934 :     return;
    1493             : }
    1494             : 
    1495             : 
    1496             : /*------------------------------------------------------------------*
    1497             :  * function Random_Fill
    1498             :  *
    1499             :  * Signed 16 bits random generator.
    1500             :  * (Avoids Store of Seed to Memory for 'n' Random Values and
    1501             :  *  Combines Scaling Operation.)
    1502             :  *------------------------------------------------------------------*/
    1503             : 
    1504       68434 : void Random_Fill(
    1505             :     Word16 *seed,  /* i/o: random seed         */
    1506             :     Word16 n,      /* i  : number of values    */
    1507             :     Word16 *y,     /* o  : output values       */
    1508             :     Word16 scaling /* i  : scaling of values   */
    1509             : )
    1510             : {
    1511             :     Word16 i;
    1512             :     Word16 local_seed;
    1513             : 
    1514       68434 :     local_seed = *seed;
    1515       68434 :     move16();
    1516     6318930 :     FOR( i = 0; i < n; i++ )
    1517             :     {
    1518     6250496 :         local_seed = extract_l( L_mac0( 13849L, local_seed, 31821 ) );
    1519     6250496 :         *y++ = shr( local_seed, scaling );
    1520     6250496 :         move16();
    1521             :     }
    1522       68434 :     *seed = local_seed;
    1523       68434 :     move16();
    1524             : 
    1525       68434 :     return;
    1526             : }
    1527             : 
    1528             : 
    1529             : /*-------------------------------------------------------------------*
    1530             :  * Scale_sig
    1531             :  * Up/down scale a 16 bits vector
    1532             :  *-------------------------------------------------------------------*/
    1533             : 
    1534   110560881 : void Scale_sig(
    1535             :     Word16 x[],       /* i/o: signal to scale                 Qx        */
    1536             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1537             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    1538             : )
    1539             : {
    1540             :     Word16 i;
    1541             :     Word16 tmp;
    1542             : 
    1543   110560881 :     IF( exp0 > 0 )
    1544             :     {
    1545 11742942984 :         FOR( i = 0; i < lg; i++ )
    1546             :         {
    1547 11719208834 :             x[i] = shl_sat( x[i], exp0 );
    1548 11719208834 :             move16(); /* saturation can occur here */
    1549             :         }
    1550    23734150 :         return;
    1551             :     }
    1552    86826731 :     IF( exp0 < 0 )
    1553             :     {
    1554    43559719 :         tmp = shl_sat( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
    1555 17384583762 :         FOR( i = 0; i < lg; i++ )
    1556             :         {
    1557 17341024043 :             x[i] = msu_r_sat( 0, x[i], tmp );
    1558 17341024043 :             move16(); /* msu instead of mac because factor is negative */
    1559             :         }
    1560    43559719 :         return;
    1561             :     }
    1562             : }
    1563             : 
    1564             : 
    1565             : /*-------------------------------------------------------------------*
    1566             :  * scale_sig
    1567             :  * Up/down scale a 16 bits vector
    1568             :  *-------------------------------------------------------------------*/
    1569             : 
    1570    10886666 : void scale_sig(
    1571             :     Word16 x[],       /* i/o: signal to scale                 Qx        */
    1572             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1573             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx   exp  */
    1574             : )
    1575             : {
    1576             :     Word16 i;
    1577             : 
    1578    10886666 :     IF( exp0 != 0 )
    1579             :     {
    1580  2932849639 :         FOR( i = 0; i < lg; i++ )
    1581             :         {
    1582  2925766288 :             x[i] = shl( x[i], exp0 );
    1583  2925766288 :             move16();
    1584             :         }
    1585             :     }
    1586    10886666 : }
    1587             : 
    1588             : /*---------------------------------------------------------------------*
    1589             :  * mean_fx()
    1590             :  *
    1591             :  *---------------------------------------------------------------------*/
    1592             : 
    1593             : /* o  : mean of vector                         */
    1594       39666 : Word16 mean_fx(
    1595             :     const Word16 *vec_fx, /* i  : input vector                           */
    1596             :     const Word16 lvec_fx  /* i  : length of input vector                 */
    1597             : )
    1598             : {
    1599             :     Word16 tmp;
    1600             :     /* this function could be written differently to minimize the risk of saturation */
    1601       39666 :     tmp = sum16_fx( vec_fx, lvec_fx );
    1602       39666 :     tmp = mult_r( tmp, div_s( 1, lvec_fx ) );
    1603             : 
    1604       39666 :     return tmp;
    1605             : }
    1606             : 
    1607             : /* o  : mean of vector         Qx */
    1608       21845 : Word16 mean_no_sat_fx(
    1609             :     const Word16 *vec_fx, /* i  : input vector           Qx */
    1610             :     const Word16 lvec_fx  /* i  : length of input vector    */
    1611             : )
    1612             : {
    1613             :     Word16 i;
    1614       21845 :     Word32 L_tmp = 0;
    1615       21845 :     move32();
    1616      720885 :     FOR( i = 0; i < lvec_fx; ++i )
    1617             :     {
    1618      699040 :         L_tmp = L_add( L_tmp, vec_fx[i] );
    1619             :     }
    1620       21845 :     L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx */
    1621             : 
    1622       21845 :     return extract_l( L_tmp );
    1623             : }
    1624             : 
    1625             : /* o  : mean of vector         Qx */
    1626        7236 : Word32 mean_no_sat_Word32_fx(
    1627             :     const Word32 *vec_fx, /* i  : input vector           Qx */
    1628             :     const Word16 lvec_fx, /* i  : length of input vector    */
    1629             :     const Word16 gb )
    1630             : {
    1631             :     Word16 i;
    1632        7236 :     Word32 L_tmp = 0;
    1633        7236 :     move32();
    1634       36180 :     FOR( i = 0; i < lvec_fx; ++i )
    1635             :     {
    1636       28944 :         L_tmp = L_add( L_tmp, L_shr( vec_fx[i], gb ) );
    1637             :     }
    1638        7236 :     L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx-gb */
    1639             : 
    1640        7236 :     return L_tmp;
    1641             : }
    1642             : 
    1643             : 
    1644             : /*-------------------------------------------------------------------*
    1645             :  * Vr_add
    1646             :  *
    1647             :  * Add two Word16 vectors together integer by integer
    1648             :  *-------------------------------------------------------------------*/
    1649             : 
    1650     4963479 : void Vr_add(
    1651             :     const Word16 *in1, /* i  : Input vector 1                                   */
    1652             :     const Word16 *in2, /* i  : Input vector 2                                   */
    1653             :     Word16 *out,       /* o  : Output vector that contains vector 1 + vector 2  */
    1654             :     Word16 Len         /* i  : Vector lenght                                    */
    1655             : )
    1656             : {
    1657             :     Word16 i;
    1658             : 
    1659   123370535 :     FOR( i = 0; i < Len; i++ )
    1660             :     {
    1661   118407056 :         out[i] = add_sat( in1[i], in2[i] );
    1662   118407056 :         move16();
    1663             :     }
    1664     4963479 : }
    1665             : 
    1666     1775519 : void sort_fx(
    1667             :     Word16 *r, /* i/o: Vector to be sorted in place */
    1668             :     Word16 lo, /* i  : Low limit of sorting range   */
    1669             :     Word16 up  /* I  : High limit of sorting range  */
    1670             : )
    1671             : {
    1672             :     Word16 i, j, i1;
    1673             :     Word16 tempr;
    1674             : 
    1675    28401775 :     FOR( i = sub( up, 1 ); i >= lo; i-- )
    1676             :     {
    1677    26626256 :         i1 = add( i, 1 );
    1678    26626256 :         tempr = r[i];
    1679    26626256 :         move16();
    1680    26626256 :         move16(); /*supplementary move for the j-1 PTR initialization*/
    1681    26654669 :         FOR( j = i1; j <= up; j++ )
    1682             :         {
    1683    26653096 :             IF( LE_16( tempr, r[j] ) )
    1684             :             {
    1685    26624683 :                 BREAK;
    1686             :             }
    1687             : 
    1688       28413 :             r[j - 1] = r[j];
    1689       28413 :             move16();
    1690             :         }
    1691    26626256 :         r[j - 1] = tempr;
    1692    26626256 :         move16();
    1693             :     }
    1694             : 
    1695     1775519 :     return;
    1696             : }
    1697             : 
    1698        9150 : void sort_32_fx(
    1699             :     Word32 *r,       /* i/o: Vector to be sorted in place */
    1700             :     const Word16 lo, /* i  : Low limit of sorting range   */
    1701             :     const Word16 up  /* I  : High limit of sorting range  */
    1702             : )
    1703             : {
    1704             :     Word16 i, j;
    1705             :     Word32 tempr;
    1706      244000 :     FOR( i = sub( up, 1 ); i >= lo; i-- )
    1707             :     {
    1708      234850 :         tempr = r[i];
    1709      234850 :         move32();
    1710     2113388 :         FOR( j = add( i, 1 ); j <= up; j++ )
    1711             :         {
    1712     2074090 :             IF( LE_32( tempr, r[j] ) )
    1713             :             {
    1714      195552 :                 BREAK;
    1715             :             }
    1716     1878538 :             r[j - 1] = r[j];
    1717     1878538 :             move32();
    1718             :         }
    1719             : 
    1720      234850 :         r[j - 1] = tempr;
    1721      234850 :         move32();
    1722             :     }
    1723             : 
    1724        9150 :     return;
    1725             : }
    1726             : 
    1727             : /* o  : index of the minimum value in the input vector */
    1728     3693755 : Word16 minimum_fx(
    1729             :     const Word16 *vec_fx, /* i  : input vector                                   */
    1730             :     const Word16 lvec_fx, /* i  : length of input vector                         */
    1731             :     Word16 *min_fx        /* o  : minimum value in the input vector              */
    1732             : )
    1733             : {
    1734             :     Word16 j, ind;
    1735             :     Word16 tmp;
    1736     3693755 :     ind = 0;
    1737     3693755 :     move16();
    1738     3693755 :     tmp = vec_fx[0];
    1739     3693755 :     move16();
    1740             : 
    1741    93724924 :     FOR( j = 1; j < lvec_fx; j++ )
    1742             :     {
    1743    90031169 :         if ( LT_16( vec_fx[j], tmp ) )
    1744             :         {
    1745     2482025 :             ind = j;
    1746     2482025 :             move16();
    1747             :             /*tmp = vec_fx[j];    move16(); */
    1748             :         }
    1749    90031169 :         tmp = s_min( tmp, vec_fx[j] );
    1750             :     }
    1751             : 
    1752     3693755 :     *min_fx = tmp;
    1753     3693755 :     move16();
    1754             : 
    1755     3693755 :     return ind;
    1756             : }
    1757             : 
    1758             : /* o  : index of the maximum value in the input vector */
    1759    32263340 : Word16 maximum_fx(
    1760             :     const Word16 *vec_fx, /* i  : input vector                                   */
    1761             :     const Word16 lvec_fx, /* i  : length of input vector                         */
    1762             :     Word16 *max_fx        /* o  : maximum value in the input vector              */
    1763             : )
    1764             : {
    1765             :     Word16 j, ind;
    1766             :     Word16 tmp;
    1767    32263340 :     ind = 0;
    1768    32263340 :     move16();
    1769    32263340 :     tmp = vec_fx[0];
    1770    32263340 :     move16();
    1771             : 
    1772   224894716 :     FOR( j = 1; j < lvec_fx; j++ )
    1773             :     {
    1774   192631376 :         if ( GT_16( vec_fx[j], tmp ) )
    1775             :         {
    1776    31272681 :             ind = j;
    1777    31272681 :             move16();
    1778             :         }
    1779   192631376 :         tmp = s_max( tmp, vec_fx[j] );
    1780             :     }
    1781    32263340 :     *max_fx = tmp;
    1782    32263340 :     move16();
    1783             : 
    1784    32263340 :     return ind;
    1785             : }
    1786             : 
    1787             : /* o  : index of the maximum value in the input vector */
    1788    28235802 : Word16 maximum_exp_fx(
    1789             :     const Word16 *vec_fx,  /* i  : input vector                                   */
    1790             :     const Word16 *exp_vec, /* i  : exponents of input vector                      */
    1791             :     const Word16 lvec_fx   /* i  : length of input vector                         */
    1792             : )
    1793             : {
    1794             :     Word16 j, ind;
    1795    28235802 :     ind = 0;
    1796    28235802 :     move16();
    1797             : 
    1798   803937153 :     FOR( j = 1; j < lvec_fx; j++ )
    1799             :     {
    1800   775701351 :         Word16 scale = sub( exp_vec[j], exp_vec[ind] );
    1801             : 
    1802   775701351 :         test();
    1803   775701351 :         if ( vec_fx[j] == 0 || vec_fx[ind] == 0 )
    1804             :         {
    1805    48331441 :             scale = 0;
    1806    48331441 :             move16();
    1807             :         }
    1808             : 
    1809   775701351 :         if ( L_mac0_sat( L_shl_sat( L_deposit_l( vec_fx[j] ), scale ), vec_fx[ind], -0x0001 ) > 0 )
    1810             :         {
    1811   140168635 :             ind = j;
    1812   140168635 :             move16();
    1813             :         }
    1814             :     }
    1815             : 
    1816    28235802 :     return ind;
    1817             : }
    1818             : 
    1819             : 
    1820             : /*---------------------------------------------------------------------*
    1821             :  * maximum_abs_16_fx()
    1822             :  *
    1823             :  * Find index and value of the absolute maximum in a vector
    1824             :  *---------------------------------------------------------------------*/
    1825             : 
    1826             : /* o  : index of the maximum abs value in the input vector */
    1827     1341980 : Word16 maximum_abs_16_fx(
    1828             :     const Word16 *vec, /* i  : input vector                                   */
    1829             :     const Word16 lvec, /* i  : length of input vector                         */
    1830             :     Word16 *max_val    /* o  : maximum value in the input vector              */
    1831             : )
    1832             : {
    1833             :     Word16 j, ind;
    1834             :     Word16 tmp;
    1835     1341980 :     ind = 0;
    1836     1341980 :     move16();
    1837     1341980 :     tmp = abs_s( vec[0] );
    1838             : 
    1839   133231468 :     FOR( j = 1; j < lvec; j++ )
    1840             :     {
    1841   131889488 :         if ( GT_16( abs_s( vec[j] ), tmp ) )
    1842             :         {
    1843     6224455 :             ind = j;
    1844     6224455 :             move16();
    1845             :         }
    1846   131889488 :         tmp = s_max( tmp, abs_s( vec[j] ) );
    1847             :     }
    1848     1341980 :     *max_val = tmp;
    1849     1341980 :     move16();
    1850             : 
    1851     1341980 :     return ind;
    1852             : }
    1853             : 
    1854             : /*---------------------------------------------------------------------*
    1855             :  * minimum_abs32_fx()
    1856             :  *
    1857             :  * Find index and value of the absolute minimum in a vector
    1858             :  *---------------------------------------------------------------------*/
    1859             : 
    1860             : /* o  : index of the minimum value in the input vector */
    1861           0 : Word16 minimum_abs32_fx(
    1862             :     const Word32 *vec_fx, /* i  : input vector                                   */
    1863             :     const Word16 lvec_fx, /* i  : length of input vector                         */
    1864             :     Word32 *min_fx        /* o  : minimum value in the input vector              */
    1865             : )
    1866             : {
    1867             :     Word16 j, ind;
    1868             :     Word32 tmp;
    1869           0 :     ind = 0;
    1870           0 :     move16();
    1871           0 :     tmp = vec_fx[0];
    1872           0 :     move16();
    1873             : 
    1874           0 :     FOR( j = 1; j < lvec_fx; j++ )
    1875             :     {
    1876           0 :         IF( LT_32( L_abs( vec_fx[j] ), tmp ) )
    1877             :         {
    1878           0 :             ind = j;
    1879           0 :             move16();
    1880             :             /*tmp = vec_fx[j];    move16(); */
    1881             :         }
    1882           0 :         tmp = L_min( tmp, L_abs( vec_fx[j] ) );
    1883             :     }
    1884             : 
    1885           0 :     *min_fx = tmp;
    1886           0 :     move16();
    1887             : 
    1888           0 :     return ind;
    1889             : }
    1890             : 
    1891             : 
    1892             : /*---------------------------------------------------------------------*
    1893             :  * minimum_32_fx()
    1894             :  *
    1895             :  * Find index and value of the minimum in a vector
    1896             :  *---------------------------------------------------------------------*/
    1897             : 
    1898             : /* o  : index of the minimum value in the input vector */
    1899      536501 : Word16 minimum_32_fx(
    1900             :     const Word32 *vec_fx, /* i  : input vector                                   */
    1901             :     const Word16 lvec_fx, /* i  : length of input vector                         */
    1902             :     Word32 *min_fx        /* o  : minimum value in the input vector              */
    1903             : )
    1904             : {
    1905             :     Word16 j, ind;
    1906             :     Word32 tmp;
    1907      536501 :     ind = 0;
    1908      536501 :     move16();
    1909      536501 :     tmp = vec_fx[0];
    1910      536501 :     move16();
    1911             : 
    1912     1229219 :     FOR( j = 1; j < lvec_fx; j++ )
    1913             :     {
    1914      692718 :         if ( LT_32( vec_fx[j], tmp ) )
    1915             :         {
    1916      285012 :             ind = j;
    1917      285012 :             move16();
    1918             :             /*tmp = vec_fx[j];    move32(); */
    1919             :         }
    1920      692718 :         tmp = L_min( tmp, vec_fx[j] );
    1921             :     }
    1922      536501 :     if ( min_fx != NULL )
    1923             :     {
    1924      424708 :         *min_fx = tmp;
    1925             :     }
    1926      536501 :     move32();
    1927             : 
    1928      536501 :     return ind;
    1929             : }
    1930             : 
    1931             : 
    1932             : /*---------------------------------------------------------------------*
    1933             :  * maximum_32_fx()
    1934             :  *
    1935             :  * Find index and value of the maximum in a vector
    1936             :  *---------------------------------------------------------------------*/
    1937             : 
    1938             : /* o  : index of the maximum value in the input vector */
    1939     6961406 : Word16 maximum_32_fx(
    1940             :     const Word32 *vec, /* i  : input vector                                   */
    1941             :     const Word16 lvec, /* i  : length of input vector                         */
    1942             :     Word32 *max_val    /* o  : maximum value in the input vector              */
    1943             : )
    1944             : {
    1945             :     Word16 j, ind;
    1946             :     Word32 tmp;
    1947     6961406 :     ind = 0;
    1948     6961406 :     move16();
    1949     6961406 :     tmp = vec[0];
    1950     6961406 :     move16();
    1951             : 
    1952    83290109 :     FOR( j = 1; j < lvec; j++ )
    1953             :     {
    1954    76328703 :         IF( GT_32( vec[j], tmp ) )
    1955             :         {
    1956     6837973 :             ind = j;
    1957     6837973 :             move16();
    1958             :         }
    1959    76328703 :         tmp = L_max( tmp, vec[j] );
    1960             :     }
    1961     6961406 :     if ( max_val != NULL )
    1962             :     {
    1963     6946163 :         *max_val = tmp;
    1964             :     }
    1965     6961406 :     move32();
    1966             : 
    1967     6961406 :     return ind;
    1968             : }
    1969             : 
    1970             : /* o  : index of the maximum abs value in the input vector */
    1971     6193410 : Word16 maximum_abs_32_fx(
    1972             :     const Word32 *vec, /* i  : input vector                                   */
    1973             :     const Word16 lvec, /* i  : length of input vector                         */
    1974             :     Word32 *max_val    /* o  : maximum value in the input vector              */
    1975             : )
    1976             : {
    1977             :     Word16 j, ind;
    1978             :     Word32 tmp;
    1979     6193410 :     ind = 0;
    1980     6193410 :     move16();
    1981     6193410 :     tmp = L_abs( vec[0] );
    1982             : 
    1983  2226400254 :     FOR( j = 1; j < lvec; j++ )
    1984             :     {
    1985  2220206844 :         if ( GT_32( L_abs( vec[j] ), tmp ) )
    1986             :         {
    1987    22935190 :             ind = j;
    1988    22935190 :             move16();
    1989             :         }
    1990  2220206844 :         tmp = L_max( tmp, L_abs( vec[j] ) );
    1991             :     }
    1992     6193410 :     *max_val = tmp;
    1993     6193410 :     move32();
    1994             : 
    1995     6193410 :     return ind;
    1996             : }
    1997             : 
    1998             : 
    1999             : /*----------------------------------------------------------------
    2000             :  *Function:
    2001             :  *Finds number of shifts to normalize a 16-bit array variable.
    2002             :  *Return value
    2003             :  *Number of shifts
    2004             :  *----------------------------------------------------------------*/
    2005             : 
    2006      128248 : Word16 Exp16Array(
    2007             :     const Word16 n,  /* (i): Array size   */
    2008             :     const Word16 *sx /* (i): Data array   */
    2009             : )
    2010             : {
    2011             :     Word16 k;
    2012             :     Word16 exp;
    2013             :     Word16 sMax;
    2014             :     Word16 sAbs;
    2015             : 
    2016      128248 :     sMax = abs_s( sx[0] );
    2017      128248 :     move16();
    2018             : 
    2019     8359488 :     FOR( k = 1; k < n; k++ )
    2020             :     {
    2021     8231240 :         sAbs = abs_s( sx[k] );
    2022     8231240 :         sMax = s_max( sMax, sAbs );
    2023             :     }
    2024             : 
    2025      128248 :     exp = norm_s( sMax );
    2026      128248 :     return exp;
    2027             : }
    2028             : 
    2029           0 : Word16 Exp32Array(
    2030             :     const Word16 n,  /* (i): Array size   */
    2031             :     const Word32 *sx /* (i): Data array   */
    2032             : )
    2033             : {
    2034             :     Word16 k;
    2035             :     Word16 exp;
    2036             :     Word32 L_Max;
    2037             :     Word32 L_Abs;
    2038             : 
    2039           0 :     L_Max = L_abs( sx[0] );
    2040           0 :     FOR( k = 1; k < n; k++ )
    2041             :     {
    2042           0 :         L_Abs = L_abs( sx[k] );
    2043           0 :         L_Max = L_max( L_Max, L_Abs );
    2044             :     }
    2045           0 :     exp = norm_l( L_Max );
    2046             : 
    2047           0 :     if ( L_Max == 0 )
    2048             :     {
    2049           0 :         exp = 31;
    2050           0 :         move16();
    2051             :     }
    2052           0 :     return exp;
    2053             : }
    2054             : 
    2055             : /* o  : index of the maximum abs value in the input vector */
    2056       21799 : Word32 sum16_32_fx(
    2057             :     const Word16 *vec, /* i  : input vector                          Qx*/
    2058             :     const Word16 lvec  /* i  : length of input vector                */
    2059             : )
    2060             : {
    2061             :     Word16 i;
    2062             :     Word32 tmp, L_var;
    2063       21799 :     tmp = 0;
    2064       21799 :     move16();
    2065     3000053 :     FOR( i = 0; i < lvec; i++ )
    2066             :     {
    2067     2978254 :         L_var = L_deposit_l( vec[i] );
    2068     2978254 :         tmp = L_add( tmp, L_var ); /*Qx */
    2069             :     }
    2070             : 
    2071       21799 :     return tmp;
    2072             : }
    2073             : 
    2074             : 
    2075             : /* o  : sum of all vector elements            Qx*/
    2076        3621 : Word32 sum32_sat(
    2077             :     const Word32 *vec, /* i  : input vector                          Qx*/
    2078             :     const Word16 lvec  /* i  : length of input vector                */
    2079             : )
    2080             : {
    2081             :     Word16 i;
    2082             :     Word32 tmp;
    2083        3621 :     tmp = 0;
    2084        3621 :     move16();
    2085      235365 :     FOR( i = 0; i < lvec; i++ )
    2086             :     {
    2087      231744 :         tmp = L_add_sat( tmp, vec[i] ); /*Qx */
    2088             :     }
    2089             : 
    2090        3621 :     return tmp;
    2091             : }
    2092             : 
    2093             : /* o: variance of vector                    Qx+16*/
    2094       10967 : Word32 var_fx_32(
    2095             :     const Word16 *x, /* i: input vector                          Qx*/
    2096             :     const Word16 Qx,
    2097             :     const Word16 len /* i: length of inputvector                 */
    2098             : )
    2099             : {
    2100             :     Word16 m;
    2101             :     Word32 v;
    2102             :     Word16 i;
    2103             :     Word16 tmp, exp, inv_len;
    2104             :     Word32 L_tmp;
    2105             : 
    2106       10967 :     L_tmp = L_add( x[0], 0 );
    2107      298901 :     FOR( i = 1; i < len; i++ )
    2108             :     {
    2109      287934 :         L_tmp = L_add( L_tmp, x[i] ); /*Qx */
    2110             :     }
    2111       10967 :     exp = norm_s( len );
    2112       10967 :     inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
    2113       10967 :     L_tmp = Mult_32_16( L_tmp, inv_len );             /*Q(14-exp+Qx) */
    2114       10967 :     m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) );    /*Qx */
    2115             : 
    2116       10967 :     v = L_deposit_l( 0 );
    2117      309868 :     FOR( i = 0; i < len; i++ )
    2118             :     {
    2119      298901 :         tmp = sub( x[i], m );          /*Qx */
    2120      298901 :         v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
    2121             :     }
    2122       10967 :     L_tmp = Mult_32_16( v, inv_len );             /*Q(14-exp+Qx+Qx) */
    2123       10967 :     v = L_shl( L_tmp, add( exp, sub( 2, Qx ) ) ); /*Qx+16 */
    2124             : 
    2125       10967 :     return v;
    2126             : }
    2127             : 
    2128             : /* o: variance of vector                    Qx*/
    2129        3618 : Word32 var_fx_32in_32out(
    2130             :     const Word32 *x,  /* i: input vector                          Qx*/
    2131             :     Word16 *Qx,       /*i/o:Q for input/output */
    2132             :     const Word16 len, /* i: length of inputvector                 */
    2133             :     const Word16 gb )
    2134             : {
    2135             :     Word16 i;
    2136             :     Word16 shift;
    2137             :     Word32 L_tmp1, L_tmp;
    2138             :     Word64 W_temp;
    2139             : 
    2140        3618 :     L_tmp = mean_no_sat_Word32_fx( x, len, gb ); /*Qx-gb */
    2141        3618 :     W_temp = 0;
    2142       18090 :     FOR( i = 0; i < len; i++ )
    2143             :     {
    2144       14472 :         L_tmp1 = L_sub( L_shr( x[i], gb ), L_tmp );                /*Qx-gb */
    2145       14472 :         W_temp = W_add( W_temp, W_mult0_32_32( L_tmp1, L_tmp1 ) ); /*Qx-gb +Qx-gb*/
    2146             :     }
    2147        3618 :     shift = W_norm( W_temp );
    2148        3618 :     L_tmp = Mult_32_16( W_extract_h( W_shl( W_temp, shift ) ), div_s( 1, len ) ); /*Q2*(Qx-gb)+shift -32 */
    2149             : 
    2150        3618 :     *Qx = sub( add( shl( sub( *Qx, gb ), 1 ), shift ), 32 );
    2151        3618 :     move16();
    2152             : 
    2153        3618 :     return L_tmp;
    2154             : }
    2155             : 
    2156             : 
    2157             : /*-------------------------------------------------------------------*
    2158             :  * conv()
    2159             :  *
    2160             :  * Convolution between vectors x[] and h[] written to y[]
    2161             :  * All vectors are of length L. Only the first L samples of the
    2162             :  * convolution are considered.
    2163             :  *-------------------------------------------------------------------*/
    2164             : 
    2165     2199117 : Flag conv_fx(
    2166             :     const Word16 x[], /* i  : input vector                              Q_new*/
    2167             :     const Word16 h[], /* i  : impulse response (or second input vector) Q(15)*/
    2168             :     Word16 y[],       /* o  : output vetor (result of convolution)      12 bits*/
    2169             :     const Word16 L    /* i  : vector size                               */
    2170             : )
    2171             : {
    2172             : 
    2173             :     Word16 i, n;
    2174             :     Word32 L_sum;
    2175     2199117 :     Flag Overflow = 0;
    2176     2199117 :     move32();
    2177     2199117 :     y[0] = mult_r( x[0], h[0] );
    2178     2199117 :     move16();
    2179   144943168 :     FOR( n = 1; n < L; n++ )
    2180             :     {
    2181   142744051 :         L_sum = L_mult( x[0], h[n] );
    2182  5069214688 :         FOR( i = 1; i < n; i++ )
    2183             :         {
    2184  4926470637 :             L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
    2185             :         }
    2186   142744051 :         y[n] = mac_ro( L_sum, x[i], h[0], &Overflow );
    2187   142744051 :         move16();
    2188             :     }
    2189             : 
    2190     2199117 :     return Overflow;
    2191             : }
    2192             : 
    2193             : 
    2194             : /*-------------------------------------------------------------------*
    2195             :  * conv_fx_32()
    2196             :  *
    2197             :  * Convolution between vectors x[] and h[] written to y[]
    2198             :  * All vectors are of length L. Only the first L samples of the
    2199             :  * convolution are considered.
    2200             :  *-------------------------------------------------------------------*/
    2201             : 
    2202        2538 : Flag conv_fx_32(
    2203             :     const Word16 x[], /* i  : input vector                              Q_new*/
    2204             :     const Word16 h[], /* i  : impulse response (or second input vector) Q(15)*/
    2205             :     Word32 y[],       /* o  : output vetor (result of convolution)      12 bits*/
    2206             :     const Word16 L    /* i  : vector size                               */
    2207             : )
    2208             : {
    2209             :     Word16 i, n;
    2210             :     Word32 L_sum;
    2211        2538 :     Flag Overflow = 0;
    2212        2538 :     y[0] = L_mult( x[0], h[0] );
    2213        2538 :     move32();
    2214       45684 :     FOR( n = 1; n < L; n++ )
    2215             :     {
    2216       43146 :         L_sum = L_mult( x[0], h[n] );
    2217      388314 :         FOR( i = 1; i < n; i++ )
    2218             :         {
    2219      345168 :             L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
    2220             :         }
    2221       43146 :         y[n] = L_mac_o( L_sum, x[i], h[0], &Overflow );
    2222       43146 :         move32();
    2223             :     }
    2224             : 
    2225        2538 :     return Overflow;
    2226             : }
    2227             : 
    2228             : /* o: variance of vector                    Qx*/
    2229      826878 : Word16 var_fx(
    2230             :     const Word16 *x, /* i: input vector                          Qx*/
    2231             :     const Word16 Qx,
    2232             :     const Word16 len /* i: length of inputvector                 */
    2233             : )
    2234             : {
    2235             :     Word16 m;
    2236             :     Word32 v;
    2237             :     Word16 v_16;
    2238             :     Word16 i;
    2239             :     Word16 tmp, exp, inv_len;
    2240             :     Word32 L_tmp;
    2241             : 
    2242      826878 :     L_tmp = x[0];
    2243      826878 :     move32();
    2244     6344710 :     FOR( i = 1; i < len; i++ )
    2245             :     {
    2246     5517832 :         L_tmp = L_add( L_tmp, x[i] ); /*Qx */
    2247             :     }
    2248      826878 :     exp = norm_s( len );
    2249      826878 :     inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
    2250      826878 :     L_tmp = Mult_32_16( L_tmp, inv_len );             /*Q(14-exp+Qx) */
    2251      826878 :     m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) );    /*Qx */
    2252             : 
    2253      826878 :     v = L_deposit_l( 0 );
    2254     7171588 :     FOR( i = 0; i < len; i++ )
    2255             :     {
    2256     6344710 :         tmp = sub_sat( x[i], m );      /*Qx */
    2257     6344710 :         v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
    2258             :     }
    2259      826878 :     L_tmp = Mult_32_16( v, inv_len );                                    /*Q(14-exp+Qx+Qx) */
    2260      826878 :     v_16 = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( 2, Qx ) ) ) ); /*Qx */
    2261             : 
    2262      826878 :     return v_16;
    2263             : }
    2264             : 
    2265             : 
    2266             : /*---------------------------------------------------------------------*
    2267             :  * std_fx()
    2268             :  *
    2269             :  * Calculate the standard deviation of a vector
    2270             :  *---------------------------------------------------------------------*/
    2271             : 
    2272             : /* o: standard deviation                    */
    2273        9150 : Word16 std_fx(
    2274             :     const Word16 x[], /* i: input vector                          */
    2275             :     const Word16 len  /* i: length of the input vector            */
    2276             : )
    2277             : {
    2278             :     Word16 i;
    2279             :     Word32 L_tmp;
    2280             :     Word16 exp1, exp2, tmp;
    2281             :     Word32 stdev;
    2282             : 
    2283        9150 :     stdev = 0;
    2284        9150 :     move16();
    2285       82350 :     FOR( i = 0; i < len; i++ )
    2286             :     {
    2287       73200 :         L_tmp = L_mult( x[i], x[i] );              /*29 */
    2288       73200 :         stdev = L_add( stdev, L_shr( L_tmp, 3 ) ); /*26 */
    2289             :     }
    2290             : 
    2291        9150 :     IF( stdev != 0 )
    2292             :     {
    2293        9150 :         exp1 = norm_l( stdev );
    2294        9150 :         tmp = div_s( 16384, extract_h( L_shl( stdev, exp1 ) ) ); /*15 + 14 - (26 + exp1 - 16) */
    2295        9150 :         L_tmp = L_mult( tmp, len );                              /*15 + 14 - (26 + exp1 - 16) + 1 */
    2296        9150 :         exp2 = norm_l( L_tmp );
    2297        9150 :         exp1 = add( sub( exp1, exp2 ), 11 );
    2298        9150 :         stdev = Isqrt_lc( L_shl( L_tmp, exp2 ), &exp1 ); /*31-exp1 */
    2299        9150 :         stdev = L_shl( stdev, sub( exp1, 1 ) );          /*30 */
    2300             :     }
    2301             : 
    2302        9150 :     return extract_h( stdev );
    2303             : }
    2304             : 
    2305             : /* o  : the dot product x'*A*x        */
    2306       92700 : Word32 dot_product_mat_fx(
    2307             :     const Word16 *x, /* i  : vector x                     Q15 */
    2308             :     const Word32 *A, /* i  : matrix A                     Q0*/
    2309             :     const Word16 m   /* i  : vector & matrix size          */
    2310             : 
    2311             : )
    2312             : {
    2313             :     Word16 i, j;
    2314             :     Word64 tmp_sum_64;
    2315             :     Word32 suma, tmp_sum;
    2316             :     const Word32 *pt_A;
    2317             :     const Word16 *pt_x;
    2318             : 
    2319       92700 :     pt_A = A;
    2320       92700 :     suma = L_deposit_l( 0 );
    2321             : 
    2322     1205100 :     FOR( i = 0; i < m; i++ )
    2323             :     {
    2324     1112400 :         tmp_sum_64 = 0;
    2325     1112400 :         move64();
    2326     1112400 :         pt_x = x;
    2327    14461200 :         FOR( j = 0; j < m; j++ )
    2328             :         {
    2329    13348800 :             tmp_sum_64 = W_mac_32_16( tmp_sum_64, *pt_A, *pt_x ); /*Q0 */
    2330    13348800 :             pt_A++;
    2331    13348800 :             pt_x++;
    2332             :         }
    2333     1112400 :         tmp_sum = W_sat_m( tmp_sum_64 );
    2334     1112400 :         suma = Madd_32_16( suma, tmp_sum, x[i] ); /*Q0 */
    2335             :     }
    2336             : 
    2337       92700 :     return suma;
    2338             : }
    2339             : 
    2340             : 
    2341             : /*-------------------------------------------------------------------*
    2342             :  *  Vr_subt
    2343             :  *
    2344             :  *  Subtract two Word16 vectors integer by integer
    2345             :  *-------------------------------------------------------------------*/
    2346             : 
    2347     3231666 : void Vr_subt(
    2348             :     const Word16 x1[], /* i  : Input vector 1                                   */
    2349             :     const Word16 x2[], /* i  : Input vector 2                                   */
    2350             :     Word16 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    2351             :     Word16 N           /* i  : Vector lenght                                    */
    2352             : )
    2353             : {
    2354             :     Word16 i;
    2355             : 
    2356    54949502 :     FOR( i = 0; i < N; i++ )
    2357             :     {
    2358    51717836 :         y[i] = sub_sat( x1[i], x2[i] );
    2359    51717836 :         move16();
    2360             :     }
    2361             : 
    2362     3231666 :     return;
    2363             : }
    2364             : 
    2365             : 
    2366             : /*-------------------------------------------------------------------*
    2367             :  * vquant()
    2368             :  *
    2369             :  * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
    2370             :  *
    2371             :  * Searches a given codebook to find the nearest neighbour in Euclidean space.
    2372             :  * Index of the winning codevector and the winning vector itself are returned.
    2373             :  *-------------------------------------------------------------------*/
    2374             : 
    2375             : /* o: index of the winning codevector         */
    2376        1402 : Word16 vquant_ivas_fx(
    2377             :     Word32 x[],            /* i: vector to quantize                  Q25 */
    2378             :     const Word32 x_mean[], /* i: vector mean to subtract (0 if none) Q25 */
    2379             :     Word32 xq[],           /* o: quantized vector                    Q25 */
    2380             :     const Word32 cb[],     /* i: codebook                            Q25 */
    2381             :     const Word16 dim,      /* i: dimension of codebook vectors           */
    2382             :     const Word16 cbsize    /* i: codebook size                           */
    2383             : )
    2384             : {
    2385             :     Word16 c, d, idx, j;
    2386             :     Word32 L_dist, L_tmp, L_mindist;
    2387             : 
    2388        1402 :     idx = 0;
    2389        1402 :     move16();
    2390        1402 :     L_mindist = MAX_32;
    2391        1402 :     move32();
    2392        1402 :     IF( x_mean != 0 )
    2393             :     {
    2394           0 :         FOR( d = 0; d < dim; d++ )
    2395             :         {
    2396             :             /*x[d] -= x_mean[d]; */
    2397           0 :             x[d] = L_sub( x[d], x_mean[d] );
    2398           0 :             move32(); /*Qx */
    2399             :         }
    2400             :     }
    2401        1402 :     j = 0;
    2402        1402 :     move16();
    2403       19330 :     FOR( c = 0; c < cbsize; c++ )
    2404             :     {
    2405       17928 :         L_dist = 0;
    2406       17928 :         move32();
    2407             : 
    2408       89640 :         FOR( d = 0; d < dim; d++ )
    2409             :         {
    2410             :             /*tmp = x[d] - cb[j++];*/
    2411       71712 :             L_tmp = L_sub( x[d], cb[j++] );                      // Q25
    2412       71712 :             L_dist = L_add( L_dist, Mpy_32_32( L_tmp, L_tmp ) ); // (Q25, Q25) -> Q19
    2413             :         }
    2414       17928 :         if ( LT_32( L_dist, L_mindist ) ) // Q19
    2415             :         {
    2416        3115 :             idx = c;
    2417        3115 :             move16();
    2418             :         }
    2419       17928 :         L_mindist = L_min( L_mindist, L_dist ); // Q19
    2420             :     }
    2421        1402 :     IF( xq == 0 )
    2422             :     {
    2423           0 :         return idx;
    2424             :     }
    2425             : 
    2426             :     /*j =  idx*dim;*/
    2427        1402 :     j = i_mult2( idx, dim );
    2428        7010 :     FOR( d = 0; d < dim; d++ )
    2429             :     {
    2430        5608 :         xq[d] = cb[j++]; // Q25
    2431        5608 :         move32();
    2432             :     }
    2433        1402 :     IF( x_mean != 0 )
    2434             :     {
    2435           0 :         FOR( d = 0; d < dim; d++ )
    2436             :         {
    2437             :             /*xq[d] += x_mean[d]; */
    2438           0 :             xq[d] = L_add( xq[d], x_mean[d] ); // Q25
    2439           0 :             move32();
    2440             :         }
    2441             :     }
    2442             : 
    2443        1402 :     return idx;
    2444             : }
    2445             : 
    2446             : /* o: index of the winning codevector         */
    2447      294218 : Word16 vquant_fx(
    2448             :     Word16 x[],            /* i: vector to quantize                  Q13 */
    2449             :     const Word16 x_mean[], /* i: vector mean to subtract (0 if none) Q13 */
    2450             :     Word16 xq[],           /* o: quantized vector                    Q13 */
    2451             :     const Word16 cb[],     /* i: codebook                            Q13 */
    2452             :     const Word16 dim,      /* i: dimension of codebook vectors           */
    2453             :     const Word16 cbsize    /* i: codebook size                           */
    2454             : )
    2455             : {
    2456             :     Word16 tmp;
    2457             :     Word16 c, d, idx, j;
    2458             :     Word32 L_dist, /*L_tmp,*/ L_mindist;
    2459             : 
    2460      294218 :     idx = 0;
    2461      294218 :     move16();
    2462      294218 :     L_mindist = MAX_32;
    2463      294218 :     move32();
    2464      294218 :     IF( x_mean != 0 )
    2465             :     {
    2466      555871 :         FOR( d = 0; d < dim; d++ )
    2467             :         {
    2468             :             /*x[d] -= x_mean[d]; */
    2469      410327 :             x[d] = sub( x[d], x_mean[d] );
    2470      410327 :             move16(); /*Qx */
    2471             :         }
    2472             :     }
    2473      294218 :     j = 0;
    2474      294218 :     move16();
    2475    10644146 :     FOR( c = 0; c < cbsize; c++ )
    2476             :     {
    2477    10349928 :         L_dist = 0;
    2478    10349928 :         move32();
    2479             : 
    2480    45282984 :         FOR( d = 0; d < dim; d++ )
    2481             :         {
    2482             :             /*tmp = x[d] - cb[j++];*/
    2483    34933056 :             tmp = sub( x[d], cb[j++] ); /*Qx */
    2484    34933056 :             L_dist = L_mac0( L_dist, tmp, tmp );
    2485             :         }
    2486    10349928 :         if ( LT_32( L_dist, L_mindist ) )
    2487             :         {
    2488     1189902 :             idx = c;
    2489     1189902 :             move16();
    2490             :         }
    2491    10349928 :         L_mindist = L_min( L_mindist, L_dist );
    2492             :     }
    2493      294218 :     IF( xq == 0 )
    2494             :     {
    2495           0 :         return idx;
    2496             :     }
    2497             : 
    2498             :     /*j =  idx*dim;*/
    2499      294218 :     j = i_mult2( idx, dim );
    2500     1299241 :     FOR( d = 0; d < dim; d++ )
    2501             :     {
    2502     1005023 :         xq[d] = cb[j++];
    2503     1005023 :         move16();
    2504             :     }
    2505      294218 :     IF( x_mean != 0 )
    2506             :     {
    2507      555871 :         FOR( d = 0; d < dim; d++ )
    2508             :         {
    2509             :             /*xq[d] += x_mean[d]; */
    2510      410327 :             xq[d] = add( xq[d], x_mean[d] );
    2511      410327 :             move16();
    2512             :         }
    2513             :     }
    2514             : 
    2515      294218 :     return idx;
    2516             : }
    2517             : 
    2518             : 
    2519             : /*-------------------------------------------------------------------*
    2520             :  * w_vquant_fx()
    2521             :  *
    2522             :  * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
    2523             :  *
    2524             :  * Searches a given codebook to find the nearest neighbour in Euclidean space.
    2525             :  * Weights are put on the error for each vector element.
    2526             :  * Index of the winning codevector and the winning vector itself are returned.
    2527             :  *-------------------------------------------------------------------*/
    2528             : 
    2529       46562 : Word16 w_vquant_fx(
    2530             :     Word16 x[], /* i: vector to quantize in Q10 */
    2531             :     Word16 Qx,
    2532             :     const Word16 weights[], /* i: error weights in Q0 */
    2533             :     Word16 xq[],            /* o: quantized vector in Q15 */
    2534             :     const Word16 cb[],      /* i: codebook in Q15 */
    2535             :     const Word16 cbsize,    /* i: codebook size */
    2536             :     const Word16 rev_vect   /* i: reverse codebook vectors */
    2537             : )
    2538             : {
    2539             :     Word16 tmp;
    2540             :     Word16 c, idx, j;
    2541             :     Word32 dist, minDist;
    2542             : 
    2543       46562 :     idx = 0;
    2544       46562 :     move16();
    2545       46562 :     minDist = 0x7fffffffL;
    2546       46562 :     move32();
    2547       46562 :     Qx = sub( 15, Qx );
    2548             : 
    2549       46562 :     j = 0;
    2550       46562 :     move16();
    2551       46562 :     IF( rev_vect )
    2552             :     {
    2553     1711357 :         FOR( c = 0; c < cbsize; c++ )
    2554             :         {
    2555     1699900 :             dist = L_deposit_l( 0 );
    2556             : 
    2557     1699900 :             tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
    2558     1699900 :             if ( weights[3] != 0 )
    2559             :             {
    2560     1525424 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2561             :             }
    2562     1699900 :             tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
    2563     1699900 :             if ( weights[2] != 0 )
    2564             :             {
    2565     1568400 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2566             :             }
    2567     1699900 :             tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
    2568     1699900 :             if ( weights[1] != 0 )
    2569             :             {
    2570     1663461 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2571             :             }
    2572     1699900 :             tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
    2573     1699900 :             if ( weights[0] != 0 )
    2574             :             {
    2575     1617546 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2576             :             }
    2577     1699900 :             if ( LT_32( dist, minDist ) )
    2578             :             {
    2579      121956 :                 idx = c;
    2580      121956 :                 move16();
    2581             :             }
    2582     1699900 :             minDist = L_min( minDist, dist );
    2583             :         }
    2584             : 
    2585       11457 :         IF( xq == 0 )
    2586             :         {
    2587           0 :             return idx;
    2588             :         }
    2589             : 
    2590       11457 :         j = shl( idx, 2 );
    2591       11457 :         xq[3] = cb[j++];
    2592       11457 :         move16(); /* in Q15 */
    2593       11457 :         xq[2] = cb[j++];
    2594       11457 :         move16(); /* in Q15 */
    2595       11457 :         xq[1] = cb[j++];
    2596       11457 :         move16(); /* in Q15 */
    2597       11457 :         xq[0] = cb[j++];
    2598       11457 :         move16(); /* in Q15 */
    2599             :     }
    2600             :     ELSE
    2601             :     {
    2602     1883897 :         FOR( c = 0; c < cbsize; c++ )
    2603             :         {
    2604     1848792 :             dist = L_deposit_l( 0 );
    2605             : 
    2606     1848792 :             tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
    2607     1848792 :             if ( weights[0] != 0 )
    2608             :             {
    2609     1696462 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2610             :             }
    2611     1848792 :             tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
    2612     1848792 :             if ( weights[1] != 0 )
    2613             :             {
    2614     1747467 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2615             :             }
    2616     1848792 :             tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
    2617     1848792 :             if ( weights[2] != 0 )
    2618             :             {
    2619     1757169 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2620             :             }
    2621     1848792 :             tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
    2622     1848792 :             if ( weights[3] != 0 )
    2623             :             {
    2624     1712755 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2625             :             }
    2626     1848792 :             if ( LT_32( dist, minDist ) )
    2627             :             {
    2628      180715 :                 idx = c;
    2629      180715 :                 move16();
    2630             :             }
    2631     1848792 :             minDist = L_min( minDist, dist );
    2632             :         }
    2633             : 
    2634       35105 :         IF( xq == 0 )
    2635             :         {
    2636       23281 :             return idx;
    2637             :         }
    2638             : 
    2639       11824 :         j = shl( idx, 2 );
    2640       11824 :         xq[0] = cb[j++];
    2641       11824 :         move16(); /* in Q15 */
    2642       11824 :         xq[1] = cb[j++];
    2643       11824 :         move16(); /* in Q15 */
    2644       11824 :         xq[2] = cb[j++];
    2645       11824 :         move16(); /* in Q15 */
    2646       11824 :         xq[3] = cb[j++];
    2647       11824 :         move16(); /* in Q15 */
    2648             :     }
    2649             : 
    2650       23281 :     return idx;
    2651             : }
    2652             : 
    2653             : 
    2654             : /*-------------------------------------------------------------------*
    2655             :  * Emaximum:
    2656             :  *
    2657             :  * Find index of a maximum energy in a vector
    2658             :  *-------------------------------------------------------------------*/
    2659             : 
    2660             : /* o  : return index with max energy value in vector  Q0 */
    2661    23743381 : Word16 emaximum_fx(
    2662             :     const Word16 Qvec, /* i  : Q of input vector                         Q0 */
    2663             :     const Word16 *vec, /* i  : input vector                              Qx */
    2664             :     const Word16 lvec, /* i  : length of input vector                    Q0 */
    2665             :     Word32 *ener_max   /* o  : maximum energy value                      Q0 */
    2666             : )
    2667             : {
    2668             :     Word16 j, ind;
    2669             :     Word32 L_tmp, L_tmp1;
    2670             :     Word32 emax;
    2671             : 
    2672    23743381 :     emax = L_mult0( vec[0], vec[0] );
    2673    23743381 :     ind = 0;
    2674    23743381 :     move16();
    2675             : 
    2676   769658348 :     FOR( j = 1; j < lvec; j++ )
    2677             :     {
    2678   745914967 :         L_tmp = L_mult0( vec[j], vec[j] );
    2679   745914967 :         L_tmp1 = L_sub( L_tmp, emax );
    2680   745914967 :         if ( L_tmp1 > 0 )
    2681             :         {
    2682    93891620 :             ind = j;
    2683    93891620 :             move16();
    2684             :         }
    2685   745914967 :         emax = L_max( emax, L_tmp );
    2686             :     }
    2687             : 
    2688    23743381 :     *ener_max = L_shr_sat( emax, add( Qvec, Qvec ) );
    2689    23743381 :     move32();
    2690             : 
    2691    23743381 :     return ind;
    2692             : }
    2693             : 
    2694             : /* o  : return index with max energy value in vector  Q0 */
    2695       42813 : Word16 emaximum_32fx(
    2696             :     const Word16 Qvec, /* i  : Q of input vector                         Q0 */
    2697             :     const Word32 *vec, /* i  : input vector                              Qx */
    2698             :     const Word16 lvec, /* i  : length of input vector                    Q0 */
    2699             :     Word32 *ener_max   /* o  : maximum energy value                      Q0 */
    2700             : )
    2701             : {
    2702             :     Word16 j, ind;
    2703             :     Word64 W_tmp, W_tmp1;
    2704             :     Word64 emax;
    2705             : 
    2706       42813 :     emax = W_mult0_32_32( vec[0], vec[0] );
    2707       42813 :     ind = 0;
    2708       42813 :     move16();
    2709             : 
    2710     4045049 :     FOR( j = 1; j < lvec; j++ )
    2711             :     {
    2712     4002236 :         W_tmp = W_mult0_32_32( vec[j], vec[j] );
    2713     4002236 :         W_tmp1 = W_sub( W_tmp, emax );
    2714     4002236 :         if ( W_tmp1 > 0 )
    2715             :         {
    2716      331222 :             ind = j;
    2717      331222 :             move16();
    2718             :         }
    2719     4002236 :         if ( LE_64( emax, W_tmp ) )
    2720             :         {
    2721      333948 :             emax = W_tmp;
    2722      333948 :             move64();
    2723             :         }
    2724             :     }
    2725             : 
    2726       42813 :     *ener_max = W_extract_l( W_shr( emax, add( Qvec, Qvec ) ) );
    2727       42813 :     move32();
    2728             : 
    2729       42813 :     return ind;
    2730             : }
    2731             : 
    2732             : 
    2733             : /*-------------------------------------------------------------------*
    2734             :  * mean32:
    2735             :  *
    2736             :  * Find the mean of a 32 bits vector
    2737             :  *-------------------------------------------------------------------*/
    2738             : /* o  : mean of the elements of the vector */
    2739        8048 : Word32 Mean32(
    2740             :     const Word32 in[], /* i  : input vector                       */
    2741             :     const Word16 L     /* i  : length of input vector             */
    2742             : )
    2743             : {
    2744             :     Word32 Ltmp;
    2745             :     Word16 inv_L;
    2746             : 
    2747        8048 :     inv_L = INV_BANDS9;
    2748        8048 :     move16();
    2749        8048 :     if ( EQ_16( L, 10 ) )
    2750             :     {
    2751        8048 :         inv_L = INV_BANDS10;
    2752        8048 :         move16();
    2753             :     }
    2754             : 
    2755        8048 :     Ltmp = sum32_fx( in, L );
    2756             : 
    2757        8048 :     Ltmp = Mult_32_16( Ltmp, inv_L );
    2758             : 
    2759        8048 :     return Ltmp;
    2760             : }
    2761             : 
    2762             : /* o  : sum of all vector elements            Qx*/
    2763      264829 : Word32 sum32_fx(
    2764             :     const Word32 *vec, /* i  : input vector                          Qx*/
    2765             :     const Word16 lvec  /* i  : length of input vector                */
    2766             : )
    2767             : {
    2768             :     Word16 i;
    2769             :     Word32 tmp;
    2770             : 
    2771      264829 :     tmp = L_deposit_l( 0 );
    2772    10364855 :     FOR( i = 0; i < lvec; i++ )
    2773             :     {
    2774    10100026 :         tmp = L_add_sat( tmp, vec[i] ); /*Qx */
    2775             :     }
    2776             : 
    2777      264829 :     return tmp;
    2778             : }
    2779             : 
    2780             : /* o  : sum of all vector elements            Qx*/
    2781     1635623 : Word16 sum16_fx(
    2782             :     const Word16 *vec, /* i  : input vector                          Qx*/
    2783             :     const Word16 lvec  /* i  : length of input vector                */
    2784             : )
    2785             : {
    2786             :     Word16 i;
    2787             :     Word16 tmp;
    2788     1635623 :     tmp = 0;
    2789     1635623 :     move16();
    2790    13171549 :     FOR( i = 0; i < lvec; i++ )
    2791             :     {
    2792    11535926 :         tmp = add_sat( tmp, vec[i] ); /*Qx */
    2793             :     }
    2794             : 
    2795     1635623 :     return tmp;
    2796             : }
    2797             : 
    2798             : 
    2799             : /*------------------------------------------------------------------*
    2800             :  * function Random
    2801             :  *
    2802             :  * Signed 16 bits random generator.
    2803             :  *------------------------------------------------------------------*/
    2804             : 
    2805             : /* o  : output random value */
    2806   818997738 : Word16 Random(
    2807             :     Word16 *seed /* i/o: random seed         */
    2808             : )
    2809             : {
    2810   818997738 :     *seed = extract_l( L_mac0( 13849L, *seed, 31821 ) );
    2811   818997738 :     move16();
    2812             : 
    2813   818997738 :     return *seed;
    2814             : }
    2815             : 
    2816      160162 : Word16 own_random2_fx(
    2817             :     Word16 seed )
    2818             : {
    2819      160162 :     return extract_l( L_mac0( 13849, seed, 31821 ) );
    2820             : }
    2821             : 
    2822             : 
    2823             : /*---------------------------------------------------------------------
    2824             :  * sign_fx()
    2825             :  *
    2826             :  *---------------------------------------------------------------------*/
    2827             : 
    2828             : /*! r: sign of x (+1/-1) */
    2829     3190213 : Word16 sign_fx(
    2830             :     const Word32 x /* i  : input value of x  */
    2831             : )
    2832             : {
    2833     3190213 :     IF( LT_32( x, 0 ) )
    2834             :     {
    2835     1045613 :         return -1;
    2836             :     }
    2837             :     ELSE
    2838             :     {
    2839     2144600 :         return 1;
    2840             :     }
    2841             : }
    2842             : 
    2843           0 : Word16 sign16_fx(
    2844             :     const Word16 x /* i  : input value of x  */
    2845             : )
    2846             : {
    2847           0 :     IF( LT_16( x, 0 ) )
    2848             :     {
    2849           0 :         return -1;
    2850             :     }
    2851             :     ELSE
    2852             :     {
    2853           0 :         return 1;
    2854             :     }
    2855             : }
    2856             : 
    2857             : 
    2858             : /*------------------------------------------------------------------*
    2859             :  * function Div_32_optmz
    2860             :  *
    2861             :  * Performs 32 bits interger division
    2862             :  *------------------------------------------------------------------*/
    2863             : 
    2864     1858896 : static Word32 Div_32_optmz(
    2865             :     Word32 L_num,
    2866             :     Word16 denom_hi )
    2867             : {
    2868             :     Word16 approx, hi, lo, n_hi, n_lo;
    2869             :     Word32 L_32;
    2870             : 
    2871             :     /* First approximation: 1 / L_denom = 1/denom_hi */
    2872             : 
    2873     1858896 :     approx = div_s( (Word16) 0x3fff, denom_hi );
    2874             : 
    2875             :     /* 1/L_denom = approx * (2.0 - L_denom * approx) */
    2876             : 
    2877     1858896 :     L_32 = L_msu( (Word32) 0x7fffffffL, denom_hi, approx );
    2878             : 
    2879     1858896 :     lo = L_Extract_lc( L_32, &hi );
    2880     1858896 :     L_32 = Mpy_32_16( hi, lo, approx );
    2881             : 
    2882             :     /* L_num * (1/L_denom) */
    2883             : 
    2884     1858896 :     lo = L_Extract_lc( L_32, &hi );
    2885     1858896 :     n_lo = L_Extract_lc( L_num, &n_hi );
    2886     1858896 :     L_32 = Mpy_32( n_hi, n_lo, hi, lo );
    2887             : 
    2888     1858896 :     return ( L_32 );
    2889             : }
    2890             : 
    2891             : 
    2892             : /*------------------------------------------------------------------*
    2893             :  * function iDiv_and_mod_32
    2894             :  *
    2895             :  * return the quotient and the modulo 32 bits numerator divided by a 16 bit denominator
    2896             :  * The denominator might be right shifted by 1
    2897             :  *------------------------------------------------------------------*/
    2898             : 
    2899     1858896 : void iDiv_and_mod_32(
    2900             :     const Word32 Numer,   /* i  : 32 bits numerator   */
    2901             :     const Word16 Denom,   /* i  : 16 bits denominator */
    2902             :     Word32 *Int_quotient, /* o  : integer result of the division (int)(num/den) */
    2903             :     Word32 *Int_mod,      /* o  : modulo result of the division  num-((int)(num/den)*den)*/
    2904             :     const Word16 rshift   /* i  : 0 if no right shift / 1 if the denom is right shifted by 1 */
    2905             : )
    2906             : {
    2907             :     Word32 Quotient;
    2908             :     Word16 expA, expB;
    2909             :     Word32 N, TEMP;
    2910             :     Word16 D;
    2911             : 
    2912             :     /* Normalize 'Numer' & 'Denom' */
    2913             :     /* Use Temporary to Preserve the Original Value */
    2914     1858896 :     expA = norm_l( Numer );
    2915     1858896 :     N = L_shl( Numer, expA );
    2916     1858896 :     expB = norm_s( Denom );
    2917     1858896 :     D = shl( Denom, expB );
    2918             : 
    2919             :     /* Need to shift right 'Numer' by 1? */
    2920     1858896 :     if ( L_mac( N, D, -32768L ) >= 0 )
    2921             :     {
    2922     1113684 :         expA = sub( expA, 1 );
    2923             :     }
    2924     1858896 :     N = L_shl( Numer, expA );
    2925             : 
    2926             :     /* Perform Approximation of the Division
    2927             :      * Since 'lo' part is '0' AND 'denom' is supposed to be constant in the targeted usage
    2928             :      * one could import the Div32 code and pre-calc the div_s and eliminate all calcs
    2929             :      * with 'lo' to save some complexity */
    2930             : 
    2931     1858896 :     Quotient = Div_32_optmz( N, D ); /* takes 36 clocks */
    2932             :     /* Bring Back to Q0 (minus 2 because we removed the left shift by 2 in the Div32_optmz) */
    2933     1858896 :     IF( rshift )
    2934             :     {
    2935           0 :         Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, sub( expB, 1 ) ) ) );
    2936             :     }
    2937             :     ELSE
    2938             :     {
    2939     1858896 :         Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, expB ) ) );
    2940             :     }
    2941             : 
    2942             :     /* Cross Check (do Quotient x Divisor)
    2943             :      * The Quotient is unsigned but we cannot just use extract_h because
    2944             :      * extract_l on the low part will get the sign of the bit #15.
    2945             :      * In a 32 bits value, what is in bits 0-15 is un unsigned 16 bits value.
    2946             :      * So, we shift left by 1, extract the hi part and mult it by 32768 (hence the L_shl by 16-1.
    2947             :      * Then we take 15 bits left (mask the others) and multiply by Denom.
    2948             :      * Technically this could overflow. But since we are mutiplying to get
    2949             :      * back to the Numer value that fitted in a 32 bits, doing Divisor x Quotient
    2950             :      * must necessarily fit in a 32 bits
    2951             :      * It is assumed that all are positive values. If not, one could
    2952             :      * check the sign of the numer and denom, turn them into abs values
    2953             :      * and restore the sign after*/
    2954     1858896 :     TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2955     1858896 :     TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2956             : 
    2957             : 
    2958             :     /* Here we test to see if the previous "Quotient x Divisor" (or TEMP) is too small
    2959             :      * that is the "Numer" minus TEMP is bigger or Equal to the Divisor.
    2960             :      * If it is then the quotient is too small. We need to increase it by 1.
    2961             :      * That is caused by our Div32 fractionnal division that can be off by 1
    2962             :      * sometimes.
    2963             :      * In some cases, when the divisor is very small (like 10 or something)
    2964             :      * the quotient could be off by more than 1 and we would need a loop
    2965             :      * to check again. That is not the case here with the current divisor */
    2966     1858896 :     IF( rshift )
    2967             :     {
    2968           0 :         TEMP = L_shl( TEMP, 1 );
    2969           0 :         WHILE( L_msu0( L_sub( Numer, TEMP ), 2, Denom ) >= 0 )
    2970             :         {
    2971           0 :             Quotient = L_add( Quotient, 1 );
    2972           0 :             TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2973           0 :             TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2974           0 :             TEMP = L_shl( TEMP, 1 );
    2975             :         }
    2976             :     }
    2977             :     ELSE{
    2978     2234535 :         WHILE( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) >= 0 ){
    2979      375639 :             Quotient = L_add( Quotient, 1 );
    2980      375639 :     TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2981      375639 :     TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2982             : }
    2983             : }
    2984     1858896 : *Int_quotient = Quotient;
    2985     1858896 : move32();
    2986     1858896 : IF( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) == 0 )
    2987             : {
    2988           0 :     *Int_mod = 0L;
    2989           0 :     move32();
    2990             : }
    2991             : ELSE
    2992             : {
    2993     1858896 :     *Int_mod = L_sub( Numer, TEMP );
    2994     1858896 :     move32();
    2995             : }
    2996     1858896 : }
    2997             : 
    2998             : /*===================================================================*/
    2999             : /* FUNCTION      :  pz_filter_sp_fx ()                                  */
    3000             : /*-------------------------------------------------------------------*/
    3001             : /* PURPOSE       :  Generic pole-zero filter routine, with single    */
    3002             : /*                  precision memory                                 */
    3003             : /*-------------------------------------------------------------------*/
    3004             : /* INPUT ARGUMENTS  :                                                */
    3005             : /*                                                                   */
    3006             : /*   _ (Word16 []) b   : zero filter coefficients (Qc).              */
    3007             : /*   _ (Word16 []) a   : pole filter coefficients (Qc), a(0)=1 in Qc */
    3008             : /*   _ (Word16 []) x   : input signal (Qn).                          */
    3009             : /*   _ (Word16)    PNR   : NR filter order                           */
    3010             : /*   _ (Word16)    PDR   : DR filter order                           */
    3011             : /*   _ (Word16)    N   : number of input samples.                    */
    3012             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    3013             : /*-------------------------------------------------------------------*/
    3014             : /* OUTPUT ARGUMENTS :                                                */
    3015             : /*                                                                   */
    3016             : /*   _ (Word16 []) y : output signal  (Qn)                           */
    3017             : /*-------------------------------------------------------------------*/
    3018             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3019             : /*                                                                   */
    3020             : /*   _ (Word16 []) buf : filter memory (Qn-Qa).                      */
    3021             : /*-------------------------------------------------------------------*/
    3022             : /* RETURN ARGUMENTS : _ None.                                        */
    3023             : /*===================================================================*/
    3024             : 
    3025           0 : void pz_filter_sp_fx(
    3026             :     const Word16 b[],
    3027             :     const Word16 a[],
    3028             :     Word16 x[],
    3029             :     Word16 y[],
    3030             :     Word16 buf[],
    3031             :     Word16 PNR,
    3032             :     Word16 PDR,
    3033             :     Word16 N,
    3034             :     Word16 Qa )
    3035             : {
    3036             :     Word16 i, j;
    3037             :     Word16 s;
    3038             :     Word16 s_mem;
    3039             :     Word32 Ltemp1;
    3040             :     Word32 Lacc;
    3041           0 :     s = negate( Qa );
    3042           0 :     s = add( s, s ); /* s=-2Qa*/
    3043           0 :     s = add( s, 1 );
    3044           0 :     FOR( i = 0; i < N; i++ )
    3045             :     {
    3046           0 :         Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
    3047           0 :         Lacc = L_shl( Lacc, s );    /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
    3048           0 :         FOR( j = PDR - 1; j >= 0; j-- )
    3049           0 :         Lacc = L_msu_sat( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
    3050             : 
    3051             : 
    3052           0 :         Lacc = L_shr( Lacc, 1 );
    3053           0 :         Ltemp1 = L_add_sat( L_shl_sat( Lacc, Qa ), 0x08000 );
    3054           0 :         s_mem = extract_h( Ltemp1 );
    3055             : 
    3056           0 :         Lacc = L_deposit_l( 0 );
    3057           0 :         FOR( j = PNR - 1; j >= 0; j-- )
    3058           0 :         Lacc = L_mac_sat( Lacc, buf[j], b[j + 1] );
    3059           0 :         Lacc = L_mac_sat( Lacc, s_mem, b[0] );
    3060             :         /* Lacc in Q(1+Qc+Qn-Qa)*/
    3061             : 
    3062           0 :         FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
    3063             :         {
    3064             :             /* Update filter memory */
    3065           0 :             buf[j] = buf[j - 1];
    3066           0 :             move16();
    3067             :         }
    3068           0 :         buf[0] = s_mem;
    3069           0 :         move16();
    3070             : 
    3071           0 :         Ltemp1 = L_add_sat( L_shr_sat( Lacc, s ), 0x08000 ); /*  Ltemp1 in Qc+Qa+Qn=Q(Qn) */
    3072           0 :         y[i] = extract_h( Ltemp1 );                          /*  y[i] in Qn */
    3073           0 :         move16();
    3074             :     }
    3075             : 
    3076           0 :     return;
    3077             : }
    3078             : 
    3079             : 
    3080      248938 : Word32 root_a_fx(
    3081             :     Word32 a,
    3082             :     Word16 Q_a,
    3083             :     Word16 *exp_out )
    3084             : {
    3085             :     Word16 exp, tmp;
    3086             :     Word32 L_tmp;
    3087             : 
    3088      248938 :     IF( a <= 0 )
    3089             :     {
    3090        5765 :         *exp_out = 0;
    3091        5765 :         move16();
    3092        5765 :         return 0;
    3093             :     }
    3094             : 
    3095      243173 :     exp = norm_l( a );
    3096      243173 :     tmp = extract_h( L_shl( a, exp ) );
    3097      243173 :     exp = sub( exp, sub( 30, Q_a ) );
    3098      243173 :     tmp = div_s( 16384, tmp );
    3099      243173 :     L_tmp = L_deposit_h( tmp );
    3100      243173 :     L_tmp = Isqrt_lc( L_tmp, &exp );
    3101             : 
    3102      243173 :     *exp_out = exp;
    3103      243173 :     move16();
    3104             : 
    3105      243173 :     return L_tmp;
    3106             : }
    3107             : 
    3108             : 
    3109     2489859 : Word32 root_a_over_b_fx(
    3110             :     Word32 a, /* Q(Q_a) */
    3111             :     Word16 Q_a,
    3112             :     Word32 b, /* Q(Q_b) */
    3113             :     Word16 Q_b,
    3114             :     Word16 *exp_out )
    3115             : {
    3116             :     Word16 tmp, num, den, scale;
    3117             :     Word16 exp, exp_num, exp_den;
    3118             :     Word32 L_tmp;
    3119             : 
    3120     2489859 :     test();
    3121     2489859 :     IF( ( a <= 0 ) || ( b <= 0 ) )
    3122             :     {
    3123       20383 :         *exp_out = 0;
    3124       20383 :         move16();
    3125       20383 :         return 0;
    3126             :     }
    3127             : 
    3128     2469476 :     exp_num = norm_l( b );
    3129     2469476 :     num = round_fx_sat( L_shl_sat( b, exp_num ) );
    3130     2469476 :     exp_num = sub( sub( 30, exp_num ), Q_b );
    3131             : 
    3132     2469476 :     exp_den = norm_l( a );
    3133     2469476 :     den = round_fx_sat( L_shl_sat( a, exp_den ) );
    3134     2469476 :     exp_den = sub( sub( 30, exp_den ), Q_a );
    3135             : 
    3136     2469476 :     scale = shr( sub( den, num ), 15 );
    3137     2469476 :     num = shl_sat( num, scale );
    3138     2469476 :     exp_num = sub( exp_num, scale );
    3139             : 
    3140     2469476 :     tmp = div_s( num, den );
    3141     2469476 :     exp = sub( exp_num, exp_den );
    3142             : 
    3143     2469476 :     L_tmp = L_deposit_h( tmp );
    3144     2469476 :     L_tmp = Isqrt_lc( L_tmp, &exp );
    3145             : 
    3146     2469476 :     *exp_out = exp;
    3147     2469476 :     move16();
    3148             : 
    3149     2469476 :     return L_tmp;
    3150             : }
    3151             : 
    3152             : 
    3153      375900 : Word32 root_a_over_b_ivas_fx(
    3154             :     Word32 a, /* Q(Q_a) */
    3155             :     Word16 Q_a,
    3156             :     Word32 b, /* Q(Q_b) */
    3157             :     Word16 Q_b,
    3158             :     Word16 *q_out )
    3159             : {
    3160             :     Word16 shift_a, shift_b, shift;
    3161             :     Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b;
    3162             :     Word32 a_sqr, b_sqr, p0, p1, p2, approx;
    3163             :     Word16 exp;
    3164             : 
    3165      375900 :     test();
    3166      375900 :     IF( ( a <= 0 ) || ( b <= 0 ) )
    3167             :     {
    3168           0 :         *q_out = 0;
    3169           0 :         move16();
    3170           0 :         return 0;
    3171             :     }
    3172             : 
    3173      375900 :     one_in_Q_a = L_shl( 1, Q_a );         // 1.0f in Q_a
    3174      375900 :     one_in_Q_b = L_shl( 1, Q_b );         // 1.0f in Q_b
    3175      375900 :     half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a
    3176      375900 :     half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b
    3177             : 
    3178      375900 :     a = L_add( a, one_in_Q_a );
    3179      375900 :     b = L_add( b, one_in_Q_b );
    3180             : 
    3181             :     /* This next piece of code implements a "norm" function */
    3182             :     /* and returns the shift needed to scale "a" to have a  */
    3183             :     /* 1 in the (MSB-1) position. This is equivalent to     */
    3184             :     /* giving a value between 0.5 & 1.0.                    */
    3185             : 
    3186      375900 :     mod_a = a;
    3187      375900 :     move32();
    3188             : 
    3189      375900 :     shift_a = 0;
    3190      375900 :     move16();
    3191      751800 :     WHILE( GT_32( mod_a, one_in_Q_a ) )
    3192             :     {
    3193      375900 :         mod_a = L_shr( mod_a, 1 );
    3194      375900 :         shift_a = sub( shift_a, 1 );
    3195             :     }
    3196             : 
    3197      375900 :     WHILE( LT_32( mod_a, half_in_Q_a ) )
    3198             :     {
    3199           0 :         mod_a = L_shl( mod_a, 1 );
    3200           0 :         shift_a = add( shift_a, 1 );
    3201             :     }
    3202             : 
    3203      375900 :     shift_a = s_and( shift_a, -2 );
    3204      375900 :     mod_a = L_shl( a, shift_a ); // Q_a
    3205             : 
    3206             :     /* This next piece of code implements a "norm" function */
    3207             :     /* and returns the shift needed to scale "b" to have a  */
    3208             :     /* 1 in the (MSB-1) position. This is equivalent to     */
    3209             :     /* giving a value between 0.5 & 1.0.                    */
    3210      375900 :     mod_b = b;
    3211      375900 :     move32();
    3212             : 
    3213      375900 :     shift_b = 0;
    3214      375900 :     move16();
    3215      751800 :     WHILE( GT_32( mod_b, one_in_Q_b ) )
    3216             :     {
    3217      375900 :         mod_b = L_shr( mod_b, 1 );
    3218      375900 :         shift_b = sub( shift_b, 1 );
    3219             :     }
    3220             : 
    3221      375900 :     WHILE( LT_32( mod_b, half_in_Q_b ) )
    3222             :     {
    3223           0 :         mod_b = L_shl( mod_b, 1 );
    3224           0 :         shift_b = add( shift_b, 1 );
    3225             :     }
    3226             : 
    3227      375900 :     shift_b = s_and( shift_b, -2 );
    3228      375900 :     mod_b = L_shl( b, shift_b ); // Q_b
    3229             : 
    3230      375900 :     shift = shr( sub( shift_b, shift_a ), 1 );
    3231             : 
    3232      375900 :     a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a
    3233      375900 :     b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b
    3234             : 
    3235      375900 :     p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
    3236      375900 :     p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) );  // Qb-2
    3237      375900 :     p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) );   // Qb-2
    3238             : 
    3239      375900 :     p2 = Madd_32_32( Madd_32_32( p2, 501759554 /* 0.9346f in Q29*/, mod_b ), -252060893 /* -0.4695f in Q29 */, b_sqr );   // Q_b-2
    3240      375900 :     p1 = Madd_32_32( Madd_32_32( p1, -1774680487 /* -3.3056f in Q29 */, mod_b ), 891635211 /* 1.6608f in Q29 */, b_sqr ); // Q_b-2
    3241      375900 :     p0 = Madd_32_32( Madd_32_32( p0, -473251709 /* -0.8815f in Q29 */, mod_b ), 237780127 /* 0.4429f in Q29 */, b_sqr );  // Q_b-2
    3242             : 
    3243             :     /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */
    3244      375900 :     approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33
    3245      375900 :     approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) );    // Q_a+Q_b-33
    3246             : 
    3247      375900 :     exp = sub( norm_l( approx ), 1 );
    3248      375900 :     approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp
    3249             : 
    3250      375900 :     *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift );
    3251      375900 :     move16();
    3252             : 
    3253      375900 :     return approx;
    3254             : }
    3255             : 
    3256             : 
    3257             : /*===================================================================*/
    3258             : /* FUNCTION      :  fir_fx ()                     */
    3259             : /*-------------------------------------------------------------------*/
    3260             : /* PURPOSE       :  Generic FIR filter routine                       */
    3261             : /*-------------------------------------------------------------------*/
    3262             : /* INPUT ARGUMENTS  :                                                */
    3263             : /*                                                                   */
    3264             : /*   _ (Word16 []) b   : filter coefficients (Qc).                   */
    3265             : /*   _ (Word16 []) x   : input signal  (Qn).                         */
    3266             : /*   _ (Word16)    P   : filter order.                               */
    3267             : /*   _ (Word16)    N   : number of input samples.                    */
    3268             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    3269             : /*-------------------------------------------------------------------*/
    3270             : /* OUTPUT ARGUMENTS :                                                */
    3271             : /*                                                                   */
    3272             : /*   _ (Word16 []) y : output signal  (Qn)                           */
    3273             : /*-------------------------------------------------------------------*/
    3274             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3275             : /*                                                                   */
    3276             : /*   _               : None                                          */
    3277             : /*-------------------------------------------------------------------*/
    3278             : /* RETURN ARGUMENTS : _ None.                                        */
    3279             : /*===================================================================*/
    3280             : 
    3281      324596 : void fir_fx(
    3282             :     const Word16 x[], /* i  : input vector                              Qx*/
    3283             :     const Word16 h[], /* i  : impulse response of the FIR filter        Q12*/
    3284             :     Word16 y[],       /* o  : output vector (result of filtering)       Qx*/
    3285             :     Word16 mem[],     /* i/o: memory of the input signal (L samples)    Qx*/
    3286             :     const Word16 L,   /* i  : input vector size                         */
    3287             :     const Word16 K,   /* i  : order of the FIR filter (K+1 coefs.)      */
    3288             :     const Word16 upd, /* i  : 1 = update the memory, 0 = not            */
    3289             :     Word16 shift      /* i  : difference between Q15 and scaling of h[] */
    3290             : )
    3291             : {
    3292             : 
    3293             :     Word16 buf_in[L_FRAME32k + L_FILT_MAX];
    3294             :     Word16 i, j;
    3295             :     Word32 s;
    3296             : 
    3297             :     /* prepare the input buffer (copy and update memory) */
    3298      324596 :     Copy( mem, buf_in, K );
    3299      324596 :     Copy( x, buf_in + K, L );
    3300      324596 :     IF( upd )
    3301             :     {
    3302         219 :         Copy( buf_in + L, mem, K );
    3303             :     }
    3304             : 
    3305             :     /* do the filtering */
    3306   100975072 :     FOR( i = 0; i < L; i++ )
    3307             :     {
    3308   100650476 :         s = L_mult_sat( buf_in[K + i], h[0] );
    3309             : 
    3310   534361884 :         FOR( j = 1; j <= K; j++ )
    3311             :         {
    3312   433711408 :             s = L_mac_sat( s, h[j], buf_in[K + i - j] );
    3313             :         }
    3314             : 
    3315   100650476 :         s = L_shl_sat( s, shift );
    3316   100650476 :         y[i] = round_fx_sat( s ); /*Qx */
    3317   100650476 :         move16();
    3318             :     }
    3319             : 
    3320      324596 :     return;
    3321             : }
    3322             : 
    3323             : 
    3324             : /*-------------------------------------------------------------------*
    3325             :  * v_add_32()
    3326             :  *
    3327             :  * Addition of two vectors sample by sample
    3328             :  *-------------------------------------------------------------------*/
    3329             : 
    3330     7410643 : void v_add_32(
    3331             :     const Word32 x1[], /* i  : Input vector 1                       */
    3332             :     const Word32 x2[], /* i  : Input vector 2                       */
    3333             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    3334             :     const Word16 N     /* i  : Vector length                                    */
    3335             : )
    3336             : {
    3337             :     Word16 i;
    3338             : 
    3339  1212319091 :     FOR( i = 0; i < N; i++ )
    3340             :     {
    3341  1204908448 :         y[i] = L_add( x1[i], x2[i] );
    3342  1204908448 :         move32();
    3343             :     }
    3344             : 
    3345     7410643 :     return;
    3346             : }
    3347             : 
    3348      477971 : void v_shr_32(
    3349             :     Word32 x1[],    /* i  : Input vector 1                       */
    3350             :     Word32 y[],     /* o  : Output vector that contains vector 1 + vector 2  */
    3351             :     const Word16 N, /* i  : Vector length                                    */
    3352             :     Word16 shift    /*shift value*/
    3353             : )
    3354             : {
    3355             :     Word16 i;
    3356             : 
    3357   358149431 :     FOR( i = 0; i < N; i++ )
    3358             :     {
    3359   357671460 :         y[i] = L_shr( x1[i], shift );
    3360   357671460 :         move32();
    3361             :     }
    3362             : 
    3363      477971 :     return;
    3364             : }
    3365             : 
    3366             : 
    3367             : /*-------------------------------------------------------------------*
    3368             :  * v_sub_32()
    3369             :  *
    3370             :  * Subtraction of two vectors sample by sample
    3371             :  *-------------------------------------------------------------------*/
    3372             : 
    3373     2586243 : void v_sub_32(
    3374             :     const Word32 x1[], /* i  : Input vector 1                                   */
    3375             :     const Word32 x2[], /* i  : Input vector 2                                   */
    3376             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    3377             :     const Word16 N     /* i  : Vector length                                    */
    3378             : )
    3379             : {
    3380             :     Word16 i;
    3381             : 
    3382   211481087 :     FOR( i = 0; i < N; i++ )
    3383             :     {
    3384   208894844 :         y[i] = L_sub( x1[i], x2[i] );
    3385   208894844 :         move32();
    3386             :     }
    3387             : 
    3388     2586243 :     return;
    3389             : }
    3390             : 
    3391             : 
    3392             : /*-------------------------------------------------------------------*
    3393             :  * v_add_16()
    3394             :  *
    3395             :  * Addition of two vectors sample by sample
    3396             :  *-------------------------------------------------------------------*/
    3397             : 
    3398       92009 : void v_add_16(
    3399             :     const Word16 x1[], /* i  : Input vector 1                       */
    3400             :     const Word16 x2[], /* i  : Input vector 2                       */
    3401             :     Word16 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    3402             :     const Word16 N     /* i  : Vector length                                    */
    3403             : )
    3404             : {
    3405             :     Word16 i;
    3406             : 
    3407     6164307 :     FOR( i = 0; i < N; i++ )
    3408             :     {
    3409     6072298 :         y[i] = add_sat( x1[i], x2[i] );
    3410     6072298 :         move16();
    3411             :     }
    3412             : 
    3413       92009 :     return;
    3414             : }
    3415             : 
    3416             : 
    3417             : /*-------------------------------------------------------------------*
    3418             :  * v_sub_16()
    3419             :  *
    3420             :  * Subtraction of two vectors sample by sample
    3421             :  *-------------------------------------------------------------------*/
    3422             : 
    3423      287503 : void v_sub_16(
    3424             :     const Word16 x1[], /* i  : Input vector 1                                   */
    3425             :     const Word16 x2[], /* i  : Input vector 2                                   */
    3426             :     Word16 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    3427             :     const Word16 N     /* i  : Vector length                                    */
    3428             : )
    3429             : {
    3430             :     Word16 i;
    3431             : 
    3432     7780140 :     FOR( i = 0; i < N; i++ )
    3433             :     {
    3434     7492637 :         y[i] = sub_sat( x1[i], x2[i] );
    3435     7492637 :         move16();
    3436             :     }
    3437             : 
    3438      287503 :     return;
    3439             : }
    3440             : 
    3441             : 
    3442             : /*--------------------------------------------------------------------------------*/
    3443             : /* squant_fx()                                                                    */
    3444             : /*--------------------------------------------------------------------------------*/
    3445             : 
    3446             : /* o: index of the winning codeword   */
    3447     7178969 : Word16 squant_fx(
    3448             :     const Word16 x,     /* i: scalar value to quantize        */
    3449             :     Word16 *xq,         /* o: quantized value                 */
    3450             :     const Word16 cb[],  /* i: codebook                        */
    3451             :     const Word16 cbsize /* i: codebook size                   */
    3452             : )
    3453             : {
    3454             :     Word16 tmp;
    3455             :     Word16 c, idx;
    3456             :     Word32 L_mindist, L_dist;
    3457             : 
    3458     7178969 :     idx = 0;
    3459     7178969 :     move16();
    3460     7178969 :     L_mindist = MAX_32;
    3461     7178969 :     move32();
    3462             : 
    3463    35943656 :     FOR( c = 0; c < cbsize; c++ )
    3464             :     {
    3465    28764687 :         L_dist = L_deposit_l( 0 );
    3466    28764687 :         tmp = sub_sat( x, cb[c] );
    3467             : 
    3468             :         /*dist += tmp*tmp; */
    3469    28764687 :         L_dist = L_mac_sat( L_dist, tmp, tmp );
    3470             : 
    3471    28764687 :         if ( LT_32( L_dist, L_mindist ) )
    3472             :         {
    3473    16166906 :             idx = c;
    3474    16166906 :             move16();
    3475             :         }
    3476    28764687 :         L_mindist = L_min( L_mindist, L_dist );
    3477             :     }
    3478             : 
    3479     7178969 :     *xq = cb[idx];
    3480     7178969 :     move16();
    3481             : 
    3482     7178969 :     return idx;
    3483             : }
    3484             : 
    3485             : /*! r: index of the winning codeword */
    3486      935215 : Word16 squant_int_fx(
    3487             :     UWord8 x,           /* i  : scalar value to quantize  */
    3488             :     UWord8 *xq,         /* o  : quantized value           */
    3489             :     const UWord8 *cb,   /* i  : codebook                  */
    3490             :     const Word16 cbsize /* i  : codebook size             */
    3491             : )
    3492             : {
    3493             :     Word16 i, idx;
    3494             :     Word32 mindist, d;
    3495             : 
    3496      935215 :     idx = 0;
    3497      935215 :     move16();
    3498      935215 :     mindist = 10000000; // Q0
    3499      935215 :     move32();
    3500     7814441 :     FOR( i = 0; i < cbsize; i++ )
    3501             :     {
    3502     6879226 :         d = L_mult0( sub( x, cb[i] ), sub( x, cb[i] ) );
    3503     6879226 :         IF( LT_32( d, mindist ) )
    3504             :         {
    3505     3138699 :             mindist = d;
    3506     3138699 :             move32();
    3507     3138699 :             idx = i;
    3508     3138699 :             move16();
    3509             :         }
    3510             :     }
    3511      935215 :     *xq = cb[idx];
    3512      935215 :     move16();
    3513             : 
    3514      935215 :     return idx;
    3515             : }
    3516             : 
    3517             : /*===================================================================*/
    3518             : /* FUNCTION      :  pz_filter_dp_fx ()                               */
    3519             : /*-------------------------------------------------------------------*/
    3520             : /* PURPOSE       :  Generic pole-zero filter routine, with double    */
    3521             : /*                  precision memory, transposed direct form II      */
    3522             : /*-------------------------------------------------------------------*/
    3523             : /* INPUT ARGUMENTS  :                                                */
    3524             : /*                                                                   */
    3525             : /*   _ (Word16 []) b   : zero filter coefficients (Qc).              */
    3526             : /*   _ (Word16 []) a   : pole filter coefficients (Qc), a(0)=1       */
    3527             : /*   _ (Word16 []) x   : input signal (Qx).                          */
    3528             : /*   _ (Word16)    P   : filter order.                               */
    3529             : /*   _ (Word16)    N   : number of input samples.                    */
    3530             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    3531             : /*-------------------------------------------------------------------*/
    3532             : /* OUTPUT ARGUMENTS :                                                */
    3533             : /*                                                                   */
    3534             : /*   _ (Word16 []) y : output signal  (Qx)                           */
    3535             : /*-------------------------------------------------------------------*/
    3536             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3537             : /*                                                                   */
    3538             : /*   _ (Word32 []) buf : filter memory (Qx+Qc)                       */
    3539             : /*-------------------------------------------------------------------*/
    3540             : /* RETURN ARGUMENTS : _ None.                                        */
    3541             : /*===================================================================*/
    3542             : 
    3543           0 : void pz_filter_dp_fx(
    3544             :     const Word16 b[],
    3545             :     const Word16 a[],
    3546             :     Word16 x[],
    3547             :     Word16 y[],
    3548             :     Word32 buf[],
    3549             :     Word16 PNR,
    3550             :     Word16 PDR,
    3551             :     Word16 N,
    3552             :     Word16 Qa )
    3553             : {
    3554             :     Word16 i, j;
    3555             :     Word16 s;
    3556             :     Word32 s_mem;
    3557             :     Word32 Ltemp1;
    3558             :     Word32 Lacc;
    3559             : 
    3560           0 :     s = negate( Qa );
    3561           0 :     s = add( s, s ); /*  s=-2Qa */
    3562           0 :     s = add( s, 1 );
    3563           0 :     FOR( i = 0; i < N; i++ )
    3564             :     {
    3565           0 :         Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
    3566           0 :         Lacc = L_shl( Lacc, s );    /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
    3567           0 :         FOR( j = PDR - 1; j >= 0; j-- )
    3568           0 :         Lacc = Msub_32_16( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
    3569             : 
    3570           0 :         s_mem = L_shl_sat( Lacc, sub( Qa, 1 ) ); /*Qn-Qa+16=Qn+Qc*/
    3571           0 :         Lacc = L_deposit_l( 0 );
    3572           0 :         FOR( j = PNR - 1; j >= 0; j-- )
    3573           0 :         Lacc = Madd_32_16( Lacc, buf[j], b[j + 1] );
    3574           0 :         Lacc = Madd_32_16( Lacc, s_mem, b[0] );
    3575             :         /* Lacc in Q(1+Qc+Qn-Qa) */
    3576             : 
    3577           0 :         FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
    3578             :         {
    3579             :             /* Update filter memory */
    3580           0 :             buf[j] = buf[j - 1];
    3581           0 :             move16();
    3582             :         }
    3583           0 :         buf[0] = s_mem;
    3584           0 :         move16();
    3585             : 
    3586           0 :         Ltemp1 = L_shr_sat( Lacc, s ); /* Ltemp1 in Qc+Qa+Qn=Q(16+Qn) */
    3587           0 :         y[i] = extract_h( Ltemp1 );    /* y[i] in Qn */
    3588           0 :         move16();
    3589             :     }
    3590             : 
    3591           0 :     return;
    3592             : }
    3593             : 
    3594             : 
    3595             : /*-------------------------------------------------------------------*
    3596             :  * Copy_Scale_sig
    3597             :  *
    3598             :  * Up/down scale a 16 bits vector x and move it into y
    3599             :  *-------------------------------------------------------------------*/
    3600             : 
    3601    11643734 : void Copy_Scale_sig32(
    3602             :     const Word32 x[], /* i  : signal to scale input           Qx        */
    3603             :     Word32 y[],       /* o  : scaled signal output            Qx        */
    3604             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    3605             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp   */
    3606             : )
    3607             : {
    3608             :     Word16 i;
    3609             :     Word32 L_tmp;
    3610    11643734 :     Word16 tmp = exp0;
    3611             : 
    3612    11643734 :     IF( exp0 == 0 )
    3613             :     {
    3614  1189791783 :         FOR( i = 0; i < lg; i++ )
    3615             :         {
    3616  1187944810 :             y[i] = x[i];
    3617  1187944810 :             move32();
    3618             :         }
    3619     1846973 :         return;
    3620             :     }
    3621     9796761 :     IF( exp0 < 0 )
    3622             :     {
    3623   710710570 :         FOR( i = 0; i < lg; i++ )
    3624             :         {
    3625   704014051 :             y[i] = L_shl_sat( x[i], tmp );
    3626   704014051 :             move16();
    3627             :         }
    3628     6696519 :         return;
    3629             :     }
    3630             : 
    3631     3100242 :     L_tmp = L_shl_sat( 1, exp0 - 1 );
    3632             : 
    3633   397848090 :     FOR( i = 0; i < lg; i++ )
    3634             :     {
    3635   394747848 :         y[i] = W_extract_l( W_mult_32_32( L_tmp, x[i] ) );
    3636   394747848 :         move32(); /* saturation can occur here */
    3637             :     }
    3638             : 
    3639     3100242 :     return;
    3640             : }
    3641             : 
    3642             : 
    3643             : /*-------------------------------------------------------------------*
    3644             :  * Copy_Scale_sig32_16
    3645             :  *
    3646             :  * Up/down scale a 32 bits vector and round to 16 bits vector
    3647             :  *-------------------------------------------------------------------*/
    3648    14506473 : void Copy_Scale_sig32_16(
    3649             :     const Word32 *src, /* i  : signal to scale                 Qx        */
    3650             :     Word16 *dst,       /* o  : scaled signal                   Qx        */
    3651             :     Word16 len,        /* i  : size of x[]                     Q0        */
    3652             :     Word16 exp0 )      /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    3653             : {
    3654             :     Word16 i;
    3655             :     Word32 L_temp;
    3656             : 
    3657    14506473 :     IF( exp0 == 0 )
    3658             :     {
    3659   458990269 :         FOR( i = 0; i < len; i++ )
    3660             :         {
    3661   452630238 :             *dst++ = round_fx_sat( *src++ );
    3662   452630238 :             move16();
    3663             :         }
    3664     6360031 :         return;
    3665             :     }
    3666             : 
    3667  4739741277 :     FOR( i = 0; i < len; i++ )
    3668             :     {
    3669  4731594835 :         L_temp = L_shl_sat( *src++, exp0 );
    3670             : 
    3671  4731594835 :         *dst++ = round_fx_sat( L_temp );
    3672  4731594835 :         move16();
    3673             :     }
    3674             : 
    3675     8146442 :     return;
    3676             : }
    3677             : 
    3678             : /*-------------------------------------------------------------------*
    3679             :  * v_multc_att()
    3680             :  *
    3681             :  * Attenuation of a vector,, attenuation factor in Q15
    3682             :  *-------------------------------------------------------------------*/
    3683             : 
    3684        2097 : void v_multc_att(
    3685             :     const Word16 x[], /* i  : Input vector   Qx                                */
    3686             :     const Word16 att, /* i  : Constant Q15, <= MAX_16                          */
    3687             :     Word16 y[],       /* o  : Output vector that contains att*x                */
    3688             :     const Word16 N    /* i  : Vector length                                    */
    3689             : )
    3690             : {
    3691             :     Word16 i;
    3692        2097 :     IF( LT_16( att, 32767 ) )
    3693             :     {
    3694           0 :         FOR( i = 0; i < N; i++ )
    3695             :         {
    3696           0 :             y[i] = mult_r( x[i], att );
    3697           0 :             move16();
    3698             :         }
    3699             :     }
    3700             : 
    3701        2097 :     return;
    3702             : }
    3703             : 
    3704             : 
    3705             : /*-------------------------------------------------------------------*
    3706             :  * v_multc_att32()
    3707             :  *
    3708             :  * Attenuation of a vector,, attenuation factor in Q15
    3709             :  *-------------------------------------------------------------------*/
    3710             : 
    3711        1307 : void v_multc_att32(
    3712             :     const Word32 x[], /* i  : Input vector   Qx                                */
    3713             :     const Word16 att, /* i  : Constant Q15, <= MAX_16                          */
    3714             :     Word32 y[],       /* o  : Output vector that contains att*x                */
    3715             :     const Word16 N    /* i  : Vector length                                    */
    3716             : )
    3717             : {
    3718             :     Word16 i;
    3719        1307 :     IF( LT_16( att, 32767 ) )
    3720             :     {
    3721           0 :         FOR( i = 0; i < N; i++ )
    3722             :         {
    3723           0 :             y[i] = Mpy_32_16_r( x[i], att );
    3724           0 :             move32();
    3725             :         }
    3726             :     }
    3727             : 
    3728        1307 :     return;
    3729             : }
    3730             : 
    3731             : /*-------------------------------------------------------------------*
    3732             :  * v_multc_att3232()
    3733             :  *
    3734             :  * Attenuation of a vector, attenuation factor in Q31
    3735             :  *-------------------------------------------------------------------*/
    3736             : 
    3737           0 : void v_multc_att3232(
    3738             :     const Word32 x[], /* i  : Input vector   Qx                                */
    3739             :     const Word32 att, /* i  : Constant Q32, <= MAX_32                          */
    3740             :     Word32 y[],       /* o  : Output vector that contains att*x                */
    3741             :     const Word16 N    /* i  : Vector length                                    */
    3742             : )
    3743             : {
    3744             :     Word16 i;
    3745           0 :     IF( LE_32( att, MAX_32 ) )
    3746             :     {
    3747           0 :         FOR( i = 0; i < N; i++ )
    3748             :         {
    3749           0 :             y[i] = Mpy_32_32_r( x[i], att );
    3750           0 :             move32();
    3751             :         }
    3752             :     }
    3753             : 
    3754           0 :     return;
    3755             : }
    3756             : 
    3757             : /*-------------------------------------------------------------------*
    3758             :  * v_L_mult_1616()
    3759             :  *
    3760             :  * Multiplication of two vectors, Output in Word32
    3761             :  *-------------------------------------------------------------------*/
    3762             : 
    3763           0 : void v_L_mult_1616(
    3764             :     const Word16 x1[], /* i  : Input vector 1                                   */
    3765             :     const Word16 x2[], /* i  : Input vector 2                                   */
    3766             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    3767             :     const Word16 N     /* i  : Vector length                                    */
    3768             : )
    3769             : {
    3770             :     Word16 i;
    3771             : 
    3772           0 :     for ( i = 0; i < N; i++ )
    3773             :     {
    3774           0 :         y[i] = L_mult( x1[i], x2[i] );
    3775           0 :         move32();
    3776             :     }
    3777             : 
    3778           0 :     return;
    3779             : }
    3780             : 
    3781             : /*-------------------------------------------------------------------*
    3782             :  * v_L_mult_3216()
    3783             :  *
    3784             :  * Multiplication of two vectors, Output in Word32
    3785             :  *-------------------------------------------------------------------*/
    3786             : 
    3787      139327 : void v_L_mult_3216(
    3788             :     const Word32 x1[], /* i  : Input vector 1                                   */
    3789             :     const Word16 x2[], /* i  : Input vector 2                                   */
    3790             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    3791             :     const Word16 N     /* i  : Vector length                                    */
    3792             : )
    3793             : {
    3794             :     Word16 i;
    3795             : 
    3796    82395071 :     for ( i = 0; i < N; i++ )
    3797             :     {
    3798    82255744 :         y[i] = Mpy_32_16_1( x1[i], x2[i] );
    3799    82255744 :         move32();
    3800             :     }
    3801             : 
    3802      139327 :     return;
    3803             : }
    3804             : 
    3805             : /*-------------------------------------------------------------------*
    3806             :  * add_vec()
    3807             :  *
    3808             :  * Addition of two vectors sample by sample
    3809             :  *-------------------------------------------------------------------*/
    3810             : 
    3811        3367 : void add_vec_fx(
    3812             :     const Word16 x1[], /* i  : Input vector 1                       */
    3813             :     const Word16 Qx1,  /* i  : SCaling of input 1                    */
    3814             :     const Word16 x2[], /* i  : Input vector 2                       */
    3815             :     const Word16 Qx2,  /* i  : SCaling of input 1                    */
    3816             :     Word16 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    3817             :     const Word16 Qy,   /* i  : SCaling of output 1                    */
    3818             :     const Word16 N     /* i  : Vector lenght                                    */
    3819             : )
    3820             : {
    3821             :     Word16 i, Qyx1, Qyx2;
    3822             : 
    3823        3367 :     Qyx1 = sub( Qx1, Qy );
    3824        3367 :     Qyx2 = sub( Qx2, Qy );
    3825        3367 :     IF( Qyx1 == 0 )
    3826             :     {
    3827     2996007 :         FOR( i = 0; i < N; i++ )
    3828             :         {
    3829     2992640 :             y[i] = add_sat( x1[i], shr_r_sat( x2[i], Qyx2 ) );
    3830     2992640 :             move16();
    3831             :         }
    3832             :     }
    3833             :     ELSE
    3834             :     {
    3835           0 :         FOR( i = 0; i < N; i++ )
    3836             :         {
    3837           0 :             y[i] = add_sat( shr_r_sat( x1[i], Qyx1 ), shr_r_sat( x2[i], Qyx2 ) ); //!!sat //!!sat
    3838           0 :             move16();
    3839             :         }
    3840             :     }
    3841             : 
    3842        3367 :     return;
    3843             : }
    3844             : 
    3845             : 
    3846             : /*-------------------------------------------------------------------*
    3847             :  *  Add_flt32_flt32
    3848             :  *
    3849             :  *  Add two Pseudo Float Value that are 32 Bits Mantisa and 16 Bits Exp
    3850             :  *-------------------------------------------------------------------*/
    3851             : 
    3852             : /* o: Result (Normalized)                */
    3853        5392 : Word32 Add_flt32_flt32(
    3854             :     Word32 a,       /* i: 1st Value                          */
    3855             :     Word16 exp_a,   /* i: Exponent of 1st Value (Q of Value) */
    3856             :     Word32 b,       /* i: 2nd Value                          */
    3857             :     Word16 exp_b,   /* i: Exponent of 2nd Value (Q of Value) */
    3858             :     Word16 *exp_out /* o: Exponent of Result                 */
    3859             : )
    3860             : {
    3861             :     Word16 temp, temp2;
    3862             :     Word32 L_temp;
    3863             : 
    3864             :     /* Subract 1 to further divide by 2 to avoid overflow on L_add */
    3865        5392 :     temp = sub( s_min( exp_a, exp_b ), 1 );
    3866             : 
    3867             :     /* Put both to same exponent */
    3868        5392 :     exp_a = sub( exp_a, temp );
    3869        5392 :     a = L_shr( a, exp_a );
    3870        5392 :     exp_b = sub( exp_b, temp );
    3871        5392 :     b = L_shr( b, exp_b );
    3872             : 
    3873             :     /* add them together */
    3874        5392 :     L_temp = L_add( a, b );
    3875        5392 :     temp2 = norm_l( L_temp );
    3876             : 
    3877        5392 :     *exp_out = add( temp, temp2 );
    3878        5392 :     move16();
    3879             : 
    3880        5392 :     return L_shl( L_temp, temp2 );
    3881             : }
    3882             : 
    3883             : 
    3884             : /*-------------------------------------------------------------------*
    3885             :  *  Mul_flt32_Q15
    3886             :  *
    3887             :  *  Multiply one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
    3888             :  *  with a Q15 value
    3889             :  *-------------------------------------------------------------------*/
    3890             : 
    3891             : /*  o: Result (Normalized)            */
    3892           0 : Word32 Mul_flt32_Q15(
    3893             :     Word32 value,  /*  i: Pseudo_float Value             */
    3894             :     Word16 *exp_v, /*i/o: Exponent of Value (Q of Value) */
    3895             :     Word16 frac    /*  i: Q15 value                      */
    3896             : )
    3897             : {
    3898             :     Word16 temp;
    3899             :     Word32 L_temp;
    3900             : 
    3901           0 :     L_temp = Mult_32_16( value, frac );
    3902           0 :     temp = norm_l( L_temp );
    3903             : 
    3904           0 :     *exp_v = add( temp, *exp_v );
    3905           0 :     move16();
    3906             : 
    3907           0 :     return L_shl( L_temp, temp );
    3908             : }
    3909             : 
    3910             : 
    3911             : /*-------------------------------------------------------------------*
    3912             :  *  Div_flt32_flt32
    3913             :  *
    3914             :  *  Divide one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
    3915             :  *  by another one
    3916             :  *-------------------------------------------------------------------*/
    3917             : 
    3918             : /* o: Result (Normalized)                */
    3919           3 : Word32 Div_flt32_flt32(
    3920             :     Word32 a,       /* i: 1st Value                          */
    3921             :     Word16 exp_a,   /* i: Exponent of 1st Value (Q of Value) */
    3922             :     Word32 b,       /* i: 2nd Value                          */
    3923             :     Word16 exp_b,   /* i: Exponent of 2nd Value (Q of Value) */
    3924             :     Word16 *exp_out /* o: Exponent of Result                 */
    3925             : )
    3926             : {
    3927             :     Word16 temp, temp2;
    3928             :     Word32 L_temp;
    3929             : 
    3930           3 :     temp = div_s( 16384, round_fx( b ) );
    3931           3 :     L_temp = Mult_32_16( a, temp );
    3932           3 :     temp2 = sub( 31 - 1, exp_b );
    3933           3 :     temp2 = add( temp2, exp_a );
    3934             : 
    3935           3 :     temp = norm_l( L_temp );
    3936             : 
    3937           3 :     *exp_out = add( temp, temp2 );
    3938           3 :     move16();
    3939             : 
    3940           3 :     return L_shl( L_temp, temp );
    3941             : }
    3942             : 
    3943             : 
    3944             : /*-------------------------------------------------------------------*
    3945             :  *  Calc_Energy_Autoscaled
    3946             :  *
    3947             :  *  Calculate Energy with overflow protection
    3948             :  *-------------------------------------------------------------------*/
    3949             : 
    3950             : /* o: Result (Energy)                  */
    3951     4491535 : Word32 Calc_Energy_Autoscaled(
    3952             :     const Word16 *signal, /* i: Signal                           */
    3953             :     Word16 signal_exp,    /* i: Exponent of Signal (Q of Signal) */
    3954             :     Word16 len,           /* i: Frame Length                     */
    3955             :     Word16 *energy_exp    /* o: Exponent of Energy (Q of Energy) */
    3956             : )
    3957             : {
    3958             :     Word16 temp, temp2;
    3959             :     Word32 L_temp, L_Energy;
    3960             :     Word16 i, j;
    3961     4491535 :     Flag Overflow = 0;
    3962     4491535 :     move32();
    3963             : 
    3964     4491535 :     Overflow = 0;
    3965     4491535 :     move16();
    3966             : 
    3967     4491535 :     temp2 = 0;
    3968     4491535 :     move16();
    3969     4491535 :     L_Energy = L_deposit_l( 1 );
    3970     4491535 :     j = s_and( 7, len );
    3971     4503375 :     FOR( i = 0; i < j; i++ )
    3972             :     {
    3973             :         /* divide by 2 so energy will be divided by 4 */
    3974       11840 :         temp = mult_r( *signal++, 16384 );
    3975       11840 :         L_Energy = L_mac0_o( L_Energy, temp, temp, &Overflow );
    3976             :     }
    3977    14748257 :     FOR( i = j; i < len; i += 8 ) /* Process 8 Samples at a time */
    3978             :     {
    3979             :         /* divide by 2 so energy will be divided by 4 */
    3980    10256722 :         temp = mult_ro( *signal++, 16384, &Overflow );
    3981    10256722 :         L_temp = L_mult0( temp, temp );
    3982    82053776 :         FOR( j = 1; j < 8; j++ )
    3983             :         {
    3984    71797054 :             temp = mult_r( *signal++, 16384 );
    3985    71797054 :             L_temp = L_mac0_o( L_temp, temp, temp, &Overflow );
    3986             :         }
    3987             :         /*Overfloe will never happen because temp2 is always positive*/
    3988    10256722 :         L_temp = L_shr( L_temp, temp2 );
    3989             :         /* Here we try the addition just to check if we can sum
    3990             :            the energy of the small (8 Iterations) loop with the
    3991             :            total energy calculated so far without an overflow.
    3992             :            The result is discarded. If there is an overflow both
    3993             :            energies are div by 2. Otherwise, nothing is done.
    3994             :            After the 'IF', the sum is done again and will always
    3995             :            be without an overflow. */
    3996    10256722 :         L_add_o( L_Energy, L_temp, &Overflow );
    3997    10256722 :         IF( Overflow != 0 )
    3998             :         {
    3999          56 :             L_Energy = L_shr( L_Energy, 1 );
    4000          56 :             L_temp = L_shr( L_temp, 1 );
    4001          56 :             temp2 = add( temp2, 1 );
    4002          56 :             Overflow = 0;
    4003          56 :             move16();
    4004             :         }
    4005    10256722 :         L_Energy = L_add_o( L_Energy, L_temp, &Overflow );
    4006             :     }
    4007             :     /* Calc Final Exponent (sub 2 because of the mult_r by 16384 that already divs the ener by 4) */
    4008     4491535 :     temp2 = sub( sub( shl( signal_exp, 1 ), temp2 ), 2 );
    4009             : 
    4010     4491535 :     *energy_exp = temp2;
    4011     4491535 :     move16();
    4012             : 
    4013     4491535 :     return L_Energy;
    4014             : }
    4015             : 
    4016     5135419 : Word16 Find_Max_Norm16(
    4017             :     const Word16 *src,
    4018             :     Word16 len )
    4019             : {
    4020             :     Word16 i;
    4021             :     Word16 max16;
    4022             : 
    4023             :     /* it starts at '0' and not '1' like in Find_Max_Norm32() */
    4024             :     /* and that is necessary. */
    4025     5135419 :     max16 = 0;
    4026     5135419 :     move16();
    4027             : 
    4028  3046653979 :     FOR( i = 0; i < len; i++ )
    4029             :     {
    4030  3041518560 :         max16 = s_max( max16, abs_s( *src++ ) );
    4031             :     }
    4032             : 
    4033     5135419 :     return norm_s( max16 );
    4034             : }
    4035             : 
    4036     4930323 : Word16 Find_Max_Norm32(
    4037             :     const Word32 *src,
    4038             :     Word16 len )
    4039             : {
    4040             :     Word16 i;
    4041             :     Word32 max32;
    4042             : 
    4043     4930323 :     max32 = L_deposit_l( 1 );
    4044             : 
    4045  3870176335 :     FOR( i = 0; i < len; i++ )
    4046             :     {
    4047  3865246012 :         max32 = L_max( max32, L_abs( *src++ ) );
    4048             :     }
    4049             : 
    4050     4930323 :     return norm_l( max32 );
    4051             : }
    4052             : 
    4053             : 
    4054             : /*-------------------------------------------------------------------*
    4055             :  *  Sqrt_Ratio32
    4056             :  *
    4057             :  *  Calculate Sqrt of Val1/Val2
    4058             :  *-------------------------------------------------------------------*/
    4059             : 
    4060             : /* o: Result in Q31 */
    4061        5529 : Word32 Sqrt_Ratio32(
    4062             :     Word32 L_val1, /* i: Mantisa of Val1                                          */
    4063             :     Word16 exp1,   /* i: Exp of Val1 (>0: Val was Left Shifted, <0:Right Shifted) */
    4064             :     Word32 L_val2, /* i: Mantisa of Val2                                          */
    4065             :     Word16 exp2,   /* i: Exp of Val2 (same as exp1)                               */
    4066             :     Word16 *exp    /* o: Exp of Result (# of 'L_shl' Req to get to Final Value)   */
    4067             : )
    4068             : {
    4069             :     Word16 temp;
    4070             : 
    4071             :     /* Normalize Energy #1 */
    4072        5529 :     temp = norm_l( L_val1 );
    4073        5529 :     L_val1 = L_shl( L_val1, temp );
    4074             :     /* Adjust Exponent of Energy #1 */
    4075        5529 :     exp1 = add( exp1, temp );
    4076             : 
    4077             :     /* Normalize Energy #2 */
    4078        5529 :     temp = norm_l( L_val2 );
    4079        5529 :     L_val2 = L_shl( L_val2, temp );
    4080             :     /* Adjust Exponent of Energy #1 */
    4081        5529 :     exp2 = add( exp2, temp );
    4082             : 
    4083             :     /* Prepare for Inverse */
    4084        5529 :     temp = round_fx_sat( L_val1 );
    4085        5529 :     temp = div_s( 16384, temp );
    4086             :     /* Mult Now */
    4087        5529 :     L_val2 = Mult_32_16( L_val2, temp );
    4088        5529 :     exp1 = add( sub( exp2, exp1 ), 15 * 2 );
    4089             : 
    4090             :     /* Here Result of ('L_val2' / 2^'exp2') / ('L_val1' / 2^'exp1') is */
    4091             :     /* 'L_val2' / 2^'exp1' */
    4092             :     /* Which is val2/val1 instead of val1/val2 because we will use Inverted Square Root */
    4093             :     /* Normalize before Square Root */
    4094        5529 :     temp = norm_l( L_val2 );
    4095        5529 :     L_val2 = L_shl( L_val2, temp );
    4096        5529 :     exp1 = add( temp, exp1 );
    4097             :     /* Do Sqrt */
    4098        5529 :     temp = sub( 31, exp1 );
    4099        5529 :     L_val1 = Isqrt_lc( L_val2, &temp );
    4100             : 
    4101        5529 :     *exp = temp;
    4102        5529 :     move16();
    4103             : 
    4104        5529 :     return L_val1;
    4105             : }
    4106             : 
    4107             : /* result in Q'15 + 'exp' */
    4108        4430 : Word16 Invert16(
    4109             :     Word16 val,
    4110             :     Word16 *exp )
    4111             : {
    4112             :     Word16 temp;
    4113             : 
    4114             :     /* prevent 0 input */
    4115        4430 :     val = s_max( val, 1 );
    4116             :     /* Normalize Value */
    4117        4430 :     temp = norm_s( val );
    4118        4430 :     val = shl( val, temp );
    4119             : 
    4120        4430 :     *exp = sub( sub( 15 - 1, *exp ), temp );
    4121        4430 :     move16(); /* -1 because of 0x4000 is 1.0 in Q14 (and not Q15) */
    4122             : 
    4123        4430 :     temp = div_s( 0x4000, val );
    4124             : 
    4125        4430 :     return temp;
    4126             : }
    4127             : 
    4128           0 : Word16 find_rem(
    4129             :     Word16 n,
    4130             :     Word16 m,
    4131             :     Word16 *r )
    4132             : {
    4133             :     Word16 i, q1, q2, qd;
    4134             :     Word32 Ltemp2;
    4135             :     Word32 Lacc;
    4136             : 
    4137           0 :     test();
    4138           0 :     test();
    4139           0 :     IF( n <= 0 || m <= 0 || n < m )
    4140             :     {
    4141           0 :         *r = n;
    4142           0 :         move16();
    4143           0 :         return ( 0 );
    4144             :     }
    4145             : 
    4146           0 :     q1 = norm_s( n );
    4147           0 :     q1 = sub( q1, 1 );
    4148           0 :     Lacc = L_deposit_h( shl( n, q1 ) );
    4149           0 :     qd = sub( q1, 1 );
    4150           0 :     q2 = norm_s( m );
    4151           0 :     q2 = sub( q2, 1 );
    4152           0 :     Ltemp2 = L_deposit_h( shl( m, q2 ) );
    4153           0 :     qd = sub( q2, qd );
    4154           0 :     q2 = add( q2, 1 );
    4155             : 
    4156           0 :     FOR( i = 0; i < qd; i++ )
    4157             :     {
    4158           0 :         Lacc = L_sub( Lacc, Ltemp2 );
    4159           0 :         IF( Lacc >= 0 )
    4160             :         {
    4161           0 :             Lacc = L_add( L_shl( Lacc, 1 ), 1 );
    4162             :         }
    4163             :         ELSE
    4164             :         {
    4165           0 :             Lacc = L_add( Lacc, Ltemp2 );
    4166           0 :             Lacc = L_shl( Lacc, 1 );
    4167             :         }
    4168             :     }
    4169           0 :     q1 = extract_l( Lacc );
    4170           0 :     Ltemp2 = L_shr( Lacc, q2 );
    4171           0 :     *r = extract_h( Ltemp2 );
    4172           0 :     move16();
    4173             : 
    4174           0 :     return ( q1 );
    4175             : }
    4176             : 
    4177             : 
    4178           0 : Word32 find_remd(
    4179             :     Word32 n,
    4180             :     Word32 m,
    4181             :     Word32 *r )
    4182             : {
    4183             :     Word16 i, q1, q2, qd;
    4184             :     Word32 Ltemp2, qo;
    4185             :     Word32 Lacc;
    4186             : 
    4187           0 :     test();
    4188           0 :     test();
    4189           0 :     IF( n <= 0 || m <= 0 || n < m )
    4190             :     {
    4191           0 :         *r = n;
    4192           0 :         move16();
    4193           0 :         return ( 0 );
    4194             :     }
    4195             : 
    4196           0 :     q1 = norm_l( n );
    4197           0 :     q1 = sub( q1, 1 );
    4198           0 :     Lacc = L_shl( n, q1 );
    4199           0 :     qd = sub( q1, 1 );
    4200           0 :     q2 = norm_l( m );
    4201           0 :     q2 = sub( q2, 1 );
    4202           0 :     Ltemp2 = L_shl( m, q2 );
    4203           0 :     qd = sub( q2, qd );
    4204           0 :     q2 = add( q2, 1 );
    4205           0 :     qo = 0;
    4206           0 :     move16();
    4207             : 
    4208           0 :     FOR( i = 0; i < qd; i++ )
    4209             :     {
    4210           0 :         Lacc = L_sub( Lacc, Ltemp2 );
    4211           0 :         qo = L_shl( qo, 1 );
    4212           0 :         IF( Lacc >= 0 )
    4213             :         {
    4214           0 :             Lacc = L_shl( Lacc, 1 );
    4215           0 :             qo = L_add( qo, 1 );
    4216             :         }
    4217             :         ELSE
    4218             :         {
    4219           0 :             Lacc = L_add( Lacc, Ltemp2 );
    4220           0 :             Lacc = L_shl( Lacc, 1 );
    4221             :         }
    4222             :     }
    4223           0 :     *r = L_shr( Lacc, q2 );
    4224           0 :     move16();
    4225             : 
    4226           0 :     return ( qo );
    4227             : }
    4228             : 
    4229             : 
    4230      101969 : Word16 rint_new_fx(
    4231             :     Word32 x /*Q16 */
    4232             : )
    4233             : {
    4234             :     Word16 a;
    4235             :     Word32 L_tmp;
    4236             :     Word16 frac, tmp;
    4237             : 
    4238             :     /* middle value point test */
    4239      101969 :     frac = lshr( extract_l( x ), 1 ); /*Q15 */
    4240      101969 :     tmp = sub( frac, 0x4000 );
    4241             : 
    4242      101969 :     IF( !tmp )
    4243             :     {
    4244           0 :         a = add( extract_h( x ), 1 );
    4245             : 
    4246           0 :         IF( s_and( a, 1 ) == 0 )
    4247             :         {
    4248           0 :             return a;
    4249             :         }
    4250           0 :         IF( s_and( a, 1 ) != 0 )
    4251             :         {
    4252           0 :             return extract_h( x );
    4253             :         }
    4254           0 :         return extract_h( x );
    4255             :     }
    4256             :     ELSE
    4257             :     {
    4258      101969 :         L_tmp = L_add( x, 32768 ); /*Q16 */
    4259      101969 :         return extract_h( L_tmp );
    4260             :     }
    4261             : }
    4262             : 
    4263             : 
    4264             : /*===================================================================*/
    4265             : /* FUNCTION      :  erb_diff_search_fx ()                            */
    4266             : /*-------------------------------------------------------------------*/
    4267             : /* PURPOSE       :  erb amplitude VQ search for QPPP                 */
    4268             : /*-------------------------------------------------------------------*/
    4269             : /* INPUT ARGUMENTS  :                                                */
    4270             : /*   _ (Word16 []) prev_erb : Previous erb amplitude, Q13            */
    4271             : /*   _ (Word16 []) curr_erb : Current erb amplitude, Q13             */
    4272             : /*   _ (Word16 []) dif_erb: erb differential, Q13                    */
    4273             : /*   _ (Word16 []) pow_spec : LPC power spectrum, Q7                 */
    4274             : /*   _ (Word16 [][]) cb_fx : differential erb codebook, Q13          */
    4275             : /*   _ (Word16) cb_size :  codebook size                             */
    4276             : /*   _ (Word16) cb_dim :  codebook dimension                         */
    4277             : /*   _ (Word16) offset :  index to current segment of erb array      */
    4278             : /*                        for quantization                           */
    4279             : /*-------------------------------------------------------------------*/
    4280             : /* OUTPUT ARGUMENTS :                                                */
    4281             : /*                    _ None                                         */
    4282             : /*-------------------------------------------------------------------*/
    4283             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    4284             : /*                    _ None                                         */
    4285             : /*-------------------------------------------------------------------*/
    4286             : /* RETURN ARGUMENTS :                                                */
    4287             : /*   _ (Word16) index: best codebook index                           */
    4288             : /*-------------------------------------------------------------------*/
    4289             : /* CALLED FROM : TX                                                  */
    4290             : /*===================================================================*/
    4291             : 
    4292           0 : Word16 erb_diff_search_fx(
    4293             :     Word16 *prev_erb,
    4294             :     const Word16 *curr_erb,
    4295             :     Word16 *dif_erb,
    4296             :     Word16 *pow_spec,
    4297             :     const Word16 *cb_fx,
    4298             :     Word16 cb_size,
    4299             :     Word16 cb_dim,
    4300             :     Word16 offset )
    4301             : {
    4302             :     Word16 i, j, mmseindex;
    4303             :     Word16 dh, dl;
    4304             :     Word32 mmse;
    4305             :     Word32 Ltemp1;
    4306             :     Word32 Lacc;
    4307             : 
    4308           0 :     mmse = EVS_LW_MAX;
    4309           0 :     move32();
    4310           0 :     mmseindex = -1;
    4311           0 :     move16();
    4312           0 :     FOR( j = 0; j < cb_size; j++ )
    4313             :     {
    4314             : 
    4315           0 :         Lacc = L_deposit_l( 0 );
    4316           0 :         FOR( i = 0; i < cb_dim; i++ )
    4317             :         {
    4318           0 :             IF( add_sat( cb_fx[j * cb_dim + i], prev_erb[i + offset] ) < 0 )
    4319             :             {
    4320           0 :                 Ltemp1 = L_mult( curr_erb[i + offset], curr_erb[i + offset] ); /* Q27 */
    4321           0 :                 dh = extract_h( Ltemp1 );
    4322           0 :                 dl = extract_l( Ltemp1 );
    4323           0 :                 IF( dl < 0 )
    4324             :                 {
    4325           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    4326           0 :                     Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
    4327           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    4328             :                 }
    4329             :                 ELSE
    4330             :                 {
    4331           0 :                     Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl );
    4332             :                 }
    4333           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) );
    4334             :             }
    4335             :             ELSE
    4336             :             {
    4337           0 :                 dh = sub_sat( dif_erb[i + offset], cb_fx[j * cb_dim + i] ); /* Q13 */
    4338           0 :                 Ltemp1 = L_mult_sat( dh, dh );                              /* Q27 */
    4339           0 :                 dh = extract_h( Ltemp1 );
    4340           0 :                 dl = extract_l( Ltemp1 );
    4341             : 
    4342           0 :                 IF( dl < 0 )
    4343             :                 {
    4344           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    4345           0 :                     Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
    4346           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    4347             :                 }
    4348             :                 ELSE
    4349             :                 {
    4350           0 :                     Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl ); /* Q33 */
    4351             :                 }
    4352             : 
    4353           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) ); /* Q18 */
    4354             :             }
    4355             : 
    4356           0 :             IF( LT_16( cb_fx[j * cb_dim + i], dif_erb[i + offset] ) )
    4357             :             {
    4358           0 :                 dh = extract_h( Ltemp1 );
    4359           0 :                 dl = extract_l( Ltemp1 );
    4360           0 :                 IF( dl < 0 )
    4361             :                 {
    4362           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    4363           0 :                     Ltemp1 = Mult_32_16( Ltemp1, 29491 );
    4364           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    4365             :                 }
    4366             :                 ELSE
    4367             :                 {
    4368           0 :                     Ltemp1 = (Word32) L_mult0( 29491, dl ); /* 29491=0.9 in Q15 */
    4369             :                 }
    4370           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( dh, 29491 ) );
    4371             :             }
    4372           0 :             Lacc = L_add( Lacc, Ltemp1 ); /* Q18 */
    4373             :         }
    4374             : 
    4375           0 :         IF( LT_32( Lacc, mmse ) )
    4376             :         {
    4377           0 :             mmse = L_add( Lacc, 0 );
    4378           0 :             mmseindex = j;
    4379           0 :             move16();
    4380             :         }
    4381             :     }
    4382             : 
    4383           0 :     return ( mmseindex );
    4384             : }
    4385             : 
    4386             : 
    4387      638137 : void Acelp_dec_total_exc(
    4388             :     Word16 *exc_fx,           /* i/o: adapt. excitation exc       */
    4389             :     Word16 *exc2_fx,          /* i/o: adapt. excitation/total exc */
    4390             :     const Word16 gain_code16, /* i  : Gain code Q0                */
    4391             :     const Word16 gain_pit_fx, /* i  ; Pitch gain in Q14           */
    4392             :     const Word16 i_subfr,     /* i  ; subfr                       */
    4393             :     const Word16 *code_fx,    /* i  : code in Q9                  */
    4394             :     const Word16 L_subfr      /* i  : Subframne lenght            */
    4395             : )
    4396             : {
    4397             :     Word16 i;
    4398             :     Word32 L_tmp;
    4399             : 
    4400    41479545 :     FOR( i = 0; i < L_subfr; i++ )
    4401             :     {
    4402    40841408 :         L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr] ), 1 );            /*Q16+Q_exc*/
    4403    40841408 :         exc2_fx[i + i_subfr] = round_fx_sat( L_tmp );                                  /*Q_exc*/
    4404    40841408 :         L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
    4405    40841408 :         exc_fx[i + i_subfr] = round_fx_sat( L_tmp );                                   /*Q_exc*/
    4406    40841408 :         move16();
    4407    40841408 :         move16();
    4408             :     }
    4409             : 
    4410      638137 :     return;
    4411             : }
    4412             : 
    4413             : 
    4414             : /*-------------------------------------------------------------------*
    4415             :  *  UL_inverse
    4416             :  *
    4417             :  *  Calculate inverse of UL_val. Output in Q_exp.
    4418             :  *-------------------------------------------------------------------*/
    4419             : 
    4420      757588 : UWord32 UL_inverse(
    4421             :     const UWord32 UL_val,
    4422             :     Word16 *exp )
    4423             : {
    4424             :     UWord32 UL_tmp;
    4425             : 
    4426      757588 :     *exp = norm_ul( UL_val );
    4427      757588 :     move16();
    4428      757588 :     UL_tmp = UL_lshl( UL_val, *exp ); /* Q32 */
    4429             : 
    4430      757588 :     *exp = add( 32, sub( 31, *exp ) );
    4431      757588 :     move16();
    4432             : 
    4433      757588 :     return UL_div( 0x80000000, UL_tmp );
    4434             : }
    4435             : 
    4436             : /*-------------------------------------------------------------------*
    4437             :  *  UL_div
    4438             :  *
    4439             :  *  Calculate UL_num/UL_den. UL_num assumed to be Q31, UL_den assumed
    4440             :  *  to be Q32, then result is in Q32.
    4441             :  *-------------------------------------------------------------------*/
    4442             : 
    4443     1133549 : UWord32 UL_div(
    4444             :     const UWord32 UL_num,
    4445             :     const UWord32 UL_den )
    4446             : {
    4447             :     UWord32 UL_e, UL_Q;
    4448             :     UWord32 UL_msb, UL_lsb;
    4449             :     Word16 i;
    4450             : 
    4451     1133549 :     UL_e = UL_subNsD( 0xffffffff, UL_den );
    4452     1133549 :     UL_Q = UL_num;
    4453     1133549 :     move32();
    4454             : 
    4455     6801294 :     FOR( i = 0; i < 5; i++ )
    4456             :     {
    4457     5667745 :         Mpy_32_32_uu( UL_Q, UL_e, &UL_msb, &UL_lsb ); /*31+32-32=31 */
    4458     5667745 :         UL_Q = UL_addNsD( UL_Q, UL_msb );
    4459     5667745 :         Mpy_32_32_uu( UL_e, UL_e, &UL_e, &UL_lsb ); /*32+32-32=32 */
    4460             :     }
    4461             : 
    4462     1133549 :     return UL_Q;
    4463             : }
    4464             : 
    4465             : /*-----------------------------------------------------------------------------
    4466             :  * ratio()
    4467             :  *
    4468             :  * Divide the numerator by the denominator.
    4469             :  *----------------------------------------------------------------------------*/
    4470     7891062 : Word16 ratio( const Word32 numer, const Word32 denom, Word16 *expo )
    4471             : {
    4472             :     Word16 expNumer, expDenom;
    4473             :     Word16 manNumer, manDenom;
    4474             :     Word16 quotient;
    4475             : 
    4476     7891062 :     expDenom = norm_l( denom );                       /* exponent */
    4477     7891062 :     manDenom = extract_h( L_shl( denom, expDenom ) ); /* mantissa */
    4478     7891062 :     expNumer = norm_l( numer );                       /* exponent */
    4479     7891062 :     manNumer = extract_h( L_shl( numer, expNumer ) ); /* mantissa */
    4480     7891062 :     manNumer = shr( manNumer, 1 );                    /* Ensure the numerator < the denominator */
    4481     7891062 :     quotient = div_s( manNumer, manDenom );           /* in Q14 */
    4482             : 
    4483     7891062 :     *expo = sub( expNumer, expDenom );
    4484     7891062 :     move16();
    4485             : 
    4486     7891062 :     return quotient; /* Q14 */
    4487             : }
    4488             : 
    4489             : 
    4490             : /*-----------------------------------------------------------------------*
    4491             :  * Function hp400_12k8()                                                 *
    4492             :  *                                                                       *
    4493             :  * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz.    *
    4494             :  * Optimized for fixed-point to get the following frequency response  :  *
    4495             :  *                                                                       *
    4496             :  *  frequency  :   0Hz   100Hz  200Hz  300Hz  400Hz  630Hz  1.5kHz  3kHz *
    4497             :  *  dB loss  :   -infdB  -30dB  -20dB  -10dB  -3dB   +6dB    +1dB    0dB *
    4498             :  *                                                                       *
    4499             :  * Algorithm  :                                                          *
    4500             :  *                                                                       *
    4501             :  *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]                         *
    4502             :  *                   + a[1]*y[i-1] + a[2]*y[i-2];                        *
    4503             :  *                                                                       *
    4504             :  *  short b[3] = {3660, -7320,  3660};       in Q12                      *
    4505             :  *  short a[3] = {4096,  7320, -3540};       in Q12                      *
    4506             :  *                                                                       *
    4507             :  *  float -->   b[3] = {0.893554687, -1.787109375,  0.893554687};        *
    4508             :  *              a[3] = {1.000000000,  1.787109375, -0.864257812};        *
    4509             :  *-----------------------------------------------------------------------*/
    4510             : 
    4511           0 : void hp400_12k8_fx(
    4512             :     Word16 signal[], /* i/o: input signal / output is divided by 16 */
    4513             :     const Word16 lg, /* i  : lenght of signal                       */
    4514             :     Word16 mem[]     /* i/o: filter memory [6]                      */
    4515             : )
    4516             : {
    4517             :     Word16 i;
    4518             :     Word16 y1_hi, y1_lo;
    4519             :     Word32 L_tmp, L_tmp2, L_tmp3;
    4520             : 
    4521           0 :     y1_hi = mem[2];
    4522           0 :     move16();
    4523           0 :     y1_lo = mem[3];
    4524           0 :     move16();
    4525             : 
    4526           0 :     L_tmp3 = L_mac( 16384L, mem[1], a_hp400_fx[2] ); /* rounding to maximize precision */
    4527           0 :     L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
    4528           0 :     L_tmp3 = L_shr( L_tmp3, 15 );
    4529           0 :     L_tmp2 = L_mac( L_tmp3, mem[0], a_hp400_fx[2] );
    4530           0 :     L_tmp2 = L_mac( L_tmp2, mem[5], b_hp400_fx[2] );
    4531           0 :     L_tmp2 = L_mac( L_tmp2, mem[4], b_hp400_fx[1] );
    4532           0 :     L_tmp3 = L_mult( mem[4], b_hp400_fx[2] );
    4533             : 
    4534           0 :     mem[5] = signal[lg - 2];
    4535           0 :     move16();
    4536           0 :     FOR( i = 1; i < lg; i++ )
    4537             :     {
    4538             :         /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
    4539             :         /*      + a[1]*y[i-1] + a[2] * y[i-2] */
    4540             : 
    4541           0 :         L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
    4542           0 :         L_tmp = L_mac( L_tmp, *signal, b_hp400_fx[0] );
    4543             : 
    4544           0 :         L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
    4545             : 
    4546           0 :         L_tmp2 = L_mac( L_tmp3, y1_hi, a_hp400_fx[2] );
    4547           0 :         L_tmp2 = L_mac( L_tmp2, *signal, b_hp400_fx[1] );
    4548           0 :         L_tmp3 = L_mac( 16384L, y1_lo, a_hp400_fx[2] ); /* rounding to maximize precision */
    4549             : 
    4550           0 :         y1_lo = L_Extract_lc( L_tmp, &y1_hi );
    4551             : 
    4552           0 :         L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
    4553           0 :         L_tmp3 = L_shr( L_tmp3, 15 );
    4554             : 
    4555           0 :         L_tmp2 = L_add( L_tmp3, L_tmp2 );
    4556             : 
    4557           0 :         L_tmp3 = L_mult( *signal, b_hp400_fx[2] );
    4558             : 
    4559             :         /* signal is divided by 16 to avoid overflow in energy computation */
    4560           0 :         *signal++ = round_fx( L_tmp );
    4561           0 :         move16();
    4562             :     }
    4563             : 
    4564             :     /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
    4565             :     /*      + a[1]*y[i-1] + a[2] * y[i-2] */
    4566             : 
    4567           0 :     L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
    4568             : 
    4569           0 :     mem[4] = *signal;
    4570           0 :     move16();
    4571           0 :     L_tmp = L_mac( L_tmp, mem[4], b_hp400_fx[0] );
    4572             : 
    4573           0 :     L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
    4574             : 
    4575           0 :     mem[0] = y1_hi;
    4576           0 :     move16();
    4577           0 :     mem[1] = y1_lo;
    4578           0 :     move16();
    4579           0 :     L_Extract( L_tmp, &mem[2], &mem[3] );
    4580             : 
    4581             :     /* signal is divided by 16 to avoid overflow in energy computation */
    4582           0 :     *signal++ = round_fx( L_tmp );
    4583           0 :     move16();
    4584             : 
    4585           0 :     return;
    4586             : }
    4587             : 
    4588             : 
    4589       64824 : void hp400_12k8_ivas_fx(
    4590             :     Word16 signal[], /* i/o: input signal / output is divided by 16 */
    4591             :     const Word16 lg, /* i  : lenght of signal                       */
    4592             :     Word16 mem[]     /* i/o: filter memory [6]                      */
    4593             : )
    4594             : {
    4595             :     Word16 i;
    4596             :     Word16 x0, x1, x2;
    4597             :     Word32 L_tmp, yy1, y2;
    4598             : 
    4599       64824 :     yy1 = L_Comp( mem[2], mem[3] ); /* Q_syn + 13 */
    4600       64824 :     y2 = L_Comp( mem[0], mem[1] );  /* Q_syn + 13 */
    4601       64824 :     x0 = mem[4];                    /* Q_syn */
    4602       64824 :     move16();
    4603       64824 :     x1 = mem[5]; /* Q_syn */
    4604       64824 :     move16();
    4605             : 
    4606     4213560 :     FOR( i = 0; i < lg; i++ )
    4607             :     {
    4608     4148736 :         x2 = x1; /* Q_syn */
    4609     4148736 :         move16();
    4610     4148736 :         x1 = x0; /* Q_syn */
    4611     4148736 :         move16();
    4612     4148736 :         x0 = signal[i]; /* Q_syn */
    4613     4148736 :         move16();
    4614             : 
    4615     4148736 :         L_tmp = Mpy_32_16_1( yy1, a_hp400_ivas_fx[1] ); /*yy1 * a_hp400[1]*/     /* Qx(Q_of_yy1) + 10 ---->( (Q_syn+13) + 12 - 15)*/
    4616     4148736 :         L_tmp = Madd_32_16( L_tmp, y2, a_hp400_ivas_fx[2] ); /*y2 * a_hp400[2]*/ /* Qx + 10 ---->( (Q_syn+13) + 12 - 15)*/
    4617     4148736 :         L_tmp = L_shl( L_tmp, 3 );                                               /* shifting by 3 to maintain same Q (Q_syn+13) */
    4618             : 
    4619     4148736 :         L_tmp = L_mac( L_tmp, x0, b_hp400_fx[0] ); /* Q_syn + 13 */
    4620     4148736 :         L_tmp = L_mac( L_tmp, x1, b_hp400_fx[1] ); /* Q_syn + 13 */
    4621     4148736 :         L_tmp = L_mac( L_tmp, x2, b_hp400_fx[2] ); /* Q_syn + 13 */
    4622             : 
    4623     4148736 :         y2 = yy1; /* Q_syn + 13 */
    4624     4148736 :         move32();
    4625     4148736 :         yy1 = L_tmp; /* Q_syn + 13 */
    4626     4148736 :         move32();
    4627             : 
    4628     4148736 :         signal[i] = round_fx( L_tmp ); /* Q_syn - 3 */
    4629     4148736 :         move16();
    4630             :     }
    4631             : 
    4632       64824 :     L_Extract( yy1, &mem[2], &mem[3] );
    4633       64824 :     L_Extract( y2, &mem[0], &mem[1] );
    4634       64824 :     mem[4] = x0; /* Q_syn */
    4635       64824 :     mem[5] = x1; /* Q_syn */
    4636       64824 :     move16();
    4637       64824 :     move16();
    4638             : 
    4639       64824 :     return;
    4640             : }
    4641             : 
    4642             : 
    4643           0 : Word16 dot_prod_satcontr(
    4644             :     const Word16 *x,
    4645             :     const Word16 *y,
    4646             :     Word16 qx,
    4647             :     Word16 qy,
    4648             :     Word16 *qo,
    4649             :     Word16 len )
    4650             : {
    4651             :     Word16 tmp_tab_x[L_FRAME16k];
    4652             :     Word16 tmp_tab_y[L_FRAME16k];
    4653             :     Word16 shift, q, ener, i;
    4654             :     Word32 L_tmp;
    4655             :     Word16 *pt1, *pt2;
    4656           0 :     Flag Overflow = 0;
    4657           0 :     move32();
    4658             : 
    4659           0 :     Copy( x, tmp_tab_x, len ); /* OPTIMIZE !!!!! the copy into local table is not necessary */
    4660           0 :     Copy( y, tmp_tab_y, len ); /* could be reworked to do a 1st iteration with the original x[] and y[] */
    4661             :     /* then check if there is an overflow and do a more complex 2nd, 3rd, ... processing */
    4662           0 :     shift = 0;
    4663           0 :     move16();
    4664             :     BASOP_SATURATE_WARNING_OFF_EVS
    4665             :     DO
    4666             :     {
    4667           0 :         Overflow = 0;
    4668           0 :         move16();
    4669           0 :         L_tmp = L_shl_o( 1, s_max( sub( add( add( qx, qy ), 7 ), shift ), 0 ), &Overflow );
    4670           0 :         pt1 = tmp_tab_x;
    4671           0 :         pt2 = tmp_tab_y;
    4672           0 :         FOR( i = 0; i < len; i++ )
    4673             :         {
    4674           0 :             L_tmp = L_mac0_o( L_tmp, *pt1++, *pt2++, &Overflow ); /*Q(qx+qy-shift) */
    4675             :         }
    4676             : 
    4677           0 :         IF( Overflow != 0 )
    4678             :         {
    4679           0 :             Scale_sig( tmp_tab_x, len, -2 );
    4680           0 :             Scale_sig( tmp_tab_y, len, -2 );
    4681           0 :             shift = add( shift, 4 );
    4682             :         }
    4683             :     }
    4684           0 :     WHILE( Overflow != 0 );
    4685             :     BASOP_SATURATE_WARNING_ON_EVS
    4686             : 
    4687           0 :     q = norm_l( L_tmp );
    4688           0 :     L_tmp = L_shl( L_tmp, q ); /*Q(qx+qy-shift+q) */
    4689           0 :     ener = extract_h( L_tmp ); /*Q(qx+qy-shift+q-16) */
    4690           0 :     q = add( q, add( qx, qy ) );
    4691           0 :     *qo = sub( q, add( shift, 16 ) );
    4692           0 :     move16();
    4693             : 
    4694           0 :     return ener;
    4695             : }
    4696             : 
    4697             : 
    4698             : /*
    4699             :  * E_UTIL_f_convolve
    4700             :  *
    4701             :  * Parameters:
    4702             :  *    x           I: input vector <14bits
    4703             :  *    h           I: impulse response (or second input vector) (1Q14)
    4704             :  *    y           O: output vetor (result of convolution)
    4705             :  *
    4706             :  * Function:
    4707             :  *    Perform the convolution between two vectors x[] and h[] and
    4708             :  *    write the result in the vector y[]. All vectors are of length L.
    4709             :  *    Only the first L samples of the convolution are considered.
    4710             :  *    Vector size = L_SUBFR
    4711             :  *
    4712             :  * Returns:
    4713             :  *    void
    4714             :  */
    4715       25772 : void E_UTIL_f_convolve(
    4716             :     const Word16 x[],
    4717             :     const Word16 h[],
    4718             :     Word16 y[],
    4719             :     const Word16 size )
    4720             : {
    4721             :     Word16 i, n;
    4722             :     Word32 L_sum;
    4723             :     Word64 L64_sum;
    4724             : 
    4725     1675180 :     FOR( n = 0; n < size; n++ )
    4726             :     {
    4727     1649408 :         L64_sum = 0;
    4728     1649408 :         move64();
    4729    53605760 :         FOR( i = 0; i < n; i++ )
    4730             :         {
    4731    51956352 :             L64_sum = W_mac_16_16( L64_sum, x[i], h[n - i] );
    4732             :         }
    4733     1649408 :         L_sum = W_sat_l( L64_sum );
    4734     1649408 :         y[n] = mac_r( L_sum, x[i], h[0] );
    4735     1649408 :         move16();
    4736             :     }
    4737             : 
    4738       25772 :     return;
    4739             : }
    4740             : 
    4741             : 
    4742             : /*-----------------------------------------------------------------------------
    4743             :  * floating_point_add:
    4744             :  *
    4745             :  * Add two floating point numbers: x <- x + y.
    4746             :  *----------------------------------------------------------------------------*/
    4747             : 
    4748    30182993 : void floating_point_add(
    4749             :     Word32 *mx,      /* io: mantissa of the addend Q31 */
    4750             :     Word16 *ex,      /* io: exponent of the addend Q0  */
    4751             :     const Word32 my, /* i:  mantissa of the adder Q31  */
    4752             :     const Word16 ey  /* i:  exponent of the adder Q0   */
    4753             : )
    4754             : {
    4755             :     Word32 accX, accY;
    4756             :     Word16 align, expo;
    4757             :     /* NB: This function will not work properly if the mantissa is zero and the exponent is not 32.
    4758             :        It is up to the caller function to avoid this condition. */
    4759             :     /* Ensure 1 bit headroom before addition. */
    4760    30182993 :     accX = L_shr( *mx, 1 );
    4761    30182993 :     accY = L_shr( my, 1 );
    4762             :     /* First, align the Q-points of the two operands. Then, add. */
    4763    30182993 :     align = sub( *ex, ey );
    4764             : 
    4765    30182993 :     IF( align < 0 )
    4766             :     {
    4767    29005455 :         accX = L_add( accX, L_shl( accY, align ) );
    4768             :     }
    4769             :     ELSE
    4770             :     {
    4771     1177538 :         accX = L_add( accY, L_shr( accX, align ) );
    4772     1177538 :         *ex = ey;
    4773     1177538 :         move16();
    4774             :     }
    4775             :     /* Normalize the result and update the mantissa and exponent. */
    4776    30182993 :     expo = norm_l( accX );
    4777    30182993 :     *mx = L_shl( accX, expo );
    4778    30182993 :     *ex = sub( add( *ex, expo ), 1 ); /* Subtract 1 due to 1-bit down-shift above ensuring 1 bit headroom before addition. */
    4779    30182993 :     move32();
    4780    30182993 :     move16();
    4781             : 
    4782    30182993 :     return;
    4783             : }
    4784             : 
    4785             : 
    4786             : /*-------------------------------------------------------------------*
    4787             :  * delay_signal_fx()
    4788             :  *
    4789             :  * Delay buffer by defined number of samples
    4790             :  *-------------------------------------------------------------------*/
    4791             : 
    4792     1132290 : void delay_signal_fx(
    4793             :     Word16 x[],        /* i/o: signal to be delayed              */
    4794             :     const Word16 len,  /* i  : length of the input signal        */
    4795             :     Word16 mem[],      /* i/o: synchronization memory            */
    4796             :     const Word16 delay /* i  : delay in samples                  */
    4797             : )
    4798             : {
    4799             :     Word16 tmp_buffer[L_FRAME48k];
    4800             : 
    4801     1132290 :     Copy( mem, tmp_buffer, delay );
    4802     1132290 :     Copy( x + sub( len, delay ), mem, delay );
    4803     1132290 :     Copy( x, x + delay, sub( len, delay ) );
    4804     1132290 :     Copy( tmp_buffer, x, delay );
    4805             : 
    4806     1132290 :     return;
    4807             : }
    4808             : 
    4809     3038277 : void delay_signal32_fx(
    4810             :     Word32 x[],        /* i/o: signal to be delayed              */
    4811             :     const Word16 len,  /* i  : length of the input signal        */
    4812             :     Word32 mem[],      /* i/o: synchronization memory            */
    4813             :     const Word16 delay /* i  : delay in samples                  */
    4814             : )
    4815             : {
    4816             :     Word32 tmp_buffer[L_FRAME48k];
    4817             : 
    4818     3038277 :     Copy32( mem, tmp_buffer, delay );
    4819     3038277 :     Copy32( x + sub( len, delay ), mem, delay );
    4820     3038277 :     Copy32( x, x + delay, sub( len, delay ) );
    4821     3038277 :     Copy32( tmp_buffer, x, delay );
    4822             : 
    4823     3038277 :     return;
    4824             : }
    4825             : 
    4826       65830 : void delay_signal_q_adj_fx(
    4827             :     Word32 x[],         /* i/o: signal to be delayed                    */
    4828             :     const Word16 len,   /* i  : length of the input signal              */
    4829             :     Word32 mem[],       /* i/o: synchronization memory                  */
    4830             :     const Word16 delay, /* i  : delay in samples                        */
    4831             :     const Word16 q_x,
    4832             :     const Word16 q_mem )
    4833             : {
    4834             : 
    4835             :     Word32 tmp_buffer[L_FRAME48k];
    4836             : 
    4837       65830 :     Copy32( mem, tmp_buffer, delay );
    4838       65830 :     Copy32( x + sub( len, delay ), mem, delay );
    4839       65830 :     Copy32( x, x + delay, sub( len, delay ) );
    4840             : 
    4841             : 
    4842       65830 :     IF( EQ_16( q_x, q_mem ) )
    4843             :     {
    4844       57543 :         Copy32( tmp_buffer, x, delay );
    4845             :     }
    4846             :     ELSE
    4847             :     {
    4848        8287 :         v_shr( tmp_buffer, sub( q_mem, q_x ), x, delay );
    4849             :     }
    4850             : 
    4851       65830 :     return;
    4852             : }
    4853             : 
    4854             : 
    4855        4410 : Word16 floor_log_2( Word32 num )
    4856             : {
    4857             : 
    4858        4410 :     IF( num == 0 )
    4859             :     {
    4860           0 :         return 0;
    4861             :     }
    4862             : 
    4863        4410 :     return ( sub( 30, norm_l( num ) ) );
    4864             : }
    4865             : 
    4866     5400444 : void v_shr(
    4867             :     const Word32 x[],   /* i  : Input vector                                     */
    4868             :     const Word16 shift, /* i  : Constant                                         */
    4869             :     Word32 y[],         /* o  : Output vector that contains x >> shift           */
    4870             :     const Word16 N      /* i  : Vector length                                    */
    4871             : )
    4872             : {
    4873             :     Word16 i;
    4874             : 
    4875   919727913 :     FOR( i = 0; i < N; i++ )
    4876             :     {
    4877   914327469 :         y[i] = L_shr( x[i], shift );
    4878   914327469 :         move32();
    4879             :     }
    4880             : 
    4881     5400444 :     return;
    4882             : }
    4883             : 
    4884           0 : void v_shr_16(
    4885             :     const Word16 x[],   /* i  : Input vector                                     */
    4886             :     const Word16 shift, /* i  : Constant                                         */
    4887             :     Word16 y[],         /* o  : Output vector that contains x >> shift               */
    4888             :     const Word16 N      /* i  : Vector length                                    */
    4889             : )
    4890             : {
    4891             :     Word16 i;
    4892             : 
    4893           0 :     FOR( i = 0; i < N; i++ )
    4894             :     {
    4895           0 :         y[i] = shr( x[i], shift );
    4896           0 :         move16();
    4897             :     }
    4898             : 
    4899           0 :     return;
    4900             : }
    4901             : 
    4902             : 
    4903             : /*---------------------------------------------------------------------*
    4904             :  * lin_interp_fx()
    4905             :  *
    4906             :  * Linearly maps x from source range <x1, x2> to the target range <y1, y2>
    4907             :  *---------------------------------------------------------------------*/
    4908             : 
    4909             : /*! r: mapped output value */
    4910         746 : Word16 lin_interp_fx(
    4911             :     const Word16 x,       /* i  : Q15 the value to be mapped                       */
    4912             :     const Word16 x1,      /* i  : Q15 source range interval: low end               */
    4913             :     const Word16 y1,      /* i  : Q15 source range interval: high end              */
    4914             :     const Word16 x2,      /* i  : Q15 target range interval: low                   */
    4915             :     const Word16 y2,      /* i  : Q15 target range interval: high                  */
    4916             :     const Word16 flag_sat /* i  : flag to indicate whether to apply saturation */
    4917             : )
    4918             : {
    4919         746 :     IF( sub( x2, x1 ) == 0 )
    4920             :     {
    4921           0 :         return y1;
    4922             :     }
    4923         746 :     ELSE IF( flag_sat )
    4924             :     {
    4925         746 :         IF( GE_16( x, s_max( x1, x2 ) ) )
    4926             :         {
    4927           0 :             IF( GT_16( x1, x2 ) )
    4928             :             {
    4929           0 :                 return y1;
    4930             :             }
    4931             :             ELSE
    4932             :             {
    4933           0 :                 return y2;
    4934             :             }
    4935             :         }
    4936         746 :         ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
    4937             :         {
    4938           0 :             IF( LT_16( x1, x2 ) )
    4939             :             {
    4940           0 :                 return y1;
    4941             :             }
    4942             :             ELSE
    4943             :             {
    4944           0 :                 return y2;
    4945             :             }
    4946             :         }
    4947             :     }
    4948             : 
    4949         746 :     return add_sat( y1, mult( sub( x, x1 ), div_s( sub( y2, y1 ), sub( x2, x1 ) ) ) );
    4950             : }
    4951             : 
    4952             : 
    4953      223649 : Word16 lin_interp_ivas_fx(
    4954             :     const Word16 x,       /* i  : Q15 the value to be mapped                       */
    4955             :     const Word16 x1,      /* i  : Q15 source range interval: low end               */
    4956             :     const Word16 y1,      /* i  : Q15 source range interval: high end              */
    4957             :     const Word16 x2,      /* i  : Q15 target range interval: low                   */
    4958             :     const Word16 y2,      /* i  : Q15 target range interval: high                  */
    4959             :     const Word16 flag_sat /* i  : flag to indicate whether to apply saturation */
    4960             : )
    4961             : {
    4962      223649 :     IF( EQ_16( sub( x2, x1 ), 0 ) )
    4963             :     {
    4964           0 :         return y1;
    4965             :     }
    4966      223649 :     ELSE IF( flag_sat )
    4967             :     {
    4968      220773 :         IF( GE_16( x, s_max( x1, x2 ) ) )
    4969             :         {
    4970         915 :             return GT_16( x1, x2 ) ? y1 : y2;
    4971             :         }
    4972      219858 :         ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
    4973             :         {
    4974      165963 :             return LT_16( x1, x2 ) ? y1 : y2;
    4975             :         }
    4976             :     }
    4977             :     Word16 div_res_e;
    4978       56771 :     Word16 div_res = BASOP_Util_Divide1616_Scale( sub( y2, y1 ), sub( x2, x1 ), &div_res_e );
    4979             :     // div_res = shl( div_res, div_res_e );
    4980       56771 :     return add_sat( y1, round_fx( L_shl( L_mult( sub( x, x1 ), div_res ), div_res_e ) ) );
    4981             : }
    4982             : 
    4983             : 
    4984             : /*---------------------------------------------------------------------
    4985             :  * sign_l()
    4986             :  *
    4987             :  *---------------------------------------------------------------------*/
    4988             : 
    4989             : /*! r: sign of x (+1/-1) */
    4990       82920 : Word32 sign_l(
    4991             :     const Word32 x /* i  : input value of x  */
    4992             : )
    4993             : {
    4994       82920 :     IF( x < 0 )
    4995             :     {
    4996       38619 :         return MIN_32;
    4997             :     }
    4998             :     ELSE
    4999             :     {
    5000       44301 :         return MAX_32;
    5001             :     }
    5002             : }
    5003             : 
    5004         220 : void v_mult16_fx(
    5005             :     const Word16 x1[], /* i  : Input vector 1                                   */
    5006             :     const Word16 x2[], /* i  : Input vector 2                                   */
    5007             :     Word16 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    5008             :     const Word16 N     /* i  : Vector length                                    */
    5009             : )
    5010             : {
    5011             :     Word16 i;
    5012             : 
    5013       15404 :     FOR( i = 0; i < N; i++ )
    5014             :     {
    5015       15184 :         y[i] = mult_r( x1[i], x2[i] );
    5016       15184 :         move16();
    5017             :     }
    5018             : 
    5019         220 :     return;
    5020             : }
    5021             : 
    5022             : /*---------------------------------------------------------------------*
    5023             :  * set_zero_fx()
    5024             :  *
    5025             :  * Set a vector vec[] of dimension lvec to zero
    5026             :  *---------------------------------------------------------------------*/
    5027             : 
    5028   271528346 : void set_zero_fx(
    5029             :     Word32 *vec,      /* o  : input vector                                    */
    5030             :     const Word16 lvec /* i  : length of the vector                            */
    5031             : )
    5032             : {
    5033             :     Word16 i;
    5034             : 
    5035 16416778976 :     FOR( i = 0; i < lvec; i++ )
    5036             :     {
    5037 16145250630 :         *vec++ = 0;
    5038 16145250630 :         move32();
    5039             :     }
    5040             : 
    5041   271528346 :     return;
    5042             : }
    5043             : 
    5044       10757 : void set_zero2_fx(
    5045             :     Word32 *vec,      /* o  : input vector                                    */
    5046             :     const Word32 lvec /* i  : length of the vector                            */
    5047             : )
    5048             : {
    5049             :     Word32 i;
    5050             : 
    5051    36656738 :     FOR( i = 0; i < lvec; i++ )
    5052             :     {
    5053    36645981 :         *vec++ = 0;
    5054    36645981 :         move32();
    5055             :     }
    5056             : 
    5057       10757 :     return;
    5058             : }
    5059             : 
    5060     7261812 : void set16_zero_fx(
    5061             :     Word16 *vec,      /* o  : input vector                                    */
    5062             :     const Word16 lvec /* i  : length of the vector                            */
    5063             : )
    5064             : {
    5065             :     Word16 i;
    5066             : 
    5067  3143125438 :     FOR( i = 0; i < lvec; i++ )
    5068             :     {
    5069  3135863626 :         *vec++ = 0;
    5070  3135863626 :         move16();
    5071             :     }
    5072             : 
    5073     7261812 :     return;
    5074             : }
    5075             : 
    5076     1894501 : UWord32 mvl2s_r(
    5077             :     const Word32 x[], /* i  : input vector  */
    5078             :     const Word16 q_x,
    5079             :     Word16 y[],    /* o  : output vector */
    5080             :     const Word16 n /* i  : vector size   */
    5081             : )
    5082             : {
    5083             :     Word16 i;
    5084             :     Word32 temp;
    5085     1894501 :     UWord32 noClipping = 0;
    5086     1894501 :     move32();
    5087             : 
    5088     1894501 :     IF( n <= 0 )
    5089             :     {
    5090             :         /* cannot transfer vectors with size 0 */
    5091         518 :         return 0;
    5092             :     }
    5093             : 
    5094     1893983 :     IF( (void *) y <= (const void *) x )
    5095             :     {
    5096           0 :         Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
    5097           0 :         FOR( i = 0; i < n; i++ )
    5098             :         {
    5099           0 :             temp = L_add( x[i], tempd );
    5100           0 :             temp = L_shr( temp, q_x );
    5101             : 
    5102           0 :             IF( GT_32( temp, MAX16B ) )
    5103             :             {
    5104           0 :                 temp = MAX16B;
    5105           0 :                 move32();
    5106           0 :                 noClipping = L_add( (Word32) noClipping, 1 );
    5107             :             }
    5108           0 :             ELSE IF( LT_32( temp, MIN16B ) )
    5109             :             {
    5110           0 :                 temp = MIN16B;
    5111           0 :                 move32();
    5112           0 :                 noClipping = L_add( (Word32) noClipping, 1 );
    5113             :             }
    5114             : 
    5115           0 :             y[i] = extract_l( temp );
    5116           0 :             move16();
    5117             :         }
    5118             :     }
    5119             :     ELSE
    5120             :     {
    5121     1893983 :         Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
    5122  1523585583 :         FOR( i = n - 1; i >= 0; i-- )
    5123             :         {
    5124  1521691600 :             temp = L_add( x[i], tempd );
    5125  1521691600 :             temp = L_shr( temp, q_x );
    5126             : 
    5127  1521691600 :             IF( GT_32( temp, MAX16B ) )
    5128             :             {
    5129         834 :                 temp = MAX16B;
    5130         834 :                 move32();
    5131         834 :                 noClipping = L_add( (Word32) noClipping, 1 );
    5132             :             }
    5133  1521690766 :             ELSE IF( LT_32( temp, MIN16B ) )
    5134             :             {
    5135        1620 :                 temp = MIN16B;
    5136        1620 :                 move32();
    5137        1620 :                 noClipping = L_add( (Word32) noClipping, 1 );
    5138             :             }
    5139             : 
    5140  1521691600 :             y[i] = extract_l( temp );
    5141  1521691600 :             move16();
    5142             :         }
    5143             :     }
    5144             : 
    5145     1893983 :     return noClipping;
    5146             : }
    5147             : 
    5148    52951440 : Word32 dotp_me_fx(
    5149             :     const Word32 x[], /* i  : vector x[]                    */
    5150             :     const Word32 y[], /* i  : vector y[]                    */
    5151             :     const Word16 n,   /* i  : vector length                 */
    5152             :     Word16 exp_x,
    5153             :     Word16 exp_y,
    5154             :     Word16 *exp_suma )
    5155             : {
    5156             :     Word16 i;
    5157             :     Word32 suma;
    5158             :     Word32 mul;
    5159    52951440 :     Word16 mul_exp = add( exp_x, exp_y );
    5160    52951440 :     suma = Mpy_32_32( x[0], y[0] );
    5161    52951440 :     *exp_suma = mul_exp;
    5162   325651356 :     FOR( i = 1; i < n; i++ )
    5163             :     {
    5164   272699916 :         mul = Mpy_32_32( x[i], y[i] );
    5165   272699916 :         suma = BASOP_Util_Add_Mant32Exp( suma, *exp_suma, mul, mul_exp, exp_suma ); // exp_x+exp_A
    5166             :     }
    5167             : 
    5168    52951440 :     return suma;
    5169             : }
    5170             : 
    5171       17440 : Word32 dotp_fx_guarded(
    5172             :     const Word32 x[], /* i  : vector x[]                    */
    5173             :     const Word32 y[], /* i  : vector y[]                    */
    5174             :     const Word16 n    /* i  : vector length                 */
    5175             : )
    5176             : {
    5177             :     Word16 i;
    5178             :     Word32 suma;
    5179       17440 :     Word16 guarded_bits = find_guarded_bits_fx( n );
    5180       17440 :     suma = L_shr( Mpy_32_32( x[0], y[0] ), guarded_bits );
    5181             : 
    5182      279040 :     FOR( i = 1; i < n; i++ )
    5183             :     {
    5184      261600 :         suma = L_add( suma, L_shr( Mpy_32_32( x[i], y[i] ), guarded_bits ) );
    5185             :     }
    5186             : 
    5187       17440 :     return suma;
    5188             : }
    5189             : 
    5190             : 
    5191         522 : Word32 dotp_fx_ivas_fx(
    5192             :     const Word32 x[], /* i  : vector x[]                    */
    5193             :     Word16 x_e,
    5194             :     const Word32 y[], /* i  : vector y[]                    */
    5195             :     Word16 y_e,
    5196             :     const Word16 n, /* i  : vector length                 */
    5197             :     Word16 *out_e )
    5198             : {
    5199             :     Word16 i, exp;
    5200         522 :     Word32 suma = 0;
    5201             : 
    5202         522 :     exp = 31;
    5203         522 :     move16();
    5204             : 
    5205      166344 :     FOR( i = 0; i < n; i++ )
    5206             :     {
    5207      165822 :         suma = BASOP_Util_Add_Mant32Exp( suma, exp, Mpy_32_32( x[i], y[i] ), x_e + y_e, &exp );
    5208             :     }
    5209             : 
    5210         522 :     *out_e = exp;
    5211         522 :     move16();
    5212             : 
    5213         522 :     return suma;
    5214             : }
    5215             : 
    5216             : 
    5217             : /*-------------------------------------------------------------------*
    5218             :  * v_mult()
    5219             :  *
    5220             :  * Multiplication of two vectors
    5221             :  *-------------------------------------------------------------------*/
    5222             : 
    5223    19716792 : void v_mult_fx(
    5224             :     const Word32 x1[], /* i  : Input vector 1                                   */
    5225             :     const Word32 x2[], /* i  : Input vector 2                                   */
    5226             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    5227             :     const Word16 N     /* i  : Vector length                                    */
    5228             : )
    5229             : {
    5230             :     Word16 i;
    5231             : 
    5232   761886520 :     FOR( i = 0; i < N; i++ )
    5233             :     {
    5234   742169728 :         y[i] = Mpy_32_32( x1[i], x2[i] );
    5235   742169728 :         move32();
    5236             :     }
    5237             : 
    5238    19716792 :     return;
    5239             : }
    5240             : 
    5241             : 
    5242             : /*-------------------------------------------------------------------*
    5243             :  * anint_fx()
    5244             :  *
    5245             :  * Round to the nearest integer.
    5246             :  *-------------------------------------------------------------------*/
    5247             : 
    5248       10414 : Word32 anint_fx(
    5249             :     const Word32 x,
    5250             :     const Word16 exp )
    5251             : {
    5252       10414 :     IF( x == 0 )
    5253             :     {
    5254        1012 :         return 0;
    5255             :     }
    5256        9402 :     IF( x >= 0 )
    5257             :     {
    5258        9402 :         return L_add( x, L_shl( 1, sub( exp, 1 ) ) );
    5259             :     }
    5260             :     ELSE
    5261             :     {
    5262           0 :         return L_sub( x, L_shl( 1, sub( exp, 1 ) ) );
    5263             :     }
    5264             : }
    5265             : 
    5266             : 
    5267             : /*-------------------------------------------------------------------*
    5268             :  * ceil_fx()
    5269             :  *
    5270             :  * Ceil to the next multiple of (1 << exp).
    5271             :  *-------------------------------------------------------------------*/
    5272             : 
    5273       40499 : Word32 ceil_fx(
    5274             :     const Word32 x,
    5275             :     const Word16 exp )
    5276             : {
    5277             :     Word32 step;
    5278             : 
    5279             :     // step = x / L_shl( 1, exp );
    5280       40499 :     step = L_shr( x, exp );
    5281       40499 :     IF( ( x % L_shl( 1, exp ) ) > 0 )
    5282             :     {
    5283       25811 :         step = L_add( step, 1 );
    5284             :     }
    5285             : 
    5286       40499 :     return L_shl( step, exp );
    5287             : }
    5288             : 
    5289         861 : void sort_l(
    5290             :     Word32 *x, /* i/o: Vector to be sorted                             */
    5291             :     Word16 len /* i/o: vector length                                   */
    5292             : )
    5293             : {
    5294             :     Word16 i, j;
    5295             :     Word32 tempr;
    5296             : 
    5297        7991 :     FOR( i = len - 2; i >= 0; i-- )
    5298             :     {
    5299        7130 :         tempr = x[i];
    5300        7130 :         move32();
    5301       26159 :         FOR( j = i + 1; ( j < len ) && ( tempr > x[j] ); j++ )
    5302             :         {
    5303       19029 :             x[j - 1] = x[j];
    5304       19029 :             move32();
    5305             :         }
    5306        7130 :         x[j - 1] = tempr;
    5307        7130 :         move32();
    5308             :     }
    5309             : 
    5310         861 :     return;
    5311             : }
    5312             : 
    5313             : 
    5314             : /*-------------------------------------------------------------------*
    5315             :  * v_add()
    5316             :  *
    5317             :  * Subtraction of two vectors sample by sample
    5318             :  *-------------------------------------------------------------------*/
    5319             : 
    5320    29393619 : void v_add_fx(
    5321             :     const Word32 x1[], /* i  : Input vector 1                       */
    5322             :     const Word32 x2[], /* i  : Input vector 2                       */
    5323             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    5324             :     const Word16 N     /* i  : Vector length                                    */
    5325             : )
    5326             : {
    5327             :     Word16 i;
    5328             : 
    5329  3342620425 :     FOR( i = 0; i < N; i++ )
    5330             :     {
    5331  3313226806 :         y[i] = L_add_sat( x1[i], x2[i] );
    5332  3313226806 :         move32();
    5333             :     }
    5334             : 
    5335    29393619 :     return;
    5336             : }
    5337             : 
    5338             : 
    5339     6591843 : void v_add_fx_hdrm(
    5340             :     const Word32 x1[], /* i  : Input vector 1                                   */
    5341             :     const Word32 x2[], /* i  : Input vector 2                                   */
    5342             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    5343             :     const Word16 N,    /* i  : Vector length                                    */
    5344             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
    5345             : )
    5346             : {
    5347             :     Word16 i;
    5348             : 
    5349   177933835 :     FOR( i = 0; i < N; i++ )
    5350             :     {
    5351   171341992 :         y[i] = L_add( L_shr( x1[i], hdrm ), L_shr( x2[i], hdrm ) );
    5352   171341992 :         move32();
    5353             :     }
    5354             : 
    5355     6591843 :     return;
    5356             : }
    5357             : 
    5358   511106135 : void v_add_fx_no_hdrm(
    5359             :     const Word32 x1[], /* i  : Input vector 1                                   */
    5360             :     const Word32 x2[], /* i  : Input vector 2                                   */
    5361             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    5362             :     const Word16 N     /* i  : Vector length                                    */
    5363             : )
    5364             : {
    5365             :     Word16 i;
    5366             : 
    5367  2851753992 :     FOR( i = 0; i < N; i++ )
    5368             :     {
    5369  2340647857 :         y[i] = L_add( x1[i], x2[i] );
    5370  2340647857 :         move32();
    5371             :     }
    5372             : 
    5373   511106135 :     return;
    5374             : }
    5375             : 
    5376     9616832 : void v_add_fx_me(
    5377             :     const Word32 x1[], /* i  : Input vector 1                                   */
    5378             :     const Word16 x1_e, /* i  : Exponent for input vector 1                      */
    5379             :     const Word32 x2[], /* i  : Input vector 2                                   */
    5380             :     const Word16 x2_e, /* i  : Exponent for input vector 2                      */
    5381             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    5382             :     Word16 *y_e,       /* i  : Exponent for output vector                       */
    5383             :     const Word16 N,    /* i  : Vector length                                    */
    5384             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
    5385             : )
    5386             : {
    5387             :     Word16 i;
    5388     9616832 :     Word16 x1_shift = sub( s_max( x1_e, x2_e ), x1_e );
    5389     9616832 :     Word16 x2_shift = sub( s_max( x1_e, x2_e ), x2_e );
    5390             : 
    5391   157870561 :     FOR( i = 0; i < N; i++ )
    5392             :     {
    5393   148253729 :         y[i] = L_add( L_shr( x1[i], hdrm + x1_shift ), L_shr( x2[i], hdrm + x2_shift ) );
    5394   148253729 :         move32();
    5395             :     }
    5396             : 
    5397     9616832 :     *y_e = add( s_max( x1_e, x2_e ), hdrm );
    5398     9616832 :     move16();
    5399             : 
    5400     9616832 :     return;
    5401             : }
    5402             : 
    5403    99330307 : Word16 find_guarded_bits_fx(
    5404             :     const Word32 n )
    5405             : {
    5406             :     // return n <= 1 ? 0 : n <= 2 ? 1
    5407             :     //   : n <= 4 ? 2
    5408             :     //   : n <= 8 ? 3
    5409             :     //   : n <= 16 ? 4
    5410             :     //   : n <= 32 ? 5
    5411             :     //   : n <= 64 ? 6
    5412             :     //   : n <= 128 ? 7
    5413             :     //   : n <= 256 ? 8
    5414             :     //   : n <= 512 ? 9
    5415             :     //   : n <= 1024 ? 10
    5416             :     //   : n <= 2048 ? 11
    5417             :     //   : n <= 4096 ? 12
    5418             :     //   : n <= 8192 ? 13
    5419             :     //   : n <= 16384 ? 14
    5420             :     //   : 15;
    5421             :     /*Word16 val = 0;
    5422             :     move32();
    5423             :     test();
    5424             :     WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) )
    5425             :     {
    5426             :         val = add( val, 1 );
    5427             :     }*/
    5428    99330307 :     IF( LE_32( n, 1 ) )
    5429             :     {
    5430    17408434 :         return 0;
    5431             :     }
    5432             :     ELSE
    5433             :     {
    5434             : 
    5435    81921873 :         return sub( 31, norm_l( L_sub( n, 1 ) ) );
    5436             :     }
    5437             : }
    5438             : 
    5439             : 
    5440  1014979321 : Word16 L_norm_arr(
    5441             :     const Word32 *arr,
    5442             :     Word16 size )
    5443             : {
    5444  1014979321 :     Word16 q = 31;
    5445  1014979321 :     move16();
    5446             : 
    5447 43829231350 :     FOR( Word16 i = 0; i < size; i++ )
    5448             :     {
    5449             :         Word16 q_tst;
    5450             : 
    5451 42814252029 :         q_tst = norm_l( arr[i] );
    5452 42814252029 :         if ( arr[i] != 0 )
    5453             :         {
    5454 35018008634 :             q = s_min( q, q_tst );
    5455             :         }
    5456             :     }
    5457             : 
    5458  1014979321 :     return q;
    5459             : }
    5460             : 
    5461    24039417 : Word16 norm_arr(
    5462             :     Word16 *arr,
    5463             :     Word16 size )
    5464             : {
    5465    24039417 :     Word16 q = 15;
    5466    24039417 :     Word16 exp = 0;
    5467    24039417 :     move16();
    5468    24039417 :     move16();
    5469             : 
    5470  9567769439 :     FOR( Word16 i = 0; i < size; i++ )
    5471             :     {
    5472  9543730022 :         if ( arr[i] != 0 )
    5473             :         {
    5474  7978253816 :             exp = norm_s( arr[i] );
    5475             :         }
    5476  9543730022 :         if ( arr[i] != 0 )
    5477             :         {
    5478  7978253816 :             q = s_min( q, exp );
    5479             :         }
    5480             :     }
    5481             : 
    5482    24039417 :     return q;
    5483             : }
    5484             : 
    5485     3720877 : Word16 W_norm_arr(
    5486             :     Word64 *arr,
    5487             :     Word16 size )
    5488             : {
    5489     3720877 :     Word16 q = 63;
    5490     3720877 :     Word16 exp = 0;
    5491     3720877 :     move16();
    5492     3720877 :     move16();
    5493             : 
    5494  1762847373 :     FOR( Word16 i = 0; i < size; i++ )
    5495             :     {
    5496  1759126496 :         if ( arr[i] != 0 )
    5497             :         {
    5498  1718840524 :             exp = W_norm( arr[i] );
    5499             :         }
    5500  1759126496 :         if ( arr[i] != 0 )
    5501             :         {
    5502  1718840524 :             q = s_min( q, exp );
    5503             :         }
    5504             :     }
    5505             : 
    5506     3720877 :     return q;
    5507             : }
    5508             : 
    5509   442139970 : Word16 get_min_scalefactor(
    5510             :     Word32 x,
    5511             :     Word32 y )
    5512             : {
    5513             :     Word16 scf_y;
    5514   442139970 :     Word16 scf = Q31;
    5515   442139970 :     move16();
    5516             : 
    5517   442139970 :     test();
    5518   442139970 :     if ( x == 0 && y == 0 )
    5519             :     {
    5520    31025078 :         scf = 0;
    5521    31025078 :         move16();
    5522             :     }
    5523             : 
    5524   442139970 :     if ( x != 0 )
    5525             :     {
    5526   411017114 :         scf = norm_l( x );
    5527             :     }
    5528             : 
    5529   442139970 :     scf_y = norm_l( y );
    5530   442139970 :     if ( y != 0 )
    5531             :     {
    5532   322877286 :         scf = s_min( scf_y, scf );
    5533             :     }
    5534             : 
    5535   442139970 :     return scf;
    5536             : }
    5537             : 
    5538             : 
    5539   589761954 : Flag is_zero_arr(
    5540             :     Word32 *arr,
    5541             :     Word16 size )
    5542             : {
    5543  1031386968 :     FOR( Word16 i = 0; i < size; i++ )
    5544             :     {
    5545   942121729 :         IF( arr[i] != 0 )
    5546             :         {
    5547   500496715 :             return 0;
    5548             :         }
    5549             :     }
    5550             : 
    5551    89265239 :     return 1;
    5552             : }
    5553             : 
    5554     2180167 : Flag is_zero_arr16(
    5555             :     Word16 *arr,
    5556             :     Word16 size )
    5557             : {
    5558   284105623 :     FOR( Word16 i = 0; i < size; i++ )
    5559   283854423 :     IF( arr[i] != 0 )
    5560             :     {
    5561     1928967 :         return 0;
    5562             :     }
    5563             : 
    5564      251200 :     return 1;
    5565             : }
    5566             : 
    5567           0 : Flag is_zero_arr64(
    5568             :     Word64 *arr,
    5569             :     Word16 size )
    5570             : {
    5571           0 :     FOR( Word16 i = 0; i < size; i++ )
    5572             :     {
    5573           0 :         IF( arr[i] != 0 )
    5574             :         {
    5575           0 :             return 0;
    5576             :         }
    5577             :     }
    5578           0 :     return 1;
    5579             : }
    5580             : 
    5581           0 : void Scale_sig64(
    5582             :     Word64 x[], /* i/o: signal to scale                 Qx        */
    5583             :     Word16 len, /* i  : size of x[]                     Q0        */
    5584             :     Word16 exp  /* i  : exponent: x = round(x << exp)   Qx exp    */
    5585             : )
    5586             : {
    5587             :     Word16 i;
    5588             : 
    5589           0 :     assert( exp <= 63 && exp >= -63 );
    5590             : 
    5591           0 :     IF( exp == 0 )
    5592             :     {
    5593           0 :         return;
    5594             :     }
    5595             : 
    5596           0 :     FOR( i = 0; i < len; i++ )
    5597             :     {
    5598             :         /* saturation can occur here */
    5599           0 :         x[i] = W_shl( x[i], exp );
    5600           0 :         move64();
    5601             :     }
    5602             : 
    5603           0 :     return;
    5604             : }

Generated by: LCOV version 1.14