LCOV - code coverage report
Current view: top level - lib_com - tools_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ d40ed931793b6a50d91fe879dc4ec795971aff53 Lines: 1336 1741 76.7 %
Date: 2025-09-18 03:57:22 Functions: 130 158 82.3 %

          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             : #define INV_BANDS10 3277                            /* 1/10 in Q15 */
      52             : #define INV_BANDS9  3641                            /* 1/9  in Q15 */
      53             : #define INV_BANDS3  10923                           /* 1/9  in Q15 */
      54             : const Word16 b_hp400_fx[3] = { 3660, -7320, 3660 }; /* Q12 (/4) */
      55             : const Word16 a_hp400_fx[3] = { 16384, 29280, -14160 };
      56             : const Word16 a_hp400_ivas_fx[3] = { 4096, 7320, -3540 }; /*Q12*/
      57             : 
      58             : #define WMC_TOOL_SKIP
      59             : 
      60             : // conversion functions:
      61     6527875 : Word32 float_to_fix( float number, Word32 Q )
      62             : {
      63     6527875 :     assert( Q >= 0 );
      64     6527875 :     if ( number == 1.0f && Q == Q31 )
      65             :     {
      66           0 :         return ONE_IN_Q31;
      67             :     }
      68     6527875 :     if ( isnan( number ) )
      69             :     {
      70           0 :         number = 0;
      71             :     }
      72     6527875 :     assert( fabs( number ) < pow( 2, 31 - Q ) );
      73     6527875 :     Word32 ret = (Word32) ( number * ( (UWord32) 1 << Q ) );
      74     6527875 :     return ret;
      75             : }
      76             : 
      77           0 : float fix_to_float( Word32 number, Word32 Q )
      78             : {
      79           0 :     assert( Q >= 0 );
      80           0 :     float ret = (float) number / ( (UWord32) 1 << Q );
      81           0 :     return ret;
      82             : }
      83             : 
      84      525436 : Word16 float_to_fix16( float number, Word16 Q )
      85             : {
      86      525436 :     assert( Q >= 0 );
      87      525436 :     IF( isnan( number ) )
      88           0 :     return 0;
      89      525436 :     if ( number == 1.0f && Q == Q15 )
      90           0 :         return MAX16B;
      91      525436 :     if ( number == -1.0f && Q == Q15 )
      92           0 :         return MIN16B;
      93      525436 :     assert( fabs( number ) < pow( 2, 15 - Q ) );
      94      525436 :     Word16 ret = (Word16) ( number * ( (UWord16) 1 << Q ) );
      95      525436 :     return ret;
      96             : }
      97             : 
      98           0 : Word16 float_to_fix16_thrld( float number, Word16 Q )
      99             : {
     100           0 :     assert( Q >= 0 );
     101           0 :     if ( number == 1.0f && Q == Q15 )
     102           0 :         return MAX16B;
     103           0 :     float limit = (float) pow( 2, 15 - Q );
     104             :     /*Add threshold*/
     105           0 :     if ( number > MAX16B_FLT )
     106             :     {
     107           0 :         number = MAX16B_FLT;
     108             :     }
     109           0 :     else if ( number < MIN16B_FLT )
     110             :     {
     111           0 :         number = MIN16B_FLT;
     112             :     }
     113           0 :     assert( number <= limit && number >= -limit );
     114           0 :     Word16 ret = (Word16) ( number * ( (UWord16) 1 << Q ) );
     115           0 :     return ret;
     116             : }
     117             : 
     118       68942 : float fix16_to_float( Word16 number, Word16 Q )
     119             : {
     120       68942 :     assert( Q >= 0 );
     121       68942 :     float ret = (float) number / ( (UWord16) 1 << Q );
     122       68942 :     return ret;
     123             : }
     124             : 
     125             : // Float to 32-bit Mantissa and Exponent
     126     4214584 : void f2me( float n, Word32 *mantissa, Word16 *expo )
     127             : {
     128             :     Word32 e;
     129     4214584 :     float mf = (float) frexp( n, &e );
     130     4214584 :     *expo = (Word16) e;
     131     4214584 :     *mantissa = float_to_fix( mf, Q31 );
     132     4214584 : }
     133             : 
     134             : // 32-bit Mantissa and Exponent to Float
     135           0 : float me2f( Word32 m, Word16 expo )
     136             : {
     137           0 :     float mf = fix_to_float( m, Q31 );
     138           0 :     return (float) ldexp( mf, expo );
     139             : }
     140             : 
     141             : // Float buffer to 32-bit mantissa buffer and common exponent.
     142          72 : void f2me_buf( const float *x, Word32 *m, Word16 *e, const Word32 n )
     143             : {
     144          72 :     Word16 max_e = -32, tmp_e;
     145             :     Word32 i;
     146             : 
     147     2107364 :     for ( i = 0; i < n; i++ )
     148             :     {
     149     2107292 :         f2me( x[i], &m[i], &tmp_e );
     150     2107292 :         max_e = ( max_e > tmp_e ) ? max_e : tmp_e;
     151             :     }
     152             : 
     153     2107364 :     for ( i = 0; i < n; i++ )
     154             :     {
     155     2107292 :         f2me( x[i], &m[i], &tmp_e );
     156     2107292 :         m[i] = L_shr( m[i], max_e - tmp_e );
     157             :     }
     158             : 
     159          72 :     *e = max_e;
     160          72 : }
     161             : 
     162             : // 32-bit Mantissa buffer and exponent into float buffer.
     163           0 : void me2f_buf( const Word32 *m, const Word16 e, float *out, const Word32 n )
     164             : {
     165           0 :     for ( int i = 0; i < n; i++ )
     166             :     {
     167           0 :         out[i] = me2f( m[i], e );
     168             :     }
     169           0 : }
     170             : 
     171             : // Float to 16-bit Mantissa and Exponent
     172           0 : void f2me_16( float n, Word16 *mantissa, Word16 *expo )
     173             : {
     174             :     Word32 e;
     175           0 :     float mf = (float) frexp( n, &e );
     176           0 :     *expo = (Word16) e;
     177           0 :     *mantissa = float_to_fix16( mf, 15 );
     178           0 : }
     179             : 
     180             : // 16-bit Mantissa and Exponent to Float
     181           0 : float me2f_16( Word16 m, Word16 expo )
     182             : {
     183           0 :     float mf = fix16_to_float( m, 15 );
     184           0 :     return (float) ldexp( mf, expo );
     185             : }
     186             : 
     187             : // Float buffer to 16-bit mantissa buffer and common exponent.
     188           0 : void f2me_buf_16( const float *x, Word16 *m, Word16 *e, const Word32 n )
     189             : {
     190           0 :     Word16 max_e = -16, tmp_e;
     191             :     Word32 i;
     192             : 
     193           0 :     for ( i = 0; i < n; i++ )
     194             :     {
     195           0 :         f2me_16( x[i], &m[i], &tmp_e );
     196           0 :         max_e = ( max_e > tmp_e ) ? max_e : tmp_e;
     197             :     }
     198             : 
     199           0 :     for ( i = 0; i < n; i++ )
     200             :     {
     201           0 :         f2me_16( x[i], &m[i], &tmp_e );
     202           0 :         m[i] = shr( m[i], max_e - tmp_e );
     203             :     }
     204             : 
     205           0 :     *e = max_e;
     206           0 : }
     207             : 
     208             : // 16-bit Mantissa buffer and exponent into float buffer.
     209           0 : void me2f_buf_16( const Word16 *m, const Word16 e, float *out, const Word32 n )
     210             : {
     211           0 :     for ( int i = 0; i < n; i++ )
     212             :     {
     213           0 :         out[i] = me2f_16( m[i], e );
     214             :     }
     215           0 : }
     216           0 : void f2fix( float *var_flt, Word32 *var_fix, Word32 expo )
     217             : {
     218           0 :     *var_fix = (Word32) ( *var_flt * pow( 2, 31 - expo ) );
     219           0 : }
     220             : 
     221           0 : void fix2f( Word32 *var_fix, float *var_flt, Word32 expo )
     222             : {
     223           0 :     float mf = fix_to_float( *var_fix, 31 );
     224           0 :     *var_flt = (float) ldexp( mf, expo );
     225           0 : }
     226             : 
     227           0 : void f2fix_16( float *var_flt, Word16 *var_fix, Word32 expo )
     228             : {
     229           0 :     *var_fix = (Word16) ( *var_flt * pow( 2, 15 - expo ) );
     230           0 : }
     231             : 
     232           0 : void fix2f_16( Word16 *var_fix, float *var_flt, Word32 expo )
     233             : {
     234           0 :     float mf = fix16_to_float( *var_fix, 15 );
     235           0 :     *var_flt = (float) ldexp( mf, expo );
     236           0 : }
     237             : 
     238             : #undef WMC_TOOL_SKIP
     239             : 
     240             : /*-------------------------------------------------------------------*
     241             :  * usdequant_fx()
     242             :  *
     243             :  * Uniform scalar de-quantizer routine
     244             :  *
     245             :  * Applies de-quantization based on scale and round operations.
     246             :  *-------------------------------------------------------------------*/
     247      300452 : Word16 usdequant_fx(                    /* Qx*/
     248             :                      const Word16 idx,  /* i: quantizer index Q0*/
     249             :                      const Word16 qlow, /* i: lowest codebook entry (index 0) Qx*/
     250             :                      const Word16 delta /* i: quantization step Qx-1*/
     251             : )
     252             : {
     253             :     Word16 g;
     254             :     Word32 L_tmp;
     255             : 
     256             :     /*g = idx * delta + qlow;*/
     257      300452 :     L_tmp = L_deposit_l( qlow );                /*Qx */
     258      300452 :     L_tmp = L_mac( L_tmp, idx, delta );         /*Qx */
     259      300452 :     g = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
     260      300452 :     return ( g );
     261             : }
     262             : 
     263      188420 : Word32 usdequant32_fx(                    /* Qx*/
     264             :                        const Word16 idx,  /* i: quantizer index Q0*/
     265             :                        const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/
     266             :                        const Word32 delta /* i: quantization step Qx-1*/
     267             : )
     268             : {
     269             :     Word32 g;
     270             :     Word64 L_tmp;
     271             : 
     272             :     /*g = idx * delta + qlow;*/
     273      188420 :     L_tmp = W_deposit32_l( qlow ); /*Qx */
     274      188420 :     L_tmp = W_mac_32_16( L_tmp, delta, idx );
     275      188420 :     IF( GE_64( L_tmp, MAX_32 ) )
     276             :     {
     277       41249 :         g = MAX_32;
     278       41249 :         move32();
     279             :     }
     280             :     ELSE
     281             :     {
     282      147171 :         g = W_extract_l( L_tmp ); /*Qx */
     283             :     }
     284      188420 :     return ( g );
     285             : }
     286             : 
     287             : /*-------------------------------------------------------------------*
     288             :  * usquant()
     289             :  *
     290             :  * Uniform scalar quantizer according to MMSE criterion
     291             :  * (nearest neighbour in Euclidean space)
     292             :  *
     293             :  * Applies quantization based on scale and round operations.
     294             :  * Index of the winning codeword and the winning codeword itself are returned.
     295             :  *-------------------------------------------------------------------*/
     296     1197618 : Word16 usquant_fx(                     /* o: index of the winning codeword   */
     297             :                    const Word16 x,     /* i: scalar value to quantize        Qx*/
     298             :                    Word16 *xq,         /* o: quantized value                 Qx*/
     299             :                    const Word16 qlow,  /* i: lowest codebook entry (index 0) Qx*/
     300             :                    const Word16 delta, /* i: quantization step               Qx-1*/
     301             :                    const Word16 cbsize /* i: codebook size                   */
     302             : )
     303             : {
     304             :     Word16 idx;
     305             :     Word16 tmp, exp;
     306             :     Word32 L_tmp;
     307             : #ifndef ISSUE_1836_replace_overflow_libcom
     308             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     309             :     Flag Overflow = 0;
     310             :     move32();
     311             : #endif
     312             : #endif
     313             : 
     314             :     /*    idx = (short)( (x - qlow)/delta + 0.5f); */
     315     1197618 :     exp = norm_s( delta );
     316     1197618 :     tmp = div_s( shl( 1, sub( 14, exp ) ), delta ); /*Q(29-exp-(Qx-1))->Q(30-exp-Qx) */
     317             : #ifdef ISSUE_1836_replace_overflow_libcom
     318     1197618 :     L_tmp = L_mult( sub_sat( x, qlow ), tmp );                                                  /*Q(31-exp) */
     319     1197618 :     idx = extract_l( L_shr_r( L_add( L_tmp, shl_sat( 1, sub( 30, exp ) ) ), sub( 31, exp ) ) ); /*Q0 */
     320             : #else
     321             :     L_tmp = L_mult( sub_o( x, qlow, &Overflow ), tmp );                                                  /*Q(31-exp) */
     322             :     idx = extract_l( L_shr_r( L_add( L_tmp, shl_o( 1, sub( 30, exp ), &Overflow ) ), sub( 31, exp ) ) ); /*Q0 */
     323             : #endif
     324             : 
     325     1197618 :     idx = s_min( idx, sub( cbsize, 1 ) );
     326     1197618 :     idx = s_max( idx, 0 );
     327             : 
     328             :     /*    *xq = idx*delta + qlow; */
     329     1197618 :     L_tmp = L_deposit_l( qlow );        /*Qx */
     330     1197618 :     L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */
     331             : #ifdef ISSUE_1836_replace_overflow_libcom
     332     1197618 :     *xq = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
     333             : #else
     334             :     *xq = round_fx_o( L_shl_o( L_tmp, 16, &Overflow ), &Overflow );                                      /*Qx */
     335             : #endif
     336     1197618 :     return idx;
     337             : }
     338             : /*-------------------------------------------------------------------*
     339             :  * Dot_product:
     340             :  *
     341             :  * Compute scalar product of <x[],y[]> using accumulator.
     342             :  * Performs no normalization, as opposed to Dot_product12()
     343             :  *-------------------------------------------------------------------*/
     344    51234322 : Word32 Dot_product(                   /* o  : Sum              */
     345             :                     const Word16 x[], /* i  : 12bits: x vector */
     346             :                     const Word16 y[], /* i  : 12bits: y vector */
     347             :                     const Word16 lg   /* i  : vector length    */
     348             : )
     349             : {
     350             :     Word16 i;
     351             :     Word32 L_sum;
     352             :     Word64 L64_sum;
     353             : 
     354    51234322 :     L64_sum = 1;
     355    51234322 :     move64();
     356  3144009533 :     FOR( i = 0; i < lg; i++ )
     357             :     {
     358  3092775211 :         L64_sum = W_mac_16_16( L64_sum, x[i], y[i] );
     359             :     }
     360    51234322 :     L_sum = W_sat_l( L64_sum );
     361    51234322 :     return L_sum;
     362             : }
     363             : /*---------------------------------------------------------------------*
     364             :  * dotp_fx()
     365             :  *
     366             :  * Dot product of vector x[] and vector y[]
     367             :  *---------------------------------------------------------------------*/
     368             : 
     369     1389980 : Word32 dotp_fx(                   /* o  : dot product of x[] and y[]    */
     370             :                 const Word16 x[], /* i  : vector x[]                    */
     371             :                 const Word16 y[], /* i  : vector y[]                    */
     372             :                 const Word16 n,   /* i  : vector length                 */
     373             :                 Word16 *exp       /* (o)    : exponent of result (0..+30)       */
     374             : )
     375             : {
     376             :     Word16 sft;
     377             :     Word32 L_sum;
     378             : 
     379     1389980 :     assert( *exp == 0 );
     380             : 
     381     1389980 :     L_sum = L_add( L_shr( Dot_product( x, y, n ), 1 ), 1 );
     382             : 
     383             :     /* Normalize acc in Q31 */
     384             : 
     385     1389980 :     sft = norm_l( L_sum );
     386     1389980 :     L_sum = L_shl( L_sum, sft );
     387             : 
     388     1389980 :     *exp = sub( 30, sft );
     389     1389980 :     move16(); /* exponent = 0..30 */
     390             : 
     391     1389980 :     return L_sum;
     392             : }
     393             : 
     394      396065 : Word32 sum2_fx(                    /* o  : sum of all squared vector elements    Q(2x+1)*/
     395             :                 const Word16 *vec, /* i  : input vector                          Qx*/
     396             :                 const Word16 lvec  /* i  : length of input vector                */
     397             : )
     398             : {
     399             :     Word16 i;
     400             :     Word32 L_tmp;
     401             : #ifndef ISSUE_1836_replace_overflow_libcom
     402             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     403             :     Flag Overflow = 0;
     404             :     move32();
     405             : #endif
     406             : #endif
     407      396065 :     L_tmp = L_deposit_l( 0 );
     408    30705553 :     FOR( i = 0; i < lvec; i++ )
     409             :     {
     410             : #ifdef ISSUE_1836_replace_overflow_libcom
     411    30309488 :         L_tmp = L_mac_sat( L_tmp, vec[i], vec[i] ); /*Q(2x+1) */
     412             : #else
     413             :         L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow );                                             /*Q(2x+1) */
     414             : #endif
     415             :     }
     416             : 
     417      396065 :     return L_tmp;
     418             : }
     419             : 
     420      131508 : Word64 sum2_fx_no_sat(                    /* o  : sum of all squared vector elements    Q(2*Qx)*/
     421             :                        const Word16 *vec, /* i  : input vector                          Qx*/
     422             :                        const Word16 lvec  /* i  : length of input vector                */
     423             : )
     424             : {
     425             :     Word16 i;
     426             :     Word64 sum;
     427             : 
     428      131508 :     sum = 0;
     429      131508 :     move64();
     430    56241588 :     FOR( i = 0; i < lvec; i++ )
     431             :     {
     432    56110080 :         sum = W_mac0_16_16( sum, vec[i], vec[i] ); // 2*Qx
     433             :     }
     434             : 
     435      131508 :     return sum;
     436             : }
     437             : 
     438       93375 : Word32 sum_32_fx(
     439             :     const Word32 *vec, /* i  : input vector                          */
     440             :     const Word16 lvec, /* i  : length of input vector                */
     441             :     Word16 *e )
     442             : {
     443             :     Word16 i, shift;
     444       93375 :     Word64 tmp = 0;
     445       93375 :     move64();
     446             :     Word32 ans;
     447             : 
     448      301777 :     FOR( i = 0; i < lvec; i++ )
     449             :     {
     450      208402 :         tmp = W_add( tmp, vec[i] ); // e
     451             :     }
     452       93375 :     shift = W_norm( tmp );
     453       93375 :     tmp = W_shl( tmp, shift ); // shift + (31 - e)
     454       93375 :     ans = W_extract_h( tmp );  // shift + (31 - e) - 32
     455       93375 :     *e = add( sub( *e, shift ), 32 );
     456       93375 :     move16();
     457             : 
     458       93375 :     return ans;
     459             : }
     460             : 
     461       70294 : Word32 sum2_fx_mod(                    /* o  : sum of all squared vector elements    Q(2x+1 -5)*/
     462             :                     const Word16 *vec, /* i  : input vector                          Qx*/
     463             :                     const Word16 lvec  /* i  : length of input vector                */
     464             : )
     465             : {
     466             :     Word16 i;
     467             :     Word32 L_tmp;
     468             : #ifndef ISSUE_1836_replace_overflow_libcom
     469             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     470             :     Flag Overflow = 0;
     471             :     move32();
     472             : #endif
     473             : #endif
     474             : 
     475       70294 :     L_tmp = L_deposit_l( 0 );
     476    45058454 :     FOR( i = 0; i < lvec; i++ )
     477             :     {
     478             : #ifdef ISSUE_1836_replace_overflow_libcom
     479    44988160 :         L_tmp = L_add_sat( L_tmp, L_shr( L_mult_sat( vec[i], vec[i] ), 9 ) );
     480             : #else
     481             :         L_tmp = L_add_o( L_tmp, L_shr( L_mult_o( vec[i], vec[i], &Overflow ), 9 ), &Overflow );
     482             : #endif
     483             :     }
     484             : 
     485       70294 :     return L_tmp;
     486             : }
     487             : /*-------------------------------------------------------------------*
     488             :  * Copy:
     489             :  *
     490             :  * Copy vector x[] to y[]
     491             :  *
     492             :  *-------------------------------------------------------------------*/
     493   176865465 : void Copy(
     494             :     const Word16 x[], /* i  : input vector  */
     495             :     Word16 y[],       /* o  : output vector */
     496             :     const Word16 L    /* i  : vector length */
     497             : )
     498             : {
     499             :     Word16 i;
     500             : 
     501   176865465 :     IF( y < x )
     502             :     {
     503 17585189660 :         FOR( i = 0; i < L; i++ )
     504             :         {
     505 17495282013 :             y[i] = x[i];
     506 17495282013 :             move16();
     507             :         }
     508             : 
     509             :         /* 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. */
     510    89907647 :         return;
     511             :     }
     512             : 
     513 17169131725 :     FOR( i = L - 1; i >= 0; i-- )
     514             :     {
     515 17082173907 :         y[i] = x[i];
     516 17082173907 :         move16();
     517             :     }
     518             : 
     519    86957818 :     return;
     520             : }
     521             : /*-------------------------------------------------------------------*
     522             :  * Copy64:
     523             :  *
     524             :  * Copy vector x[] to y[] (64 bits)
     525             :  *-------------------------------------------------------------------*/
     526        8214 : void Copy64(
     527             :     const Word64 x[], /* i  : input vector  */
     528             :     Word64 y[],       /* o  : output vector */
     529             :     const Word16 L    /* i  : vector length */
     530             : )
     531             : {
     532             :     Word16 i;
     533        8214 :     IF( y < x )
     534             :     {
     535           0 :         FOR( i = 0; i < L; i++ )
     536             :         {
     537           0 :             y[i] = x[i];
     538           0 :             move64();
     539             :         }
     540             : 
     541             :         /* 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. */
     542           0 :         return;
     543             :     }
     544             : 
     545       35814 :     FOR( i = L - 1; i >= 0; i-- )
     546             :     {
     547       27600 :         y[i] = x[i];
     548       27600 :         move64();
     549             :     }
     550             : 
     551        8214 :     return;
     552             : }
     553             : 
     554    10120249 : void set64_fx(
     555             :     Word64 y[],     /* i/o: Vector to set                       */
     556             :     const Word64 a, /* i  : Value to set the vector to          */
     557             :     const Word16 N  /* i  : Lenght of the vector                */
     558             : )
     559             : {
     560             :     Word16 i;
     561   397851773 :     FOR( i = 0; i < N; i++ )
     562             :     {
     563   387731524 :         y[i] = a;
     564   387731524 :         move64();
     565             :     }
     566             : 
     567    10120249 :     return;
     568             : }
     569             : 
     570      146722 : void Copy_pword(
     571             :     const PWord16 x[], /* i  : input vector  */
     572             :     PWord16 y[],       /* o  : output vector */
     573             :     const Word16 L     /* i  : vector length */
     574             : )
     575             : {
     576             :     Word16 i;
     577             : 
     578      146722 :     IF( y < x )
     579             :     {
     580     2865090 :         FOR( i = 0; i < L; i++ )
     581             :         {
     582     2731118 :             y[i].v.im = x[i].v.im;
     583     2731118 :             y[i].v.re = x[i].v.re;
     584     2731118 :             move16();
     585     2731118 :             move16();
     586             :         }
     587             : 
     588             :         /* 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. */
     589      133972 :         return;
     590             :     }
     591             : 
     592      792650 :     FOR( i = L - 1; i >= 0; i-- )
     593             :     {
     594      779900 :         y[i].v.im = x[i].v.im;
     595      779900 :         y[i].v.re = x[i].v.re;
     596      779900 :         move16();
     597      779900 :         move16();
     598             :     }
     599             : 
     600       12750 :     return;
     601             : }
     602             : /*-------------------------------------------------------------------*
     603             :  * Copy32:
     604             :  *
     605             :  * Copy vector x[] to y[] (32 bits)
     606             :  *-------------------------------------------------------------------*/
     607   320665764 : void Copy32(
     608             :     const Word32 x[], /* i  : input vector  */
     609             :     Word32 y[],       /* o  : output vector */
     610             :     const Word16 L    /* i  : vector length */
     611             : )
     612             : {
     613             :     Word16 i;
     614   320665764 :     IF( y < x )
     615             :     {
     616 35372221041 :         FOR( i = 0; i < L; i++ )
     617             :         {
     618 35213441121 :             y[i] = x[i];
     619 35213441121 :             move32();
     620             :         }
     621             : 
     622   158779920 :         return;
     623             :     }
     624             : 
     625 32470002237 :     FOR( i = L - 1; i >= 0; i-- )
     626             :     {
     627 32308116393 :         y[i] = x[i];
     628 32308116393 :         move32();
     629             :     }
     630             : }
     631             : 
     632       86971 : void set8_fx(
     633             :     Word8 y[],     /* i/o: Vector to set                       */
     634             :     const Word8 a, /* i  : Value to set the vector to          */
     635             :     const Word16 N /* i  : Lenght of the vector                */
     636             : )
     637             : {
     638             :     Word16 i;
     639             : 
     640    49445867 :     FOR( i = 0; i < N; i++ )
     641             :     {
     642    49358896 :         y[i] = a;
     643    49358896 :         move16();
     644             :     }
     645             : 
     646       86971 :     return;
     647             : }
     648             : 
     649             : /*-------------------------------------------------------------------*
     650             :  * set16_fx()
     651             :  * set32_fx()
     652             :  *
     653             :  * Set the vector elements to a value
     654             :  *-------------------------------------------------------------------*/
     655   265118329 : void set16_fx(
     656             :     Word16 y[],     /* i/o: Vector to set                       */
     657             :     const Word16 a, /* i  : Value to set the vector to          */
     658             :     const Word16 N  /* i  : Lenght of the vector                */
     659             : )
     660             : {
     661             :     Word16 i;
     662             : 
     663 34631906662 :     FOR( i = 0; i < N; i++ )
     664             :     {
     665 34366788333 :         y[i] = a;
     666 34366788333 :         move16();
     667             :     }
     668             : 
     669   265118329 :     return;
     670             : }
     671             : 
     672   670298935 : void set32_fx(
     673             :     Word32 y[],     /* i/o: Vector to set                       */
     674             :     const Word32 a, /* i  : Value to set the vector to          */
     675             :     const Word16 N  /* i  : Lenght of the vector                */
     676             : )
     677             : {
     678             :     Word16 i;
     679             : 
     680 66776738762 :     FOR( i = 0; i < N; i++ )
     681             :     {
     682 66106439827 :         y[i] = a;
     683 66106439827 :         move32();
     684             :     }
     685             : 
     686   670298935 :     return;
     687             : }
     688             : /*-------------------------------------------------------------------*
     689             :  * Copy_Scale_sig
     690             :  *
     691             :  * Up/down scale a 16 bits vector x and move it into y
     692             :  *-------------------------------------------------------------------*/
     693    20160305 : void Copy_Scale_sig(
     694             :     const Word16 x[], /* i  : signal to scale input           Qx        */
     695             :     Word16 y[],       /* o  : scaled signal output            Qx        */
     696             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     697             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     698             : )
     699             : {
     700             :     Word16 i;
     701             :     Word16 tmp;
     702             : #ifndef ISSUE_1836_replace_overflow_libcom
     703             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     704             :     Flag Overflow = 0;
     705             :     move32();
     706             : #endif
     707             : #endif
     708    20160305 :     IF( exp0 == 0 )
     709             :     {
     710  1962459905 :         FOR( i = 0; i < lg; i++ )
     711             :         {
     712  1958809919 :             y[i] = x[i];
     713  1958809919 :             move16();
     714             :         }
     715     3649986 :         return;
     716             :     }
     717    16510319 :     IF( exp0 < 0 )
     718             :     {
     719    12621075 :         tmp = shl( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
     720  5539962438 :         FOR( i = 0; i < lg; i++ )
     721             :         {
     722  5527341363 :             y[i] = msu_r( 0, x[i], tmp );
     723  5527341363 :             move16();
     724             :         }
     725    12621075 :         return;
     726             :     }
     727  2020655445 :     FOR( i = 0; i < lg; i++ )
     728             :     {
     729             : #ifdef ISSUE_1836_replace_overflow_libcom
     730  2016766201 :         y[i] = shl_sat( x[i], exp0 );
     731             : #else
     732             :         y[i] = shl_o( x[i], exp0, &Overflow );
     733             : #endif
     734  2016766201 :         move16(); /* saturation can occur here */
     735             :     }
     736             : }
     737             : /*-------------------------------------------------------------------*
     738             :  * Copy_Scale_sig
     739             :  *
     740             :  * Up/down scale a 16 bits vector x and move it into y
     741             :  *-------------------------------------------------------------------*/
     742     3703527 : void Copy_Scale_sig_16_32_DEPREC(
     743             :     const Word16 x[], /* i  : signal to scale input           Qx        */
     744             :     Word32 y[],       /* o  : scaled signal output            Qx        */
     745             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     746             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     747             : )
     748             : {
     749             :     Word16 i;
     750             :     Word16 tmp;
     751             : #ifndef ISSUE_1836_replace_overflow_libcom
     752             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     753             :     Flag Overflow = 0;
     754             :     move32();
     755             : #endif
     756             : #endif
     757             : 
     758             : 
     759     3703527 :     IF( exp0 == 0 )
     760             :     {
     761  1097287870 :         FOR( i = 0; i < lg; i++ )
     762             :         {
     763  1095090667 :             y[i] = L_deposit_l( x[i] );
     764  1095090667 :             move32();
     765             :         }
     766     2197203 :         return;
     767             :     }
     768     1506324 :     IF( exp0 < 0 )
     769             :     {
     770             :         /*Should not happen */
     771    61691106 :         FOR( i = 0; i < lg; i++ )
     772             :         {
     773             : #ifdef ISSUE_1836_replace_overflow_libcom
     774    61512748 :             y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
     775             : #else
     776             :             y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) );
     777             : #endif
     778    61512748 :             move32();
     779             :         }
     780      178358 :         return;
     781             :     }
     782             : #ifdef DEBUGGING
     783             :     if ( exp0 >= 16 )
     784             :     {
     785             :         printf( "Issue in Copy_Scale_sig_16_32_DEPREC\n" );
     786             :     }
     787             : #else
     788     1327966 :     assert( exp0 < 16 );
     789             : #endif
     790             : #ifdef ISSUE_1836_replace_overflow_libcom
     791     1327966 :     tmp = shl_sat( 1, exp0 );
     792             : #else
     793             :     tmp = shl_o( 1, exp0, &Overflow );
     794             : #endif
     795   421457972 :     FOR( i = 0; i < lg; i++ )
     796             :     {
     797   420130006 :         y[i] = L_mult0( x[i], tmp );
     798   420130006 :         move32(); /* saturation can occur here */
     799             :     }
     800             : }
     801             : 
     802    16810513 : void Copy_Scale_sig_16_32_no_sat(
     803             :     const Word16 x[], /* i  : signal to scale input           Qx        */
     804             :     Word32 y[],       /* o  : scaled signal output            Qx        */
     805             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     806             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     807             : )
     808             : {
     809             :     Word16 i;
     810             :     Word32 L_tmp;
     811             : #ifndef ISSUE_1836_replace_overflow_libcom
     812             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     813             :     Flag Overflow = 0;
     814             :     move32();
     815             : #endif
     816             : #endif
     817             : 
     818             : 
     819    16810513 :     IF( exp0 == 0 )
     820             :     {
     821   572200102 :         FOR( i = 0; i < lg; i++ )
     822             :         {
     823   569980919 :             y[i] = L_deposit_l( x[i] );
     824   569980919 :             move32();
     825             :         }
     826     2219183 :         return;
     827             :     }
     828    14591330 :     IF( exp0 < 0 )
     829             :     {
     830             :         /*Should not happen */
     831   273541668 :         FOR( i = 0; i < lg; i++ )
     832             :         {
     833             : #ifdef ISSUE_1836_replace_overflow_libcom
     834   272884714 :             y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
     835             : #else
     836             :             y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) );
     837             : #endif
     838   272884714 :             move32();
     839             :         }
     840      656954 :         return;
     841             :     }
     842             : #ifdef ISSUE_1836_replace_overflow_libcom
     843    13934376 :     L_tmp = L_shl_sat( 1, exp0 - 1 );
     844             : #else
     845             :     L_tmp = L_shl_o( 1, exp0 - 1, &Overflow );
     846             : #endif
     847             : 
     848    13934376 :     IF( L_tmp >= 0x7FFF )
     849             :     {
     850  1541747252 :         FOR( i = 0; i < lg; i++ )
     851             :         {
     852             :             // y[i] = L_mult0(x[i], L_tmp);
     853  1539129961 :             y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) );
     854  1539129961 :             move32(); /* Overflow can occur here */
     855             :         }
     856     2617291 :         return;
     857             :     }
     858             :     // ELSE
     859             :     {
     860    11317085 :         Word16 tmp = extract_l( L_tmp );
     861  5218173985 :         FOR( i = 0; i < lg; i++ )
     862             :         {
     863  5206856900 :             y[i] = L_mult( x[i], tmp );
     864  5206856900 :             move32();
     865             :         }
     866             :     }
     867             : }
     868             : 
     869    10263768 : void Copy_Scale_sig_32_16(
     870             :     const Word32 x[], /* i  : signal to scale input           Qx        */
     871             :     Word16 y[],       /* o  : scaled signal output            Qx        */
     872             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     873             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     874             : )
     875             : {
     876             :     Word16 i;
     877             :     Word16 tmp;
     878             : #ifndef ISSUE_1836_replace_overflow_libcom
     879             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     880             :     Flag Overflow = 0;
     881             :     move32();
     882             : #endif
     883             : #endif
     884             : 
     885    10263768 :     tmp = add( 16, exp0 );
     886    10263768 :     IF( tmp != 0 )
     887             :     {
     888  6744362302 :         FOR( i = 0; i < lg; i++ )
     889             :         {
     890             : #ifdef ISSUE_1836_replace_overflow_libcom
     891  6734427596 :             y[i] = round_fx_sat( L_shl_sat( x[i], tmp ) );
     892             : #else
     893             :             y[i] = round_fx_o( L_shl_o( x[i], tmp, &Overflow ), &Overflow );
     894             : #endif
     895  6734427596 :             move16();
     896             :         }
     897             :     }
     898             :     ELSE
     899             :     {
     900    85833472 :         FOR( i = 0; i < lg; i++ )
     901             :         {
     902             : #ifdef ISSUE_1836_replace_overflow_libcom
     903    85504410 :             y[i] = round_fx_sat( x[i] );
     904             : #else
     905             :             y[i] = round_fx_o( x[i], &Overflow );
     906             : #endif
     907    85504410 :             move16();
     908             :         }
     909             :     }
     910    10263768 : }
     911             : 
     912             : /*-------------------------------------------------------------------*
     913             :  * Scale_sig32
     914             :  *
     915             :  * Up/down scale a 32 bits vector
     916             :  *-------------------------------------------------------------------*/
     917   112112567 : void Scale_sig32(
     918             :     Word32 x[],       /* i/o: signal to scale                 Qx        */
     919             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     920             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     921             : )
     922             : {
     923             :     Word16 i;
     924             : #ifndef ISSUE_1836_replace_overflow_libcom
     925             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     926             :     Flag Overflow = 0;
     927             :     move32();
     928             : #endif
     929             : #endif
     930   112112567 :     IF( 0 == exp0 )
     931             :     {
     932    32110348 :         return;
     933             :     }
     934             : 
     935 29605660366 :     FOR( i = 0; i < lg; i++ )
     936             :     {
     937             : #ifdef ISSUE_1836_replace_overflow_libcom
     938 29525658147 :         x[i] = L_shl_sat( x[i], exp0 );
     939             : #else
     940             :         x[i] = L_shl_o( x[i], exp0, &Overflow );
     941             : #endif
     942 29525658147 :         move32(); /* saturation can occur here */
     943             :     }
     944             : }
     945             : 
     946             : /*------------------------------------------------------------------*
     947             :  * function Random_Fill
     948             :  *
     949             :  * Signed 16 bits random generator.
     950             :  * (Avoids Store of Seed to Memory for 'n' Random Values and
     951             :  *  Combines Scaling Operation.)
     952             :  *------------------------------------------------------------------*/
     953       62672 : void Random_Fill(
     954             :     Word16 *seed,  /* i/o: random seed         */
     955             :     Word16 n,      /* i  : number of values    */
     956             :     Word16 *y,     /* o  : output values       */
     957             :     Word16 scaling /* i  : scaling of values   */
     958             : )
     959             : {
     960             :     Word16 i;
     961             :     Word16 local_seed;
     962             : 
     963       62672 :     local_seed = *seed;
     964       62672 :     move16();
     965     5849232 :     FOR( i = 0; i < n; i++ )
     966             :     {
     967     5786560 :         local_seed = extract_l( L_mac0( 13849L, local_seed, 31821 ) );
     968     5786560 :         *y++ = shr( local_seed, scaling );
     969     5786560 :         move16();
     970             :     }
     971       62672 :     *seed = local_seed;
     972       62672 :     move16();
     973       62672 : }
     974             : /*-------------------------------------------------------------------*
     975             :  * Scale_sig
     976             :  * Up/down scale a 16 bits vector
     977             :  *-------------------------------------------------------------------*/
     978    89421030 : void Scale_sig(
     979             :     Word16 x[],       /* i/o: signal to scale                 Qx        */
     980             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     981             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
     982             : )
     983             : {
     984             :     Word16 i;
     985             :     Word16 tmp;
     986             : 
     987    89421030 :     IF( exp0 > 0 )
     988             :     {
     989  9909085040 :         FOR( i = 0; i < lg; i++ )
     990             :         {
     991  9889299077 :             x[i] = shl_sat( x[i], exp0 );
     992  9889299077 :             move16(); /* saturation can occur here */
     993             :         }
     994    19785963 :         return;
     995             :     }
     996    69635067 :     IF( exp0 < 0 )
     997             :     {
     998    36258107 :         tmp = shl_sat( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
     999 14755156941 :         FOR( i = 0; i < lg; i++ )
    1000             :         {
    1001 14718898834 :             x[i] = msu_r_sat( 0, x[i], tmp );
    1002 14718898834 :             move16(); /* msu instead of mac because factor is negative */
    1003             :         }
    1004    36258107 :         return;
    1005             :     }
    1006             : }
    1007             : 
    1008             : /*-------------------------------------------------------------------*
    1009             :  * scale_sig
    1010             :  * Up/down scale a 16 bits vector
    1011             :  *-------------------------------------------------------------------*/
    1012     9160317 : void scale_sig(
    1013             :     Word16 x[],       /* i/o: signal to scale                 Qx        */
    1014             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    1015             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx   exp  */
    1016             : )
    1017             : {
    1018             :     Word16 i;
    1019             : 
    1020     9160317 :     IF( exp0 != 0 )
    1021             :     {
    1022  2347871685 :         FOR( i = 0; i < lg; i++ )
    1023             :         {
    1024  2341940950 :             x[i] = shl( x[i], exp0 );
    1025  2341940950 :             move16();
    1026             :         }
    1027             :     }
    1028     9160317 : }
    1029             : 
    1030             : /*---------------------------------------------------------------------*
    1031             :  * mean_fx()
    1032             :  *
    1033             :  *---------------------------------------------------------------------*/
    1034       33065 : Word16 mean_fx(                       /* o  : mean of vector                         */
    1035             :                 const Word16 *vec_fx, /* i  : input vector                           */
    1036             :                 const Word16 lvec_fx  /* i  : length of input vector                 */
    1037             : )
    1038             : {
    1039             :     Word16 tmp;
    1040             :     // PMT("TBV : this function could be written differently to minimize the risk of saturation");
    1041       33065 :     tmp = sum16_fx( vec_fx, lvec_fx );
    1042       33065 :     tmp = mult_r( tmp, div_s( 1, lvec_fx ) );
    1043             : 
    1044       33065 :     return tmp;
    1045             : }
    1046             : 
    1047       21405 : Word16 mean_no_sat_fx(                       /* o  : mean of vector         Qx */
    1048             :                        const Word16 *vec_fx, /* i  : input vector           Qx */
    1049             :                        const Word16 lvec_fx  /* i  : length of input vector    */
    1050             : )
    1051             : {
    1052             :     Word16 i;
    1053       21405 :     Word32 L_tmp = 0;
    1054       21405 :     move32();
    1055      706365 :     FOR( i = 0; i < lvec_fx; ++i )
    1056             :     {
    1057      684960 :         L_tmp = L_add( L_tmp, vec_fx[i] );
    1058             :     }
    1059       21405 :     L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx */
    1060             : 
    1061       21405 :     return extract_l( L_tmp );
    1062             : }
    1063        7424 : Word32 mean_no_sat_Word32_fx(                       /* o  : mean of vector         Qx */
    1064             :                               const Word32 *vec_fx, /* i  : input vector           Qx */
    1065             :                               const Word16 lvec_fx, /* i  : length of input vector    */
    1066             :                               const Word16 gb )
    1067             : {
    1068             :     Word16 i;
    1069        7424 :     Word32 L_tmp = 0;
    1070        7424 :     move32();
    1071       37120 :     FOR( i = 0; i < lvec_fx; ++i )
    1072             :     {
    1073       29696 :         L_tmp = L_add( L_tmp, L_shr( vec_fx[i], gb ) );
    1074             :     }
    1075        7424 :     L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx-gb */
    1076             : 
    1077        7424 :     return L_tmp;
    1078             : }
    1079             : /*-------------------------------------------------------------------*
    1080             :  * Vr_add
    1081             :  *
    1082             :  * Add two Word16 vectors together integer by integer
    1083             :  *-------------------------------------------------------------------*/
    1084     3955150 : void Vr_add(
    1085             :     const Word16 *in1, /* i  : Input vector 1                                   */
    1086             :     const Word16 *in2, /* i  : Input vector 2                                   */
    1087             :     Word16 *out,       /* o  : Output vector that contains vector 1 + vector 2  */
    1088             :     Word16 Len         /* i  : Vector lenght                                    */
    1089             : )
    1090             : {
    1091             :     Word16 i;
    1092             : 
    1093   100845358 :     FOR( i = 0; i < Len; i++ )
    1094             :     {
    1095    96890208 :         out[i] = add_sat( in1[i], in2[i] );
    1096    96890208 :         move16();
    1097             :     }
    1098     3955150 : }
    1099             : 
    1100     1429421 : void sort_fx(
    1101             :     Word16 *r, /* i/o: Vector to be sorted in place */
    1102             :     Word16 lo, /* i  : Low limit of sorting range   */
    1103             :     Word16 up  /* I  : High limit of sorting range  */
    1104             : )
    1105             : {
    1106             :     Word16 i, j, i1;
    1107             :     Word16 tempr;
    1108             : 
    1109    22865400 :     FOR( i = sub( up, 1 ); i >= lo; i-- )
    1110             :     {
    1111    21435979 :         i1 = add( i, 1 );
    1112    21435979 :         tempr = r[i];
    1113    21435979 :         move16();
    1114    21435979 :         move16(); /*supplementary move for the j-1 PTR initialization*/
    1115    21457595 :         FOR( j = i1; j <= up; j++ )
    1116             :         {
    1117    21456539 :             IF( LE_16( tempr, r[j] ) )
    1118             :             {
    1119    21434923 :                 BREAK;
    1120             :             }
    1121             : 
    1122       21616 :             r[j - 1] = r[j];
    1123       21616 :             move16();
    1124             :         }
    1125    21435979 :         r[j - 1] = tempr;
    1126    21435979 :         move16();
    1127             :     }
    1128     1429421 : }
    1129             : 
    1130        6150 : void sort_32_fx(
    1131             :     Word32 *r,       /* i/o: Vector to be sorted in place */
    1132             :     const Word16 lo, /* i  : Low limit of sorting range   */
    1133             :     const Word16 up  /* I  : High limit of sorting range  */
    1134             : )
    1135             : {
    1136             :     Word16 i, j;
    1137             :     Word32 tempr;
    1138      164000 :     FOR( i = sub( up, 1 ); i >= lo; i-- )
    1139             :     {
    1140      157850 :         tempr = r[i];
    1141      157850 :         move32();
    1142     1416574 :         FOR( j = add( i, 1 ); j <= up; j++ )
    1143             :         {
    1144     1390083 :             IF( LE_32( tempr, r[j] ) )
    1145             :             {
    1146      131359 :                 BREAK;
    1147             :             }
    1148     1258724 :             r[j - 1] = r[j];
    1149     1258724 :             move32();
    1150             :         }
    1151             : 
    1152      157850 :         r[j - 1] = tempr;
    1153      157850 :         move32();
    1154             :     }
    1155             : 
    1156        6150 :     return;
    1157             : }
    1158             : 
    1159     2701095 : Word16 minimum_fx(                       /* o  : index of the minimum value in the input vector */
    1160             :                    const Word16 *vec_fx, /* i  : input vector                                   */
    1161             :                    const Word16 lvec_fx, /* i  : length of input vector                         */
    1162             :                    Word16 *min_fx        /* o  : minimum value in the input vector              */
    1163             : )
    1164             : {
    1165             :     Word16 j, ind;
    1166             :     Word16 tmp;
    1167     2701095 :     ind = 0;
    1168     2701095 :     move16();
    1169     2701095 :     tmp = vec_fx[0];
    1170     2701095 :     move16();
    1171             : 
    1172    75576330 :     FOR( j = 1; j < lvec_fx; j++ )
    1173             :     {
    1174    72875235 :         if ( LT_16( vec_fx[j], tmp ) )
    1175             :         {
    1176     1380976 :             ind = j;
    1177     1380976 :             move16();
    1178             :             /*tmp = vec_fx[j];    move16(); */
    1179             :         }
    1180    72875235 :         tmp = s_min( tmp, vec_fx[j] );
    1181             :     }
    1182             : 
    1183     2701095 :     *min_fx = tmp;
    1184     2701095 :     move16();
    1185             : 
    1186     2701095 :     return ind;
    1187             : }
    1188             : 
    1189    27396584 : Word16 maximum_fx(                       /* o  : index of the maximum value in the input vector */
    1190             :                    const Word16 *vec_fx, /* i  : input vector                                   */
    1191             :                    const Word16 lvec_fx, /* i  : length of input vector                         */
    1192             :                    Word16 *max_fx        /* o  : maximum value in the input vector              */
    1193             : )
    1194             : {
    1195             :     Word16 j, ind;
    1196             :     Word16 tmp;
    1197    27396584 :     ind = 0;
    1198    27396584 :     move16();
    1199    27396584 :     tmp = vec_fx[0];
    1200    27396584 :     move16();
    1201             : 
    1202   180515441 :     FOR( j = 1; j < lvec_fx; j++ )
    1203             :     {
    1204   153118857 :         if ( GT_16( vec_fx[j], tmp ) )
    1205             :         {
    1206    26683747 :             ind = j;
    1207    26683747 :             move16();
    1208             :         }
    1209   153118857 :         tmp = s_max( tmp, vec_fx[j] );
    1210             :     }
    1211    27396584 :     *max_fx = tmp;
    1212    27396584 :     move16();
    1213             : 
    1214    27396584 :     return ind;
    1215             : }
    1216             : 
    1217    24536664 : Word16 maximum_exp_fx(                        /* o  : index of the maximum value in the input vector */
    1218             :                        const Word16 *vec_fx,  /* i  : input vector                                   */
    1219             :                        const Word16 *exp_vec, /* i  : exponents of input vector                      */
    1220             :                        const Word16 lvec_fx   /* i  : length of input vector                         */
    1221             : )
    1222             : {
    1223             :     Word16 j, ind;
    1224             :     Word16 tmp, exp;
    1225    24536664 :     ind = 0;
    1226    24536664 :     move16();
    1227    24536664 :     tmp = vec_fx[0];
    1228    24536664 :     move16();
    1229    24536664 :     exp = exp_vec[0];
    1230    24536664 :     move16();
    1231             : 
    1232   698782848 :     FOR( j = 1; j < lvec_fx; j++ )
    1233             :     {
    1234   674246184 :         IF( LT_16( tmp, shr_sat( vec_fx[j], sub( exp, exp_vec[j] ) ) ) )
    1235             :         {
    1236   121946525 :             ind = j;
    1237   121946525 :             move16();
    1238   121946525 :             tmp = vec_fx[j];
    1239   121946525 :             move16();
    1240   121946525 :             exp = exp_vec[j];
    1241   121946525 :             move16();
    1242             :         }
    1243             :     }
    1244             : 
    1245    24536664 :     return ind;
    1246             : }
    1247             : 
    1248             : /*---------------------------------------------------------------------*
    1249             :  * maximum_abs_16_fx()
    1250             :  *
    1251             :  * Find index and value of the absolute maximum in a vector
    1252             :  *---------------------------------------------------------------------*/
    1253             : 
    1254      870116 : Word16 maximum_abs_16_fx(                    /* o  : index of the maximum abs value in the input vector */
    1255             :                           const Word16 *vec, /* i  : input vector                                   */
    1256             :                           const Word16 lvec, /* i  : length of input vector                         */
    1257             :                           Word16 *max_val    /* o  : maximum value in the input vector              */
    1258             : )
    1259             : {
    1260             :     Word16 j, ind;
    1261             :     Word16 tmp;
    1262      870116 :     ind = 0;
    1263      870116 :     move16();
    1264      870116 :     tmp = abs_s( vec[0] );
    1265             : 
    1266   104712536 :     FOR( j = 1; j < lvec; j++ )
    1267             :     {
    1268   103842420 :         if ( GT_16( abs_s( vec[j] ), tmp ) )
    1269             :         {
    1270     4321161 :             ind = j;
    1271     4321161 :             move16();
    1272             :         }
    1273   103842420 :         tmp = s_max( tmp, abs_s( vec[j] ) );
    1274             :     }
    1275      870116 :     *max_val = tmp;
    1276      870116 :     move16();
    1277             : 
    1278      870116 :     return ind;
    1279             : }
    1280             : 
    1281             : /*---------------------------------------------------------------------*
    1282             :  * minimum_abs32_fx()
    1283             :  *
    1284             :  * Find index and value of the absolute minimum in a vector
    1285             :  *---------------------------------------------------------------------*/
    1286           0 : Word16 minimum_abs32_fx(                       /* o  : index of the minimum value in the input vector */
    1287             :                          const Word32 *vec_fx, /* i  : input vector                                   */
    1288             :                          const Word16 lvec_fx, /* i  : length of input vector                         */
    1289             :                          Word32 *min_fx        /* o  : minimum value in the input vector              */
    1290             : )
    1291             : {
    1292             :     Word16 j, ind;
    1293             :     Word32 tmp;
    1294           0 :     ind = 0;
    1295           0 :     move16();
    1296           0 :     tmp = vec_fx[0];
    1297           0 :     move16();
    1298             : 
    1299           0 :     FOR( j = 1; j < lvec_fx; j++ )
    1300             :     {
    1301           0 :         IF( LT_32( L_abs( vec_fx[j] ), tmp ) )
    1302             :         {
    1303           0 :             ind = j;
    1304           0 :             move16();
    1305             :             /*tmp = vec_fx[j];    move16(); */
    1306             :         }
    1307           0 :         tmp = L_min( tmp, L_abs( vec_fx[j] ) );
    1308             :     }
    1309             : 
    1310           0 :     *min_fx = tmp;
    1311           0 :     move16();
    1312             : 
    1313           0 :     return ind;
    1314             : }
    1315             : 
    1316             : /*---------------------------------------------------------------------*
    1317             :  * minimum_32_fx()
    1318             :  *
    1319             :  * Find index and value of the minimum in a vector
    1320             :  *---------------------------------------------------------------------*/
    1321             : 
    1322      447481 : Word16 minimum_32_fx(                       /* o  : index of the minimum value in the input vector */
    1323             :                       const Word32 *vec_fx, /* i  : input vector                                   */
    1324             :                       const Word16 lvec_fx, /* i  : length of input vector                         */
    1325             :                       Word32 *min_fx        /* o  : minimum value in the input vector              */
    1326             : )
    1327             : {
    1328             :     Word16 j, ind;
    1329             :     Word32 tmp;
    1330      447481 :     ind = 0;
    1331      447481 :     move16();
    1332      447481 :     tmp = vec_fx[0];
    1333      447481 :     move16();
    1334             : 
    1335     1035537 :     FOR( j = 1; j < lvec_fx; j++ )
    1336             :     {
    1337      588056 :         if ( LT_32( vec_fx[j], tmp ) )
    1338             :         {
    1339      240655 :             ind = j;
    1340      240655 :             move16();
    1341             :             /*tmp = vec_fx[j];    move32(); */
    1342             :         }
    1343      588056 :         tmp = L_min( tmp, vec_fx[j] );
    1344             :     }
    1345      447481 :     if ( min_fx != NULL )
    1346             :     {
    1347      348058 :         *min_fx = tmp;
    1348             :     }
    1349      447481 :     move32();
    1350             : 
    1351      447481 :     return ind;
    1352             : }
    1353             : 
    1354             : /*---------------------------------------------------------------------*
    1355             :  * maximum_32_fx()
    1356             :  *
    1357             :  * Find index and value of the maximum in a vector
    1358             :  *---------------------------------------------------------------------*/
    1359             : 
    1360     5571469 : Word16 maximum_32_fx(                    /* o  : index of the maximum value in the input vector */
    1361             :                       const Word32 *vec, /* i  : input vector                                   */
    1362             :                       const Word16 lvec, /* i  : length of input vector                         */
    1363             :                       Word32 *max_val    /* o  : maximum value in the input vector              */
    1364             : )
    1365             : {
    1366             :     Word16 j, ind;
    1367             :     Word32 tmp;
    1368     5571469 :     ind = 0;
    1369     5571469 :     move16();
    1370     5571469 :     tmp = vec[0];
    1371     5571469 :     move16();
    1372             : 
    1373    66841385 :     FOR( j = 1; j < lvec; j++ )
    1374             :     {
    1375    61269916 :         IF( GT_32( vec[j], tmp ) )
    1376             :         {
    1377     5405660 :             ind = j;
    1378     5405660 :             move16();
    1379             :         }
    1380    61269916 :         tmp = L_max( tmp, vec[j] );
    1381             :     }
    1382     5571469 :     if ( max_val != NULL )
    1383             :     {
    1384     5557548 :         *max_val = tmp;
    1385             :     }
    1386     5571469 :     move32();
    1387             : 
    1388     5571469 :     return ind;
    1389             : }
    1390             : 
    1391     4905909 : Word16 maximum_abs_32_fx(                    /* o  : index of the maximum abs value in the input vector */
    1392             :                           const Word32 *vec, /* i  : input vector                                   */
    1393             :                           const Word16 lvec, /* i  : length of input vector                         */
    1394             :                           Word32 *max_val    /* o  : maximum value in the input vector              */
    1395             : )
    1396             : {
    1397             :     Word16 j, ind;
    1398             :     Word32 tmp;
    1399     4905909 :     ind = 0;
    1400     4905909 :     move16();
    1401     4905909 :     tmp = L_abs( vec[0] );
    1402             : 
    1403  1801845650 :     FOR( j = 1; j < lvec; j++ )
    1404             :     {
    1405  1796939741 :         if ( GT_32( L_abs( vec[j] ), tmp ) )
    1406             :         {
    1407    19377206 :             ind = j;
    1408    19377206 :             move16();
    1409             :         }
    1410  1796939741 :         tmp = L_max( tmp, L_abs( vec[j] ) );
    1411             :     }
    1412     4905909 :     *max_val = tmp;
    1413     4905909 :     move32();
    1414             : 
    1415     4905909 :     return ind;
    1416             : }
    1417             : 
    1418             : 
    1419             : /*----------------------------------------------------------------
    1420             :  *Function:
    1421             :  *Finds number of shifts to normalize a 16-bit array variable.
    1422             :  *Return value
    1423             :  *Number of shifts
    1424             :  *----------------------------------------------------------------*/
    1425       92655 : Word16 Exp16Array(
    1426             :     const Word16 n,  /* (i): Array size   */
    1427             :     const Word16 *sx /* (i): Data array   */
    1428             : )
    1429             : {
    1430             :     Word16 k;
    1431             :     Word16 exp;
    1432             :     Word16 sMax;
    1433             :     Word16 sAbs;
    1434             : 
    1435       92655 :     sMax = abs_s( sx[0] );
    1436       92655 :     move16();
    1437             : 
    1438     5994560 :     FOR( k = 1; k < n; k++ )
    1439             :     {
    1440     5901905 :         sAbs = abs_s( sx[k] );
    1441     5901905 :         sMax = s_max( sMax, sAbs );
    1442             :     }
    1443             : 
    1444       92655 :     exp = norm_s( sMax );
    1445       92655 :     return exp;
    1446             : }
    1447             : 
    1448           0 : Word16 Exp32Array(
    1449             :     const Word16 n,  /* (i): Array size   */
    1450             :     const Word32 *sx /* (i): Data array   */
    1451             : )
    1452             : {
    1453             :     Word16 k;
    1454             :     Word16 exp;
    1455             :     Word32 L_Max;
    1456             :     Word32 L_Abs;
    1457             : 
    1458           0 :     L_Max = L_abs( sx[0] );
    1459           0 :     FOR( k = 1; k < n; k++ )
    1460             :     {
    1461           0 :         L_Abs = L_abs( sx[k] );
    1462           0 :         L_Max = L_max( L_Max, L_Abs );
    1463             :     }
    1464           0 :     exp = norm_l( L_Max );
    1465             : 
    1466           0 :     if ( L_Max == 0 )
    1467             :     {
    1468           0 :         exp = 31;
    1469           0 :         move16();
    1470             :     }
    1471           0 :     return exp;
    1472             : }
    1473             : 
    1474       16124 : Word32 sum16_32_fx(                    /* o  : sum of all vector elements            Qx*/
    1475             :                     const Word16 *vec, /* i  : input vector                          Qx*/
    1476             :                     const Word16 lvec  /* i  : length of input vector                */
    1477             : )
    1478             : {
    1479             :     Word16 i;
    1480             :     Word32 tmp, L_var;
    1481       16124 :     tmp = 0;
    1482       16124 :     move16();
    1483     1708778 :     FOR( i = 0; i < lvec; i++ )
    1484             :     {
    1485     1692654 :         L_var = L_deposit_l( vec[i] );
    1486     1692654 :         tmp = L_add( tmp, L_var ); /*Qx */
    1487             :     }
    1488             : 
    1489       16124 :     return tmp;
    1490             : }
    1491             : 
    1492        2095 : Word32 sum32_sat(                    /* o  : sum of all vector elements            Qx*/
    1493             :                   const Word32 *vec, /* i  : input vector                          Qx*/
    1494             :                   const Word16 lvec  /* i  : length of input vector                */
    1495             : )
    1496             : {
    1497             :     Word16 i;
    1498             :     Word32 tmp;
    1499        2095 :     tmp = 0;
    1500        2095 :     move16();
    1501      136175 :     FOR( i = 0; i < lvec; i++ )
    1502             :     {
    1503      134080 :         tmp = L_add_sat( tmp, vec[i] ); /*Qx */
    1504             :     }
    1505             : 
    1506        2095 :     return tmp;
    1507             : }
    1508             : 
    1509        7351 : Word32 var_fx_32(                  /* o: variance of vector                    Qx+16*/
    1510             :                   const Word16 *x, /* i: input vector                          Qx*/
    1511             :                   const Word16 Qx,
    1512             :                   const Word16 len /* i: length of inputvector                 */
    1513             : )
    1514             : {
    1515             :     Word16 m;
    1516             :     Word32 v;
    1517             :     Word16 i;
    1518             :     Word16 tmp, exp, inv_len;
    1519             :     Word32 L_tmp;
    1520             : 
    1521             : 
    1522        7351 :     L_tmp = L_add( x[0], 0 );
    1523      200275 :     FOR( i = 1; i < len; i++ )
    1524             :     {
    1525      192924 :         L_tmp = L_add( L_tmp, x[i] ); /*Qx */
    1526             :     }
    1527        7351 :     exp = norm_s( len );
    1528        7351 :     inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
    1529        7351 :     L_tmp = Mult_32_16( L_tmp, inv_len );             /*Q(14-exp+Qx) */
    1530        7351 :     m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) );    /*Qx */
    1531             : 
    1532        7351 :     v = L_deposit_l( 0 );
    1533      207626 :     FOR( i = 0; i < len; i++ )
    1534             :     {
    1535      200275 :         tmp = sub( x[i], m );          /*Qx */
    1536      200275 :         v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
    1537             :     }
    1538        7351 :     L_tmp = Mult_32_16( v, inv_len );             /*Q(14-exp+Qx+Qx) */
    1539        7351 :     v = L_shl( L_tmp, add( exp, sub( 2, Qx ) ) ); /*Qx+16 */
    1540             : 
    1541        7351 :     return v;
    1542             : }
    1543             : 
    1544        3712 : Word32 var_fx_32in_32out(                   /* o: variance of vector                    Qx*/
    1545             :                           const Word32 *x,  /* i: input vector                          Qx*/
    1546             :                           Word16 *Qx,       /*i/o:Q for input/output */
    1547             :                           const Word16 len, /* i: length of inputvector                 */
    1548             :                           const Word16 gb )
    1549             : {
    1550             :     Word16 i;
    1551             :     Word16 shift;
    1552             :     Word32 L_tmp1, L_tmp;
    1553             :     Word64 W_temp;
    1554             : 
    1555        3712 :     L_tmp = mean_no_sat_Word32_fx( x, len, gb ); /*Qx-gb */
    1556        3712 :     W_temp = 0;
    1557       18560 :     FOR( i = 0; i < len; i++ )
    1558             :     {
    1559       14848 :         L_tmp1 = L_sub( L_shr( x[i], gb ), L_tmp );                /*Qx-gb */
    1560       14848 :         W_temp = W_add( W_temp, W_mult0_32_32( L_tmp1, L_tmp1 ) ); /*Qx-gb +Qx-gb*/
    1561             :     }
    1562        3712 :     shift = W_norm( W_temp );
    1563        3712 :     L_tmp = Mult_32_16( W_extract_h( W_shl( W_temp, shift ) ), div_s( 1, len ) ); /*Q2*(Qx-gb)+shift -32 */
    1564             : 
    1565        3712 :     *Qx = sub( add( shl( sub( *Qx, gb ), 1 ), shift ), 32 );
    1566        3712 :     move16();
    1567        3712 :     return L_tmp;
    1568             : }
    1569             : /*-------------------------------------------------------------------*
    1570             :  * conv()
    1571             :  *
    1572             :  * Convolution between vectors x[] and h[] written to y[]
    1573             :  * All vectors are of length L. Only the first L samples of the
    1574             :  * convolution are considered.
    1575             :  *-------------------------------------------------------------------*/
    1576             : 
    1577     1784491 : Flag conv_fx(
    1578             :     const Word16 x[], /* i  : input vector                              Q_new*/
    1579             :     const Word16 h[], /* i  : impulse response (or second input vector) Q(15)*/
    1580             :     Word16 y[],       /* o  : output vetor (result of convolution)      12 bits*/
    1581             :     const Word16 L    /* i  : vector size                               */
    1582             : )
    1583             : {
    1584             : 
    1585             :     Word16 i, n;
    1586             :     Word32 L_sum;
    1587             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1588     1784491 :     Flag Overflow = 0;
    1589     1784491 :     move32();
    1590             : #endif
    1591     1784491 :     y[0] = mult_r( x[0], h[0] );
    1592     1784491 :     move16();
    1593   117898112 :     FOR( n = 1; n < L; n++ )
    1594             :     {
    1595   116113621 :         L_sum = L_mult( x[0], h[n] );
    1596  4153655872 :         FOR( i = 1; i < n; i++ )
    1597             :         {
    1598  4037542251 :             L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
    1599             :         }
    1600   116113621 :         y[n] = mac_ro( L_sum, x[i], h[0], &Overflow );
    1601   116113621 :         move16();
    1602             :     }
    1603     1784491 :     return Overflow;
    1604             : }
    1605             : 
    1606             : /*-------------------------------------------------------------------*
    1607             :  * conv_fx_32()
    1608             :  *
    1609             :  * Convolution between vectors x[] and h[] written to y[]
    1610             :  * All vectors are of length L. Only the first L samples of the
    1611             :  * convolution are considered.
    1612             :  *-------------------------------------------------------------------*/
    1613        2526 : Flag conv_fx_32(
    1614             :     const Word16 x[], /* i  : input vector                              Q_new*/
    1615             :     const Word16 h[], /* i  : impulse response (or second input vector) Q(15)*/
    1616             :     Word32 y[],       /* o  : output vetor (result of convolution)      12 bits*/
    1617             :     const Word16 L    /* i  : vector size                               */
    1618             : )
    1619             : {
    1620             : 
    1621             :     Word16 i, n;
    1622             :     Word32 L_sum;
    1623        2526 :     Flag Overflow = 0;
    1624        2526 :     y[0] = L_mult( x[0], h[0] );
    1625        2526 :     move32();
    1626       45468 :     FOR( n = 1; n < L; n++ )
    1627             :     {
    1628       42942 :         L_sum = L_mult( x[0], h[n] );
    1629      386478 :         FOR( i = 1; i < n; i++ )
    1630             :         {
    1631      343536 :             L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
    1632             :         }
    1633       42942 :         y[n] = L_mac_o( L_sum, x[i], h[0], &Overflow );
    1634       42942 :         move32();
    1635             :     }
    1636        2526 :     return Overflow;
    1637             : }
    1638      579563 : Word16 var_fx(                  /* o: variance of vector                    Qx*/
    1639             :                const Word16 *x, /* i: input vector                          Qx*/
    1640             :                const Word16 Qx,
    1641             :                const Word16 len /* i: length of inputvector                 */
    1642             : )
    1643             : {
    1644             :     Word16 m;
    1645             :     Word32 v;
    1646             :     Word16 v_16;
    1647             :     Word16 i;
    1648             :     Word16 tmp, exp, inv_len;
    1649             :     Word32 L_tmp;
    1650             : 
    1651      579563 :     L_tmp = x[0];
    1652      579563 :     move32();
    1653     4795662 :     FOR( i = 1; i < len; i++ )
    1654             :     {
    1655     4216099 :         L_tmp = L_add( L_tmp, x[i] ); /*Qx */
    1656             :     }
    1657      579563 :     exp = norm_s( len );
    1658      579563 :     inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
    1659      579563 :     L_tmp = Mult_32_16( L_tmp, inv_len );             /*Q(14-exp+Qx) */
    1660      579563 :     m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) );    /*Qx */
    1661             : 
    1662      579563 :     v = L_deposit_l( 0 );
    1663     5375225 :     FOR( i = 0; i < len; i++ )
    1664             :     {
    1665     4795662 :         tmp = sub_sat( x[i], m );      /*Qx */
    1666     4795662 :         v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
    1667             :     }
    1668      579563 :     L_tmp = Mult_32_16( v, inv_len );                                    /*Q(14-exp+Qx+Qx) */
    1669      579563 :     v_16 = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( 2, Qx ) ) ) ); /*Qx */
    1670             : 
    1671      579563 :     return v_16;
    1672             : }
    1673             : 
    1674             : /*---------------------------------------------------------------------*
    1675             :  * std_fx()
    1676             :  *
    1677             :  * Calculate the standard deviation of a vector
    1678             :  *---------------------------------------------------------------------*/
    1679             : 
    1680        6150 : Word16 std_fx(                   /* o: standard deviation                    */
    1681             :                const Word16 x[], /* i: input vector                          */
    1682             :                const Word16 len  /* i: length of the input vector            */
    1683             : )
    1684             : {
    1685             :     Word16 i;
    1686             :     Word32 L_tmp;
    1687             :     Word16 exp1, exp2, tmp;
    1688             :     Word32 stdev;
    1689             : 
    1690        6150 :     stdev = 0;
    1691        6150 :     move16();
    1692       55350 :     FOR( i = 0; i < len; i++ )
    1693             :     {
    1694       49200 :         L_tmp = L_mult( x[i], x[i] );              /*29 */
    1695       49200 :         stdev = L_add( stdev, L_shr( L_tmp, 3 ) ); /*26 */
    1696             :     }
    1697             : 
    1698        6150 :     IF( stdev != 0 )
    1699             :     {
    1700        6150 :         exp1 = norm_l( stdev );
    1701        6150 :         tmp = div_s( 16384, extract_h( L_shl( stdev, exp1 ) ) ); /*15 + 14 - (26 + exp1 - 16) */
    1702        6150 :         L_tmp = L_mult( tmp, len );                              /*15 + 14 - (26 + exp1 - 16) + 1 */
    1703        6150 :         exp2 = norm_l( L_tmp );
    1704        6150 :         exp1 = add( sub( exp1, exp2 ), 11 );
    1705        6150 :         stdev = Isqrt_lc( L_shl( L_tmp, exp2 ), &exp1 ); /*31-exp1 */
    1706        6150 :         stdev = L_shl( stdev, sub( exp1, 1 ) );          /*30 */
    1707             :     }
    1708             : 
    1709             : 
    1710        6150 :     return extract_h( stdev );
    1711             : }
    1712             : 
    1713       55800 : Word32 dot_product_mat_fx(                  /* o  : the dot product x'*A*x        */
    1714             :                            const Word16 *x, /* i  : vector x                     Q15 */
    1715             :                            const Word32 *A, /* i  : matrix A                     Q0*/
    1716             :                            const Word16 m   /* i  : vector & matrix size          */
    1717             : 
    1718             : )
    1719             : {
    1720             :     Word16 i, j;
    1721             :     Word64 tmp_sum_64;
    1722             :     Word32 suma, tmp_sum;
    1723             :     const Word32 *pt_A;
    1724             :     const Word16 *pt_x;
    1725             : 
    1726       55800 :     pt_A = A;
    1727       55800 :     suma = L_deposit_l( 0 );
    1728             : 
    1729      725400 :     FOR( i = 0; i < m; i++ )
    1730             :     {
    1731      669600 :         tmp_sum_64 = 0;
    1732      669600 :         move64();
    1733      669600 :         pt_x = x;
    1734     8704800 :         FOR( j = 0; j < m; j++ )
    1735             :         {
    1736     8035200 :             tmp_sum_64 = W_mac_32_16( tmp_sum_64, *pt_A, *pt_x ); /*Q0 */
    1737     8035200 :             pt_A++;
    1738     8035200 :             pt_x++;
    1739             :         }
    1740      669600 :         tmp_sum = W_sat_m( tmp_sum_64 );
    1741      669600 :         suma = Madd_32_16( suma, tmp_sum, x[i] ); /*Q0 */
    1742             :     }
    1743       55800 :     return suma;
    1744             : }
    1745             : /*-------------------------------------------------------------------*
    1746             :  *  Vr_subt
    1747             :  *
    1748             :  *  Subtract two Word16 vectors integer by integer
    1749             :  *-------------------------------------------------------------------*/
    1750     2623527 : void Vr_subt(
    1751             :     const Word16 x1[], /* i  : Input vector 1                                   */
    1752             :     const Word16 x2[], /* i  : Input vector 2                                   */
    1753             :     Word16 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    1754             :     Word16 N           /* i  : Vector lenght                                    */
    1755             : )
    1756             : {
    1757             :     Word16 i;
    1758             : 
    1759    44567803 :     FOR( i = 0; i < N; i++ )
    1760             :     {
    1761    41944276 :         y[i] = sub_sat( x1[i], x2[i] );
    1762    41944276 :         move16();
    1763             :     }
    1764     2623527 : }
    1765             : /*-------------------------------------------------------------------*
    1766             :  * vquant()
    1767             :  *
    1768             :  * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
    1769             :  *
    1770             :  * Searches a given codebook to find the nearest neighbour in Euclidean space.
    1771             :  * Index of the winning codevector and the winning vector itself are returned.
    1772             :  *-------------------------------------------------------------------*/
    1773        1402 : Word16 vquant_ivas_fx(                        /* o: index of the winning codevector         */
    1774             :                        Word32 x[],            /* i: vector to quantize                  Q25 */
    1775             :                        const Word32 x_mean[], /* i: vector mean to subtract (0 if none) Q25 */
    1776             :                        Word32 xq[],           /* o: quantized vector                    Q25 */
    1777             :                        const Word32 cb[],     /* i: codebook                            Q25 */
    1778             :                        const Word16 dim,      /* i: dimension of codebook vectors           */
    1779             :                        const Word16 cbsize    /* i: codebook size                           */
    1780             : )
    1781             : {
    1782             :     Word16 c, d, idx, j;
    1783             :     Word32 L_dist, L_tmp, L_mindist;
    1784             : 
    1785        1402 :     idx = 0;
    1786        1402 :     move16();
    1787        1402 :     L_mindist = MAX_32;
    1788        1402 :     move32();
    1789        1402 :     IF( x_mean != 0 )
    1790             :     {
    1791           0 :         FOR( d = 0; d < dim; d++ )
    1792             :         {
    1793             :             /*x[d] -= x_mean[d]; */
    1794           0 :             x[d] = L_sub( x[d], x_mean[d] );
    1795           0 :             move32(); /*Qx */
    1796             :         }
    1797             :     }
    1798        1402 :     j = 0;
    1799        1402 :     move16();
    1800       19330 :     FOR( c = 0; c < cbsize; c++ )
    1801             :     {
    1802       17928 :         L_dist = 0;
    1803       17928 :         move32();
    1804             : 
    1805       89640 :         FOR( d = 0; d < dim; d++ )
    1806             :         {
    1807             :             /*tmp = x[d] - cb[j++];*/
    1808       71712 :             L_tmp = L_sub( x[d], cb[j++] );                      // Q25
    1809       71712 :             L_dist = L_add( L_dist, Mpy_32_32( L_tmp, L_tmp ) ); // (Q25, Q25) -> Q19
    1810             :         }
    1811       17928 :         if ( LT_32( L_dist, L_mindist ) ) // Q19
    1812             :         {
    1813        3119 :             idx = c;
    1814        3119 :             move16();
    1815             :         }
    1816       17928 :         L_mindist = L_min( L_mindist, L_dist ); // Q19
    1817             :     }
    1818        1402 :     IF( xq == 0 )
    1819             :     {
    1820           0 :         return idx;
    1821             :     }
    1822             : 
    1823             :     /*j =  idx*dim;*/
    1824        1402 :     j = i_mult2( idx, dim );
    1825        7010 :     FOR( d = 0; d < dim; d++ )
    1826             :     {
    1827        5608 :         xq[d] = cb[j++]; // Q25
    1828        5608 :         move32();
    1829             :     }
    1830        1402 :     IF( x_mean != 0 )
    1831             :     {
    1832           0 :         FOR( d = 0; d < dim; d++ )
    1833             :         {
    1834             :             /*xq[d] += x_mean[d]; */
    1835           0 :             xq[d] = L_add( xq[d], x_mean[d] ); // Q25
    1836           0 :             move32();
    1837             :         }
    1838             :     }
    1839             : 
    1840        1402 :     return idx;
    1841             : }
    1842             : 
    1843      240726 : Word16 vquant_fx(                        /* o: index of the winning codevector         */
    1844             :                   Word16 x[],            /* i: vector to quantize                  Q13 */
    1845             :                   const Word16 x_mean[], /* i: vector mean to subtract (0 if none) Q13 */
    1846             :                   Word16 xq[],           /* o: quantized vector                    Q13 */
    1847             :                   const Word16 cb[],     /* i: codebook                            Q13 */
    1848             :                   const Word16 dim,      /* i: dimension of codebook vectors           */
    1849             :                   const Word16 cbsize    /* i: codebook size                           */
    1850             : )
    1851             : {
    1852             :     Word16 tmp;
    1853             :     Word16 c, d, idx, j;
    1854             :     Word32 L_dist, /*L_tmp,*/ L_mindist;
    1855             : 
    1856      240726 :     idx = 0;
    1857      240726 :     move16();
    1858      240726 :     L_mindist = MAX_32;
    1859      240726 :     move32();
    1860      240726 :     IF( x_mean != 0 )
    1861             :     {
    1862      478367 :         FOR( d = 0; d < dim; d++ )
    1863             :         {
    1864             :             /*x[d] -= x_mean[d]; */
    1865      354738 :             x[d] = sub( x[d], x_mean[d] );
    1866      354738 :             move16(); /*Qx */
    1867             :         }
    1868             :     }
    1869      240726 :     j = 0;
    1870      240726 :     move16();
    1871     8863310 :     FOR( c = 0; c < cbsize; c++ )
    1872             :     {
    1873     8622584 :         L_dist = 0;
    1874     8622584 :         move32();
    1875             : 
    1876    37613976 :         FOR( d = 0; d < dim; d++ )
    1877             :         {
    1878             :             /*tmp = x[d] - cb[j++];*/
    1879    28991392 :             tmp = sub( x[d], cb[j++] ); /*Qx */
    1880    28991392 :             L_dist = L_mac0( L_dist, tmp, tmp );
    1881             :         }
    1882     8622584 :         if ( LT_32( L_dist, L_mindist ) )
    1883             :         {
    1884      941730 :             idx = c;
    1885      941730 :             move16();
    1886             :         }
    1887     8622584 :         L_mindist = L_min( L_mindist, L_dist );
    1888             :     }
    1889      240726 :     IF( xq == 0 )
    1890             :     {
    1891           0 :         return idx;
    1892             :     }
    1893             : 
    1894             :     /*j =  idx*dim;*/
    1895      240726 :     j = i_mult2( idx, dim );
    1896     1063852 :     FOR( d = 0; d < dim; d++ )
    1897             :     {
    1898      823126 :         xq[d] = cb[j++];
    1899      823126 :         move16();
    1900             :     }
    1901      240726 :     IF( x_mean != 0 )
    1902             :     {
    1903      478367 :         FOR( d = 0; d < dim; d++ )
    1904             :         {
    1905             :             /*xq[d] += x_mean[d]; */
    1906      354738 :             xq[d] = add( xq[d], x_mean[d] );
    1907      354738 :             move16();
    1908             :         }
    1909             :     }
    1910             : 
    1911      240726 :     return idx;
    1912             : }
    1913             : 
    1914             : /*-------------------------------------------------------------------*
    1915             :  * w_vquant_fx()
    1916             :  *
    1917             :  * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
    1918             :  *
    1919             :  * Searches a given codebook to find the nearest neighbour in Euclidean space.
    1920             :  * Weights are put on the error for each vector element.
    1921             :  * Index of the winning codevector and the winning vector itself are returned.
    1922             :  *-------------------------------------------------------------------*/
    1923       50070 : Word16 w_vquant_fx(
    1924             :     Word16 x[], /* i: vector to quantize in Q10 */
    1925             :     Word16 Qx,
    1926             :     const Word16 weights[], /* i: error weights in Q0 */
    1927             :     Word16 xq[],            /* o: quantized vector in Q15 */
    1928             :     const Word16 cb[],      /* i: codebook in Q15 */
    1929             :     const Word16 cbsize,    /* i: codebook size */
    1930             :     const Word16 rev_vect   /* i: reverse codebook vectors */
    1931             : )
    1932             : {
    1933             :     Word16 tmp;
    1934             :     Word16 c, idx, j;
    1935             :     Word32 dist, minDist;
    1936             : #ifndef ISSUE_1836_replace_overflow_libcom
    1937             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1938             :     Flag Overflow = 0;
    1939             :     move32();
    1940             : #endif
    1941             : #endif
    1942             : 
    1943             : 
    1944       50070 :     idx = 0;
    1945       50070 :     move16();
    1946       50070 :     minDist = 0x7fffffffL;
    1947       50070 :     move32();
    1948       50070 :     Qx = sub( 15, Qx );
    1949             : 
    1950       50070 :     j = 0;
    1951       50070 :     move16();
    1952       50070 :     IF( rev_vect )
    1953             :     {
    1954     1838488 :         FOR( c = 0; c < cbsize; c++ )
    1955             :         {
    1956     1826207 :             dist = L_deposit_l( 0 );
    1957             : 
    1958             : #ifdef ISSUE_1836_replace_overflow_libcom
    1959     1826207 :             tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
    1960     1826207 :             if ( weights[3] != 0 )
    1961             :             {
    1962     1652193 :                 dist = L_mac0_sat( dist, tmp, tmp );
    1963             :             }
    1964     1826207 :             tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
    1965     1826207 :             if ( weights[2] != 0 )
    1966             :             {
    1967     1694444 :                 dist = L_mac0_sat( dist, tmp, tmp );
    1968             :             }
    1969     1826207 :             tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
    1970     1826207 :             if ( weights[1] != 0 )
    1971             :             {
    1972     1788879 :                 dist = L_mac0_sat( dist, tmp, tmp );
    1973             :             }
    1974     1826207 :             tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
    1975     1826207 :             if ( weights[0] != 0 )
    1976             :             {
    1977     1738514 :                 dist = L_mac0_sat( dist, tmp, tmp );
    1978             :             }
    1979             : #else
    1980             :             tmp = sub_o( x[3], shr( cb[j++], Qx ), &Overflow );
    1981             :             if ( weights[3] != 0 )
    1982             :             {
    1983             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    1984             :             }
    1985             :             tmp = sub_o( x[2], shr( cb[j++], Qx ), &Overflow );
    1986             :             if ( weights[2] != 0 )
    1987             :             {
    1988             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    1989             :             }
    1990             :             tmp = sub_o( x[1], shr( cb[j++], Qx ), &Overflow );
    1991             :             if ( weights[1] != 0 )
    1992             :             {
    1993             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    1994             :             }
    1995             :             tmp = sub_o( x[0], shr( cb[j++], Qx ), &Overflow );
    1996             :             if ( weights[0] != 0 )
    1997             :             {
    1998             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    1999             :             }
    2000             : #endif
    2001     1826207 :             if ( LT_32( dist, minDist ) )
    2002             :             {
    2003      131688 :                 idx = c;
    2004      131688 :                 move16();
    2005             :             }
    2006     1826207 :             minDist = L_min( minDist, dist );
    2007             :         }
    2008             : 
    2009       12281 :         IF( xq == 0 )
    2010             :         {
    2011           0 :             return idx;
    2012             :         }
    2013             : 
    2014       12281 :         j = shl( idx, 2 );
    2015       12281 :         xq[3] = cb[j++];
    2016       12281 :         move16(); /* in Q15 */
    2017       12281 :         xq[2] = cb[j++];
    2018       12281 :         move16(); /* in Q15 */
    2019       12281 :         xq[1] = cb[j++];
    2020       12281 :         move16(); /* in Q15 */
    2021       12281 :         xq[0] = cb[j++];
    2022       12281 :         move16(); /* in Q15 */
    2023             :     }
    2024             :     ELSE
    2025             :     {
    2026     2038426 :         FOR( c = 0; c < cbsize; c++ )
    2027             :         {
    2028     2000637 :             dist = L_deposit_l( 0 );
    2029             : 
    2030             : #ifdef ISSUE_1836_replace_overflow_libcom
    2031     2000637 :             tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
    2032     2000637 :             if ( weights[0] != 0 )
    2033             :             {
    2034     1839764 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2035             :             }
    2036     2000637 :             tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
    2037     2000637 :             if ( weights[1] != 0 )
    2038             :             {
    2039     1893642 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2040             :             }
    2041     2000637 :             tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
    2042     2000637 :             if ( weights[2] != 0 )
    2043             :             {
    2044     1911124 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2045             :             }
    2046     2000637 :             tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
    2047     2000637 :             if ( weights[3] != 0 )
    2048             :             {
    2049     1865818 :                 dist = L_mac0_sat( dist, tmp, tmp );
    2050             :             }
    2051             : #else
    2052             :             tmp = sub_o( x[0], shr( cb[j++], Qx ), &Overflow );
    2053             :             if ( weights[0] != 0 )
    2054             :             {
    2055             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    2056             :             }
    2057             :             tmp = sub_o( x[1], shr( cb[j++], Qx ), &Overflow );
    2058             :             if ( weights[1] != 0 )
    2059             :             {
    2060             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    2061             :             }
    2062             :             tmp = sub_o( x[2], shr( cb[j++], Qx ), &Overflow );
    2063             :             if ( weights[2] != 0 )
    2064             :             {
    2065             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    2066             :             }
    2067             :             tmp = sub_o( x[3], shr( cb[j++], Qx ), &Overflow );
    2068             :             if ( weights[3] != 0 )
    2069             :             {
    2070             :                 dist = L_mac0_o( dist, tmp, tmp, &Overflow );
    2071             :             }
    2072             : #endif
    2073     2000637 :             if ( LT_32( dist, minDist ) )
    2074             :             {
    2075      196137 :                 idx = c;
    2076      196137 :                 move16();
    2077             :             }
    2078     2000637 :             minDist = L_min( minDist, dist );
    2079             :         }
    2080             : 
    2081       37789 :         IF( xq == 0 )
    2082             :         {
    2083       25035 :             return idx;
    2084             :         }
    2085             : 
    2086       12754 :         j = shl( idx, 2 );
    2087       12754 :         xq[0] = cb[j++];
    2088       12754 :         move16(); /* in Q15 */
    2089       12754 :         xq[1] = cb[j++];
    2090       12754 :         move16(); /* in Q15 */
    2091       12754 :         xq[2] = cb[j++];
    2092       12754 :         move16(); /* in Q15 */
    2093       12754 :         xq[3] = cb[j++];
    2094       12754 :         move16(); /* in Q15 */
    2095             :     }
    2096             : 
    2097       25035 :     return idx;
    2098             : }
    2099             : /*-------------------------------------------------------------------*
    2100             :  * Emaximum:
    2101             :  *
    2102             :  * Find index of a maximum energy in a vector
    2103             :  *-------------------------------------------------------------------*/
    2104    20573221 : Word16 emaximum_fx(                    /* o  : return index with max energy value in vector  Q0 */
    2105             :                     const Word16 Qvec, /* i  : Q of input vector                         Q0 */
    2106             :                     const Word16 *vec, /* i  : input vector                              Qx */
    2107             :                     const Word16 lvec, /* i  : length of input vector                    Q0 */
    2108             :                     Word32 *ener_max   /* o  : maximum energy value                      Q0 */
    2109             : )
    2110             : {
    2111             :     Word16 j, ind;
    2112             :     Word32 L_tmp, L_tmp1;
    2113             :     Word32 emax;
    2114             : 
    2115    20573221 :     emax = L_mult0( vec[0], vec[0] );
    2116    20573221 :     ind = 0;
    2117    20573221 :     move16();
    2118             : 
    2119   665839907 :     FOR( j = 1; j < lvec; j++ )
    2120             :     {
    2121   645266686 :         L_tmp = L_mult0( vec[j], vec[j] );
    2122   645266686 :         L_tmp1 = L_sub( L_tmp, emax );
    2123   645266686 :         if ( L_tmp1 > 0 )
    2124             :         {
    2125    82206944 :             ind = j;
    2126    82206944 :             move16();
    2127             :         }
    2128   645266686 :         emax = L_max( emax, L_tmp );
    2129             :     }
    2130             : 
    2131    20573221 :     *ener_max = L_shr_sat( emax, add( Qvec, Qvec ) );
    2132    20573221 :     move32();
    2133             : 
    2134    20573221 :     return ind;
    2135             : }
    2136             : 
    2137       33899 : Word16 emaximum_32fx(                    /* o  : return index with max energy value in vector  Q0 */
    2138             :                       const Word16 Qvec, /* i  : Q of input vector                         Q0 */
    2139             :                       const Word32 *vec, /* i  : input vector                              Qx */
    2140             :                       const Word16 lvec, /* i  : length of input vector                    Q0 */
    2141             :                       Word32 *ener_max   /* o  : maximum energy value                      Q0 */
    2142             : )
    2143             : {
    2144             :     Word16 j, ind;
    2145             :     Word64 W_tmp, W_tmp1;
    2146             :     Word64 emax;
    2147             : 
    2148       33899 :     emax = W_mult0_32_32( vec[0], vec[0] );
    2149       33899 :     ind = 0;
    2150       33899 :     move16();
    2151             : 
    2152     3239136 :     FOR( j = 1; j < lvec; j++ )
    2153             :     {
    2154     3205237 :         W_tmp = W_mult0_32_32( vec[j], vec[j] );
    2155     3205237 :         W_tmp1 = W_sub( W_tmp, emax );
    2156     3205237 :         if ( W_tmp1 > 0 )
    2157             :         {
    2158      262832 :             ind = j;
    2159      262832 :             move16();
    2160             :         }
    2161     3205237 :         if ( LE_64( emax, W_tmp ) )
    2162             :         {
    2163      265524 :             emax = W_tmp;
    2164      265524 :             move64();
    2165             :         }
    2166             :     }
    2167             : 
    2168       33899 :     *ener_max = W_extract_l( W_shr( emax, add( Qvec, Qvec ) ) );
    2169       33899 :     move32();
    2170             : 
    2171       33899 :     return ind;
    2172             : }
    2173             : 
    2174             : /*-------------------------------------------------------------------*
    2175             :  * mean32:
    2176             :  *
    2177             :  * Find the mean of a 32 bits vector
    2178             :  *-------------------------------------------------------------------*/
    2179        4852 : Word32 Mean32(                    /* o  : mean of the elements of the vector */
    2180             :                const Word32 in[], /* i  : input vector                       */
    2181             :                const Word16 L     /* i  : length of input vector             */
    2182             : )
    2183             : {
    2184             :     Word32 Ltmp;
    2185             :     Word16 inv_L;
    2186             : 
    2187        4852 :     inv_L = INV_BANDS9;
    2188        4852 :     move16();
    2189        4852 :     if ( EQ_16( L, 10 ) )
    2190             :     {
    2191        4852 :         inv_L = INV_BANDS10;
    2192        4852 :         move16();
    2193             :     }
    2194             : 
    2195        4852 :     Ltmp = sum32_fx( in, L );
    2196             : 
    2197        4852 :     Ltmp = Mult_32_16( Ltmp, inv_L );
    2198             : 
    2199        4852 :     return Ltmp;
    2200             : }
    2201      187973 : Word32 sum32_fx(                    /* o  : sum of all vector elements            Qx*/
    2202             :                  const Word32 *vec, /* i  : input vector                          Qx*/
    2203             :                  const Word16 lvec  /* i  : length of input vector                */
    2204             : )
    2205             : {
    2206             :     Word16 i;
    2207             :     Word32 tmp;
    2208             : 
    2209      187973 :     tmp = L_deposit_l( 0 );
    2210     7055764 :     FOR( i = 0; i < lvec; i++ )
    2211             :     {
    2212     6867791 :         tmp = L_add_sat( tmp, vec[i] ); /*Qx */
    2213             :     }
    2214             : 
    2215      187973 :     return tmp;
    2216             : }
    2217     1152954 : Word16 sum16_fx(                    /* o  : sum of all vector elements            Qx*/
    2218             :                  const Word16 *vec, /* i  : input vector                          Qx*/
    2219             :                  const Word16 lvec  /* i  : length of input vector                */
    2220             : )
    2221             : {
    2222             :     Word16 i;
    2223             :     Word16 tmp;
    2224     1152954 :     tmp = 0;
    2225     1152954 :     move16();
    2226     8414302 :     FOR( i = 0; i < lvec; i++ )
    2227             :     {
    2228     7261348 :         tmp = add_sat( tmp, vec[i] ); /*Qx */
    2229             :     }
    2230             : 
    2231     1152954 :     return tmp;
    2232             : }
    2233             : /*------------------------------------------------------------------*
    2234             :  * function Random
    2235             :  *
    2236             :  * Signed 16 bits random generator.
    2237             :  *------------------------------------------------------------------*/
    2238   676840939 : Word16 Random(              /* o  : output random value */
    2239             :                Word16 *seed /* i/o: random seed         */
    2240             : )
    2241             : {
    2242   676840939 :     *seed = extract_l( L_mac0( 13849L, *seed, 31821 ) );
    2243   676840939 :     move16();
    2244   676840939 :     return *seed;
    2245             : }
    2246             : 
    2247      115272 : Word16 own_random2_fx( Word16 seed )
    2248             : {
    2249      115272 :     return extract_l( L_mac0( 13849, seed, 31821 ) );
    2250             : }
    2251             : 
    2252             : /*---------------------------------------------------------------------
    2253             :  * sign_fx()
    2254             :  *
    2255             :  *---------------------------------------------------------------------*/
    2256             : 
    2257             : /*! r: sign of x (+1/-1) */
    2258     2102172 : Word16 sign_fx(
    2259             :     const Word32 x /* i  : input value of x  */
    2260             : )
    2261             : {
    2262     2102172 :     IF( LT_32( x, 0 ) )
    2263             :     {
    2264      697824 :         return -1;
    2265             :     }
    2266             :     ELSE
    2267             :     {
    2268     1404348 :         return 1;
    2269             :     }
    2270             : }
    2271             : 
    2272           0 : Word16 sign16_fx(
    2273             :     const Word16 x /* i  : input value of x  */
    2274             : )
    2275             : {
    2276           0 :     IF( LT_16( x, 0 ) )
    2277             :     {
    2278           0 :         return -1;
    2279             :     }
    2280             :     ELSE
    2281             :     {
    2282           0 :         return 1;
    2283             :     }
    2284             : }
    2285             : 
    2286             : /*------------------------------------------------------------------*
    2287             :  * function Div_32_optmz
    2288             :  *
    2289             :  * Performs 32 bits interger division
    2290             :  *------------------------------------------------------------------*/
    2291     3987877 : static Word32 Div_32_optmz( Word32 L_num, Word16 denom_hi )
    2292             : {
    2293             :     Word16 approx, hi, lo, n_hi, n_lo;
    2294             :     Word32 L_32;
    2295             : 
    2296             :     /* First approximation: 1 / L_denom = 1/denom_hi */
    2297             : 
    2298     3987877 :     approx = div_s( (Word16) 0x3fff, denom_hi );
    2299             : 
    2300             :     /* 1/L_denom = approx * (2.0 - L_denom * approx) */
    2301             : 
    2302     3987877 :     L_32 = L_msu( (Word32) 0x7fffffffL, denom_hi, approx );
    2303             : 
    2304     3987877 :     lo = L_Extract_lc( L_32, &hi );
    2305     3987877 :     L_32 = Mpy_32_16( hi, lo, approx );
    2306             : 
    2307             :     /* L_num * (1/L_denom) */
    2308             : 
    2309     3987877 :     lo = L_Extract_lc( L_32, &hi );
    2310     3987877 :     n_lo = L_Extract_lc( L_num, &n_hi );
    2311     3987877 :     L_32 = Mpy_32( n_hi, n_lo, hi, lo );
    2312             : 
    2313     3987877 :     return ( L_32 );
    2314             : }
    2315             : /*------------------------------------------------------------------*
    2316             :  * function iDiv_and_mod_32
    2317             :  *
    2318             :  * return the quotient and the modulo 32 bits numerator divided by a 16 bit denominator
    2319             :  * The denominator might be right shifted by 1
    2320             :  *------------------------------------------------------------------*/
    2321     3987877 : void iDiv_and_mod_32(
    2322             :     const Word32 Numer,   /* i  : 32 bits numerator   */
    2323             :     const Word16 Denom,   /* i  : 16 bits denominator */
    2324             :     Word32 *Int_quotient, /* o  : integer result of the division (int)(num/den) */
    2325             :     Word32 *Int_mod,      /* o  : modulo result of the division  num-((int)(num/den)*den)*/
    2326             :     const Word16 rshift   /* i  : 0 if no right shift / 1 if the denom is right shifted by 1 */
    2327             : )
    2328             : {
    2329             :     Word32 Quotient;
    2330             :     Word16 expA, expB;
    2331             :     Word32 N, TEMP;
    2332             :     Word16 D;
    2333             : 
    2334             :     /* Normalize 'Numer' & 'Denom' */
    2335             :     /* Use Temporary to Preserve the Original Value */
    2336     3987877 :     expA = norm_l( Numer );
    2337     3987877 :     N = L_shl( Numer, expA );
    2338     3987877 :     expB = norm_s( Denom );
    2339     3987877 :     D = shl( Denom, expB );
    2340             : 
    2341             :     /* Need to shift right 'Numer' by 1? */
    2342     3987877 :     if ( L_mac( N, D, -32768L ) >= 0 )
    2343             :     {
    2344     2220026 :         expA = sub( expA, 1 );
    2345             :     }
    2346     3987877 :     N = L_shl( Numer, expA );
    2347             : 
    2348             :     /* Perform Approximation of the Division
    2349             :      * Since 'lo' part is '0' AND 'denom' is supposed to be constant in the targeted usage
    2350             :      * one could import the Div32 code and pre-calc the div_s and eliminate all calcs
    2351             :      * with 'lo' to save some complexity */
    2352             : 
    2353     3987877 :     Quotient = Div_32_optmz( N, D ); /* takes 36 clocks */
    2354             :     /* Bring Back to Q0 (minus 2 because we removed the left shift by 2 in the Div32_optmz) */
    2355     3987877 :     IF( rshift )
    2356             :     {
    2357           0 :         Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, sub( expB, 1 ) ) ) );
    2358             :     }
    2359             :     ELSE
    2360             :     {
    2361     3987877 :         Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, expB ) ) );
    2362             :     }
    2363             : 
    2364             :     /* Cross Check (do Quotient x Divisor)
    2365             :      * The Quotient is unsigned but we cannot just use extract_h because
    2366             :      * extract_l on the low part will get the sign of the bit #15.
    2367             :      * In a 32 bits value, what is in bits 0-15 is un unsigned 16 bits value.
    2368             :      * So, we shift left by 1, extract the hi part and mult it by 32768 (hence the L_shl by 16-1.
    2369             :      * Then we take 15 bits left (mask the others) and multiply by Denom.
    2370             :      * Technically this could overflow. But since we are mutiplying to get
    2371             :      * back to the Numer value that fitted in a 32 bits, doing Divisor x Quotient
    2372             :      * must necessarily fit in a 32 bits
    2373             :      * It is assumed that all are positive values. If not, one could
    2374             :      * check the sign of the numer and denom, turn them into abs values
    2375             :      * and restore the sign after*/
    2376     3987877 :     TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2377     3987877 :     TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2378             : 
    2379             : 
    2380             :     /* Here we test to see if the previous "Quotient x Divisor" (or TEMP) is too small
    2381             :      * that is the "Numer" minus TEMP is bigger or Equal to the Divisor.
    2382             :      * If it is then the quotient is too small. We need to increase it by 1.
    2383             :      * That is caused by our Div32 fractionnal division that can be off by 1
    2384             :      * sometimes.
    2385             :      * In some cases, when the divisor is very small (like 10 or something)
    2386             :      * the quotient could be off by more than 1 and we would need a loop
    2387             :      * to check again. That is not the case here with the current divisor */
    2388     3987877 :     IF( rshift )
    2389             :     {
    2390           0 :         TEMP = L_shl( TEMP, 1 );
    2391           0 :         WHILE( L_msu0( L_sub( Numer, TEMP ), 2, Denom ) >= 0 )
    2392             :         {
    2393           0 :             Quotient = L_add( Quotient, 1 );
    2394           0 :             TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2395           0 :             TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2396           0 :             TEMP = L_shl( TEMP, 1 );
    2397             :         }
    2398             :     }
    2399             :     ELSE{
    2400     6624423 :         WHILE( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) >= 0 ){
    2401     2636546 :             Quotient = L_add( Quotient, 1 );
    2402     2636546 :     TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
    2403     2636546 :     TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
    2404             : }
    2405             : }
    2406     3987877 : *Int_quotient = Quotient;
    2407     3987877 : move32();
    2408     3987877 : IF( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) == 0 )
    2409             : {
    2410           0 :     *Int_mod = 0L;
    2411           0 :     move32();
    2412             : }
    2413             : ELSE
    2414             : {
    2415     3987877 :     *Int_mod = L_sub( Numer, TEMP );
    2416     3987877 :     move32();
    2417             : }
    2418     3987877 : }
    2419             : 
    2420             : /*===================================================================*/
    2421             : /* FUNCTION      :  pz_filter_sp_fx ()                                  */
    2422             : /*-------------------------------------------------------------------*/
    2423             : /* PURPOSE       :  Generic pole-zero filter routine, with single    */
    2424             : /*                  precision memory                                 */
    2425             : /*-------------------------------------------------------------------*/
    2426             : /* INPUT ARGUMENTS  :                                                */
    2427             : /*                                                                   */
    2428             : /*   _ (Word16 []) b   : zero filter coefficients (Qc).              */
    2429             : /*   _ (Word16 []) a   : pole filter coefficients (Qc), a(0)=1 in Qc */
    2430             : /*   _ (Word16 []) x   : input signal (Qn).                          */
    2431             : /*   _ (Word16)    PNR   : NR filter order                           */
    2432             : /*   _ (Word16)    PDR   : DR filter order                           */
    2433             : /*   _ (Word16)    N   : number of input samples.                    */
    2434             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    2435             : /*-------------------------------------------------------------------*/
    2436             : /* OUTPUT ARGUMENTS :                                                */
    2437             : /*                                                                   */
    2438             : /*   _ (Word16 []) y : output signal  (Qn)                           */
    2439             : /*-------------------------------------------------------------------*/
    2440             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2441             : /*                                                                   */
    2442             : /*   _ (Word16 []) buf : filter memory (Qn-Qa).                      */
    2443             : /*-------------------------------------------------------------------*/
    2444             : /* RETURN ARGUMENTS : _ None.                                        */
    2445             : /*===================================================================*/
    2446             : 
    2447           0 : void pz_filter_sp_fx(
    2448             :     const Word16 b[],
    2449             :     const Word16 a[],
    2450             :     Word16 x[],
    2451             :     Word16 y[],
    2452             :     Word16 buf[],
    2453             :     Word16 PNR,
    2454             :     Word16 PDR,
    2455             :     Word16 N,
    2456             :     Word16 Qa )
    2457             : {
    2458             :     Word16 i, j;
    2459             :     Word16 s;
    2460             :     Word16 s_mem;
    2461             :     Word32 Ltemp1;
    2462             :     Word32 Lacc;
    2463           0 :     s = negate( Qa );
    2464           0 :     s = add( s, s ); /* s=-2Qa*/
    2465           0 :     s = add( s, 1 );
    2466           0 :     FOR( i = 0; i < N; i++ )
    2467             :     {
    2468           0 :         Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
    2469           0 :         Lacc = L_shl( Lacc, s );    /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
    2470           0 :         FOR( j = PDR - 1; j >= 0; j-- )
    2471           0 :         Lacc = L_msu_sat( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
    2472             : 
    2473             : 
    2474           0 :         Lacc = L_shr( Lacc, 1 );
    2475           0 :         Ltemp1 = L_add_sat( L_shl_sat( Lacc, Qa ), 0x08000 );
    2476           0 :         s_mem = extract_h( Ltemp1 );
    2477             : 
    2478           0 :         Lacc = L_deposit_l( 0 );
    2479           0 :         FOR( j = PNR - 1; j >= 0; j-- )
    2480           0 :         Lacc = L_mac_sat( Lacc, buf[j], b[j + 1] );
    2481           0 :         Lacc = L_mac_sat( Lacc, s_mem, b[0] );
    2482             :         /* Lacc in Q(1+Qc+Qn-Qa)*/
    2483             : 
    2484           0 :         FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
    2485             :         {
    2486             :             /* Update filter memory */
    2487           0 :             buf[j] = buf[j - 1];
    2488           0 :             move16();
    2489             :         }
    2490           0 :         buf[0] = s_mem;
    2491           0 :         move16();
    2492             : 
    2493           0 :         Ltemp1 = L_add_sat( L_shr_sat( Lacc, s ), 0x08000 ); /*  Ltemp1 in Qc+Qa+Qn=Q(Qn) */
    2494           0 :         y[i] = extract_h( Ltemp1 );                          /*  y[i] in Qn */
    2495           0 :         move16();
    2496             :     }
    2497           0 : }
    2498             : 
    2499             : 
    2500      208234 : Word32 root_a_fx(
    2501             :     Word32 a,
    2502             :     Word16 Q_a,
    2503             :     Word16 *exp_out )
    2504             : {
    2505             :     Word16 exp, tmp;
    2506             :     Word32 L_tmp;
    2507             : 
    2508      208234 :     IF( a <= 0 )
    2509             :     {
    2510        2794 :         *exp_out = 0;
    2511        2794 :         move16();
    2512        2794 :         return 0;
    2513             :     }
    2514             : 
    2515      205440 :     exp = norm_l( a );
    2516      205440 :     tmp = extract_h( L_shl( a, exp ) );
    2517      205440 :     exp = sub( exp, sub( 30, Q_a ) );
    2518      205440 :     tmp = div_s( 16384, tmp );
    2519      205440 :     L_tmp = L_deposit_h( tmp );
    2520      205440 :     L_tmp = Isqrt_lc( L_tmp, &exp );
    2521             : 
    2522      205440 :     *exp_out = exp;
    2523      205440 :     move16();
    2524             : 
    2525      205440 :     return L_tmp;
    2526             : }
    2527             : 
    2528             : 
    2529     1932983 : Word32 root_a_over_b_fx(
    2530             :     Word32 a, /* Q(Q_a) */
    2531             :     Word16 Q_a,
    2532             :     Word32 b, /* Q(Q_b) */
    2533             :     Word16 Q_b,
    2534             :     Word16 *exp_out )
    2535             : {
    2536             :     Word16 tmp, num, den, scale;
    2537             :     Word16 exp, exp_num, exp_den;
    2538             :     Word32 L_tmp;
    2539             : #ifndef ISSUE_1836_replace_overflow_libcom
    2540             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2541             :     Flag Overflow = 0;
    2542             :     move32();
    2543             : #endif
    2544             : #endif
    2545     1932983 :     test();
    2546     1932983 :     IF( ( a <= 0 ) || ( b <= 0 ) )
    2547             :     {
    2548       10103 :         *exp_out = 0;
    2549       10103 :         move16();
    2550       10103 :         return 0;
    2551             :     }
    2552             : 
    2553     1922880 :     exp_num = norm_l( b );
    2554             : #ifdef ISSUE_1836_replace_overflow_libcom
    2555     1922880 :     num = round_fx_sat( L_shl_sat( b, exp_num ) );
    2556             : #else
    2557             :     num = round_fx_o( L_shl_o( b, exp_num, &Overflow ), &Overflow );
    2558             : #endif
    2559     1922880 :     exp_num = sub( sub( 30, exp_num ), Q_b );
    2560             : 
    2561     1922880 :     exp_den = norm_l( a );
    2562             : #ifdef ISSUE_1836_replace_overflow_libcom
    2563     1922880 :     den = round_fx_sat( L_shl_sat( a, exp_den ) );
    2564             : #else
    2565             :     den = round_fx_o( L_shl_o( a, exp_den, &Overflow ), &Overflow );
    2566             : #endif
    2567     1922880 :     exp_den = sub( sub( 30, exp_den ), Q_a );
    2568             : 
    2569     1922880 :     scale = shr( sub( den, num ), 15 );
    2570             : #ifdef ISSUE_1836_replace_overflow_libcom
    2571     1922880 :     num = shl_sat( num, scale );
    2572             : #else
    2573             :     num = shl_o( num, scale, &Overflow );
    2574             : #endif
    2575     1922880 :     exp_num = sub( exp_num, scale );
    2576             : 
    2577     1922880 :     tmp = div_s( num, den );
    2578     1922880 :     exp = sub( exp_num, exp_den );
    2579             : 
    2580     1922880 :     L_tmp = L_deposit_h( tmp );
    2581     1922880 :     L_tmp = Isqrt_lc( L_tmp, &exp );
    2582             : 
    2583     1922880 :     *exp_out = exp;
    2584     1922880 :     move16();
    2585             : 
    2586     1922880 :     return L_tmp;
    2587             : }
    2588             : 
    2589      332590 : Word32 root_a_over_b_ivas_fx(
    2590             :     Word32 a, /* Q(Q_a) */
    2591             :     Word16 Q_a,
    2592             :     Word32 b, /* Q(Q_b) */
    2593             :     Word16 Q_b,
    2594             :     Word16 *q_out )
    2595             : {
    2596             :     Word16 shift_a, shift_b, shift;
    2597             :     Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b;
    2598             :     Word32 a_sqr, b_sqr, p0, p1, p2, approx;
    2599             :     Word16 exp;
    2600             : 
    2601      332590 :     test();
    2602      332590 :     IF( ( a <= 0 ) || ( b <= 0 ) )
    2603             :     {
    2604           0 :         *q_out = 0;
    2605           0 :         move16();
    2606           0 :         return 0;
    2607             :     }
    2608             : 
    2609      332590 :     one_in_Q_a = L_shl( 1, Q_a );         // 1.0f in Q_a
    2610      332590 :     one_in_Q_b = L_shl( 1, Q_b );         // 1.0f in Q_b
    2611      332590 :     half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a
    2612      332590 :     half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b
    2613             : 
    2614      332590 :     a = L_add( a, one_in_Q_a );
    2615      332590 :     b = L_add( b, one_in_Q_b );
    2616             : 
    2617             :     /* This next piece of code implements a "norm" function */
    2618             :     /* and returns the shift needed to scale "a" to have a  */
    2619             :     /* 1 in the (MSB-1) position. This is equivalent to     */
    2620             :     /* giving a value between 0.5 & 1.0.                    */
    2621             : 
    2622      332590 :     mod_a = a;
    2623      332590 :     move32();
    2624             : 
    2625      332590 :     shift_a = 0;
    2626      332590 :     move16();
    2627      665180 :     WHILE( GT_32( mod_a, one_in_Q_a ) )
    2628             :     {
    2629      332590 :         mod_a = L_shr( mod_a, 1 );
    2630      332590 :         shift_a = sub( shift_a, 1 );
    2631             :     }
    2632             : 
    2633      332590 :     WHILE( LT_32( mod_a, half_in_Q_a ) )
    2634             :     {
    2635           0 :         mod_a = L_shl( mod_a, 1 );
    2636           0 :         shift_a = add( shift_a, 1 );
    2637             :     }
    2638             : 
    2639      332590 :     shift_a = s_and( shift_a, -2 );
    2640      332590 :     mod_a = L_shl( a, shift_a ); // Q_a
    2641             : 
    2642             :     /* This next piece of code implements a "norm" function */
    2643             :     /* and returns the shift needed to scale "b" to have a  */
    2644             :     /* 1 in the (MSB-1) position. This is equivalent to     */
    2645             :     /* giving a value between 0.5 & 1.0.                    */
    2646      332590 :     mod_b = b;
    2647      332590 :     move32();
    2648             : 
    2649      332590 :     shift_b = 0;
    2650      332590 :     move16();
    2651      665180 :     WHILE( GT_32( mod_b, one_in_Q_b ) )
    2652             :     {
    2653      332590 :         mod_b = L_shr( mod_b, 1 );
    2654      332590 :         shift_b = sub( shift_b, 1 );
    2655             :     }
    2656             : 
    2657      332590 :     WHILE( LT_32( mod_b, half_in_Q_b ) )
    2658             :     {
    2659           0 :         mod_b = L_shl( mod_b, 1 );
    2660           0 :         shift_b = add( shift_b, 1 );
    2661             :     }
    2662             : 
    2663      332590 :     shift_b = s_and( shift_b, -2 );
    2664      332590 :     mod_b = L_shl( b, shift_b ); // Q_b
    2665             : 
    2666      332590 :     shift = shr( sub( shift_b, shift_a ), 1 );
    2667             : 
    2668      332590 :     a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a
    2669      332590 :     b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b
    2670             : 
    2671      332590 :     p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
    2672      332590 :     p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) );  // Qb-2
    2673      332590 :     p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) );   // Qb-2
    2674             : 
    2675      332590 :     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
    2676      332590 :     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
    2677      332590 :     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
    2678             : 
    2679             :     /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */
    2680      332590 :     approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33
    2681      332590 :     approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) );    // Q_a+Q_b-33
    2682             : 
    2683      332590 :     exp = sub( norm_l( approx ), 1 );
    2684      332590 :     approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp
    2685             : 
    2686      332590 :     *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift );
    2687      332590 :     move16();
    2688             : 
    2689      332590 :     return approx;
    2690             : }
    2691             : 
    2692             : /*===================================================================*/
    2693             : /* FUNCTION      :  fir_fx ()                     */
    2694             : /*-------------------------------------------------------------------*/
    2695             : /* PURPOSE       :  Generic FIR filter routine                       */
    2696             : /*-------------------------------------------------------------------*/
    2697             : /* INPUT ARGUMENTS  :                                                */
    2698             : /*                                                                   */
    2699             : /*   _ (Word16 []) b   : filter coefficients (Qc).                   */
    2700             : /*   _ (Word16 []) x   : input signal  (Qn).                         */
    2701             : /*   _ (Word16)    P   : filter order.                               */
    2702             : /*   _ (Word16)    N   : number of input samples.                    */
    2703             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    2704             : /*-------------------------------------------------------------------*/
    2705             : /* OUTPUT ARGUMENTS :                                                */
    2706             : /*                                                                   */
    2707             : /*   _ (Word16 []) y : output signal  (Qn)                           */
    2708             : /*-------------------------------------------------------------------*/
    2709             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2710             : /*                                                                   */
    2711             : /*   _               : None                                          */
    2712             : /*-------------------------------------------------------------------*/
    2713             : /* RETURN ARGUMENTS : _ None.                                        */
    2714             : /*===================================================================*/
    2715      252993 : void fir_fx( const Word16 x[], /* i  : input vector                              Qx*/
    2716             :              const Word16 h[], /* i  : impulse response of the FIR filter        Q12*/
    2717             :              Word16 y[],       /* o  : output vector (result of filtering)       Qx*/
    2718             :              Word16 mem[],     /* i/o: memory of the input signal (L samples)    Qx*/
    2719             :              const Word16 L,   /* i  : input vector size                         */
    2720             :              const Word16 K,   /* i  : order of the FIR filter (K+1 coefs.)      */
    2721             :              const Word16 upd  /* i  : 1 = update the memory, 0 = not            */
    2722             :              ,
    2723             :              Word16 shift /* i  : difference between Q15 and scaling of h[] */
    2724             : )
    2725             : {
    2726             : 
    2727             :     Word16 buf_in[L_FRAME32k + L_FILT_MAX];
    2728             :     Word16 i, j;
    2729             :     Word32 s;
    2730             : #ifndef ISSUE_1836_replace_overflow_libcom
    2731             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2732             :     Flag Overflow = 0;
    2733             :     move32();
    2734             : #endif
    2735             : #endif
    2736             :     /* prepare the input buffer (copy and update memory) */
    2737      252993 :     Copy( mem, buf_in, K );
    2738      252993 :     Copy( x, buf_in + K, L );
    2739      252993 :     IF( upd )
    2740             :     {
    2741         153 :         Copy( buf_in + L, mem, K );
    2742             :     }
    2743             : 
    2744             :     /* do the filtering */
    2745    77872261 :     FOR( i = 0; i < L; i++ )
    2746             :     {
    2747             : #ifdef ISSUE_1836_replace_overflow_libcom
    2748    77619268 :         s = L_mult_sat( buf_in[K + i], h[0] );
    2749             : #else
    2750             :         s = L_mult_o( buf_in[K + i], h[0], &Overflow );
    2751             : #endif
    2752             : 
    2753   417451572 :         FOR( j = 1; j <= K; j++ )
    2754             :         {
    2755             : #ifdef ISSUE_1836_replace_overflow_libcom
    2756   339832304 :             s = L_mac_sat( s, h[j], buf_in[K + i - j] );
    2757             : #else
    2758             :             s = L_mac_o( s, h[j], buf_in[K + i - j], &Overflow );
    2759             : #endif
    2760             :         }
    2761             : #ifdef ISSUE_1836_replace_overflow_libcom
    2762    77619268 :         s = L_shl_sat( s, shift );
    2763    77619268 :         y[i] = round_fx_sat( s ); /*Qx */
    2764             : #else
    2765             :         s = L_shl_o( s, shift, &Overflow );
    2766             :         y[i] = round_fx_o( s, &Overflow ); /*Qx */
    2767             : #endif
    2768    77619268 :         move16();
    2769             :     }
    2770      252993 : }
    2771             : 
    2772             : /*-------------------------------------------------------------------*
    2773             :  * v_add_32()
    2774             :  *
    2775             :  * Addition of two vectors sample by sample
    2776             :  *-------------------------------------------------------------------*/
    2777             : 
    2778     5738932 : void v_add_32(
    2779             :     const Word32 x1[], /* i  : Input vector 1                       */
    2780             :     const Word32 x2[], /* i  : Input vector 2                       */
    2781             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    2782             :     const Word16 N     /* i  : Vector length                                    */
    2783             : )
    2784             : {
    2785             :     Word16 i;
    2786             : 
    2787  1046488077 :     FOR( i = 0; i < N; i++ )
    2788             :     {
    2789  1040749145 :         y[i] = L_add( x1[i], x2[i] );
    2790  1040749145 :         move32();
    2791             :     }
    2792             : 
    2793     5738932 :     return;
    2794             : }
    2795             : 
    2796      408560 : void v_shr_32(
    2797             :     Word32 x1[],    /* i  : Input vector 1                       */
    2798             :     Word32 y[],     /* o  : Output vector that contains vector 1 + vector 2  */
    2799             :     const Word16 N, /* i  : Vector length                                    */
    2800             :     Word16 shift    /*shift value*/
    2801             : )
    2802             : {
    2803             :     Word16 i;
    2804             : 
    2805   295466498 :     FOR( i = 0; i < N; i++ )
    2806             :     {
    2807   295057938 :         y[i] = L_shr( x1[i], shift );
    2808   295057938 :         move32();
    2809             :     }
    2810             : 
    2811      408560 :     return;
    2812             : }
    2813             : 
    2814             : 
    2815             : /*-------------------------------------------------------------------*
    2816             :  * v_sub_32()
    2817             :  *
    2818             :  * Subtraction of two vectors sample by sample
    2819             :  *-------------------------------------------------------------------*/
    2820             : 
    2821     2511171 : void v_sub_32(
    2822             :     const Word32 x1[], /* i  : Input vector 1                                   */
    2823             :     const Word32 x2[], /* i  : Input vector 2                                   */
    2824             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    2825             :     const Word16 N     /* i  : Vector length                                    */
    2826             : )
    2827             : {
    2828             :     Word16 i;
    2829             : 
    2830   205304386 :     FOR( i = 0; i < N; i++ )
    2831             :     {
    2832   202793215 :         y[i] = L_sub( x1[i], x2[i] );
    2833   202793215 :         move32();
    2834             :     }
    2835             : 
    2836     2511171 :     return;
    2837             : }
    2838             : 
    2839             : 
    2840             : /*-------------------------------------------------------------------*
    2841             :  * v_add_16()
    2842             :  *
    2843             :  * Addition of two vectors sample by sample
    2844             :  *-------------------------------------------------------------------*/
    2845             : 
    2846       79763 : void v_add_16(
    2847             :     const Word16 x1[], /* i  : Input vector 1                       */
    2848             :     const Word16 x2[], /* i  : Input vector 2                       */
    2849             :     Word16 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    2850             :     const Word16 N     /* i  : Vector length                                    */
    2851             : )
    2852             : {
    2853             :     Word16 i;
    2854             : 
    2855     4988809 :     FOR( i = 0; i < N; i++ )
    2856             :     {
    2857     4909046 :         y[i] = add_sat( x1[i], x2[i] );
    2858     4909046 :         move16();
    2859             :     }
    2860             : 
    2861       79763 :     return;
    2862             : }
    2863             : 
    2864             : 
    2865             : /*-------------------------------------------------------------------*
    2866             :  * v_sub_16()
    2867             :  *
    2868             :  * Subtraction of two vectors sample by sample
    2869             :  *-------------------------------------------------------------------*/
    2870             : 
    2871      236921 : void v_sub_16(
    2872             :     const Word16 x1[], /* i  : Input vector 1                                   */
    2873             :     const Word16 x2[], /* i  : Input vector 2                                   */
    2874             :     Word16 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    2875             :     const Word16 N     /* i  : Vector length                                    */
    2876             : )
    2877             : {
    2878             :     Word16 i;
    2879             : 
    2880     6802047 :     FOR( i = 0; i < N; i++ )
    2881             :     {
    2882     6565126 :         y[i] = sub_sat( x1[i], x2[i] );
    2883     6565126 :         move16();
    2884             :     }
    2885             : 
    2886      236921 :     return;
    2887             : }
    2888             : 
    2889             : 
    2890             : /*--------------------------------------------------------------------------------*/
    2891             : /* squant_fx()                                                                    */
    2892             : /*--------------------------------------------------------------------------------*/
    2893     5072060 : Word16 squant_fx(                     /* o: index of the winning codeword   */
    2894             :                   const Word16 x,     /* i: scalar value to quantize        */
    2895             :                   Word16 *xq,         /* o: quantized value                 */
    2896             :                   const Word16 cb[],  /* i: codebook                        */
    2897             :                   const Word16 cbsize /* i: codebook size                   */
    2898             : )
    2899             : {
    2900             :     Word16 tmp;
    2901             :     Word16 c, idx;
    2902             :     Word32 L_mindist, L_dist;
    2903             : #ifndef ISSUE_1836_replace_overflow_libcom
    2904             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2905             :     Flag Overflow = 0;
    2906             : #endif
    2907             : #endif
    2908             : 
    2909     5072060 :     idx = 0;
    2910     5072060 :     move16();
    2911     5072060 :     L_mindist = MAX_32;
    2912     5072060 :     move32();
    2913             : 
    2914    25280351 :     FOR( c = 0; c < cbsize; c++ )
    2915             :     {
    2916    20208291 :         L_dist = L_deposit_l( 0 );
    2917             : #ifdef ISSUE_1836_replace_overflow_libcom
    2918    20208291 :         tmp = sub_sat( x, cb[c] );
    2919             : #else
    2920             :         tmp = sub_o( x, cb[c], &Overflow );
    2921             : #endif
    2922             : 
    2923             :         /*dist += tmp*tmp; */
    2924             : #ifdef ISSUE_1836_replace_overflow_libcom
    2925    20208291 :         L_dist = L_mac_sat( L_dist, tmp, tmp );
    2926             : #else
    2927             :         L_dist = L_mac_o( L_dist, tmp, tmp, &Overflow );
    2928             : #endif
    2929             : 
    2930    20208291 :         if ( LT_32( L_dist, L_mindist ) )
    2931             :         {
    2932    11583176 :             idx = c;
    2933    11583176 :             move16();
    2934             :         }
    2935    20208291 :         L_mindist = L_min( L_mindist, L_dist );
    2936             :     }
    2937             : 
    2938     5072060 :     *xq = cb[idx];
    2939     5072060 :     move16();
    2940             : 
    2941     5072060 :     return idx;
    2942             : }
    2943             : 
    2944             : /*! r: index of the winning codeword */
    2945      401128 : Word16 squant_int_fx(
    2946             :     UWord8 x,           /* i  : scalar value to quantize  */
    2947             :     UWord8 *xq,         /* o  : quantized value           */
    2948             :     const UWord8 *cb,   /* i  : codebook                  */
    2949             :     const Word16 cbsize /* i  : codebook size             */
    2950             : )
    2951             : {
    2952             :     Word16 i, idx;
    2953             :     Word32 mindist, d;
    2954             : 
    2955      401128 :     idx = 0;
    2956      401128 :     move16();
    2957      401128 :     mindist = 10000000; // Q0
    2958      401128 :     move32();
    2959     3348042 :     FOR( i = 0; i < cbsize; i++ )
    2960             :     {
    2961     2946914 :         d = L_mult0( sub( x, cb[i] ), sub( x, cb[i] ) );
    2962     2946914 :         IF( LT_32( d, mindist ) )
    2963             :         {
    2964      723360 :             mindist = d;
    2965      723360 :             move32();
    2966      723360 :             idx = i;
    2967      723360 :             move16();
    2968             :         }
    2969             :     }
    2970      401128 :     *xq = cb[idx];
    2971      401128 :     move16();
    2972             : 
    2973      401128 :     return idx;
    2974             : }
    2975             : 
    2976             : /*===================================================================*/
    2977             : /* FUNCTION      :  pz_filter_dp_fx ()                               */
    2978             : /*-------------------------------------------------------------------*/
    2979             : /* PURPOSE       :  Generic pole-zero filter routine, with double    */
    2980             : /*                  precision memory, transposed direct form II      */
    2981             : /*-------------------------------------------------------------------*/
    2982             : /* INPUT ARGUMENTS  :                                                */
    2983             : /*                                                                   */
    2984             : /*   _ (Word16 []) b   : zero filter coefficients (Qc).              */
    2985             : /*   _ (Word16 []) a   : pole filter coefficients (Qc), a(0)=1       */
    2986             : /*   _ (Word16 []) x   : input signal (Qx).                          */
    2987             : /*   _ (Word16)    P   : filter order.                               */
    2988             : /*   _ (Word16)    N   : number of input samples.                    */
    2989             : /*   _ (Word16)    Qa  : Q factor compensation (Qa=16-Qc)            */
    2990             : /*-------------------------------------------------------------------*/
    2991             : /* OUTPUT ARGUMENTS :                                                */
    2992             : /*                                                                   */
    2993             : /*   _ (Word16 []) y : output signal  (Qx)                           */
    2994             : /*-------------------------------------------------------------------*/
    2995             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2996             : /*                                                                   */
    2997             : /*   _ (Word32 []) buf : filter memory (Qx+Qc)                          */
    2998             : /*-------------------------------------------------------------------*/
    2999             : /* RETURN ARGUMENTS : _ None.                                        */
    3000             : /*===================================================================*/
    3001             : 
    3002           0 : void pz_filter_dp_fx(
    3003             :     const Word16 b[],
    3004             :     const Word16 a[],
    3005             :     Word16 x[],
    3006             :     Word16 y[],
    3007             :     Word32 buf[],
    3008             :     Word16 PNR,
    3009             :     Word16 PDR,
    3010             :     Word16 N,
    3011             :     Word16 Qa )
    3012             : {
    3013             :     Word16 i, j;
    3014             :     Word16 s;
    3015             :     Word32 s_mem;
    3016             :     Word32 Ltemp1;
    3017             :     Word32 Lacc;
    3018             : 
    3019           0 :     s = negate( Qa );
    3020           0 :     s = add( s, s ); /*  s=-2Qa */
    3021           0 :     s = add( s, 1 );
    3022           0 :     FOR( i = 0; i < N; i++ )
    3023             :     {
    3024           0 :         Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
    3025           0 :         Lacc = L_shl( Lacc, s );    /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
    3026           0 :         FOR( j = PDR - 1; j >= 0; j-- )
    3027           0 :         Lacc = Msub_32_16( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
    3028             : 
    3029           0 :         s_mem = L_shl_sat( Lacc, sub( Qa, 1 ) ); /*Qn-Qa+16=Qn+Qc*/
    3030           0 :         Lacc = L_deposit_l( 0 );
    3031           0 :         FOR( j = PNR - 1; j >= 0; j-- )
    3032           0 :         Lacc = Madd_32_16( Lacc, buf[j], b[j + 1] );
    3033           0 :         Lacc = Madd_32_16( Lacc, s_mem, b[0] );
    3034             :         /* Lacc in Q(1+Qc+Qn-Qa) */
    3035             : 
    3036           0 :         FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
    3037             :         {
    3038             :             /* Update filter memory */
    3039           0 :             buf[j] = buf[j - 1];
    3040           0 :             move16();
    3041             :         }
    3042           0 :         buf[0] = s_mem;
    3043           0 :         move16();
    3044             : 
    3045           0 :         Ltemp1 = L_shr_sat( Lacc, s ); /* Ltemp1 in Qc+Qa+Qn=Q(16+Qn) */
    3046           0 :         y[i] = extract_h( Ltemp1 );    /* y[i] in Qn */
    3047           0 :         move16();
    3048             :     }
    3049           0 : }
    3050             : 
    3051             : /*-------------------------------------------------------------------*
    3052             :  * Copy_Scale_sig
    3053             :  *
    3054             :  * Up/down scale a 16 bits vector x and move it into y
    3055             :  *-------------------------------------------------------------------*/
    3056     8469923 : void Copy_Scale_sig32(
    3057             :     const Word32 x[], /* i  : signal to scale input           Qx        */
    3058             :     Word32 y[],       /* o  : scaled signal output            Qx        */
    3059             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
    3060             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    3061             : )
    3062             : {
    3063             :     Word16 i;
    3064             :     Word32 L_tmp;
    3065     8469923 :     Word16 tmp = exp0;
    3066             : #ifndef ISSUE_1836_replace_overflow_libcom
    3067             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    3068             :     Flag Overflow = 0;
    3069             :     move32();
    3070             : #endif
    3071             : #endif
    3072     8469923 :     IF( exp0 == 0 )
    3073             :     {
    3074   987166654 :         FOR( i = 0; i < lg; i++ )
    3075             :         {
    3076   985693757 :             y[i] = x[i];
    3077   985693757 :             move32();
    3078             :         }
    3079     1472897 :         return;
    3080             :     }
    3081     6997026 :     IF( exp0 < 0 )
    3082             :     {
    3083   531914343 :         FOR( i = 0; i < lg; i++ )
    3084             :         {
    3085             : #ifdef ISSUE_1836_replace_overflow_libcom
    3086   527239721 :             y[i] = L_shl_sat( x[i], tmp );
    3087             : #else
    3088             :             y[i] = L_shl_o( x[i], tmp, &Overflow );
    3089             : #endif
    3090   527239721 :             move16();
    3091             :         }
    3092     4674622 :         return;
    3093             :     }
    3094             : #ifdef ISSUE_1836_replace_overflow_libcom
    3095     2322404 :     L_tmp = L_shl_sat( 1, exp0 - 1 );
    3096             : #else
    3097             :     L_tmp = L_shl_o( 1, exp0 - 1, &Overflow );
    3098             : #endif
    3099   304473914 :     FOR( i = 0; i < lg; i++ )
    3100             :     {
    3101   302151510 :         y[i] = W_extract_l( W_mult_32_32( L_tmp, x[i] ) );
    3102   302151510 :         move32(); /* saturation can occur here */
    3103             :     }
    3104             : }
    3105             : 
    3106             : 
    3107             : /*-------------------------------------------------------------------*
    3108             :  * Copy_Scale_sig32_16
    3109             :  *
    3110             :  * Up/down scale a 32 bits vector and round to 16 bits vector
    3111             :  *-------------------------------------------------------------------*/
    3112    11748360 : void Copy_Scale_sig32_16(
    3113             :     const Word32 *src, /* i  : signal to scale                 Qx        */
    3114             :     Word16 *dst,       /* o  : scaled signal                   Qx        */
    3115             :     Word16 len,        /* i  : size of x[]                     Q0        */
    3116             :     Word16 exp0 )      /* i  : exponent: x = round(x << exp)   Qx ?exp  */
    3117             : {
    3118             :     Word16 i;
    3119             :     Word32 L_temp;
    3120             : 
    3121    11748360 :     IF( exp0 == 0 )
    3122             :     {
    3123   196342222 :         FOR( i = 0; i < len; i++ )
    3124             :         {
    3125   192043747 :             *dst++ = round_fx_sat( *src++ );
    3126   192043747 :             move16();
    3127             :         }
    3128     4298475 :         return;
    3129             :     }
    3130             : 
    3131  4171681508 :     FOR( i = 0; i < len; i++ )
    3132             :     {
    3133  4164231623 :         L_temp = L_shl_sat( *src++, exp0 );
    3134             : 
    3135  4164231623 :         *dst++ = round_fx_sat( L_temp );
    3136  4164231623 :         move16();
    3137             :     }
    3138             : }
    3139             : 
    3140             : /*-------------------------------------------------------------------*
    3141             :  * v_multc_att()
    3142             :  *
    3143             :  * Attenuation of a vector,, attenuation factor in Q15
    3144             :  *-------------------------------------------------------------------*/
    3145             : 
    3146        1423 : void v_multc_att(
    3147             :     const Word16 x[], /* i  : Input vector   Qx                                */
    3148             :     const Word16 att, /* i  : Constant Q15, <= MAX_16                          */
    3149             :     Word16 y[],       /* o  : Output vector that contains att*x                */
    3150             :     const Word16 N    /* i  : Vector length                                    */
    3151             : )
    3152             : {
    3153             :     Word16 i;
    3154        1423 :     IF( LT_16( att, 32767 ) )
    3155             :     {
    3156           0 :         FOR( i = 0; i < N; i++ )
    3157             :         {
    3158           0 :             y[i] = mult_r( x[i], att );
    3159           0 :             move16();
    3160             :         }
    3161             :     }
    3162        1423 : } /*-------------------------------------------------------------------*
    3163             :    * v_multc_att32()
    3164             :    *
    3165             :    * Attenuation of a vector,, attenuation factor in Q15
    3166             :    *-------------------------------------------------------------------*/
    3167             : 
    3168         860 : void v_multc_att32(
    3169             :     const Word32 x[], /* i  : Input vector   Qx                                */
    3170             :     const Word16 att, /* i  : Constant Q15, <= MAX_16                          */
    3171             :     Word32 y[],       /* o  : Output vector that contains att*x                */
    3172             :     const Word16 N    /* i  : Vector length                                    */
    3173             : )
    3174             : {
    3175             :     Word16 i;
    3176         860 :     IF( LT_16( att, 32767 ) )
    3177             :     {
    3178           0 :         FOR( i = 0; i < N; i++ )
    3179             :         {
    3180           0 :             y[i] = Mpy_32_16_r( x[i], att );
    3181           0 :             move32();
    3182             :         }
    3183             :     }
    3184         860 : }
    3185             : 
    3186             : /*-------------------------------------------------------------------*
    3187             :  * v_multc_att3232()
    3188             :  *
    3189             :  * Attenuation of a vector, attenuation factor in Q31
    3190             :  *-------------------------------------------------------------------*/
    3191             : 
    3192           0 : void v_multc_att3232(
    3193             :     const Word32 x[], /* i  : Input vector   Qx                                */
    3194             :     const Word32 att, /* i  : Constant Q32, <= MAX_32                          */
    3195             :     Word32 y[],       /* o  : Output vector that contains att*x                */
    3196             :     const Word16 N    /* i  : Vector length                                    */
    3197             : )
    3198             : {
    3199             :     Word16 i;
    3200           0 :     IF( LE_32( att, MAX_32 ) )
    3201             :     {
    3202           0 :         FOR( i = 0; i < N; i++ )
    3203             :         {
    3204           0 :             y[i] = Mpy_32_32_r( x[i], att );
    3205           0 :             move32();
    3206             :         }
    3207             :     }
    3208           0 : }
    3209             : 
    3210             : /*-------------------------------------------------------------------*
    3211             :  * v_L_mult_1616()
    3212             :  *
    3213             :  * Multiplication of two vectors, Output in Word32
    3214             :  *-------------------------------------------------------------------*/
    3215             : 
    3216           0 : void v_L_mult_1616(
    3217             :     const Word16 x1[], /* i  : Input vector 1                                   */
    3218             :     const Word16 x2[], /* i  : Input vector 2                                   */
    3219             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    3220             :     const Word16 N     /* i  : Vector length                                    */
    3221             : )
    3222             : {
    3223             :     Word16 i;
    3224             : 
    3225           0 :     for ( i = 0; i < N; i++ )
    3226             :     {
    3227           0 :         y[i] = L_mult( x1[i], x2[i] );
    3228           0 :         move32();
    3229             :     }
    3230             : 
    3231           0 :     return;
    3232             : }
    3233             : 
    3234             : /*-------------------------------------------------------------------*
    3235             :  * v_L_mult_3216()
    3236             :  *
    3237             :  * Multiplication of two vectors, Output in Word32
    3238             :  *-------------------------------------------------------------------*/
    3239             : 
    3240       92161 : void v_L_mult_3216(
    3241             :     const Word32 x1[], /* i  : Input vector 1                                   */
    3242             :     const Word16 x2[], /* i  : Input vector 2                                   */
    3243             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    3244             :     const Word16 N     /* i  : Vector length                                    */
    3245             : )
    3246             : {
    3247             :     Word16 i;
    3248             : 
    3249    53648257 :     for ( i = 0; i < N; i++ )
    3250             :     {
    3251    53556096 :         y[i] = Mpy_32_16_1( x1[i], x2[i] );
    3252    53556096 :         move32();
    3253             :     }
    3254             : 
    3255       92161 :     return;
    3256             : }
    3257             : 
    3258             : /*-------------------------------------------------------------------*
    3259             :  * add_vec()
    3260             :  *
    3261             :  * Addition of two vectors sample by sample
    3262             :  *-------------------------------------------------------------------*/
    3263             : 
    3264        2058 : void add_vec_fx(
    3265             :     const Word16 x1[], /* i  : Input vector 1                       */
    3266             :     const Word16 Qx1,  /* i  : SCaling of input 1                    */
    3267             :     const Word16 x2[], /* i  : Input vector 2                       */
    3268             :     const Word16 Qx2,  /* i  : SCaling of input 1                    */
    3269             :     Word16 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    3270             :     const Word16 Qy,   /* i  : SCaling of output 1                    */
    3271             :     const Word16 N     /* i  : Vector lenght                                    */
    3272             : )
    3273             : {
    3274             :     Word16 i, Qyx1, Qyx2;
    3275             : #ifndef ISSUE_1836_replace_overflow_libcom
    3276             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    3277             :     Flag Overflow = 0;
    3278             :     move32();
    3279             : #endif
    3280             : #endif
    3281        2058 :     Qyx1 = sub( Qx1, Qy );
    3282        2058 :     Qyx2 = sub( Qx2, Qy );
    3283        2058 :     IF( Qyx1 == 0 )
    3284             :     {
    3285     1738058 :         FOR( i = 0; i < N; i++ )
    3286             :         {
    3287             : #ifdef ISSUE_1836_replace_overflow_libcom
    3288     1736000 :             y[i] = add_sat( x1[i], shr_r_sat( x2[i], Qyx2 ) );
    3289             : #else
    3290             :             y[i] = add_o( x1[i], shr_r_sat( x2[i], Qyx2 ), &Overflow );
    3291             : #endif
    3292     1736000 :             move16();
    3293             :         }
    3294             :     }
    3295             :     ELSE
    3296             :     {
    3297           0 :         FOR( i = 0; i < N; i++ )
    3298             :         {
    3299             : #ifdef ISSUE_1836_replace_overflow_libcom
    3300           0 :             y[i] = add_sat( shr_r_sat( x1[i], Qyx1 ), shr_r_sat( x2[i], Qyx2 ) ); //!!sat //!!sat
    3301             : #else
    3302             :             y[i] = add_o( shr_r_sat( x1[i], Qyx1 ), shr_r_sat( x2[i], Qyx2 ), &Overflow );
    3303             : #endif
    3304           0 :             move16();
    3305             :         }
    3306             :     }
    3307        2058 :     return;
    3308             : }
    3309             : 
    3310             : /*-------------------------------------------------------------------*
    3311             :  *  Add_flt32_flt32
    3312             :  *
    3313             :  *  Add two Pseudo Float Value that are 32 Bits Mantisa and 16 Bits Exp
    3314             :  *-------------------------------------------------------------------*/
    3315        5392 : Word32 Add_flt32_flt32(                 /* o: Result (Normalized)                */
    3316             :                         Word32 a,       /* i: 1st Value                          */
    3317             :                         Word16 exp_a,   /* i: Exponent of 1st Value (Q of Value) */
    3318             :                         Word32 b,       /* i: 2nd Value                          */
    3319             :                         Word16 exp_b,   /* i: Exponent of 2nd Value (Q of Value) */
    3320             :                         Word16 *exp_out /* o: Exponent of Result                 */
    3321             : )
    3322             : {
    3323             :     Word16 temp, temp2;
    3324             :     Word32 L_temp;
    3325             : 
    3326             :     /* Subract 1 to further divide by 2 to avoid overflow on L_add */
    3327        5392 :     temp = sub( s_min( exp_a, exp_b ), 1 );
    3328             : 
    3329             :     /* Put both to same exponent */
    3330        5392 :     exp_a = sub( exp_a, temp );
    3331        5392 :     a = L_shr( a, exp_a );
    3332        5392 :     exp_b = sub( exp_b, temp );
    3333        5392 :     b = L_shr( b, exp_b );
    3334             : 
    3335             :     /* add them together */
    3336        5392 :     L_temp = L_add( a, b );
    3337        5392 :     temp2 = norm_l( L_temp );
    3338             : 
    3339        5392 :     *exp_out = add( temp, temp2 );
    3340        5392 :     move16();
    3341             : 
    3342        5392 :     return L_shl( L_temp, temp2 );
    3343             : }
    3344             : 
    3345             : /*-------------------------------------------------------------------*
    3346             :  *  Mul_flt32_Q15
    3347             :  *
    3348             :  *  Multiply one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
    3349             :  *  with a Q15 value
    3350             :  *-------------------------------------------------------------------*/
    3351           0 : Word32 Mul_flt32_Q15(                /*  o: Result (Normalized)            */
    3352             :                       Word32 value,  /*  i: Pseudo_float Value             */
    3353             :                       Word16 *exp_v, /*i/o: Exponent of Value (Q of Value) */
    3354             :                       Word16 frac    /*  i: Q15 value                      */
    3355             : )
    3356             : {
    3357             :     Word16 temp;
    3358             :     Word32 L_temp;
    3359             : 
    3360           0 :     L_temp = Mult_32_16( value, frac );
    3361           0 :     temp = norm_l( L_temp );
    3362             : 
    3363           0 :     *exp_v = add( temp, *exp_v );
    3364           0 :     move16();
    3365             : 
    3366           0 :     return L_shl( L_temp, temp );
    3367             : }
    3368             : 
    3369             : /*-------------------------------------------------------------------*
    3370             :  *  Div_flt32_flt32
    3371             :  *
    3372             :  *  Divide one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
    3373             :  *  by another one
    3374             :  *-------------------------------------------------------------------*/
    3375           3 : Word32 Div_flt32_flt32(                 /* o: Result (Normalized)                */
    3376             :                         Word32 a,       /* i: 1st Value                          */
    3377             :                         Word16 exp_a,   /* i: Exponent of 1st Value (Q of Value) */
    3378             :                         Word32 b,       /* i: 2nd Value                          */
    3379             :                         Word16 exp_b,   /* i: Exponent of 2nd Value (Q of Value) */
    3380             :                         Word16 *exp_out /* o: Exponent of Result                 */
    3381             : )
    3382             : {
    3383             :     Word16 temp, temp2;
    3384             :     Word32 L_temp;
    3385             : 
    3386           3 :     temp = div_s( 16384, round_fx( b ) );
    3387           3 :     L_temp = Mult_32_16( a, temp );
    3388           3 :     temp2 = sub( 31 - 1, exp_b );
    3389           3 :     temp2 = add( temp2, exp_a );
    3390             : 
    3391           3 :     temp = norm_l( L_temp );
    3392             : 
    3393           3 :     *exp_out = add( temp, temp2 );
    3394           3 :     move16();
    3395             : 
    3396           3 :     return L_shl( L_temp, temp );
    3397             : }
    3398             : 
    3399             : 
    3400             : /*-------------------------------------------------------------------*
    3401             :  *  Calc_Energy_Autoscaled
    3402             :  *
    3403             :  *  Calculate Energy with overflow protection
    3404             :  *-------------------------------------------------------------------*/
    3405     3528830 : Word32 Calc_Energy_Autoscaled(                       /* o: Result (Energy)                  */
    3406             :                                const Word16 *signal, /* i: Signal                           */
    3407             :                                Word16 signal_exp,    /* i: Exponent of Signal (Q of Signal) */
    3408             :                                Word16 len,           /* i: Frame Length                     */
    3409             :                                Word16 *energy_exp    /* o: Exponent of Energy (Q of Energy) */
    3410             : )
    3411             : {
    3412             :     Word16 temp, temp2;
    3413             :     Word32 L_temp, L_Energy;
    3414             :     Word16 i, j;
    3415             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    3416     3528830 :     Flag Overflow = 0;
    3417     3528830 :     move32();
    3418             : #endif
    3419             : 
    3420     3528830 :     Overflow = 0;
    3421     3528830 :     move16();
    3422             : 
    3423     3528830 :     temp2 = 0;
    3424     3528830 :     move16();
    3425     3528830 :     L_Energy = L_deposit_l( 1 );
    3426     3528830 :     j = s_and( 7, len );
    3427     3540670 :     FOR( i = 0; i < j; i++ )
    3428             :     {
    3429             :         /* divide by 2 so energy will be divided by 4 */
    3430             : #ifdef ISSUE_1836_replace_overflow_libcom
    3431       11840 :         temp = mult_r( *signal++, 16384 );
    3432             : #else
    3433             :         temp = mult_ro( *signal++, 16384, &Overflow );
    3434             : #endif
    3435       11840 :         L_Energy = L_mac0_o( L_Energy, temp, temp, &Overflow );
    3436             :     }
    3437    11676104 :     FOR( i = j; i < len; i += 8 ) /* Process 8 Samples at a time */
    3438             :     {
    3439             :         /* divide by 2 so energy will be divided by 4 */
    3440     8147274 :         temp = mult_ro( *signal++, 16384, &Overflow );
    3441     8147274 :         L_temp = L_mult0( temp, temp );
    3442    65178192 :         FOR( j = 1; j < 8; j++ )
    3443             :         {
    3444             : #ifdef ISSUE_1836_replace_overflow_libcom
    3445    57030918 :             temp = mult_r( *signal++, 16384 );
    3446             : #else
    3447             :             temp = mult_ro( *signal++, 16384, &Overflow );
    3448             : #endif
    3449    57030918 :             L_temp = L_mac0_o( L_temp, temp, temp, &Overflow );
    3450             :         }
    3451             :         /*Overfloe will never happen because temp2 is always positive*/
    3452     8147274 :         L_temp = L_shr( L_temp, temp2 );
    3453             :         /* Here we try the addition just to check if we can sum
    3454             :            the energy of the small (8 Iterations) loop with the
    3455             :            total energy calculated so far without an overflow.
    3456             :            The result is discarded. If there is an overflow both
    3457             :            energies are div by 2. Otherwise, nothing is done.
    3458             :            After the 'IF', the sum is done again and will always
    3459             :            be without an overflow. */
    3460     8147274 :         L_add_o( L_Energy, L_temp, &Overflow );
    3461     8147274 :         IF( Overflow != 0 )
    3462             :         {
    3463          41 :             L_Energy = L_shr( L_Energy, 1 );
    3464          41 :             L_temp = L_shr( L_temp, 1 );
    3465          41 :             temp2 = add( temp2, 1 );
    3466          41 :             Overflow = 0;
    3467          41 :             move16();
    3468             :         }
    3469     8147274 :         L_Energy = L_add_o( L_Energy, L_temp, &Overflow );
    3470             :     }
    3471             :     /* Calc Final Exponent (sub 2 because of the mult_r by 16384 that already divs the ener by 4) */
    3472     3528830 :     temp2 = sub( sub( shl( signal_exp, 1 ), temp2 ), 2 );
    3473             : 
    3474     3528830 :     *energy_exp = temp2;
    3475     3528830 :     move16();
    3476             : 
    3477     3528830 :     return L_Energy;
    3478             : }
    3479             : 
    3480     4200525 : Word16 Find_Max_Norm16( const Word16 *src, Word16 len )
    3481             : {
    3482             :     Word16 i;
    3483             :     Word16 max16;
    3484             : 
    3485             :     /* it starts at '0' and not '1' like in Find_Max_Norm32() */
    3486             :     /* and that is necessary. */
    3487     4200525 :     max16 = 0;
    3488     4200525 :     move16();
    3489             : 
    3490  2495825613 :     FOR( i = 0; i < len; i++ )
    3491             :     {
    3492  2491625088 :         max16 = s_max( max16, abs_s( *src++ ) );
    3493             :     }
    3494             : 
    3495     4200525 :     return norm_s( max16 );
    3496             : }
    3497             : 
    3498     4111487 : Word16 Find_Max_Norm32( const Word32 *src, Word16 len )
    3499             : {
    3500             :     Word16 i;
    3501             :     Word32 max32;
    3502             : 
    3503     4111487 :     max32 = L_deposit_l( 1 );
    3504             : 
    3505  3173935596 :     FOR( i = 0; i < len; i++ )
    3506             :     {
    3507  3169824109 :         max32 = L_max( max32, L_abs( *src++ ) );
    3508             :     }
    3509             : 
    3510     4111487 :     return norm_l( max32 );
    3511             : }
    3512             : 
    3513             : /*-------------------------------------------------------------------*
    3514             :  *  Sqrt_Ratio32
    3515             :  *
    3516             :  *  Calculate Sqrt of Val1/Val2
    3517             :  *-------------------------------------------------------------------*/
    3518        5529 : Word32 Sqrt_Ratio32(                /* o: Result in Q31                                            */
    3519             :                      Word32 L_val1, /* i: Mantisa of Val1                                          */
    3520             :                      Word16 exp1,   /* i: Exp of Val1 (>0: Val was Left Shifted, <0:Right Shifted) */
    3521             :                      Word32 L_val2, /* i: Mantisa of Val2                                          */
    3522             :                      Word16 exp2,   /* i: Exp of Val2 (same as exp1)                               */
    3523             :                      Word16 *exp    /* o: Exp of Result (# of 'L_shl' Req to get to Final Value)   */
    3524             : )
    3525             : {
    3526             :     Word16 temp;
    3527             : 
    3528             :     /* Normalize Energy #1 */
    3529        5529 :     temp = norm_l( L_val1 );
    3530        5529 :     L_val1 = L_shl( L_val1, temp );
    3531             :     /* Adjust Exponent of Energy #1 */
    3532        5529 :     exp1 = add( exp1, temp );
    3533             : 
    3534             :     /* Normalize Energy #2 */
    3535        5529 :     temp = norm_l( L_val2 );
    3536        5529 :     L_val2 = L_shl( L_val2, temp );
    3537             :     /* Adjust Exponent of Energy #1 */
    3538        5529 :     exp2 = add( exp2, temp );
    3539             : 
    3540             :     /* Prepare for Inverse */
    3541        5529 :     temp = round_fx_sat( L_val1 );
    3542        5529 :     temp = div_s( 16384, temp );
    3543             :     /* Mult Now */
    3544        5529 :     L_val2 = Mult_32_16( L_val2, temp );
    3545        5529 :     exp1 = add( sub( exp2, exp1 ), 15 * 2 );
    3546             : 
    3547             :     /* Here Result of ('L_val2' / 2^'exp2') / ('L_val1' / 2^'exp1') is */
    3548             :     /* 'L_val2' / 2^'exp1' */
    3549             :     /* Which is val2/val1 instead of val1/val2 because we will use Inverted Square Root */
    3550             :     /* Normalize before Square Root */
    3551        5529 :     temp = norm_l( L_val2 );
    3552        5529 :     L_val2 = L_shl( L_val2, temp );
    3553        5529 :     exp1 = add( temp, exp1 );
    3554             :     /* Do Sqrt */
    3555        5529 :     temp = sub( 31, exp1 );
    3556        5529 :     L_val1 = Isqrt_lc( L_val2, &temp );
    3557             : 
    3558        5529 :     *exp = temp;
    3559        5529 :     move16();
    3560             : 
    3561        5529 :     return L_val1;
    3562             : }
    3563             : 
    3564        4430 : Word16 Invert16( /* result in Q'15 + 'exp' */
    3565             :                  Word16 val,
    3566             :                  Word16 *exp )
    3567             : {
    3568             :     Word16 temp;
    3569             : 
    3570             :     /* prevent 0 input */
    3571        4430 :     val = s_max( val, 1 );
    3572             :     /* Normalize Value */
    3573        4430 :     temp = norm_s( val );
    3574        4430 :     val = shl( val, temp );
    3575             : 
    3576        4430 :     *exp = sub( sub( 15 - 1, *exp ), temp );
    3577        4430 :     move16(); /* -1 because of 0x4000 is 1.0 in Q14 (and not Q15) */
    3578             : 
    3579        4430 :     temp = div_s( 0x4000, val );
    3580             : 
    3581        4430 :     return temp;
    3582             : }
    3583             : 
    3584           0 : Word16 find_rem( Word16 n, Word16 m, Word16 *r )
    3585             : {
    3586             :     Word16 i, q1, q2, qd;
    3587             :     Word32 Ltemp2;
    3588             :     Word32 Lacc;
    3589             : 
    3590           0 :     test();
    3591           0 :     test();
    3592           0 :     IF( n <= 0 || m <= 0 || n < m )
    3593             :     {
    3594           0 :         *r = n;
    3595           0 :         move16();
    3596           0 :         return ( 0 );
    3597             :     }
    3598             : 
    3599           0 :     q1 = norm_s( n );
    3600           0 :     q1 = sub( q1, 1 );
    3601           0 :     Lacc = L_deposit_h( shl( n, q1 ) );
    3602           0 :     qd = sub( q1, 1 );
    3603           0 :     q2 = norm_s( m );
    3604           0 :     q2 = sub( q2, 1 );
    3605           0 :     Ltemp2 = L_deposit_h( shl( m, q2 ) );
    3606           0 :     qd = sub( q2, qd );
    3607           0 :     q2 = add( q2, 1 );
    3608             : 
    3609           0 :     FOR( i = 0; i < qd; i++ )
    3610             :     {
    3611           0 :         Lacc = L_sub( Lacc, Ltemp2 );
    3612           0 :         IF( Lacc >= 0 )
    3613             :         {
    3614           0 :             Lacc = L_add( L_shl( Lacc, 1 ), 1 );
    3615             :         }
    3616             :         ELSE
    3617             :         {
    3618           0 :             Lacc = L_add( Lacc, Ltemp2 );
    3619           0 :             Lacc = L_shl( Lacc, 1 );
    3620             :         }
    3621             :     }
    3622           0 :     q1 = extract_l( Lacc );
    3623           0 :     Ltemp2 = L_shr( Lacc, q2 );
    3624           0 :     *r = extract_h( Ltemp2 );
    3625           0 :     move16();
    3626           0 :     return ( q1 );
    3627             : }
    3628             : 
    3629             : 
    3630           0 : Word32 find_remd( Word32 n, Word32 m, Word32 *r )
    3631             : {
    3632             :     Word16 i, q1, q2, qd;
    3633             :     Word32 Ltemp2, qo;
    3634             :     Word32 Lacc;
    3635             : 
    3636           0 :     test();
    3637           0 :     test();
    3638           0 :     IF( n <= 0 || m <= 0 || n < m )
    3639             :     {
    3640           0 :         *r = n;
    3641           0 :         move16();
    3642           0 :         return ( 0 );
    3643             :     }
    3644             : 
    3645           0 :     q1 = norm_l( n );
    3646           0 :     q1 = sub( q1, 1 );
    3647           0 :     Lacc = L_shl( n, q1 );
    3648           0 :     qd = sub( q1, 1 );
    3649           0 :     q2 = norm_l( m );
    3650           0 :     q2 = sub( q2, 1 );
    3651           0 :     Ltemp2 = L_shl( m, q2 );
    3652           0 :     qd = sub( q2, qd );
    3653           0 :     q2 = add( q2, 1 );
    3654           0 :     qo = 0;
    3655           0 :     move16();
    3656             : 
    3657           0 :     FOR( i = 0; i < qd; i++ )
    3658             :     {
    3659           0 :         Lacc = L_sub( Lacc, Ltemp2 );
    3660           0 :         qo = L_shl( qo, 1 );
    3661           0 :         IF( Lacc >= 0 )
    3662             :         {
    3663           0 :             Lacc = L_shl( Lacc, 1 );
    3664           0 :             qo = L_add( qo, 1 );
    3665             :         }
    3666             :         ELSE
    3667             :         {
    3668           0 :             Lacc = L_add( Lacc, Ltemp2 );
    3669           0 :             Lacc = L_shl( Lacc, 1 );
    3670             :         }
    3671             :     }
    3672           0 :     *r = L_shr( Lacc, q2 );
    3673           0 :     move16();
    3674           0 :     return ( qo );
    3675             : }
    3676             : 
    3677       30442 : Word16 rint_new_fx(
    3678             :     Word32 x /*Q16 */
    3679             : )
    3680             : {
    3681             :     Word16 a;
    3682             :     Word32 L_tmp;
    3683             :     Word16 frac, tmp;
    3684             : 
    3685             :     /* middle value point test */
    3686       30442 :     frac = lshr( extract_l( x ), 1 ); /*Q15 */
    3687       30442 :     tmp = sub( frac, 0x4000 );
    3688             : 
    3689       30442 :     IF( !tmp )
    3690             :     {
    3691           0 :         a = add( extract_h( x ), 1 );
    3692             : 
    3693           0 :         IF( s_and( a, 1 ) == 0 )
    3694             :         {
    3695           0 :             return a;
    3696             :         }
    3697           0 :         IF( s_and( a, 1 ) != 0 )
    3698             :         {
    3699           0 :             return extract_h( x );
    3700             :         }
    3701           0 :         return extract_h( x );
    3702             :     }
    3703             :     ELSE
    3704             :     {
    3705       30442 :         L_tmp = L_add( x, 32768 ); /*Q16 */
    3706       30442 :         return extract_h( L_tmp );
    3707             :     }
    3708             : }
    3709             : 
    3710             : 
    3711             : /*===================================================================*/
    3712             : /* FUNCTION      :  erb_diff_search_fx ()                            */
    3713             : /*-------------------------------------------------------------------*/
    3714             : /* PURPOSE       :  erb amplitude VQ search for QPPP                 */
    3715             : /*-------------------------------------------------------------------*/
    3716             : /* INPUT ARGUMENTS  :                                                */
    3717             : /*   _ (Word16 []) prev_erb : Previous erb amplitude, Q13            */
    3718             : /*   _ (Word16 []) curr_erb : Current erb amplitude, Q13             */
    3719             : /*   _ (Word16 []) dif_erb: erb differential, Q13                    */
    3720             : /*   _ (Word16 []) pow_spec : LPC power spectrum, Q7                 */
    3721             : /*   _ (Word16 [][]) cb_fx : differential erb codebook, Q13          */
    3722             : /*   _ (Word16) cb_size :  codebook size                             */
    3723             : /*   _ (Word16) cb_dim :  codebook dimension                         */
    3724             : /*   _ (Word16) offset :  index to current segment of erb array      */
    3725             : /*                        for quantization                           */
    3726             : /*-------------------------------------------------------------------*/
    3727             : /* OUTPUT ARGUMENTS :                                                */
    3728             : /*                    _ None                                         */
    3729             : /*-------------------------------------------------------------------*/
    3730             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3731             : /*                    _ None                                         */
    3732             : /*-------------------------------------------------------------------*/
    3733             : /* RETURN ARGUMENTS :                                                */
    3734             : /*   _ (Word16) index: best codebook index                           */
    3735             : /*-------------------------------------------------------------------*/
    3736             : /* CALLED FROM : TX                                                  */
    3737             : /*===================================================================*/
    3738             : 
    3739           0 : Word16 erb_diff_search_fx( Word16 *prev_erb, const Word16 *curr_erb, Word16 *dif_erb, Word16 *pow_spec, const Word16 *cb_fx, Word16 cb_size, Word16 cb_dim, Word16 offset )
    3740             : {
    3741             :     Word16 i, j, mmseindex;
    3742             :     Word16 dh, dl;
    3743             :     Word32 mmse;
    3744             :     Word32 Ltemp1;
    3745             :     Word32 Lacc;
    3746             : 
    3747           0 :     mmse = EVS_LW_MAX;
    3748           0 :     move32();
    3749           0 :     mmseindex = -1;
    3750           0 :     move16();
    3751           0 :     FOR( j = 0; j < cb_size; j++ )
    3752             :     {
    3753             : 
    3754           0 :         Lacc = L_deposit_l( 0 );
    3755           0 :         FOR( i = 0; i < cb_dim; i++ )
    3756             :         {
    3757           0 :             IF( add_sat( cb_fx[j * cb_dim + i], prev_erb[i + offset] ) < 0 )
    3758             :             {
    3759           0 :                 Ltemp1 = L_mult( curr_erb[i + offset], curr_erb[i + offset] ); /* Q27 */
    3760           0 :                 dh = extract_h( Ltemp1 );
    3761           0 :                 dl = extract_l( Ltemp1 );
    3762           0 :                 IF( dl < 0 )
    3763             :                 {
    3764           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    3765           0 :                     Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
    3766           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    3767             :                 }
    3768             :                 ELSE
    3769             :                 {
    3770           0 :                     Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl );
    3771             :                 }
    3772           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) );
    3773             :             }
    3774             :             ELSE
    3775             :             {
    3776           0 :                 dh = sub_sat( dif_erb[i + offset], cb_fx[j * cb_dim + i] ); /* Q13 */
    3777           0 :                 Ltemp1 = L_mult_sat( dh, dh );                              /* Q27 */
    3778           0 :                 dh = extract_h( Ltemp1 );
    3779           0 :                 dl = extract_l( Ltemp1 );
    3780             : 
    3781           0 :                 IF( dl < 0 )
    3782             :                 {
    3783           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    3784           0 :                     Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
    3785           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    3786             :                 }
    3787             :                 ELSE
    3788             :                 {
    3789           0 :                     Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl ); /* Q33 */
    3790             :                 }
    3791             : 
    3792           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) ); /* Q18 */
    3793             :             }
    3794             : 
    3795           0 :             IF( LT_16( cb_fx[j * cb_dim + i], dif_erb[i + offset] ) )
    3796             :             {
    3797           0 :                 dh = extract_h( Ltemp1 );
    3798           0 :                 dl = extract_l( Ltemp1 );
    3799           0 :                 IF( dl < 0 )
    3800             :                 {
    3801           0 :                     Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
    3802           0 :                     Ltemp1 = Mult_32_16( Ltemp1, 29491 );
    3803           0 :                     Ltemp1 = L_shl( Ltemp1, 1 );
    3804             :                 }
    3805             :                 ELSE
    3806             :                 {
    3807           0 :                     Ltemp1 = (Word32) L_mult0( 29491, dl ); /* 29491=0.9 in Q15 */
    3808             :                 }
    3809           0 :                 Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( dh, 29491 ) );
    3810             :             }
    3811           0 :             Lacc = L_add( Lacc, Ltemp1 ); /* Q18 */
    3812             :         }
    3813             : 
    3814           0 :         IF( LT_32( Lacc, mmse ) )
    3815             :         {
    3816           0 :             mmse = L_add( Lacc, 0 );
    3817           0 :             mmseindex = j;
    3818           0 :             move16();
    3819             :         }
    3820             :     }
    3821             : 
    3822           0 :     return ( mmseindex );
    3823             : }
    3824      492617 : void Acelp_dec_total_exc(
    3825             :     Word16 *exc_fx,           /* i/o: adapt. excitation exc       */
    3826             :     Word16 *exc2_fx,          /* i/o: adapt. excitation/total exc */
    3827             :     const Word16 gain_code16, /* i  : Gain code Q0                */
    3828             :     const Word16 gain_pit_fx, /* i  ; Pitch gain in Q14           */
    3829             :     const Word16 i_subfr,     /* i  ; subfr                       */
    3830             :     const Word16 *code_fx,    /* i  : code in Q9                  */
    3831             :     const Word16 L_subfr      /* i  : Subframne lenght            */
    3832             : )
    3833             : {
    3834             :     Word16 i;
    3835             :     Word32 L_tmp;
    3836             : 
    3837    32020745 :     FOR( i = 0; i < L_subfr; i++ )
    3838             :     {
    3839    31528128 :         L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr] ), 1 );            /*Q16+Q_exc*/
    3840    31528128 :         exc2_fx[i + i_subfr] = round_fx_sat( L_tmp );                                  /*Q_exc*/
    3841    31528128 :         L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
    3842    31528128 :         exc_fx[i + i_subfr] = round_fx_sat( L_tmp );                                   /*Q_exc*/
    3843    31528128 :         move16();
    3844    31528128 :         move16();
    3845             :     }
    3846      492617 : }
    3847             : 
    3848             : /*-------------------------------------------------------------------*
    3849             :  *  UL_inverse
    3850             :  *
    3851             :  *  Calculate inverse of UL_val. Output in Q_exp.
    3852             :  *-------------------------------------------------------------------*/
    3853      623874 : UWord32 UL_inverse( const UWord32 UL_val, Word16 *exp )
    3854             : {
    3855             :     UWord32 UL_tmp;
    3856             : 
    3857      623874 :     *exp = norm_ul( UL_val );
    3858      623874 :     move16();
    3859      623874 :     UL_tmp = UL_lshl( UL_val, *exp ); /* Q32 */
    3860             : 
    3861      623874 :     *exp = add( 32, sub( 31, *exp ) );
    3862      623874 :     move16();
    3863             : 
    3864      623874 :     return UL_div( 0x80000000, UL_tmp );
    3865             : }
    3866             : 
    3867             : /*-------------------------------------------------------------------*
    3868             :  *  UL_div
    3869             :  *
    3870             :  *  Calculate UL_num/UL_den. UL_num assumed to be Q31, UL_den assumed
    3871             :  *  to be Q32, then result is in Q32.
    3872             :  *-------------------------------------------------------------------*/
    3873      923204 : UWord32 UL_div( const UWord32 UL_num, const UWord32 UL_den )
    3874             : {
    3875             :     UWord32 UL_e, UL_Q;
    3876             :     UWord32 UL_msb, UL_lsb;
    3877             :     Word16 i;
    3878             : 
    3879      923204 :     UL_e = UL_subNsD( 0xffffffff, UL_den );
    3880      923204 :     UL_Q = UL_num;
    3881      923204 :     move32();
    3882             : 
    3883     5539224 :     FOR( i = 0; i < 5; i++ )
    3884             :     {
    3885     4616020 :         Mpy_32_32_uu( UL_Q, UL_e, &UL_msb, &UL_lsb ); /*31+32-32=31 */
    3886     4616020 :         UL_Q = UL_addNsD( UL_Q, UL_msb );
    3887     4616020 :         Mpy_32_32_uu( UL_e, UL_e, &UL_e, &UL_lsb ); /*32+32-32=32 */
    3888             :     }
    3889             : 
    3890      923204 :     return UL_Q;
    3891             : }
    3892             : 
    3893             : /*-----------------------------------------------------------------------------
    3894             :  * ratio()
    3895             :  *
    3896             :  * Divide the numerator by the denominator.
    3897             :  *----------------------------------------------------------------------------*/
    3898     7184138 : Word16 ratio( const Word32 numer, const Word32 denom, Word16 *expo )
    3899             : {
    3900             :     Word16 expNumer, expDenom;
    3901             :     Word16 manNumer, manDenom;
    3902             :     Word16 quotient;
    3903             : 
    3904     7184138 :     expDenom = norm_l( denom );                       /* exponent */
    3905     7184138 :     manDenom = extract_h( L_shl( denom, expDenom ) ); /* mantissa */
    3906     7184138 :     expNumer = norm_l( numer );                       /* exponent */
    3907     7184138 :     manNumer = extract_h( L_shl( numer, expNumer ) ); /* mantissa */
    3908     7184138 :     manNumer = shr( manNumer, 1 );                    /* Ensure the numerator < the denominator */
    3909     7184138 :     quotient = div_s( manNumer, manDenom );           /* in Q14 */
    3910             : 
    3911     7184138 :     *expo = sub( expNumer, expDenom );
    3912     7184138 :     move16();
    3913     7184138 :     return quotient; /* Q14 */
    3914             : }
    3915             : 
    3916             : /*-----------------------------------------------------------------------*
    3917             :  * Function hp400_12k8()                                                 *
    3918             :  *                                                                       *
    3919             :  * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz.    *
    3920             :  * Optimized for fixed-point to get the following frequency response  :  *
    3921             :  *                                                                       *
    3922             :  *  frequency  :   0Hz   100Hz  200Hz  300Hz  400Hz  630Hz  1.5kHz  3kHz *
    3923             :  *  dB loss  :   -infdB  -30dB  -20dB  -10dB  -3dB   +6dB    +1dB    0dB *
    3924             :  *                                                                       *
    3925             :  * Algorithm  :                                                          *
    3926             :  *                                                                       *
    3927             :  *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]                         *
    3928             :  *                   + a[1]*y[i-1] + a[2]*y[i-2];                        *
    3929             :  *                                                                       *
    3930             :  *  short b[3] = {3660, -7320,  3660};       in Q12                      *
    3931             :  *  short a[3] = {4096,  7320, -3540};       in Q12                      *
    3932             :  *                                                                       *
    3933             :  *  float -->   b[3] = {0.893554687, -1.787109375,  0.893554687};        *
    3934             :  *              a[3] = {1.000000000,  1.787109375, -0.864257812};        *
    3935             :  *-----------------------------------------------------------------------*/
    3936           0 : void hp400_12k8_fx(
    3937             :     Word16 signal[], /* i/o: input signal / output is divided by 16 */
    3938             :     const Word16 lg, /* i  : lenght of signal                       */
    3939             :     Word16 mem[]     /* i/o: filter memory [6]                      */
    3940             : )
    3941             : {
    3942             :     Word16 i;
    3943             :     Word16 y1_hi, y1_lo;
    3944             :     Word32 L_tmp, L_tmp2, L_tmp3;
    3945             : 
    3946           0 :     y1_hi = mem[2];
    3947           0 :     move16();
    3948           0 :     y1_lo = mem[3];
    3949           0 :     move16();
    3950             : 
    3951           0 :     L_tmp3 = L_mac( 16384L, mem[1], a_hp400_fx[2] ); /* rounding to maximize precision */
    3952           0 :     L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
    3953           0 :     L_tmp3 = L_shr( L_tmp3, 15 );
    3954           0 :     L_tmp2 = L_mac( L_tmp3, mem[0], a_hp400_fx[2] );
    3955           0 :     L_tmp2 = L_mac( L_tmp2, mem[5], b_hp400_fx[2] );
    3956           0 :     L_tmp2 = L_mac( L_tmp2, mem[4], b_hp400_fx[1] );
    3957           0 :     L_tmp3 = L_mult( mem[4], b_hp400_fx[2] );
    3958             : 
    3959           0 :     mem[5] = signal[lg - 2];
    3960           0 :     move16();
    3961           0 :     FOR( i = 1; i < lg; i++ )
    3962             :     {
    3963             :         /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
    3964             :         /*      + a[1]*y[i-1] + a[2] * y[i-2] */
    3965             : 
    3966           0 :         L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
    3967           0 :         L_tmp = L_mac( L_tmp, *signal, b_hp400_fx[0] );
    3968             : 
    3969           0 :         L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
    3970             : 
    3971           0 :         L_tmp2 = L_mac( L_tmp3, y1_hi, a_hp400_fx[2] );
    3972           0 :         L_tmp2 = L_mac( L_tmp2, *signal, b_hp400_fx[1] );
    3973           0 :         L_tmp3 = L_mac( 16384L, y1_lo, a_hp400_fx[2] ); /* rounding to maximize precision */
    3974             : 
    3975           0 :         y1_lo = L_Extract_lc( L_tmp, &y1_hi );
    3976             : 
    3977           0 :         L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
    3978           0 :         L_tmp3 = L_shr( L_tmp3, 15 );
    3979             : 
    3980           0 :         L_tmp2 = L_add( L_tmp3, L_tmp2 );
    3981             : 
    3982           0 :         L_tmp3 = L_mult( *signal, b_hp400_fx[2] );
    3983             : 
    3984             :         /* signal is divided by 16 to avoid overflow in energy computation */
    3985           0 :         *signal++ = round_fx( L_tmp );
    3986           0 :         move16();
    3987             :     }
    3988             : 
    3989             :     /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
    3990             :     /*      + a[1]*y[i-1] + a[2] * y[i-2] */
    3991             : 
    3992           0 :     L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
    3993             : 
    3994           0 :     mem[4] = *signal;
    3995           0 :     move16();
    3996           0 :     L_tmp = L_mac( L_tmp, mem[4], b_hp400_fx[0] );
    3997             : 
    3998           0 :     L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
    3999             : 
    4000           0 :     mem[0] = y1_hi;
    4001           0 :     move16();
    4002           0 :     mem[1] = y1_lo;
    4003           0 :     move16();
    4004           0 :     L_Extract( L_tmp, &mem[2], &mem[3] );
    4005             : 
    4006             :     /* signal is divided by 16 to avoid overflow in energy computation */
    4007           0 :     *signal++ = round_fx( L_tmp );
    4008           0 :     move16();
    4009             : 
    4010           0 :     return;
    4011             : }
    4012             : 
    4013       59076 : void hp400_12k8_ivas_fx(
    4014             :     Word16 signal[], /* i/o: input signal / output is divided by 16 */
    4015             :     const Word16 lg, /* i  : lenght of signal                       */
    4016             :     Word16 mem[]     /* i/o: filter memory [6]                      */
    4017             : )
    4018             : {
    4019             :     Word16 i;
    4020             :     Word16 x0, x1, x2;
    4021             :     Word32 L_tmp, yy1, y2;
    4022             : 
    4023       59076 :     yy1 = L_Comp( mem[2], mem[3] ); /* Q_syn + 13 */
    4024       59076 :     y2 = L_Comp( mem[0], mem[1] );  /* Q_syn + 13 */
    4025       59076 :     x0 = mem[4];                    /* Q_syn */
    4026       59076 :     move16();
    4027       59076 :     x1 = mem[5]; /* Q_syn */
    4028       59076 :     move16();
    4029             : 
    4030     3839940 :     FOR( i = 0; i < lg; i++ )
    4031             :     {
    4032     3780864 :         x2 = x1; /* Q_syn */
    4033     3780864 :         move16();
    4034     3780864 :         x1 = x0; /* Q_syn */
    4035     3780864 :         move16();
    4036     3780864 :         x0 = signal[i]; /* Q_syn */
    4037     3780864 :         move16();
    4038             : 
    4039     3780864 :         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)*/
    4040     3780864 :         L_tmp = Madd_32_16( L_tmp, y2, a_hp400_ivas_fx[2] ); /*y2 * a_hp400[2]*/ /* Qx + 10 ---->( (Q_syn+13) + 12 - 15)*/
    4041     3780864 :         L_tmp = L_shl( L_tmp, 3 );                                               /* shifting by 3 to maintain same Q (Q_syn+13) */
    4042             : 
    4043     3780864 :         L_tmp = L_mac( L_tmp, x0, b_hp400_fx[0] ); /* Q_syn + 13 */
    4044     3780864 :         L_tmp = L_mac( L_tmp, x1, b_hp400_fx[1] ); /* Q_syn + 13 */
    4045     3780864 :         L_tmp = L_mac( L_tmp, x2, b_hp400_fx[2] ); /* Q_syn + 13 */
    4046             : 
    4047     3780864 :         y2 = yy1; /* Q_syn + 13 */
    4048     3780864 :         move32();
    4049     3780864 :         yy1 = L_tmp; /* Q_syn + 13 */
    4050     3780864 :         move32();
    4051             : 
    4052     3780864 :         signal[i] = round_fx( L_tmp ); /* Q_syn - 3 */
    4053     3780864 :         move16();
    4054             :     }
    4055             : 
    4056       59076 :     L_Extract( yy1, &mem[2], &mem[3] );
    4057       59076 :     L_Extract( y2, &mem[0], &mem[1] );
    4058       59076 :     mem[4] = x0; /* Q_syn */
    4059       59076 :     mem[5] = x1; /* Q_syn */
    4060       59076 :     move16();
    4061       59076 :     move16();
    4062       59076 :     return;
    4063             : }
    4064             : 
    4065           0 : Word16 dot_prod_satcontr( const Word16 *x, const Word16 *y, Word16 qx, Word16 qy, Word16 *qo, Word16 len )
    4066             : {
    4067             :     Word16 tmp_tab_x[L_FRAME16k];
    4068             :     Word16 tmp_tab_y[L_FRAME16k];
    4069             :     Word16 shift, q, ener, i;
    4070             :     Word32 L_tmp;
    4071             :     Word16 *pt1, *pt2;
    4072             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    4073           0 :     Flag Overflow = 0;
    4074           0 :     move32();
    4075             : #endif
    4076             : 
    4077             : 
    4078           0 :     Copy( x, tmp_tab_x, len ); /* OPTIMIZE !!!!! the copy into local table is not necessary */
    4079           0 :     Copy( y, tmp_tab_y, len ); /* could be reworked to do a 1st iteration with the original x[] and y[] */
    4080             :     /* then check if there is an overflow and do a more complex 2nd, 3rd, ... processing */
    4081           0 :     shift = 0;
    4082           0 :     move16();
    4083             :     BASOP_SATURATE_WARNING_OFF_EVS
    4084             :     DO
    4085             :     {
    4086           0 :         Overflow = 0;
    4087           0 :         move16();
    4088           0 :         L_tmp = L_shl_o( 1, s_max( sub( add( add( qx, qy ), 7 ), shift ), 0 ), &Overflow );
    4089           0 :         pt1 = tmp_tab_x;
    4090           0 :         pt2 = tmp_tab_y;
    4091           0 :         FOR( i = 0; i < len; i++ )
    4092             :         {
    4093           0 :             L_tmp = L_mac0_o( L_tmp, *pt1++, *pt2++, &Overflow ); /*Q(qx+qy-shift) */
    4094             :         }
    4095             : 
    4096           0 :         IF( Overflow != 0 )
    4097             :         {
    4098           0 :             Scale_sig( tmp_tab_x, len, -2 );
    4099           0 :             Scale_sig( tmp_tab_y, len, -2 );
    4100           0 :             shift = add( shift, 4 );
    4101             :         }
    4102             :     }
    4103           0 :     WHILE( Overflow != 0 );
    4104             :     BASOP_SATURATE_WARNING_ON_EVS
    4105             : 
    4106           0 :     q = norm_l( L_tmp );
    4107           0 :     L_tmp = L_shl( L_tmp, q ); /*Q(qx+qy-shift+q) */
    4108           0 :     ener = extract_h( L_tmp ); /*Q(qx+qy-shift+q-16) */
    4109           0 :     q = add( q, add( qx, qy ) );
    4110           0 :     *qo = sub( q, add( shift, 16 ) );
    4111           0 :     move16();
    4112           0 :     return ener;
    4113             : }
    4114             : 
    4115             : 
    4116             : /*
    4117             :  * E_UTIL_f_convolve
    4118             :  *
    4119             :  * Parameters:
    4120             :  *    x           I: input vector <14bits
    4121             :  *    h           I: impulse response (or second input vector) (1Q14)
    4122             :  *    y           O: output vetor (result of convolution)
    4123             :  *
    4124             :  * Function:
    4125             :  *    Perform the convolution between two vectors x[] and h[] and
    4126             :  *    write the result in the vector y[]. All vectors are of length L.
    4127             :  *    Only the first L samples of the convolution are considered.
    4128             :  *    Vector size = L_SUBFR
    4129             :  *
    4130             :  * Returns:
    4131             :  *    void
    4132             :  */
    4133       15530 : void E_UTIL_f_convolve( const Word16 x[], const Word16 h[], Word16 y[], const Word16 size )
    4134             : {
    4135             :     Word16 i, n;
    4136             :     Word32 L_sum;
    4137             :     Word64 L64_sum;
    4138             : 
    4139     1009450 :     FOR( n = 0; n < size; n++ )
    4140             :     {
    4141      993920 :         L64_sum = 0;
    4142      993920 :         move64();
    4143    32302400 :         FOR( i = 0; i < n; i++ )
    4144             :         {
    4145    31308480 :             L64_sum = W_mac_16_16( L64_sum, x[i], h[n - i] );
    4146             :         }
    4147      993920 :         L_sum = W_sat_l( L64_sum );
    4148      993920 :         y[n] = mac_r( L_sum, x[i], h[0] );
    4149      993920 :         move16();
    4150             :     }
    4151       15530 :     return;
    4152             : }
    4153             : 
    4154             : /*-----------------------------------------------------------------------------
    4155             :  * floating_point_add:
    4156             :  *
    4157             :  * Add two floating point numbers: x <- x + y.
    4158             :  *----------------------------------------------------------------------------*/
    4159    23313244 : void floating_point_add(
    4160             :     Word32 *mx,      /* io: mantissa of the addend Q31 */
    4161             :     Word16 *ex,      /* io: exponent of the addend Q0  */
    4162             :     const Word32 my, /* i:  mantissa of the adder Q31  */
    4163             :     const Word16 ey  /* i:  exponent of the adder Q0   */
    4164             : )
    4165             : {
    4166             :     Word32 accX, accY;
    4167             :     Word16 align, expo;
    4168             :     /* NB: This function will not work properly if the mantissa is zero and the exponent is not 32.
    4169             :        It is up to the caller function to avoid this condition. */
    4170             :     /* Ensure 1 bit headroom before addition. */
    4171    23313244 :     accX = L_shr( *mx, 1 );
    4172    23313244 :     accY = L_shr( my, 1 );
    4173             :     /* First, align the Q-points of the two operands. Then, add. */
    4174    23313244 :     align = sub( *ex, ey );
    4175             : 
    4176    23313244 :     IF( align < 0 )
    4177             :     {
    4178    22396531 :         accX = L_add( accX, L_shl( accY, align ) );
    4179             :     }
    4180             :     ELSE
    4181             :     {
    4182      916713 :         accX = L_add( accY, L_shr( accX, align ) );
    4183      916713 :         *ex = ey;
    4184      916713 :         move16();
    4185             :     }
    4186             :     /* Normalize the result and update the mantissa and exponent. */
    4187    23313244 :     expo = norm_l( accX );
    4188    23313244 :     *mx = L_shl( accX, expo );
    4189    23313244 :     *ex = sub( add( *ex, expo ), 1 ); /* Subtract 1 due to 1-bit down-shift above ensuring 1 bit headroom before addition. */
    4190    23313244 :     move32();
    4191    23313244 :     move16();
    4192    23313244 :     return;
    4193             : }
    4194             : 
    4195             : /*-------------------------------------------------------------------*
    4196             :  * delay_signal_fx()
    4197             :  *
    4198             :  * Delay buffer by defined number of samples
    4199             :  *-------------------------------------------------------------------*/
    4200             : 
    4201      960120 : void delay_signal_fx(
    4202             :     Word16 x[],        /* i/o: signal to be delayed              */
    4203             :     const Word16 len,  /* i  : length of the input signal        */
    4204             :     Word16 mem[],      /* i/o: synchronization memory            */
    4205             :     const Word16 delay /* i  : delay in samples                  */
    4206             : )
    4207             : {
    4208             :     Word16 tmp_buffer[L_FRAME48k];
    4209             : 
    4210      960120 :     Copy( mem, tmp_buffer, delay );
    4211      960120 :     Copy( x + sub( len, delay ), mem, delay );
    4212      960120 :     Copy( x, x + delay, sub( len, delay ) );
    4213      960120 :     Copy( tmp_buffer, x, delay );
    4214             : 
    4215      960120 :     return;
    4216             : }
    4217             : 
    4218     2522209 : void delay_signal32_fx(
    4219             :     Word32 x[],        /* i/o: signal to be delayed              */
    4220             :     const Word16 len,  /* i  : length of the input signal        */
    4221             :     Word32 mem[],      /* i/o: synchronization memory            */
    4222             :     const Word16 delay /* i  : delay in samples                  */
    4223             : )
    4224             : {
    4225             :     Word32 tmp_buffer[L_FRAME48k];
    4226             : 
    4227     2522209 :     Copy32( mem, tmp_buffer, delay );
    4228     2522209 :     Copy32( x + sub( len, delay ), mem, delay );
    4229     2522209 :     Copy32( x, x + delay, sub( len, delay ) );
    4230     2522209 :     Copy32( tmp_buffer, x, delay );
    4231             : 
    4232     2522209 :     return;
    4233             : }
    4234             : 
    4235       54098 : void delay_signal_q_adj_fx(
    4236             :     Word32 x[],         /* i/o: signal to be delayed                    */
    4237             :     const Word16 len,   /* i  : length of the input signal              */
    4238             :     Word32 mem[],       /* i/o: synchronization memory                  */
    4239             :     const Word16 delay, /* i  : delay in samples                        */
    4240             :     const Word16 q_x,
    4241             :     const Word16 q_mem )
    4242             : {
    4243             : 
    4244             :     Word32 tmp_buffer[L_FRAME48k];
    4245             : 
    4246       54098 :     Copy32( mem, tmp_buffer, delay );
    4247       54098 :     Copy32( x + sub( len, delay ), mem, delay );
    4248       54098 :     Copy32( x, x + delay, sub( len, delay ) );
    4249             : 
    4250             : 
    4251       54098 :     IF( EQ_16( q_x, q_mem ) )
    4252             :     {
    4253       46120 :         Copy32( tmp_buffer, x, delay );
    4254             :     }
    4255             :     ELSE
    4256             :     {
    4257        7978 :         v_shr( tmp_buffer, sub( q_mem, q_x ), x, delay );
    4258             :     }
    4259             : 
    4260       54098 :     return;
    4261             : }
    4262             : 
    4263    24671177 : void v_add_fx(
    4264             :     const Word32 x1[], /* i  : Input vector 1                       */
    4265             :     const Word32 x2[], /* i  : Input vector 2                       */
    4266             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    4267             :     const Word16 N     /* i  : Vector length                                    */
    4268             : )
    4269             : {
    4270             :     Word16 i;
    4271             : 
    4272  2999102455 :     FOR( i = 0; i < N; i++ )
    4273             :     {
    4274  2974431278 :         y[i] = L_add_sat( x1[i], x2[i] );
    4275  2974431278 :         move32();
    4276             :     }
    4277             : 
    4278    24671177 :     return;
    4279             : }
    4280        3779 : Word16 floor_log_2( Word32 num )
    4281             : {
    4282             : 
    4283        3779 :     IF( num == 0 )
    4284             :     {
    4285           0 :         return 0;
    4286             :     }
    4287             : 
    4288        3779 :     return ( sub( 30, norm_l( num ) ) );
    4289             : }
    4290             : 
    4291     3577012 : void v_shr(
    4292             :     const Word32 x[],   /* i  : Input vector                                     */
    4293             :     const Word16 shift, /* i  : Constant                                         */
    4294             :     Word32 y[],         /* o  : Output vector that contains x >> shift           */
    4295             :     const Word16 N      /* i  : Vector length                                    */
    4296             : )
    4297             : {
    4298             :     Word16 i;
    4299             : 
    4300   635659260 :     FOR( i = 0; i < N; i++ )
    4301             :     {
    4302   632082248 :         y[i] = L_shr( x[i], shift );
    4303   632082248 :         move32();
    4304             :     }
    4305             : 
    4306     3577012 :     return;
    4307             : }
    4308             : 
    4309           0 : void v_shr_16(
    4310             :     const Word16 x[],   /* i  : Input vector                                     */
    4311             :     const Word16 shift, /* i  : Constant                                         */
    4312             :     Word16 y[],         /* o  : Output vector that contains x >> shift               */
    4313             :     const Word16 N      /* i  : Vector length                                    */
    4314             : )
    4315             : {
    4316             :     Word16 i;
    4317             : 
    4318           0 :     FOR( i = 0; i < N; i++ )
    4319             :     {
    4320           0 :         y[i] = shr( x[i], shift );
    4321           0 :         move16();
    4322             :     }
    4323             : 
    4324           0 :     return;
    4325             : }
    4326             : 
    4327             : /*---------------------------------------------------------------------*
    4328             :  * lin_interp_fx()
    4329             :  *
    4330             :  * Linearly maps x from source range <x1, x2> to the target range <y1, y2>
    4331             :  *---------------------------------------------------------------------*/
    4332             : 
    4333             : /*! r: mapped output value */
    4334         705 : Word16 lin_interp_fx(
    4335             :     const Word16 x,       /* i  : Q15 the value to be mapped                       */
    4336             :     const Word16 x1,      /* i  : Q15 source range interval: low end               */
    4337             :     const Word16 y1,      /* i  : Q15 source range interval: high end              */
    4338             :     const Word16 x2,      /* i  : Q15 target range interval: low                   */
    4339             :     const Word16 y2,      /* i  : Q15 target range interval: high                  */
    4340             :     const Word16 flag_sat /* i  : flag to indicate whether to apply saturation */
    4341             : )
    4342             : {
    4343         705 :     IF( sub( x2, x1 ) == 0 )
    4344             :     {
    4345           0 :         return y1;
    4346             :     }
    4347         705 :     ELSE IF( flag_sat )
    4348             :     {
    4349         705 :         IF( GE_16( x, s_max( x1, x2 ) ) )
    4350             :         {
    4351           0 :             IF( GT_16( x1, x2 ) )
    4352             :             {
    4353           0 :                 return y1;
    4354             :             }
    4355             :             ELSE
    4356             :             {
    4357           0 :                 return y2;
    4358             :             }
    4359             :         }
    4360         705 :         ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
    4361             :         {
    4362           8 :             IF( LT_16( x1, x2 ) )
    4363             :             {
    4364           8 :                 return y1;
    4365             :             }
    4366             :             ELSE
    4367             :             {
    4368           0 :                 return y2;
    4369             :             }
    4370             :         }
    4371             :     }
    4372             : 
    4373         697 :     return add_sat( y1, mult( sub( x, x1 ), div_s( sub( y2, y1 ), sub( x2, x1 ) ) ) );
    4374             : }
    4375             : 
    4376             : 
    4377      164897 : Word16 lin_interp_ivas_fx(
    4378             :     const Word16 x,       /* i  : Q15 the value to be mapped                       */
    4379             :     const Word16 x1,      /* i  : Q15 source range interval: low end               */
    4380             :     const Word16 y1,      /* i  : Q15 source range interval: high end              */
    4381             :     const Word16 x2,      /* i  : Q15 target range interval: low                   */
    4382             :     const Word16 y2,      /* i  : Q15 target range interval: high                  */
    4383             :     const Word16 flag_sat /* i  : flag to indicate whether to apply saturation */
    4384             : )
    4385             : {
    4386      164897 :     IF( EQ_16( sub( x2, x1 ), 0 ) )
    4387             :     {
    4388           0 :         return y1;
    4389             :     }
    4390      164897 :     ELSE IF( flag_sat )
    4391             :     {
    4392      162102 :         IF( GE_16( x, s_max( x1, x2 ) ) )
    4393             :         {
    4394         776 :             return GT_16( x1, x2 ) ? y1 : y2;
    4395             :         }
    4396      161326 :         ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
    4397             :         {
    4398      124430 :             return LT_16( x1, x2 ) ? y1 : y2;
    4399             :         }
    4400             :     }
    4401             :     Word16 div_res_e;
    4402       39691 :     Word16 div_res = BASOP_Util_Divide1616_Scale( sub( y2, y1 ), sub( x2, x1 ), &div_res_e );
    4403             :     // div_res = shl( div_res, div_res_e );
    4404       39691 :     return add_sat( y1, round_fx( L_shl( L_mult( sub( x, x1 ), div_res ), div_res_e ) ) );
    4405             : }
    4406             : 
    4407             : /*---------------------------------------------------------------------
    4408             :  * sign_l()
    4409             :  *
    4410             :  *---------------------------------------------------------------------*/
    4411             : 
    4412             : /*! r: sign of x (+1/-1) */
    4413       56280 : Word32 sign_l(
    4414             :     const Word32 x /* i  : input value of x  */
    4415             : )
    4416             : {
    4417       56280 :     IF( x < 0 )
    4418             :     {
    4419       25127 :         return MIN_32;
    4420             :     }
    4421             :     ELSE
    4422             :     {
    4423       31153 :         return MAX_32;
    4424             :     }
    4425             : }
    4426             : 
    4427         132 : void v_mult16_fixed(
    4428             :     const Word16 x1[], /* i  : Input vector 1                                   */
    4429             :     const Word16 x2[], /* i  : Input vector 2                                   */
    4430             :     Word16 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    4431             :     const Word16 N     /* i  : Vector length                                    */
    4432             : )
    4433             : {
    4434             :     Word16 i;
    4435             : 
    4436        9674 :     FOR( i = 0; i < N; i++ )
    4437             :     {
    4438        9542 :         y[i] = mult_r( x1[i], x2[i] );
    4439        9542 :         move16();
    4440             :     }
    4441             : 
    4442         132 :     return;
    4443             : }
    4444             : 
    4445             : /*---------------------------------------------------------------------*
    4446             :  * set_zero_fx()
    4447             :  *
    4448             :  * Set a vector vec[] of dimension lvec to zero
    4449             :  *---------------------------------------------------------------------*/
    4450             : 
    4451   227593674 : void set_zero_fx(
    4452             :     Word32 *vec,      /* o  : input vector                                    */
    4453             :     const Word16 lvec /* i  : length of the vector                            */
    4454             : )
    4455             : {
    4456             :     Word16 i;
    4457             : 
    4458 20422129366 :     FOR( i = 0; i < lvec; i++ )
    4459             :     {
    4460 20194535692 :         *vec++ = 0;
    4461 20194535692 :         move32();
    4462             :     }
    4463             : 
    4464   227593674 :     return;
    4465             : }
    4466        9059 : void set_zero2_fx(
    4467             :     Word32 *vec,      /* o  : input vector                                    */
    4468             :     const Word32 lvec /* i  : length of the vector                            */
    4469             : )
    4470             : {
    4471             :     Word32 i;
    4472             : 
    4473    34153899 :     FOR( i = 0; i < lvec; i++ )
    4474             :     {
    4475    34144840 :         *vec++ = 0;
    4476    34144840 :         move32();
    4477             :     }
    4478             : 
    4479        9059 :     return;
    4480             : }
    4481             : 
    4482     6560552 : void set16_zero_fx(
    4483             :     Word16 *vec,      /* o  : input vector                                    */
    4484             :     const Word16 lvec /* i  : length of the vector                            */
    4485             : )
    4486             : {
    4487             :     Word16 i;
    4488             : 
    4489  2749717075 :     FOR( i = 0; i < lvec; i++ )
    4490             :     {
    4491  2743156523 :         *vec++ = 0;
    4492  2743156523 :         move16();
    4493             :     }
    4494             : 
    4495     6560552 :     return;
    4496             : }
    4497             : 
    4498     1533492 : UWord32 mvl2s_r(
    4499             :     const Word32 x[], /* i  : input vector  */
    4500             :     const Word16 q_x,
    4501             :     Word16 y[],    /* o  : output vector */
    4502             :     const Word16 n /* i  : vector size   */
    4503             : )
    4504             : {
    4505             :     Word16 i;
    4506             :     Word32 temp;
    4507     1533492 :     UWord32 noClipping = 0;
    4508     1533492 :     move32();
    4509             : 
    4510     1533492 :     IF( n <= 0 )
    4511             :     {
    4512             :         /* cannot transfer vectors with size 0 */
    4513          46 :         return 0;
    4514             :     }
    4515             : 
    4516     1533446 :     IF( (void *) y <= (const void *) x )
    4517             :     {
    4518           0 :         Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
    4519           0 :         FOR( i = 0; i < n; i++ )
    4520             :         {
    4521           0 :             temp = L_add( x[i], tempd );
    4522           0 :             temp = L_shr( temp, q_x );
    4523             : 
    4524           0 :             IF( GT_32( temp, MAX16B ) )
    4525             :             {
    4526           0 :                 temp = MAX16B;
    4527           0 :                 move32();
    4528           0 :                 noClipping = L_add( (Word32) noClipping, 1 );
    4529             :             }
    4530           0 :             ELSE IF( LT_32( temp, MIN16B ) )
    4531             :             {
    4532           0 :                 temp = MIN16B;
    4533           0 :                 move32();
    4534           0 :                 noClipping = L_add( (Word32) noClipping, 1 );
    4535             :             }
    4536             : 
    4537           0 :             y[i] = extract_l( temp );
    4538           0 :             move16();
    4539             :         }
    4540             :     }
    4541             :     ELSE
    4542             :     {
    4543     1533446 :         Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
    4544  1227495306 :         FOR( i = n - 1; i >= 0; i-- )
    4545             :         {
    4546  1225961860 :             temp = L_add( x[i], tempd );
    4547  1225961860 :             temp = L_shr( temp, q_x );
    4548             : 
    4549  1225961860 :             IF( GT_32( temp, MAX16B ) )
    4550             :             {
    4551         325 :                 temp = MAX16B;
    4552         325 :                 move32();
    4553         325 :                 noClipping = L_add( (Word32) noClipping, 1 );
    4554             :             }
    4555  1225961535 :             ELSE IF( LT_32( temp, MIN16B ) )
    4556             :             {
    4557         414 :                 temp = MIN16B;
    4558         414 :                 move32();
    4559         414 :                 noClipping = L_add( (Word32) noClipping, 1 );
    4560             :             }
    4561             : 
    4562  1225961860 :             y[i] = extract_l( temp );
    4563  1225961860 :             move16();
    4564             :         }
    4565             :     }
    4566             : 
    4567     1533446 :     return noClipping;
    4568             : }
    4569             : 
    4570    46030160 : Word32 dotp_me_fx(
    4571             :     const Word32 x[], /* i  : vector x[]                    */
    4572             :     const Word32 y[], /* i  : vector y[]                    */
    4573             :     const Word16 n,   /* i  : vector length                 */
    4574             :     Word16 exp_x,
    4575             :     Word16 exp_y,
    4576             :     Word16 *exp_suma )
    4577             : {
    4578             :     Word16 i;
    4579             :     Word32 suma;
    4580             :     Word32 mul;
    4581    46030160 :     Word16 mul_exp = add( exp_x, exp_y );
    4582    46030160 :     suma = Mpy_32_32( x[0], y[0] );
    4583    46030160 :     *exp_suma = mul_exp;
    4584   283085484 :     FOR( i = 1; i < n; i++ )
    4585             :     {
    4586   237055324 :         mul = Mpy_32_32( x[i], y[i] );
    4587   237055324 :         suma = BASOP_Util_Add_Mant32Exp( suma, *exp_suma, mul, mul_exp, exp_suma ); // exp_x+exp_A
    4588             :     }
    4589             : 
    4590    46030160 :     return suma;
    4591             : }
    4592             : 
    4593       17500 : Word32 dotp_fixed_guarded(
    4594             :     const Word32 x[], /* i  : vector x[]                    */
    4595             :     const Word32 y[], /* i  : vector y[]                    */
    4596             :     const Word16 n    /* i  : vector length                 */
    4597             : )
    4598             : {
    4599             :     Word16 i;
    4600             :     Word32 suma;
    4601       17500 :     Word16 guarded_bits = find_guarded_bits_fx( n );
    4602       17500 :     suma = L_shr( Mpy_32_32( x[0], y[0] ), guarded_bits );
    4603             : 
    4604      280000 :     FOR( i = 1; i < n; i++ )
    4605             :     {
    4606      262500 :         suma = L_add( suma, L_shr( Mpy_32_32( x[i], y[i] ), guarded_bits ) );
    4607             :     }
    4608             : 
    4609       17500 :     return suma;
    4610             : }
    4611             : 
    4612             : 
    4613         372 : Word32 dotp_fixed_ivas_fx(
    4614             :     const Word32 x[], /* i  : vector x[]                    */
    4615             :     Word16 x_e,
    4616             :     const Word32 y[], /* i  : vector y[]                    */
    4617             :     Word16 y_e,
    4618             :     const Word16 n, /* i  : vector length                 */
    4619             :     Word16 *out_e )
    4620             : {
    4621             :     Word16 i, exp;
    4622         372 :     Word32 suma = 0;
    4623             : 
    4624         372 :     exp = 31;
    4625         372 :     move16();
    4626             : 
    4627      118544 :     FOR( i = 0; i < n; i++ )
    4628             :     {
    4629      118172 :         suma = BASOP_Util_Add_Mant32Exp( suma, exp, Mpy_32_32( x[i], y[i] ), x_e + y_e, &exp );
    4630             :     }
    4631             : 
    4632         372 :     *out_e = exp;
    4633         372 :     move16();
    4634         372 :     return suma;
    4635             : }
    4636             : 
    4637             : /*-------------------------------------------------------------------*
    4638             :  * v_mult()
    4639             :  *
    4640             :  * Multiplication of two vectors
    4641             :  *-------------------------------------------------------------------*/
    4642             : 
    4643             : 
    4644    14169980 : void v_mult_fixed(
    4645             :     const Word32 x1[], /* i  : Input vector 1                                   */
    4646             :     const Word32 x2[], /* i  : Input vector 2                                   */
    4647             :     Word32 y[],        /* o  : Output vector that contains vector 1 .* vector 2 */
    4648             :     const Word16 N     /* i  : Vector length                                    */
    4649             : )
    4650             : {
    4651             :     Word16 i;
    4652             : 
    4653   555201563 :     FOR( i = 0; i < N; i++ )
    4654             :     {
    4655   541031583 :         y[i] = Mpy_32_32( x1[i], x2[i] );
    4656   541031583 :         move32();
    4657             :     }
    4658             : 
    4659    14169980 :     return;
    4660             : }
    4661             : 
    4662             : /*-------------------------------------------------------------------*
    4663             :  * anint_fixed()
    4664             :  *
    4665             :  * Round to the nearest integer.
    4666             :  *-------------------------------------------------------------------*/
    4667        9400 : Word32 anint_fixed( Word32 x, Word16 exp )
    4668             : {
    4669        9400 :     IF( x == 0 )
    4670             :     {
    4671         856 :         return 0;
    4672             :     }
    4673        8544 :     IF( x >= 0 )
    4674             :     {
    4675        8544 :         return L_add( x, L_shl( 1, sub( exp, 1 ) ) );
    4676             :     }
    4677             :     ELSE
    4678             :     {
    4679           0 :         return L_sub( x, L_shl( 1, sub( exp, 1 ) ) );
    4680             :     }
    4681             : }
    4682             : 
    4683             : /*-------------------------------------------------------------------*
    4684             :  * ceil_fixed()
    4685             :  *
    4686             :  * Ceil to the next multiple of (1 << exp).
    4687             :  *-------------------------------------------------------------------*/
    4688       25515 : Word32 ceil_fixed( Word32 x, Word16 exp )
    4689             : {
    4690             :     Word32 step;
    4691             :     // step = x / L_shl( 1, exp );
    4692       25515 :     step = L_shr( x, exp );
    4693       25515 :     IF( ( x % L_shl( 1, exp ) ) > 0 )
    4694             :     {
    4695       15269 :         step = L_add( step, 1 );
    4696             :     }
    4697       25515 :     return L_shl( step, exp );
    4698             : }
    4699             : 
    4700         783 : void sort_l(
    4701             :     Word32 *x, /* i/o: Vector to be sorted                             */
    4702             :     Word16 len /* i/o: vector length                                   */
    4703             : )
    4704             : {
    4705             :     Word16 i, j;
    4706             :     Word32 tempr;
    4707             : 
    4708        7133 :     FOR( i = len - 2; i >= 0; i-- )
    4709             :     {
    4710        6350 :         tempr = x[i];
    4711        6350 :         move32();
    4712       23195 :         FOR( j = i + 1; ( j < len ) && ( tempr > x[j] ); j++ )
    4713             :         {
    4714       16845 :             x[j - 1] = x[j];
    4715       16845 :             move32();
    4716             :         }
    4717        6350 :         x[j - 1] = tempr;
    4718        6350 :         move32();
    4719             :     }
    4720             : 
    4721         783 :     return;
    4722             : }
    4723             : 
    4724             : /*-------------------------------------------------------------------*
    4725             :  * v_add_fixed()
    4726             :  *
    4727             :  * Subtraction of two vectors sample by sample
    4728             :  *-------------------------------------------------------------------*/
    4729             : 
    4730     4623210 : void v_add_fixed(
    4731             :     const Word32 x1[], /* i  : Input vector 1                                   */
    4732             :     const Word32 x2[], /* i  : Input vector 2                                   */
    4733             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    4734             :     const Word16 N,    /* i  : Vector length                                    */
    4735             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
    4736             : )
    4737             : {
    4738             :     Word16 i;
    4739             : 
    4740   146553112 :     FOR( i = 0; i < N; i++ )
    4741             :     {
    4742   141929902 :         y[i] = L_add( L_shr( x1[i], hdrm ), L_shr( x2[i], hdrm ) );
    4743   141929902 :         move32();
    4744             :     }
    4745             : 
    4746     4623210 :     return;
    4747             : }
    4748             : 
    4749   475646925 : void v_add_fixed_no_hdrm(
    4750             :     const Word32 x1[], /* i  : Input vector 1                                   */
    4751             :     const Word32 x2[], /* i  : Input vector 2                                   */
    4752             :     Word32 y[],        /* o  : Output vector that contains vector 1 + vector 2  */
    4753             :     const Word16 N     /* i  : Vector length                                    */
    4754             : )
    4755             : {
    4756             :     Word16 i;
    4757             : 
    4758  2600924948 :     FOR( i = 0; i < N; i++ )
    4759             :     {
    4760  2125278023 :         y[i] = L_add( x1[i], x2[i] );
    4761  2125278023 :         move32();
    4762             :     }
    4763             : 
    4764   475646925 :     return;
    4765             : }
    4766             : 
    4767     8866906 : void v_add_fixed_me(
    4768             :     const Word32 x1[], /* i  : Input vector 1                                   */
    4769             :     const Word16 x1_e, /* i  : Exponent for input vector 1                      */
    4770             :     const Word32 x2[], /* i  : Input vector 2                                   */
    4771             :     const Word16 x2_e, /* i  : Exponent for input vector 2                      */
    4772             :     Word32 y[],        /* o  : Output vector that contains vector 1 - vector 2  */
    4773             :     Word16 *y_e,       /* i  : Exponent for output vector                       */
    4774             :     const Word16 N,    /* i  : Vector length                                    */
    4775             :     const Word16 hdrm  /* i  : headroom for when subtraction result > 1 or < -1 */
    4776             : )
    4777             : {
    4778             :     Word16 i;
    4779     8866906 :     Word16 x1_shift = sub( s_max( x1_e, x2_e ), x1_e );
    4780     8866906 :     Word16 x2_shift = sub( s_max( x1_e, x2_e ), x2_e );
    4781             : 
    4782   139144085 :     FOR( i = 0; i < N; i++ )
    4783             :     {
    4784   130277179 :         y[i] = L_add( L_shr( x1[i], hdrm + x1_shift ), L_shr( x2[i], hdrm + x2_shift ) );
    4785   130277179 :         move32();
    4786             :     }
    4787             : 
    4788     8866906 :     *y_e = add( s_max( x1_e, x2_e ), hdrm );
    4789     8866906 :     move16();
    4790             : 
    4791     8866906 :     return;
    4792             : }
    4793             : 
    4794    73774555 : Word16 find_guarded_bits_fx( Word32 n )
    4795             : {
    4796             :     // return n <= 1 ? 0 : n <= 2 ? 1
    4797             :     //   : n <= 4 ? 2
    4798             :     //   : n <= 8 ? 3
    4799             :     //   : n <= 16 ? 4
    4800             :     //   : n <= 32 ? 5
    4801             :     //   : n <= 64 ? 6
    4802             :     //   : n <= 128 ? 7
    4803             :     //   : n <= 256 ? 8
    4804             :     //   : n <= 512 ? 9
    4805             :     //   : n <= 1024 ? 10
    4806             :     //   : n <= 2048 ? 11
    4807             :     //   : n <= 4096 ? 12
    4808             :     //   : n <= 8192 ? 13
    4809             :     //   : n <= 16384 ? 14
    4810             :     //   : 15;
    4811             :     /*Word16 val = 0;
    4812             :     move32();
    4813             :     test();
    4814             :     WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) )
    4815             :     {
    4816             :         val = add( val, 1 );
    4817             :     }*/
    4818    73774555 :     IF( LE_32( n, 1 ) )
    4819             :     {
    4820     5457684 :         return 0;
    4821             :     }
    4822             :     ELSE
    4823             :     {
    4824             : 
    4825    68316871 :         return sub( 31, norm_l( L_sub( n, 1 ) ) );
    4826             :     }
    4827             : }
    4828             : 
    4829   644880838 : Word16 L_norm_arr( const Word32 *arr, Word16 size )
    4830             : {
    4831   644880838 :     Word16 q = 31;
    4832   644880838 :     move16();
    4833 33420970820 :     FOR( Word16 i = 0; i < size; i++ )
    4834             :     {
    4835             :         Word16 q_tst;
    4836             : 
    4837 32776089982 :         q_tst = norm_l( arr[i] );
    4838 32776089982 :         if ( arr[i] != 0 )
    4839             :         {
    4840 26727089763 :             q = s_min( q, q_tst );
    4841             :         }
    4842             :     }
    4843             : 
    4844   644880838 :     return q;
    4845             : }
    4846             : 
    4847    20375057 : Word16 norm_arr( Word16 *arr, Word16 size )
    4848             : {
    4849    20375057 :     Word16 q = 15;
    4850    20375057 :     Word16 exp = 0;
    4851    20375057 :     move16();
    4852    20375057 :     move16();
    4853  8060982785 :     FOR( Word16 i = 0; i < size; i++ )
    4854             :     {
    4855  8040607728 :         if ( arr[i] != 0 )
    4856             :         {
    4857  6726000404 :             exp = norm_s( arr[i] );
    4858             :         }
    4859  8040607728 :         if ( arr[i] != 0 )
    4860             :         {
    4861  6726000404 :             q = s_min( q, exp );
    4862             :         }
    4863             :     }
    4864    20375057 :     return q;
    4865             : }
    4866             : 
    4867     3317060 : Word16 W_norm_arr( Word64 *arr, Word16 size )
    4868             : {
    4869     3317060 :     Word16 q = 63;
    4870     3317060 :     Word16 exp = 0;
    4871     3317060 :     move16();
    4872     3317060 :     move16();
    4873  1573168004 :     FOR( Word16 i = 0; i < size; i++ )
    4874             :     {
    4875  1569850944 :         if ( arr[i] != 0 )
    4876             :         {
    4877  1536395516 :             exp = W_norm( arr[i] );
    4878             :         }
    4879  1569850944 :         if ( arr[i] != 0 )
    4880             :         {
    4881  1536395516 :             q = s_min( q, exp );
    4882             :         }
    4883             :     }
    4884     3317060 :     return q;
    4885             : }
    4886             : 
    4887   273754020 : Word16 get_min_scalefactor( Word32 x, Word32 y )
    4888             : {
    4889             :     Word16 scf_y;
    4890   273754020 :     Word16 scf = Q31;
    4891   273754020 :     move16();
    4892             : 
    4893   273754020 :     test();
    4894   273754020 :     if ( x == 0 && y == 0 )
    4895             :     {
    4896    20282128 :         scf = 0;
    4897    20282128 :         move16();
    4898             :     }
    4899             : 
    4900   273754020 :     if ( x != 0 )
    4901             :     {
    4902   253415908 :         scf = norm_l( x );
    4903             :     }
    4904             : 
    4905   273754020 :     scf_y = norm_l( y );
    4906   273754020 :     if ( y != 0 )
    4907             :     {
    4908   195216482 :         scf = s_min( scf_y, scf );
    4909             :     }
    4910             : 
    4911   273754020 :     return scf;
    4912             : }
    4913             : 
    4914             : 
    4915   361055240 : Flag is_zero_arr( Word32 *arr, Word16 size )
    4916             : {
    4917   655666676 :     FOR( Word16 i = 0; i < size; i++ )
    4918   591756789 :     IF( arr[i] != 0 )
    4919             :     {
    4920   297145353 :         return 0;
    4921             :     }
    4922             : 
    4923    63909887 :     return 1;
    4924             : }
    4925             : 
    4926     1924024 : Flag is_zero_arr16( Word16 *arr, Word16 size )
    4927             : {
    4928   251817508 :     FOR( Word16 i = 0; i < size; i++ )
    4929   251595179 :     IF( arr[i] != 0 )
    4930             :     {
    4931     1701695 :         return 0;
    4932             :     }
    4933             : 
    4934      222329 :     return 1;
    4935             : }
    4936             : 
    4937           0 : Flag is_zero_arr64( Word64 *arr, Word16 size )
    4938             : {
    4939           0 :     FOR( Word16 i = 0; i < size; i++ )
    4940             :     {
    4941           0 :         IF( arr[i] != 0 )
    4942             :         {
    4943           0 :             return 0;
    4944             :         }
    4945             :     }
    4946           0 :     return 1;
    4947             : }
    4948             : 
    4949           0 : void Scale_sig64(
    4950             :     Word64 x[], /* i/o: signal to scale                 Qx        */
    4951             :     Word16 len, /* i  : size of x[]                     Q0        */
    4952             :     Word16 exp  /* i  : exponent: x = round(x << exp)   Qx exp    */
    4953             : )
    4954             : {
    4955             :     Word16 i;
    4956           0 :     assert( exp <= 63 && exp >= -63 );
    4957           0 :     IF( exp == 0 )
    4958             :     {
    4959           0 :         return;
    4960             :     }
    4961             : 
    4962           0 :     FOR( i = 0; i < len; i++ )
    4963             :     {
    4964             :         /* saturation can occur here */
    4965           0 :         x[i] = W_shl( x[i], exp );
    4966           0 :         move64();
    4967             :     }
    4968             : }

Generated by: LCOV version 1.14