LCOV - code coverage report
Current view: top level - lib_com - tools_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ ba2aad75b0355694da9bfd9eb509be7f65687f8c Lines: 1556 2016 77.2 %
Date: 2025-10-31 02:19:39 Functions: 156 192 81.2 %

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

Generated by: LCOV version 1.14