LCOV - code coverage report
Current view: top level - lib_com - hq_tools_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1135 1246 91.1 %
Date: 2025-05-03 01:55:50 Functions: 27 27 100.0 %

          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             : #include <stdint.h>
      37             : #include <stdlib.h>
      38             : #include "options.h" /* Compilation switches                   */
      39             : #include "rom_com.h" /* Static table prototypes FIP version    */
      40             : #include "stl.h"     /* required for wmc_tool */
      41             : #include "prot_fx.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : /*--------------------------------------------------------------------------*
      45             :  * Local function prototypes
      46             :  *--------------------------------------------------------------------------*/
      47             : 
      48             : static void overlap_hq_bwe_fx( const Word32 *hq_swb_overlap_buf, Word32 *coeff_out, const Word16 n_swb_overlap_offset, const Word16 n_swb_overlap, const Word16 *R, const Word16 num_env_bands, const Word16 num_sfm, const Word16 *sfm_end );
      49             : 
      50             : 
      51             : /*--------------------------------------------------------------------------*
      52             :  * hq_swb_harmonic_calc_norm_envelop()
      53             :  *
      54             :  * Calculate normalization envelop
      55             :  *--------------------------------------------------------------------------*/
      56             : 
      57        1957 : void hq_swb_harmonic_calc_norm_envelop_fx(
      58             :     const Word32 *L_SWB_signal, /* i  : input signal                Q=12*/
      59             :     Word32 *L_envelope,         /* o  : output envelope             Q=12*/
      60             :     const Word16 L_swb_norm,    /* i  : length of normaliztion          Q0*/
      61             :     const Word16 SWB_flength    /* i  : length of input signal          Q0*/
      62             : )
      63             : {
      64             : 
      65             :     Word16 lookback;
      66             :     Word16 env_index;
      67             :     Word16 n_freq;
      68             :     Word16 n_lag_now;
      69             :     Word16 n_lag;
      70             :     Word16 i;
      71             :     Word32 L_tmp;
      72             : 
      73        1957 :     lookback = shr( L_swb_norm, 1 ); /*Q0*/
      74        1957 :     env_index = 0;
      75        1957 :     move16();
      76       42310 :     FOR( n_freq = 0; n_freq < lookback; n_freq++ )
      77             :     {
      78       40353 :         n_lag_now = add( lookback, n_freq );
      79             : 
      80             :         /* Apply MA filter */
      81       40353 :         L_envelope[env_index] = EPSILLON_FX;
      82       40353 :         move16();
      83             : 
      84     1424037 :         FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
      85             :         {
      86     1383684 :             L_tmp = L_abs( L_SWB_signal[n_lag] );                              /*Q12*/
      87     1383684 :             L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
      88     1383684 :             move32();
      89             :         }
      90       40353 :         env_index = add( env_index, 1 );
      91             :     }
      92             : 
      93        1957 :     n_lag_now = L_swb_norm; /*Q0*/
      94        1957 :     move16();
      95             : 
      96      315631 :     FOR( n_freq = 0; n_freq < SWB_flength - L_swb_norm; n_freq++ )
      97             :     {
      98             :         /* Apply MA filter */
      99      313674 :         L_envelope[env_index] = EPSILLON_FX;
     100      313674 :         move16();
     101    12983068 :         FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
     102             :         {
     103    12669394 :             L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] );                 /*Q12*/
     104    12669394 :             L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
     105    12669394 :             move32();
     106             :         }
     107      313674 :         env_index = add( env_index, 1 );
     108             :     }
     109             : 
     110        1957 :     i = 0;
     111        1957 :     move16();
     112       43244 :     FOR( n_freq = SWB_flength - L_swb_norm; n_freq < SWB_flength - lookback; n_freq++ )
     113             :     {
     114       41287 :         n_lag_now = sub( L_swb_norm, i );
     115             : 
     116             :         /* Apply MA filter */
     117       41287 :         L_envelope[env_index] = L_deposit_l( EPSILLON_FX );
     118       41287 :         move32();
     119     1504920 :         FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
     120             :         {
     121     1463633 :             L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] );                 /*Q12*/
     122     1463633 :             L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
     123     1463633 :             move32();
     124             :         }
     125       41287 :         env_index = add( env_index, 1 );
     126       41287 :         i = add( i, 1 );
     127             :     }
     128             : 
     129        1957 :     return;
     130             : }
     131             : 
     132             : 
     133             : /*--------------------------------------------------------------------------*
     134             :  * noise_level_calc_fx()
     135             :  *
     136             :  * Calculate noise level and limited band
     137             :  *--------------------------------------------------------------------------*/
     138             : 
     139        1529 : void limit_band_noise_level_calc_fx(
     140             :     const Word16 *wnorm,     /* i  : reordered norm of sub-vectors        Q0*/
     141             :     Word16 *limit,           /* o  : highest band of bit allocation       Q0*/
     142             :     const Word32 core_brate, /* i  : bit rate                             Q0*/
     143             :     Word16 *noise_level      /* o  : noise level                          Q15*/
     144             : )
     145             : {
     146             :     Word16 ener_limit, ener_sum;
     147             :     Word16 i;
     148             :     Word16 nb_sfm;
     149             :     Word32 fact;
     150             :     Word16 tmp;
     151             : 
     152        1529 :     nb_sfm = *limit; /*Q0*/
     153        1529 :     move16();
     154        1529 :     ener_limit = 0;
     155        1529 :     move16();
     156        1529 :     *noise_level = 0;
     157        1529 :     move16();
     158       16819 :     FOR( i = 0; i < 10; i++ )
     159             :     {
     160       15290 :         ener_limit = add( ener_limit, wnorm[i] );                                   /*Q0*/
     161       15290 :         *noise_level = add( *noise_level, abs_s( sub( wnorm[i + 1], wnorm[i] ) ) ); /*Q15*/
     162       15290 :         move16();
     163             :     }
     164        1529 :     ener_sum = ener_limit; /*Q0*/
     165        1529 :     move16();
     166             : 
     167        1529 :     tmp = sub( nb_sfm, 1 );
     168       31723 :     FOR( i = 10; i < tmp; i++ )
     169             :     {
     170       30194 :         ener_sum = add( ener_sum, wnorm[i] );                                       /*Q0*/
     171       30194 :         *noise_level = add( *noise_level, abs_s( sub( wnorm[i + 1], wnorm[i] ) ) ); /*Q15*/
     172       30194 :         move16();
     173             :     }
     174        1529 :     ener_sum = add( ener_sum, wnorm[nb_sfm - 1] ); /*Q0*/
     175             : 
     176             : 
     177        1529 :     fact = 2022929597; /*Q31*/
     178        1529 :     move32();
     179        1529 :     if ( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
     180             :     {
     181         786 :         fact = L_add( 1900523029, 1 ); /*Q31*/
     182             :     }
     183             : 
     184        1529 :     fact = Mult_32_16( fact, ener_sum ); /*Q16*/
     185        1529 :     i = 9;
     186        1529 :     move16();
     187        1529 :     test();
     188       26955 :     WHILE( LT_32( L_deposit_h( ener_limit ), fact ) && LT_16( add( i, 1 ), nb_sfm ) )
     189             :     {
     190       25426 :         ener_limit = add( ener_limit, wnorm[++i] ); /*Q0*/
     191       25426 :         test();
     192             :     }
     193        1529 :     *limit = i;
     194        1529 :     move16();
     195             : 
     196             :     /* calculate noise level for spectrum filling */
     197        1529 :     if ( *noise_level < 0 )
     198             :     {
     199           0 :         *noise_level = 0;
     200           0 :         move16();
     201             :     }
     202             : 
     203        1529 :     IF( GE_16( *noise_level, shr( ener_sum, 2 ) ) )
     204             :     {
     205         302 :         *noise_level = 0;
     206         302 :         move16();
     207             :     }
     208             :     ELSE
     209             :     {
     210        1227 :         IF( ener_sum != 0 )
     211             :         {
     212        1227 :             *noise_level = sub( 8192 /*Q15*/, div_s( *noise_level, ener_sum ) );
     213             :         }
     214             :         ELSE
     215             :         {
     216           0 :             *noise_level = 8192; /*Q15*/
     217             :         }
     218        1227 :         move16();
     219             :     }
     220             : 
     221        1529 :     return;
     222             : }
     223             : 
     224             : /*--------------------------------------------------------------------------*
     225             :  * build_nf_codebook_fx()
     226             :  *
     227             :  * Build noise-fill codebook for HQ mode
     228             :  * NOTE: Q values preliminary
     229             :  *--------------------------------------------------------------------------*/
     230             : 
     231        6499 : Word16 build_nf_codebook_fx(                               /* o  : Number of coefficients in nf codebook Q=0*/
     232             :                              const Word16 flag_32K_env_ho, /* i  : Envelope attenuation hangover flag Q=0*/
     233             :                              const Word16 *coeff,          /* i  : Coded spectral coefficients   Q=12*/
     234             :                              const Word16 *sfm_start,      /* i  : Subband start indices         Q=0*/
     235             :                              const Word16 *sfmsize,        /* i  : Subband widths                Q=0*/
     236             :                              const Word16 *sfm_end,        /* i  : Subband end indices           Q=0*/
     237             :                              const Word16 last_sfm,        /* i  : Last coded  band              Q=0*/
     238             :                              const Word16 *R,              /* i  : Per-band bit allocation       Q=0*/
     239             :                              Word16 *CodeBook,             /* o  : Noise-fill codebook           Q=12*/
     240             :                              Word16 *CodeBook_mod          /* o  : Densified noise-fill codebook Q=12*/
     241             : )
     242             : {
     243             :     Word16 sfm_base;
     244             :     Word16 sfm;
     245             :     Word16 E_cb_vec;
     246             :     Word16 i, j;
     247             :     Word16 cb_size;
     248             : 
     249             :     /* Build codebook */
     250             : 
     251        6499 :     cb_size = 0;
     252        6499 :     move16();
     253             : 
     254      195334 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
     255             :     {
     256      188835 :         IF( R[sfm] != 0 )
     257             :         {
     258      140138 :             IF( flag_32K_env_ho )
     259             :             {
     260             :                 /* Build compressed (+/- 1) noise-fill codebook */
     261        7040 :                 sfm_base = sfm_start[sfm]; /*Q0*/
     262        7040 :                 move16();
     263       19253 :                 FOR( i = 0; i < sfmsize[sfm] / 8; i++ )
     264             :                 {
     265       12213 :                     E_cb_vec = 0;
     266       12213 :                     move16();
     267      109917 :                     FOR( j = sfm_base + i * 8; j < sfm_base + ( i + 1 ) * 8; j++ )
     268             :                     {
     269       97704 :                         IF( coeff[j] > 0 )
     270             :                         {
     271       17211 :                             CodeBook_mod[cb_size] = 1 << 12; /*Q12*/
     272       17211 :                             move16();
     273       17211 :                             E_cb_vec = add( E_cb_vec, 1 );
     274             :                         }
     275       80493 :                         ELSE IF( coeff[j] < 0 )
     276             :                         {
     277       17414 :                             CodeBook_mod[cb_size] = -1 * ( 1 << 12 ); /*Q12*/
     278       17414 :                             move16();
     279       17414 :                             E_cb_vec = add( E_cb_vec, 1 );
     280             :                         }
     281             :                         ELSE
     282             :                         {
     283       63079 :                             CodeBook_mod[cb_size] = 0;
     284       63079 :                             move16();
     285             :                         }
     286       97704 :                         cb_size = add( cb_size, 1 );
     287             :                     }
     288             : 
     289       12213 :                     if ( E_cb_vec < 2 )
     290             :                     {
     291        2872 :                         cb_size = sub( cb_size, 8 );
     292             :                     }
     293             :                 }
     294             :             }
     295             :             ELSE
     296             :             {
     297     1843664 :                 FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
     298             :                 {
     299     1710566 :                     CodeBook[cb_size] = coeff[j]; /*Q12*/
     300     1710566 :                     move16();
     301     1710566 :                     cb_size = add( cb_size, 1 );
     302             :                 }
     303             :             }
     304             :         }
     305             :     }
     306             : 
     307        6499 :     IF( flag_32K_env_ho )
     308             :     {
     309       75134 :         FOR( j = 0; j < cb_size; j++ )
     310             :         {
     311       74728 :             IF( CodeBook_mod[j] != 0 )
     312             :             {
     313             :                 /* Densify codebook */
     314       32664 :                 CodeBook[j] = -4096; /*Q12*/
     315       32664 :                 move16();
     316       32664 :                 if ( CodeBook_mod[j] > 0 )
     317             :                 {
     318       16278 :                     CodeBook[j] = 4096; /*Q12*/
     319       16278 :                     move16();
     320             :                 }
     321             : 
     322       32664 :                 IF( CodeBook_mod[cb_size - j - 1] != 0 )
     323             :                 {
     324       14310 :                     CodeBook[j] = shl( CodeBook[j], 1 ); /*Q12*/
     325       14310 :                     move16();                            /* Mult by 2 */
     326             :                 }
     327             :             }
     328             :             ELSE
     329             :             {
     330       42064 :                 CodeBook[j] = CodeBook_mod[cb_size - j - 1]; /*Q12*/
     331       42064 :                 move16();
     332             :             }
     333             :         }
     334             :     }
     335             : 
     336        6499 :     return cb_size; /*Q0*/
     337             : }
     338             : 
     339             : 
     340             : /*--------------------------------------------------------------------------*
     341             :  * find_last_band()
     342             :  *
     343             :  * Find the last band which has bits allocated
     344             :  *--------------------------------------------------------------------------*/
     345             : 
     346       12216 : Word16 find_last_band_fx(                         /* o  : index of last band              */
     347             :                           const Word16 *bitalloc, /* i  : bit allocation                  Q0*/
     348             :                           const Word16 nb_sfm     /* i  : number of possibly coded bands  Q0*/
     349             : )
     350             : {
     351             :     Word16 sfm, core_sfm;
     352             : 
     353       12216 :     core_sfm = sub( nb_sfm, 1 ); /*Q0*/
     354             : 
     355      175706 :     FOR( sfm = nb_sfm - 1; sfm >= 0; sfm-- )
     356             :     {
     357      175706 :         IF( bitalloc[sfm] != 0 )
     358             :         {
     359       12216 :             core_sfm = sfm; /*Q0*/
     360       12216 :             move16();
     361       12216 :             BREAK;
     362             :         }
     363             :     }
     364             : 
     365       12216 :     return core_sfm; /*Q0*/
     366             : }
     367             : 
     368             : /*--------------------------------------------------------------------------*
     369             :  * apply_noisefill_HQ()
     370             :  *
     371             :  * Inject noise in non-coded bands
     372             :  *--------------------------------------------------------------------------*/
     373             : 
     374        6499 : void apply_noisefill_HQ_fx(
     375             :     const Word16 *R,              /* i  : bit allocation                     Q0  */
     376             :     const Word16 length,          /* i  : input frame length                 Q0  */
     377             :     const Word16 flag_32K_env_ho, /* i  : envelope stability hangover flag   Q0  */
     378             :     const Word32 L_core_brate,    /* i  : core bit rate                      Q0  */
     379             :     const Word16 last_sfm,        /* i  : last coded subband                 Q0  */
     380             :     const Word16 *CodeBook,       /* i  : Noise-fill codebook                Q12 */
     381             :     const Word16 *CodeBook_mod,   /* i  : Densified noise-fill codebook      Q12 */
     382             :     const Word16 cb_size,         /* i  : Codebook length                    Q0  */
     383             :     const Word16 *sfm_start,      /* i  : Subband start coefficient          Q0  */
     384             :     const Word16 *sfm_end,        /* i  : Subband end coefficient            Q0  */
     385             :     const Word16 *sfmsize,        /* i  : Subband band width                 Q0  */
     386             :     Word16 *coeff                 /* i/o: coded/noisefilled spectrum         Q12 */
     387             : )
     388             : {
     389             :     Word16 sfm;
     390             :     Word16 cb_pos;
     391             :     Word16 E_corr;
     392             :     Word16 cb_buff[PVQ_MAX_BAND_SIZE];
     393             :     Word16 i, j;
     394             :     Word16 istart;
     395             :     UWord16 lsb;
     396             :     Word32 L_E_cb_vec;
     397             :     Word32 L_E_corr;
     398             : 
     399        6499 :     test();
     400        6499 :     IF( ( GE_16( length, L_FRAME32k ) ) || ( NE_32( L_core_brate, HQ_32k ) ) )
     401             :     {
     402             :         /* Read from codebook */
     403        6499 :         cb_pos = 0;
     404        6499 :         move16();
     405             : 
     406      195334 :         FOR( sfm = 0; sfm <= last_sfm; sfm++ )
     407             :         {
     408      188835 :             IF( R[sfm] == 0 )
     409             :             {
     410       48697 :                 IF( EQ_16( flag_32K_env_ho, 1 ) )
     411             :                 {
     412        4871 :                     L_E_cb_vec = L_deposit_l( 0 );
     413        4871 :                     IF( LT_16( sfm, 20 ) )
     414             :                     {
     415       35649 :                         FOR( i = 0; i < sfmsize[sfm]; i++ )
     416             :                         {
     417       32216 :                             cb_buff[i] = CodeBook_mod[cb_pos++]; /*Q12*/
     418       32216 :                             move16();
     419       32216 :                             L_E_cb_vec = L_mac0_sat( L_E_cb_vec, cb_buff[i], cb_buff[i] ); /*Q24 (12+12) */
     420             : 
     421       32216 :                             if ( GE_16( cb_pos, cb_size ) )
     422             :                             {
     423          51 :                                 cb_pos = 0;
     424          51 :                                 move16();
     425             :                             }
     426             :                         }
     427             :                     }
     428             :                     ELSE
     429             :                     {
     430       32262 :                         FOR( i = 0; i < sfmsize[sfm]; i++ )
     431             :                         {
     432       30824 :                             cb_buff[i] = CodeBook[cb_pos++]; /*Q12*/
     433       30824 :                             move16();
     434       30824 :                             L_E_cb_vec = L_mac0_sat( L_E_cb_vec, cb_buff[i], cb_buff[i] ); /*Q24 (12+12) */
     435             : 
     436       30824 :                             if ( GE_16( cb_pos, cb_size ) )
     437             :                             {
     438         208 :                                 cb_pos = 0;
     439         208 :                                 move16();
     440             :                             }
     441             :                         }
     442             :                     }
     443             : 
     444             :                     /*E_corr = E_cb_vec / ((float) sfmsize[sfm]); */
     445        4871 :                     Mpy_32_16_ss( L_E_cb_vec, inv_tbl_fx[sfmsize[sfm]], &L_E_corr, &lsb ); /*Q24 (24+15+1-16) */
     446        4871 :                     move16();
     447             : 
     448             :                     /*E_corr = 1.0f / (float)sqrt(E_corr); */
     449        4871 :                     L_E_corr = Isqrt( L_E_corr );                /*Q19 (31-24/2) */
     450        4871 :                     E_corr = extract_h( L_shl( L_E_corr, 10 ) ); /*Q13 (13-(19-16)) */
     451             : 
     452        4871 :                     istart = sfm_start[sfm]; /*Q0*/
     453        4871 :                     move16();
     454       67911 :                     FOR( j = istart; j < sfm_end[sfm]; j++ )
     455             :                     {
     456             :                         /*coeff[j] = cb_buff[j - istart] * E_corr; */
     457       63040 :                         coeff[j] = extract_h( L_shl( L_mult( cb_buff[j - istart], E_corr ), 2 ) ); /*Q12 (12+13+1+2-16) */
     458       63040 :                         move16();
     459             :                     }
     460             :                 }
     461             :                 ELSE
     462             :                 {
     463      737560 :                     FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
     464             :                     {
     465      693734 :                         coeff[j] = CodeBook[cb_pos++]; /*Q12*/
     466      693734 :                         move16();
     467      693734 :                         if ( GE_16( cb_pos, cb_size ) )
     468             :                         {
     469        1544 :                             cb_pos = 0;
     470        1544 :                             move16();
     471             :                         }
     472             :                     }
     473             :                 }
     474             :             }
     475             :         }
     476             :     }
     477             : 
     478        6499 :     return;
     479             : }
     480             : 
     481             : /*--------------------------------------------------------------------------*
     482             :  * harm_bwe_fine_fx()
     483             :  *
     484             :  * Prepare harmonic BWE fine structure
     485             :  *--------------------------------------------------------------------------*/
     486             : 
     487         728 : void harm_bwe_fine_fx(
     488             :     const Word16 *R,         /* i  : bit allocation                              Q0*/
     489             :     const Word16 last_sfm,   /* i  : last coded subband                          Q0*/
     490             :     const Word16 high_sfm,   /* i  : higher transition band to BWE               Q0*/
     491             :     const Word16 num_sfm,    /* i  : total number of bands                       Q0*/
     492             :     const Word16 *norm,      /* i  : quantization indices for norms              Q0*/
     493             :     const Word16 *sfm_start, /* i  : Subband start coefficient                   Q0*/
     494             :     const Word16 *sfm_end,   /* i  : Subband end coefficient                     Q0*/
     495             :     Word16 *prev_L_swb_norm, /* i/o: last normalize length                       Q0*/
     496             :     Word16 *coeff,           /* i/o: coded/noisefilled normalized spectrum       Q12*/
     497             :     Word32 *coeff_out,       /* o  : coded/noisefilled spectrum                  Q12*/
     498             :     Word16 *coeff_fine       /* o  : BWE fine structure                          Q15*/
     499             : )
     500             : {
     501             :     Word16 sfm;
     502             :     Word16 i;
     503             :     Word32 normq;
     504             :     Word16 SWB_signal[L_HARMONIC_EXC];
     505             :     Word32 envelope[L_HARMONIC_EXC], L_signal[L_HARMONIC_EXC];
     506             :     Word16 enve_lo[L_HARMONIC_EXC], enve_hi[L_HARMONIC_EXC];
     507             :     Word16 *src, *dst, *end;
     508             :     Word16 norm_signal;
     509             : 
     510         728 :     Word16 norm_width = 64;
     511         728 :     move16();
     512             : 
     513             :     /* shape the spectrum */
     514       19311 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
     515             :     {
     516       18583 :         IF( R[sfm] != 0 )
     517             :         {
     518       14871 :             normq = dicn_fx[norm[sfm]]; /*Q14*/
     519       14871 :             move32();
     520             : 
     521      222823 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
     522             :             {
     523      207952 :                 coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*12 14+12+1+1-16  */
     524      207952 :                 move32();
     525             :             }
     526             :         }
     527             :         ELSE
     528             :         {
     529       50512 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
     530             :             {
     531       46800 :                 coeff_out[i] = L_deposit_l( 0 ); /*Q12*/
     532       46800 :                 move16();
     533             :             }
     534             :         }
     535             :     }
     536             : 
     537             :     /* excitation replication */
     538         728 :     Copy32( coeff_out, L_signal, L_HARMONIC_EXC ); /*Q12*/
     539         728 :     calc_normal_length_fx_32( HQ_CORE, coeff_out, HQ_HARMONIC, -1, &norm_width, prev_L_swb_norm );
     540         728 :     hq_swb_harmonic_calc_norm_envelop_fx( L_signal, envelope, norm_width, L_HARMONIC_EXC );
     541             : 
     542             :     /* Normalize with envelope */
     543      147784 :     FOR( i = 0; i < L_HARMONIC_EXC; i++ )
     544             :     {
     545      147056 :         IF( L_signal[i] > 0 )
     546             :         {
     547       21882 :             norm_signal = norm_l( envelope[i] );
     548       21882 :             enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] ); /*Q12+norm_signal-16*/
     549       21882 :             L_signal[i] = Div_32( L_signal[i], enve_hi[i], enve_lo[i] );                 /*Q31 - norm_signal*/
     550       21882 :             SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) );       /*Q15*/
     551       21882 :             move16();
     552       21882 :             move16();
     553       21882 :             move32();
     554             :         }
     555             :         ELSE
     556             :         {
     557      125174 :             norm_signal = norm_l( envelope[i] );
     558      125174 :             enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] );         /*Q12+norm_signal-16*/
     559      125174 :             L_signal[i] = L_negate( Div_32( L_negate( L_signal[i] ), enve_hi[i], enve_lo[i] ) ); /*Q31 - norm_signal*/
     560      125174 :             SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) );               /*Q15*/
     561      125174 :             move16();
     562      125174 :             move16();
     563      125174 :             move32();
     564             :         }
     565             :     }
     566             : 
     567         728 :     dst = coeff_fine + sfm_end[last_sfm];    /*Q15*/
     568         728 :     end = coeff_fine + sfm_end[num_sfm - 1]; /*Q15*/
     569             : 
     570         728 :     IF( LE_16( sub( sfm_end[last_sfm], sfm_end[high_sfm] ), ( L_HARMONIC_EXC - START_EXC ) ) )
     571             :     {
     572         544 :         src = SWB_signal + START_EXC + sub( sfm_end[last_sfm], sfm_end[high_sfm] ); /*Q15*/
     573             :     }
     574             :     ELSE
     575             :     {
     576         184 :         src = SWB_signal + L_HARMONIC_EXC - 1; /*Q15*/
     577             :     }
     578             : 
     579        2427 :     WHILE( dst < end )
     580             :     {
     581        1699 :         logic32();
     582      153149 :         WHILE( dst < end && src < &SWB_signal[L_HARMONIC_EXC] )
     583             :         {
     584      151450 :             *dst++ = *src++; /*Q15*/
     585      151450 :             move16();
     586             :         }
     587        1699 :         src--;
     588             : 
     589        1699 :         logic32();
     590      163017 :         WHILE( dst < end && src >= &SWB_signal[START_EXC] )
     591             :         {
     592      161318 :             *dst++ = *src--; /*Q15*/
     593      161318 :             move16();
     594             :         }
     595        1699 :         src++;
     596             :     }
     597             : 
     598         728 :     return;
     599             : }
     600             : 
     601             : /*--------------------------------------------------------------------------*
     602             :  * hvq_bwe_fine()
     603             :  *
     604             :  * Prepare HVQ BWE fine structure
     605             :  *--------------------------------------------------------------------------*/
     606             : 
     607        1229 : void hvq_bwe_fine_fx(
     608             :     const Word16 last_sfm,   /* i  : last coded subband                        Q0  */
     609             :     const Word16 num_sfm,    /* i  : total number of bands                     Q0  */
     610             :     const Word16 *sfm_end,   /* i  : Subband end coefficient                   Q0  */
     611             :     const Word16 *peak_idx,  /* i  : Peak index                                Q0  */
     612             :     const Word16 Npeaks,     /* i  : Number of peaks                           Q0  */
     613             :     Word16 *peak_pos,        /* o  : Peak positions                            Q0  */
     614             :     Word16 *prev_L_swb_norm, /* i/o: last normalize length                     Q0  */
     615             :     Word32 *L_coeff,         /* i  : coded/noisefilled normalized spectrum     Q12 */
     616             :     Word16 *bwe_peaks,       /* o  : Positions of peaks in BWE                 Q0  */
     617             :     Word16 *coeff_fine       /* o  : HVQ BWE fine structure                    Q15 */
     618             : )
     619             : {
     620             :     Word16 i, j;
     621             :     Word16 SWB_signal[L_HARMONIC_EXC];
     622             :     Word32 L_envelope[L_HARMONIC_EXC];
     623             :     Word16 *src, *dst, *end;
     624             :     Word16 *peak_dst, *peak_src;
     625        1229 :     Word16 norm_width = 64;
     626             :     Word16 tmp;
     627             :     Word16 shift, shift2;
     628             :     Word32 L_tmp;
     629             :     UWord16 lsb;
     630             : 
     631        1229 :     calc_normal_length_fx_32( HQ_CORE, L_coeff, HQ_HVQ, -1, &norm_width, prev_L_swb_norm );
     632             : 
     633        1229 :     hq_swb_harmonic_calc_norm_envelop_fx( L_coeff, L_envelope, norm_width, L_HARMONIC_EXC );
     634             : 
     635             :     /* Normalize with envelope */
     636      249487 :     FOR( i = 0; i < L_HARMONIC_EXC; i++ )
     637             :     {
     638             :         /*SWB_signal[i] = SWB_signal[i] / envelope[i]; */
     639             : 
     640      248258 :         shift = norm_l( L_envelope[i] );
     641      248258 :         tmp = round_fx_sat( L_shl_sat( L_envelope[i], shift ) ); /* 12+s-16=Q(-4+s) */
     642             :         /* Avoid division by zero */
     643      248258 :         if ( tmp == 0 )
     644             :         {
     645           0 :             tmp = 1 << 14;
     646           0 :             move16();
     647             :         }
     648             : 
     649      248258 :         tmp = div_s( 1 << 14, tmp );                   /* 15+14-(-4+s)=Q(33-s) */
     650      248258 :         Mpy_32_16_ss( L_coeff[i], tmp, &L_tmp, &lsb ); /* 12+33-s+1-16=Q(30-s) */
     651      248258 :         shift2 = add( shift, 1 );
     652      248258 :         tmp = round_fx( L_shl( L_tmp, shift2 ) );                                 /* 30-s+s+1-16=Q(15) */
     653      248258 :         SWB_signal[i] = add( tmp, extract_l( L_shr( lsb, sub( 32, shift2 ) ) ) ); /* Q15 */
     654      248258 :         move16();
     655             :         /*SWB_signal[i] = round_fx(L_shl(L_tmp, add(shift, 1)));      // 30-s+s+1-16=Q(15) */
     656             :     }
     657             : 
     658        1229 :     dst = coeff_fine;                                            /*Q15*/
     659        1229 :     end = coeff_fine + sfm_end[num_sfm - 1] - sfm_end[last_sfm]; /*Q15*/
     660             : 
     661        1229 :     src = SWB_signal + START_EXC;    /*Q15*/
     662        1229 :     peak_src = peak_pos + START_EXC; /*Q0*/
     663             : 
     664       22321 :     FOR( i = 0; i < Npeaks; i++ )
     665             :     {
     666       21092 :         if ( LT_16( peak_idx[i], L_HARMONIC_EXC ) )
     667             :         {
     668       16398 :             peak_pos[peak_idx[i]] = 1;
     669       16398 :             move16();
     670             :         }
     671             :     }
     672             : 
     673        1229 :     i = sub( L_HARMONIC_EXC, 1 );
     674       21534 :     WHILE( i-- > 0 )
     675             :     {
     676       21534 :         IF( EQ_16( peak_pos[i], 1 ) )
     677             :         {
     678        1229 :             BREAK;
     679             :         }
     680             :     }
     681             : 
     682        1229 :     if ( LT_16( i, 180 ) )
     683             :     {
     684         267 :         i = 180;
     685         267 :         move16();
     686             :     }
     687             : 
     688       18216 :     FOR( j = L_HARMONIC_EXC - 1; j > i + 1; j-- )
     689             :     {
     690       16987 :         SWB_signal[j] = 0;
     691       16987 :         move16();
     692             :     }
     693             : 
     694        1229 :     peak_dst = bwe_peaks + sfm_end[last_sfm]; /*Q0*/
     695        4223 :     WHILE( dst < end )
     696             :     {
     697        2994 :         test();
     698      353962 :         WHILE( dst < end && src < &SWB_signal[L_HARMONIC_EXC] )
     699             :         {
     700      350968 :             *dst++ = *src++; /*Q15*/
     701      350968 :             move16();
     702      350968 :             *peak_dst++ = *peak_src++; /*Q0*/
     703      350968 :             move16();
     704             :         }
     705        2994 :         peak_src--; /*Q0*/
     706        2994 :         src--;
     707             : 
     708        2994 :         test();
     709      281434 :         WHILE( dst < end && src >= &SWB_signal[START_EXC] )
     710             :         {
     711      278440 :             *dst++ = *src--; /*Q15*/
     712      278440 :             move16();
     713      278440 :             *peak_dst++ = *peak_src--; /*Q0*/
     714      278440 :             move16();
     715             :         }
     716        2994 :         peak_src++; /*Q0*/
     717        2994 :         src++;
     718             :     }
     719             : 
     720        1229 :     return;
     721             : }
     722             : 
     723             : /*--------------------------------------------------------------------------*
     724             :  * hq_fold_bwe_fx()
     725             :  *
     726             :  * HQ mode folding BWE
     727             :  *--------------------------------------------------------------------------*/
     728             : 
     729        2470 : void hq_fold_bwe_fx(
     730             :     const Word16 last_sfm, /* i  : last coded subband                     Q0 */
     731             :     const Word16 *sfm_end, /* i  : Subband end coefficient                Q0 */
     732             :     const Word16 num_sfm,  /* i  : Number of subbands                     Q0 */
     733             :     Word16 *coeff          /* i/o: coded/noisefilled normalized spectrum  Q12 */
     734             : )
     735             : {
     736             :     Word16 low_coeff;
     737             :     Word16 first_coeff;
     738             :     Word16 *src, *dst, *end;
     739             : 
     740        2470 :     low_coeff = shr( sfm_end[last_sfm], 1 ); /*Q0*/
     741        2470 :     src = coeff + sfm_end[last_sfm] - 1;     /*Q12*/
     742             : 
     743        2470 :     first_coeff = sfm_end[last_sfm]; /*Q0*/
     744        2470 :     move16();
     745        2470 :     dst = coeff + sfm_end[last_sfm];    /*Q12*/
     746        2470 :     end = coeff + sfm_end[num_sfm - 1]; /*Q12*/
     747             : 
     748        5503 :     WHILE( dst < end )
     749             :     {
     750        3033 :         test();
     751      414154 :         WHILE( dst < end && src >= &coeff[low_coeff] )
     752             :         {
     753      411121 :             test();
     754      411121 :             *dst++ = *src--; /*Q12*/
     755      411121 :             move16();
     756             :         }
     757             : 
     758        3033 :         src++;
     759        3033 :         test();
     760      222076 :         WHILE( dst < end && src < &coeff[first_coeff] )
     761             :         {
     762      219043 :             test();
     763      219043 :             *dst++ = *src++; /*Q12*/
     764      219043 :             move16();
     765             :         }
     766             :     }
     767        2470 :     return;
     768             : }
     769             : 
     770             : /*--------------------------------------------------------------------------*
     771             :  * apply_nf_gain()
     772             :  *
     773             :  * Apply noise fill gain
     774             :  *--------------------------------------------------------------------------*/
     775             : 
     776        6417 : void apply_nf_gain_fx(
     777             :     const Word16 nf_idx,     /* i  : noise fill gain index                   Q0 */
     778             :     const Word16 last_sfm,   /* i  : last coded subband                      Q0 */
     779             :     const Word16 *R,         /* i  : bit allocation                          Q0 */
     780             :     const Word16 *sfm_start, /* i  : Subband start coefficient               Q0 */
     781             :     const Word16 *sfm_end,   /* i  : Subband end coefficient                 Q0 */
     782             :     Word16 *coeff            /* i/o: coded/noisefilled normalized spectrum   Q12 */
     783             : )
     784             : {
     785             :     Word16 sfm;
     786             :     Word16 j;
     787             : 
     788      193217 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
     789             :     {
     790      186800 :         IF( R[sfm] == 0 )
     791             :         {
     792      801577 :             FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
     793             :             {
     794             :                 /* Scale NoiseFill */
     795      753150 :                 coeff[j] = shr( coeff[j], nf_idx ); /*Q12*/
     796      753150 :                 move16();
     797             :             }
     798             :         }
     799             :     }
     800             : 
     801        6417 :     return;
     802             : }
     803             : 
     804             : 
     805             : /*--------------------------------------------------------------------------*
     806             :  * harm_bwe_fx()
     807             :  *
     808             :  * HQ Harmonic BWE
     809             :  *--------------------------------------------------------------------------*/
     810             : 
     811         708 : void ivas_harm_bwe_fx(
     812             :     const Word16 *coeff_fine,  /* i  : fine structure for BWE                  Q12*/
     813             :     const Word16 *coeff,       /* i  : coded/noisefilled normalized spectrum   Q12*/
     814             :     const Word16 num_sfm,      /* i  : Number of subbands                      Q0*/
     815             :     const Word16 *sfm_start,   /* i  : Subband start coefficient               Q0*/
     816             :     const Word16 *sfm_end,     /* i  : Subband end coefficient                 Q0*/
     817             :     const Word16 last_sfm,     /* i  : last coded subband                      Q0*/
     818             :     const Word16 *R,           /* i  : bit allocation                          Q0*/
     819             :     const Word16 prev_hq_mode, /* i  : previous hq mode                        Q0*/
     820             :     Word16 *norm,              /* i/o: quantization indices for norms          Q0*/
     821             :     Word16 *noise_level,       /* i/o: noise levels for harmonic modes         Q15*/
     822             :     Word16 *prev_noise_level,  /* i/o: noise factor in previous frame          Q15*/
     823             :     Word16 *bwe_seed,          /* i/o: random seed for generating BWE input    Q0*/
     824             :     Word32 *coeff_out,         /* o  : coded/noisefilled spectrum              Q12*/
     825             :     const Word16 element_mode  /* i  : IVAS element mode                       Q0*/
     826             : )
     827             : {
     828             :     Word16 i, j;
     829             :     Word16 sfm, band_width;
     830             :     Word32 normq, L_tmp, L_tmp2;
     831             :     Word32 E_L;
     832         708 :     Word16 alfa = 16384;
     833         708 :     move16();
     834             :     Word16 tmp, tmp1, exp1;
     835             :     Word16 beta;
     836             :     Word32 *src, *dst;
     837             : 
     838         708 :     move16(); /* alfa */
     839             : 
     840       18805 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
     841             :     {
     842       18097 :         IF( R[sfm] == 0 )
     843             :         {
     844        3613 :             normq = dicn_fx[norm[sfm]]; /*Q14  */
     845        3613 :             move16();
     846             : 
     847       49445 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
     848             :             {
     849       45832 :                 coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*Q12*/
     850       45832 :                 move32();
     851             :             }
     852             :         }
     853             :     }
     854         708 :     noise_level[1] = noise_level[0]; /*Q15*/
     855         708 :     move16();
     856             : 
     857             :     /* shaping the BWE spectrum further by envelopes and noise factors */
     858         708 :     L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[0] );                      /*  15 +1 +15 */
     859         708 :     noise_level[0] = round_fx( L_mac( L_tmp, 3277 /*0.1 in Q15*/, noise_level[0] ) ); /*15  */
     860         708 :     move16();
     861             : 
     862         708 :     L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[1] );                      /*Q31*/
     863         708 :     noise_level[1] = round_fx( L_mac( L_tmp, 3277 /*0.1 in Q15*/, noise_level[1] ) ); /*Q15*/
     864         708 :     move16();
     865             : 
     866         708 :     test();
     867         708 :     IF( ( prev_hq_mode == HQ_NORMAL ) || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
     868             :     {
     869         129 :         IF( LT_16( noise_level[0], 8192 ) )
     870             :         {
     871         129 :             noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
     872         129 :             move16();
     873             :         }
     874             : 
     875         129 :         IF( LT_16( noise_level[1], 8192 ) )
     876             :         {
     877         129 :             noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
     878         129 :             move16();
     879             :         }
     880             :     }
     881             : 
     882        5829 :     FOR( i = add( last_sfm, 1 ); i < num_sfm; i++ )
     883             :     {
     884        5121 :         E_L = 1;
     885        5121 :         move32();
     886      311073 :         FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
     887             :         {
     888      305952 :             L_tmp = L_mult0( coeff_fine[j], coeff_fine[j] ); /*Q30  */
     889      305952 :             E_L = L_add( E_L, L_shr( L_tmp, 6 ) );           /*Q24 */
     890             :         }
     891             : 
     892        5121 :         normq = dicn_fx[norm[i]]; /*Q14*/
     893        5121 :         move32();
     894             : 
     895        5121 :         alfa = noise_level[0]; /*Q15*/
     896        5121 :         move16();
     897        5121 :         IF( GT_16( i, 27 ) )
     898             :         {
     899        3387 :             alfa = noise_level[1]; /*Q15*/
     900        3387 :             move16();
     901             :         }
     902             : 
     903        5121 :         band_width = sub( sfm_end[i], sfm_start[i] ); /* Q0 */
     904        5121 :         exp1 = norm_l( E_L );
     905        5121 :         IF( EQ_16( exp1, 0 ) )
     906             :         {
     907           0 :             E_L = Mult_32_16( E_L, inv_tbl_fx[band_width] ); /* Q24 (24+15+1-16) */ /*24+15+1-16  */
     908           0 :             tmp = div_l( E_L, sub( 32767, alfa ) );                                 /*Q24-15-1 =8 */
     909           0 :             tmp = s_max( 1, tmp );
     910           0 :             L_tmp = L_deposit_h( tmp ); /*24 */
     911           0 :             E_L = Isqrt( L_tmp );       /* Q19 (31-24/2) */
     912             :         }
     913             :         ELSE
     914             :         {
     915        5121 :             exp1 = sub( exp1, 1 );
     916        5121 :             E_L = Mult_32_16( L_shl( E_L, exp1 ), inv_tbl_fx[band_width] ); /* Q24+exp1 (24+exp1+15+1-16) */
     917        5121 :             tmp = div_l( E_L, sub( 32767, alfa ) );                         /*Q24+exp1-15-1 =8+exp1 */
     918        5121 :             tmp = s_max( 1, tmp );
     919        5121 :             L_tmp = L_shl( L_deposit_l( tmp ), sub( 16, exp1 ) ); /*24  8+exp1+16-exp1 */
     920        5121 :             E_L = Isqrt( L_tmp );                                 /* Q19 (31-24/2) */
     921             :         }
     922             : 
     923        5121 :         exp1 = norm_s( alfa );
     924        5121 :         tmp1 = shl( alfa, exp1 ); /*Q15+exp1*/
     925        5121 :         IF( EQ_16( element_mode, EVS_MONO ) )
     926             :         {
     927           0 :             exp1 = add( 1, exp1 );
     928             :         }
     929             : #ifdef DEBUGGING
     930             :         else
     931             :         {
     932             :             // PMT("VERIFY if this really matches IVAS float")
     933             :         }
     934             : #endif
     935        5121 :         tmp1 = s_max( tmp1, 16384 );
     936        5121 :         tmp1 = div_s( 16384, tmp1 );
     937        5121 :         L_tmp2 = L_deposit_h( tmp1 );
     938        5121 :         L_tmp2 = Isqrt_lc( L_tmp2, &exp1 ); /*Q31 - exp1*/
     939             : 
     940        5121 :         beta = round_fx_sat( L_shl_sat( L_tmp2, exp1 ) ); /*Q15 */
     941        5121 :         beta = shr( beta, 1 );                            /*Q15*/
     942             : 
     943             : 
     944      311073 :         FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ )
     945             :         {
     946      305952 :             L_tmp = Mult_32_16( E_L, coeff_fine[sfm] );                  /*Q19 19 + 15 +1-16   */
     947      305952 :             L_tmp = L_shl_sat( L_tmp, 9 );                               /*Q28 */
     948      305952 :             tmp = Random( bwe_seed );                                    /*Q15 */
     949      305952 :             L_tmp2 = L_shr( L_mult( beta, tmp ), 3 );                    /* Q28 31-3  15+15 +1-3 */
     950      305952 :             L_tmp = L_add_sat( L_tmp, L_tmp2 );                          /*Q28 */
     951      305952 :             coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12  28 +14 +1 -31 */
     952      305952 :             move32();
     953             :         }
     954             :     }
     955             : 
     956         708 :     prev_noise_level[0] = noise_level[0]; /*Q15*/
     957         708 :     move16();
     958         708 :     prev_noise_level[1] = noise_level[1]; /*Q15*/
     959         708 :     move16();
     960             : 
     961         708 :     src = &coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /*Q12 */
     962             : 
     963         708 :     dst = src - 1; /*Q12*/
     964       12036 :     FOR( i = 0; i < 16; i++ )
     965             :     {
     966       11328 :         *src = Mult_32_16( *src, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
     967       11328 :         move32();
     968       11328 :         src++;
     969       11328 :         *dst = Mult_32_16( *dst, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
     970       11328 :         move32();
     971       11328 :         dst--;
     972             :     }
     973         708 :     IF( EQ_16( num_sfm, 33 ) )
     974             :     {
     975         635 :         set32_fx( &coeff_out[800], 0, 160 );
     976             :     }
     977         708 :     return;
     978             : }
     979             : 
     980          20 : void harm_bwe_fx(
     981             :     const Word16 *coeff_fine,  /* i  : fine structure for BWE                  Q12*/
     982             :     const Word16 *coeff,       /* i  : coded/noisefilled normalized spectrum   Q12*/
     983             :     const Word16 num_sfm,      /* i  : Number of subbands                      Q0*/
     984             :     const Word16 *sfm_start,   /* i  : Subband start coefficient               Q0*/
     985             :     const Word16 *sfm_end,     /* i  : Subband end coefficient                 Q0*/
     986             :     const Word16 last_sfm,     /* i  : last coded subband                      Q0*/
     987             :     const Word16 *R,           /* i  : bit allocation                          Q0*/
     988             :     const Word16 prev_hq_mode, /* i  : previous hq mode                        Q0*/
     989             :     Word16 *norm,              /* i/o: quantization indices for norms          Q0*/
     990             :     Word16 *noise_level,       /* i/o: noise levels for harmonic modes         Q15*/
     991             :     Word16 *prev_noise_level,  /* i/o: noise factor in previous frame          Q15*/
     992             :     Word16 *bwe_seed,          /* i/o: random seed for generating BWE input    Q0*/
     993             :     Word32 *coeff_out,         /* o  : coded/noisefilled spectrum              Q12*/
     994             :     const Word16 element_mode  /* i  : IVAS element mode                       Q0*/
     995             : )
     996             : {
     997             :     Word16 i, j;
     998             :     Word16 sfm, band_width;
     999             :     Word32 normq, L_tmp, L_tmp2;
    1000             :     Word32 E_L;
    1001          20 :     Word16 alfa = 16384;
    1002          20 :     move16();
    1003             :     Word16 tmp, tmp1, exp1;
    1004             :     Word16 beta;
    1005             :     Word32 *src, *dst;
    1006             : 
    1007          20 :     move16(); /* alfa */
    1008             : 
    1009         506 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
    1010             :     {
    1011         486 :         IF( R[sfm] == 0 )
    1012             :         {
    1013          99 :             normq = dicn_fx[norm[sfm]]; /*Q14  */
    1014          99 :             move16();
    1015             : 
    1016        1067 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    1017             :             {
    1018         968 :                 coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*12 Q(14 +12+1-16 +1) */
    1019         968 :                 move32();
    1020             :             }
    1021             :         }
    1022             :     }
    1023          20 :     noise_level[1] = noise_level[0]; /*Q15*/
    1024          20 :     move16();
    1025             : 
    1026             :     /* shaping the BWE spectrum further by envelopes and noise factors */
    1027          20 :     L_tmp = L_mult( 29491, prev_noise_level[0] );                      /*  15 +1 +15 */
    1028          20 :     noise_level[0] = round_fx( L_mac( L_tmp, 3277, noise_level[0] ) ); /*15  */
    1029          20 :     move16();
    1030             : 
    1031          20 :     L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[1] );       /*Q31*/
    1032          20 :     noise_level[1] = round_fx( L_mac( L_tmp, 3277, noise_level[1] ) ); /*Q15*/
    1033          20 :     move16();
    1034             : 
    1035          20 :     test();
    1036          20 :     IF( prev_hq_mode == HQ_NORMAL || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
    1037             :     {
    1038          10 :         IF( LT_16( noise_level[0], 8192 /*Q15*/ ) )
    1039             :         {
    1040          10 :             noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
    1041          10 :             move16();
    1042             :         }
    1043             : 
    1044          10 :         IF( LT_16( noise_level[1], 8192 /*Q15*/ ) )
    1045             :         {
    1046          10 :             noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
    1047          10 :             move16();
    1048             :         }
    1049             :     }
    1050             : 
    1051         154 :     FOR( i = add( last_sfm, 1 ); i < num_sfm; i++ )
    1052             :     {
    1053         134 :         E_L = 1;
    1054         134 :         move32();
    1055        6950 :         FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
    1056             :         {
    1057        6816 :             L_tmp = L_mult0( coeff_fine[j], coeff_fine[j] ); /*Q30  */
    1058        6816 :             E_L = L_add( E_L, L_shr( L_tmp, 6 ) );           /*Q24 */
    1059             :         }
    1060             : 
    1061         134 :         normq = dicn_fx[norm[i]]; /*Q14*/
    1062         134 :         move32();
    1063             : 
    1064         134 :         alfa = noise_level[0]; /*Q15*/
    1065         134 :         move16();
    1066         134 :         if ( GT_16( i, 27 ) )
    1067             :         {
    1068          60 :             alfa = noise_level[1]; /*Q15*/
    1069          60 :             move16();
    1070             :         }
    1071             : 
    1072         134 :         band_width = sub( sfm_end[i], sfm_start[i] ); /* */
    1073         134 :         exp1 = norm_l( E_L );
    1074         134 :         IF( exp1 == 0 )
    1075             :         {
    1076           0 :             E_L = Mult_32_16( E_L, inv_tbl_fx[band_width] ); /* Q24 (24+15+1-16) */ /*24+15+1-16  */
    1077           0 :             tmp = div_l( E_L, sub( 32767, alfa ) );                                 /*Q24-15-1 =8 */
    1078           0 :             tmp = s_max( 1, tmp );
    1079           0 :             L_tmp = L_deposit_h( tmp ); /*24 */
    1080           0 :             E_L = Isqrt( L_tmp );       /* Q19 (31-24/2) */
    1081             :         }
    1082             :         ELSE
    1083             :         {
    1084         134 :             exp1 = sub( exp1, 1 );
    1085         134 :             E_L = Mult_32_16( L_shl( E_L, exp1 ), inv_tbl_fx[band_width] ); /* Q24+exp1 (24+exp1+15+1-16) */
    1086         134 :             tmp = div_l( E_L, sub( 32767, alfa ) );                         /*Q24+exp1-15-1 =8+exp1 */
    1087         134 :             tmp = s_max( 1, tmp );
    1088         134 :             L_tmp = L_shl( L_deposit_l( tmp ), sub( 16, exp1 ) ); /*24  8+exp1+16-exp1 */
    1089         134 :             E_L = Isqrt( L_tmp );                                 /* Q19 (31-24/2) */
    1090             :         }
    1091             : 
    1092         134 :         exp1 = norm_s( alfa );
    1093         134 :         tmp1 = shl( alfa, exp1 );
    1094         134 :         if ( EQ_16( element_mode, EVS_MONO ) )
    1095             :         {
    1096         134 :             exp1 = add( 1, exp1 );
    1097             :         }
    1098             : #ifdef DEBUGGING
    1099             :         else
    1100             :         {
    1101             :             // PMT("VERIFY if this really matches IVAS float")
    1102             :         }
    1103             : #endif
    1104         134 :         tmp1 = s_max( tmp1, 16384 );
    1105         134 :         tmp1 = div_s( 16384, tmp1 );        /*Q15*/
    1106         134 :         L_tmp2 = L_deposit_h( tmp1 );       /*Q31*/
    1107         134 :         L_tmp2 = Isqrt_lc( L_tmp2, &exp1 ); /*Q31 - exp1*/
    1108             : 
    1109         134 :         beta = round_fx( L_shl( L_tmp2, exp1 ) ); /*Q15*/
    1110         134 :         beta = shr( beta, 1 );                    /*Q15 */
    1111             : 
    1112             : 
    1113        6950 :         FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ )
    1114             :         {
    1115        6816 :             L_tmp = Mult_32_16( E_L, coeff_fine[sfm] );                  /*Q19 19 + 15 +1-16   */
    1116        6816 :             L_tmp = L_shl_sat( L_tmp, 9 );                               /*Q28 */
    1117        6816 :             tmp = Random( bwe_seed );                                    /*Q15 */
    1118        6816 :             L_tmp2 = L_shr( L_mult( beta, tmp ), 3 );                    /* Q28 31-3  15+15 +1-3 */
    1119        6816 :             L_tmp = L_add_sat( L_tmp, L_tmp2 );                          /*Q28 */
    1120        6816 :             coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12  28 +14 +1 -31 */
    1121        6816 :             move32();
    1122             :         }
    1123             :     }
    1124             : 
    1125          20 :     prev_noise_level[0] = noise_level[0]; /*Q15*/
    1126          20 :     move16();
    1127          20 :     prev_noise_level[1] = noise_level[1]; /*Q15*/
    1128          20 :     move16();
    1129             : 
    1130          20 :     src = &coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /*Q12 */
    1131             : 
    1132          20 :     dst = src - 1;
    1133         340 :     FOR( i = 0; i < 16; i++ )
    1134             :     {
    1135         320 :         *src = Mult_32_16( *src, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
    1136         320 :         move32();
    1137         320 :         src++;
    1138         320 :         *dst = Mult_32_16( *dst, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
    1139         320 :         move32();
    1140         320 :         dst--;
    1141             :     }
    1142          20 :     IF( EQ_16( num_sfm, 33 ) )
    1143             :     {
    1144           0 :         set32_fx( &coeff_out[800], 0, 160 );
    1145             :     }
    1146          20 :     return;
    1147             : }
    1148             : 
    1149             : /*--------------------------------------------------------------------------*
    1150             :  * HVQ_bwe_fx()
    1151             :  *
    1152             :  * HQ HVQ BWE
    1153             :  *--------------------------------------------------------------------------*/
    1154             : 
    1155        1229 : void hvq_bwe_fx(
    1156             :     const Word32 *L_coeff,     /* i  : coded/noisefilled normalized spectrum  Q12 */
    1157             :     const Word16 *coeff_fine,  /* i  : coded/noisefilled normalized spectrum  Qin */
    1158             :     const Word16 *sfm_start,   /* i  : Subband start coefficient              Q0  */
    1159             :     const Word16 *sfm_end,     /* i  : Subband end coefficient                Q0  */
    1160             :     const Word16 *sfm_len,     /* i  : Subband length                         Q0  */
    1161             :     const Word16 last_sfm,     /* i  : last coded subband                     Q0  */
    1162             :     const Word16 prev_hq_mode, /* i  : previous hq mode                       Q0  */
    1163             :     const Word16 *bwe_peaks,   /* i  : HVQ bwe peaks                          Q0  */
    1164             :     const Word16 bin_th,       /* i  : HVQ transition bin                     Q0  */
    1165             :     const Word16 num_sfm,      /* i  : Number of bands                        Q0  */
    1166             :     const Word32 core_brate,   /* i  : Core bitrate                           Q0  */
    1167             :     const Word16 *R,           /* i  : Bit allocation                             */
    1168             :     Word16 *norm,              /* i/o: quantization indices for norms         Q0  */
    1169             :     Word16 *noise_level,       /* i/o: noise levels for harmonic modes        Q15 */
    1170             :     Word16 *prev_noise_level,  /* i/o: noise factor in previous frame         Q15 */
    1171             :     Word16 *bwe_seed,          /* i/o: random seed for generating BWE input   Q0  */
    1172             :     Word32 *L_coeff_out,       /* o  : coded/noisefilled spectrum             Qout*/
    1173             :     const Word16 qin,
    1174             :     const Word16 qout )
    1175             : {
    1176             :     Word16 i, j;
    1177             :     Word16 N;
    1178             :     Word32 L_normq;
    1179             :     Word32 L_E;
    1180        1229 :     Word32 L_tmp_norm = 0;
    1181        1229 :     move32();
    1182        1229 :     Word16 bwe_noise_th = 0;
    1183        1229 :     move16();
    1184             :     Word16 peak_band, low, high, sel_norm;
    1185             :     Word16 norm_ind;
    1186             :     Word32 *L_src, *L_dst;
    1187             :     Word16 istart, iend;
    1188        1229 :     Word16 offset = sfm_end[last_sfm]; /*Q0*/
    1189             : 
    1190             :     /* Fx specific variables */
    1191             :     Word32 L_tmp0, L_tmp1;
    1192             :     Word16 tmp, tmp2, band_size;
    1193             :     Word16 last_norm_ind;
    1194             :     Word16 shift, power_shift;
    1195             :     Word16 coeff_s[L_FRAME48k];
    1196             :     Word16 j_N;
    1197             :     Word16 n_c;
    1198             :     UWord16 lsb;
    1199             : 
    1200        1229 :     move32(); /* L_tmp_norm */
    1201        1229 :     move16(); /* bwe_noise_th */
    1202             : 
    1203        1229 :     bwe_noise_th = add( bin_th, shr( sub( sfm_end[( num_sfm - 1 )], bin_th ), 1 ) );
    1204        1229 :     logqnorm_fx( &L_coeff_out[sfm_start[last_sfm]], qout, &norm[last_sfm], 40, sfm_len[last_sfm], 0 );
    1205        1229 :     move16();
    1206             : 
    1207             :     /* shaping the BWE spectrum further by envelopes and noise factors */
    1208        1229 :     noise_level[0] = round_fx( L_mac( L_mult( 29491 /*0.9 Q15*/, prev_noise_level[0] ), 3277 /*0.1 Q15*/, noise_level[0] ) ); /* Q15 (15+15+1-16) */
    1209        1229 :     noise_level[1] = round_fx( L_mac( L_mult( 29491 /*0.9 Q15*/, prev_noise_level[1] ), 3277 /*0.1 Q15*/, noise_level[1] ) ); /* Q15 (15+15+1-16) */
    1210        1229 :     move16();
    1211        1229 :     move16();
    1212             : 
    1213        1229 :     test();
    1214        1229 :     IF( prev_hq_mode == HQ_NORMAL || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
    1215             :     {
    1216         117 :         IF( LT_16( noise_level[0], 8192 /* 0.25f */ ) )
    1217             :         {
    1218         117 :             noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
    1219         117 :             move16();
    1220             :         }
    1221             : 
    1222         117 :         IF( LT_16( noise_level[1], 8192 /* 0.25f */ ) )
    1223             :         {
    1224         117 :             noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
    1225         117 :             move16();
    1226             :         }
    1227             :     }
    1228             : 
    1229        1229 :     norm_ind = add( last_sfm, 1 );
    1230        1229 :     IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
    1231             :     {
    1232         708 :         peak_band = 0;
    1233         708 :         move16();
    1234             : 
    1235         708 :         tmp = 1;
    1236         708 :         move16();
    1237       46020 :         FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind + 1]; i++ )
    1238             :         {
    1239       45312 :             tmp2 = abs_s( coeff_fine[i - offset] ); /*Qin*/
    1240       45312 :             tmp = s_max( tmp, tmp2 );
    1241             :         }
    1242         708 :         band_size = sub( sfm_end[norm_ind + 1], sfm_start[norm_ind] );
    1243             : 
    1244             :         /* Headroom for square and accumulate */
    1245         708 :         shift = sub( norm_s( tmp ), sqac_headroom_fx[band_size] );
    1246         708 :         L_E = L_deposit_l( 1 );
    1247       46020 :         FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind + 1]; i++ )
    1248             :         {
    1249       45312 :             if ( bwe_peaks[i] )
    1250             :             {
    1251        1981 :                 peak_band = 1;
    1252        1981 :                 move16();
    1253             :             }
    1254             :             /* E_L += coeff_fine[i-offset] * coeff_fine[i-offset]; */
    1255       45312 :             coeff_s[i] = shl( coeff_fine[i - offset], shift ); /*Qin*/
    1256       45312 :             move16();                                          /* Q15 + shift */
    1257       45312 :             L_E = L_mac0( L_E, coeff_s[i], coeff_s[i] );       /* Q2*(qin + shift) */
    1258             :         }
    1259         708 :         power_shift = shl( shift, 1 );
    1260             : 
    1261         708 :         L_E = L_shr( L_E, sub( power_shift, sub( 28, shl( qin, 1 ) ) ) ); /* Q28 */
    1262             : 
    1263             :         /* E_L = (float)sqrt((sfm_end[norm_ind+1] - sfm_start[norm_ind])/E_L); */
    1264         708 :         L_E = Mult_32_16( L_E, inv_tbl_fx[band_size] ); /* Q28 (28+15+1-16) */
    1265             :         /* To avoid overflow in Isqrt() */
    1266         708 :         if ( L_E == 0 )
    1267             :         {
    1268           0 :             L_E = L_deposit_l( 1 );
    1269             :         }
    1270         708 :         L_E = Isqrt( L_E ); /* Q17 (31-28/2) */
    1271             : 
    1272             :         /* normq = 0.1f*dicn[norm[norm_ind-1]] + 0.8f*dicn[norm[norm_ind]] + 0.1f*dicn[norm[norm_ind+1]]; */
    1273             :         /* tmp_norm = 0.1f*dicn[norm[norm_ind]] + 0.8f*dicn[norm[norm_ind+1]] + 0.1f*dicn[norm[norm_ind+2]]; */
    1274         708 :         L_tmp0 = L_add( dicn_fx[norm[norm_ind]], 0 );                                                                                                                       /*Q14*/
    1275         708 :         L_tmp1 = L_add( dicn_fx[norm[norm_ind + 1]], 0 );                                                                                                                   /*Q14*/
    1276         708 :         L_normq = Madd_32_16( Madd_32_16( Mult_32_16( L_tmp0, 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind - 1]], 3277 /* Q15, 0.1f */ ), L_tmp1, 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
    1277         708 :         move16();
    1278         708 :         L_tmp_norm = Madd_32_16( Madd_32_16( Mult_32_16( L_tmp1, 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind + 2]], 3277 /* Q15, 0.1f */ ), L_tmp0, 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
    1279         708 :         move16();
    1280             : 
    1281         708 :         istart = sfm_start[norm_ind];
    1282         708 :         move16();
    1283             :         /* iend = istart + sfm_len[norm_ind]/2; */
    1284         708 :         iend = 240;
    1285         708 :         move16();
    1286             : 
    1287         708 :         noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, istart, iend, noise_level[0], L_coeff_out, qin, qout );
    1288             : 
    1289         708 :         j = 0;
    1290         708 :         move16();
    1291             :         /* N = sfm_len[norm_ind]/2+sfm_len[norm_ind+1]/2-1; */
    1292         708 :         N = 31;
    1293         708 :         move16();
    1294         708 :         j_N = N;
    1295         708 :         move16();
    1296             : 
    1297         708 :         istart = iend;
    1298         708 :         move16();
    1299             :         /* iend = sfm_start[norm_ind+1] + sfm_len[norm_ind+1]/2; */
    1300         708 :         iend = 272;
    1301         708 :         move16();
    1302             : 
    1303             :         /* special case that is not handled by noise_mix_fx() */
    1304         708 :         n_c = sub( MAX_16, noise_level[0] ); /* Q15 */
    1305       23364 :         FOR( i = istart; i < iend; i++ )
    1306             :         {
    1307             :             /* coeff_out[i] = ((float)(N-j)/N*normq + (float)j/N*tmp_norm)*((1.0f - noise_level[i/bwe_noise_th])*coeff_fine[i-offset]*E_L + noise_level[i/bwe_noise_th]*own_random(bwe_seed)/32768.0f); */
    1308       22656 :             L_tmp1 = Madd_32_16( Mult_32_16( L_normq, inv_N_fx[j_N] ), L_tmp_norm, inv_N_fx[j] ); /* Q14 (14+15+1-16) */
    1309       22656 :             j = add( j, 1 );
    1310       22656 :             j_N = sub( j_N, 1 );
    1311             : 
    1312       22656 :             Mpy_32_16_ss( L_E, coeff_fine[i - offset], &L_tmp0, &lsb ); /* Qin+2 (17+qin+1-16) */
    1313       22656 :             Mpy_32_16_ss( L_tmp0, n_c, &L_tmp0, &lsb );                 /* Qin+2-15 (qin+2+15+1-16) */
    1314             : 
    1315       22656 :             IF( L_tmp0 != 0 )
    1316             :             {
    1317             :                 /* Normalize with 1 bit headroom for addition */
    1318       22644 :                 tmp = sub( 30, add( qin, 2 ) ); /* Assuming fixed Q values */
    1319       22644 :                 tmp = s_min( norm_l( L_tmp0 ), tmp );
    1320       22644 :                 tmp = sub( tmp, 1 );
    1321             : 
    1322       22644 :                 L_tmp0 = L_add( L_shl( L_tmp0, tmp ), L_shr( lsb, sub( 16, tmp ) ) ); /* Qin+2+tmp */
    1323             : 
    1324       22644 :                 L_tmp0 = L_add( L_tmp0, L_shr( L_mult0( noise_level[0], Random( bwe_seed ) ), sub( sub( 30, add( qin, 2 ) ), tmp ) ) ); /* Qin+2+tmp */
    1325       22644 :                 tmp = round_fx( L_shl( L_tmp0, sub( sub( 27, add( qin, 2 ) ), tmp ) ) );                                                /* Q11 (Qin+2+tmp+27-qin-2-tmp-16) */
    1326             : 
    1327       22644 :                 Mpy_32_16_ss( L_tmp1, tmp, &L_tmp0, &lsb );                                                           /* Q10 (14+11+1-16) */
    1328       22644 :                 L_coeff_out[i] = L_add( L_shl( L_tmp0, sub( qout, 10 ) ), L_shr( lsb, add( 10, sub( 16, qout ) ) ) ); /*Qout*/
    1329       22644 :                 move32();
    1330             :             }
    1331             :             ELSE
    1332             :             {
    1333          12 :                 L_tmp0 = L_mult0( noise_level[0], Random( bwe_seed ) ); /* Q30 (15+15) */
    1334          12 :                 tmp = round_fx( L_tmp0 );                               /* Q14 (30-16) */
    1335          12 :                 Mpy_32_16_ss( L_tmp1, tmp, &L_tmp0, &lsb );             /* Q13 (14+14+1-16) */
    1336          12 :                 L_coeff_out[i] = L_shr( L_tmp0, sub( 13, qout ) );      /*Qout*/
    1337          12 :                 move32();
    1338             :             }
    1339             :         }
    1340             : 
    1341         708 :         istart = iend;
    1342         708 :         move16();
    1343         708 :         iend = sfm_end[norm_ind + 1];
    1344         708 :         move16();
    1345             : 
    1346         708 :         noise_mix_fx( &coeff_fine[-offset], L_E, L_tmp_norm, bwe_seed, istart, iend, noise_level[0], L_coeff_out, qin, qout );
    1347             : 
    1348         708 :         norm_ind = add( norm_ind, 2 );
    1349             :     }
    1350             : 
    1351       11413 :     FOR( ; norm_ind < num_sfm; norm_ind++ )
    1352             :     {
    1353       10184 :         IF( R[norm_ind] == 0 )
    1354             :         {
    1355        9929 :             peak_band = 0;
    1356        9929 :             move16();
    1357             : 
    1358      582457 :             FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind]; i++ )
    1359             :             {
    1360      572528 :                 if ( bwe_peaks[i] )
    1361             :                 {
    1362       30962 :                     peak_band = 1;
    1363       30962 :                     move16();
    1364             :                 }
    1365             :             }
    1366             : 
    1367        9929 :             istart = sfm_start[norm_ind];
    1368        9929 :             move16();
    1369        9929 :             iend = sfm_end[norm_ind];
    1370        9929 :             move16();
    1371             : 
    1372        9929 :             last_norm_ind = sub( num_sfm, 1 );
    1373        9929 :             test();
    1374        9929 :             test();
    1375        9929 :             IF( EQ_16( peak_band, 1 ) && GT_16( norm_ind, add( last_sfm, 1 ) ) && LT_16( norm_ind, last_norm_ind ) )
    1376             :             {
    1377        7713 :                 istart = sub( istart, shr( sfm_len[norm_ind - 1], 1 ) );
    1378        7713 :                 iend = add( iend, shr( sfm_len[norm_ind + 1], 1 ) );
    1379             :             }
    1380             : 
    1381        9929 :             tmp = 1;
    1382        9929 :             move16();
    1383     1006873 :             FOR( i = istart; i < iend; i++ )
    1384             :             {
    1385      996944 :                 tmp2 = abs_s( coeff_fine[i - offset] );
    1386      996944 :                 tmp = s_max( tmp, tmp2 );
    1387             :             }
    1388        9929 :             band_size = sub( iend, istart );
    1389             :             /* Headroom for square and accumulate */
    1390        9929 :             shift = sub( norm_s( tmp ), sqac_headroom_fx[band_size] );
    1391             : 
    1392        9929 :             L_E = 1L;
    1393        9929 :             move32();
    1394     1006873 :             FOR( i = istart; i < iend; i++ )
    1395             :             {
    1396             :                 /* E_L += coeff_fine[i-offset] * coeff_fine[i-offset]; */
    1397      996944 :                 coeff_s[i] = shl( coeff_fine[i - offset], shift );
    1398      996944 :                 move16();                                    /* Q15 + shift */
    1399      996944 :                 L_E = L_mac0( L_E, coeff_s[i], coeff_s[i] ); /* Q2*(15 + shift) */
    1400             :             }
    1401        9929 :             power_shift = shl( shift, 1 );
    1402             : 
    1403        9929 :             L_E = L_shr( L_E, sub( power_shift, sub( 28, imult1616( 2, qin ) ) ) ); /* Q28 */
    1404             : 
    1405             :             /* E_L = (float)sqrt((iend - istart)/E_L); */
    1406        9929 :             L_E = Mult_32_16( L_E, inv_tbl_fx[band_size] ); /* Q28 (28+15+1-16) */
    1407             :             /* To avoid overflow in Isqrt() */
    1408        9929 :             if ( L_E == 0 )
    1409             :             {
    1410           0 :                 L_E = 1L;
    1411           0 :                 move32();
    1412             :             }
    1413        9929 :             L_E = Isqrt( L_E ); /* Q17 (31-28/2) */
    1414             : 
    1415        9929 :             IF( peak_band )
    1416             :             {
    1417        9395 :                 IF( GT_16( add( norm_ind, 2 ), num_sfm ) )
    1418             :                 {
    1419             :                     /* normq = 0.15f*dicn[norm[norm_ind-1]] + 0.85f*dicn[norm[norm_ind]]; */
    1420        1220 :                     L_normq = Madd_32_16( Mult_32_16( dicn_fx[norm[norm_ind]], 27853 /* Q15, 0.85f */ ), dicn_fx[norm[norm_ind - 1]], 4915 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
    1421        1220 :                     move16();
    1422        1220 :                     move16();
    1423             :                 }
    1424             :                 ELSE
    1425             :                 {
    1426             :                     /* normq = 0.1f*dicn[norm[norm_ind-1]] + 0.8f*dicn[norm[norm_ind]] + 0.1f*dicn[norm[norm_ind+1]]; */
    1427        8175 :                     L_normq = Madd_32_16( Madd_32_16( Mult_32_16( dicn_fx[norm[norm_ind]], 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind + 1]], 3277 /* Q15, 0.1f */ ), dicn_fx[norm[norm_ind - 1]], 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
    1428        8175 :                     move16();
    1429        8175 :                     move16();
    1430        8175 :                     move16();
    1431             :                 }
    1432             :             }
    1433             :             ELSE
    1434             :             {
    1435         534 :                 low = norm_ind;
    1436         534 :                 move16();
    1437         534 :                 high = s_min( add( norm_ind, 1 ), last_norm_ind );
    1438         534 :                 move16();
    1439         534 :                 sel_norm = norm[norm_ind - 1]; /*Q0*/
    1440         534 :                 move16();
    1441        1593 :                 FOR( j = low; j <= high; j++ )
    1442             :                 {
    1443        1059 :                     if ( GT_16( norm[j], sel_norm ) )
    1444             :                     {
    1445         532 :                         sel_norm = norm[j]; /*Q0*/
    1446         532 :                         move16();
    1447             :                     }
    1448             :                 }
    1449         534 :                 L_normq = dicn_fx[sel_norm]; /*Q14*/
    1450         534 :                 move16();
    1451             :             }
    1452             : 
    1453        9929 :             iend = s_min( sfm_end[norm_ind], bwe_noise_th );
    1454        9929 :             move16();
    1455        9929 :             IF( GT_16( iend, sfm_start[norm_ind] ) )
    1456             :             {
    1457        5712 :                 noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, sfm_start[norm_ind], iend, noise_level[0], L_coeff_out, qin, qout );
    1458             :             }
    1459             :             ELSE
    1460             :             {
    1461        4217 :                 iend = sfm_end[norm_ind];
    1462        4217 :                 move16();
    1463        4217 :                 noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, sfm_start[norm_ind], iend, noise_level[1], L_coeff_out, qin, qout );
    1464             :             }
    1465             :             /* Noisemix up to threshold done */
    1466        9929 :             IF( EQ_16( iend, bwe_noise_th ) )
    1467             :             {
    1468        1229 :                 noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, iend, sfm_end[norm_ind], noise_level[1], L_coeff_out, qin, qout );
    1469             :             }
    1470             :         }
    1471             :         ELSE /* R[norm_ind] > 0 */
    1472             :         {
    1473       11823 :             FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind]; i++ )
    1474             :             {
    1475       11568 :                 L_coeff_out[i] = L_coeff[i]; /* Scaling already applied Q12*/
    1476       11568 :                 move32();
    1477             :             }
    1478             :         }
    1479             :     }
    1480             : 
    1481        1229 :     prev_noise_level[0] = noise_level[0]; /*Q15*/
    1482        1229 :     move16();
    1483        1229 :     prev_noise_level[1] = noise_level[1]; /*Q15*/
    1484        1229 :     move16();
    1485        1229 :     L_src = &L_coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /* Address initialization Qout*/
    1486        1229 :     L_dst = L_src - 1;                                                        /* Address computation Qout*/
    1487             : 
    1488       20893 :     FOR( i = 0; i < 16; i++ )
    1489             :     {
    1490       19664 :         *L_src = Mult_32_16( *L_src, hvq_bwe_fac_fx[i] ); /* Qout (Qout+15+1-16) */
    1491       19664 :         L_src++;                                          /* Qout (Qout+15+1-16) */
    1492       19664 :         move32();
    1493       19664 :         *L_dst = Mult_32_16( *L_dst, hvq_bwe_fac_fx[i] ); /* Qout (Qout+15+1-16) */
    1494       19664 :         L_dst--;                                          /* Qout (Qout+15+1-16) */
    1495       19664 :         move32();
    1496             :     }
    1497             : 
    1498        1229 :     return;
    1499             : }
    1500             : 
    1501             : /*-------------------------------------------------------------------*
    1502             :  * hvq_concat_bands_fx()
    1503             :  *
    1504             :  * Compute the band limits for concatenated bands for PVQ target signal in HVQ
    1505             :  *--------------------------------------------------------------------------*/
    1506        2692 : void hvq_concat_bands_fx(
    1507             :     const Word16 pvq_bands,  /* i  : Number of bands in concatenated PVQ target  Q0*/
    1508             :     const Word16 *sel_bnds,  /* i  : Array of selected high bands                Q0*/
    1509             :     const Word16 n_sel_bnds, /* i  : Number of selected high bands               Q0*/
    1510             :     Word16 *hvq_band_start,  /* i  : Band start indices                          Q0*/
    1511             :     Word16 *hvq_band_width,  /* i  : Band widths                                 Q0*/
    1512             :     Word16 *hvq_band_end     /* i  : Band end indices                            Q0*/
    1513             : )
    1514             : {
    1515             :     Word16 k, k_1;
    1516             :     const Word16 *pSelBnds;
    1517             : 
    1518        2692 :     pSelBnds = sel_bnds;
    1519        7972 :     FOR( k = 0; k < pvq_bands; k++ )
    1520             :     {
    1521             : 
    1522        5280 :         IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
    1523             :         {
    1524         691 :             k_1 = sub( k, 1 );
    1525         691 :             hvq_band_start[k] = hvq_band_end[k_1]; /*Q0*/
    1526         691 :             move16();
    1527         691 :             hvq_band_width[k] = band_len_harm[*pSelBnds++]; /*Q0*/
    1528         691 :             move16();
    1529         691 :             move16();
    1530         691 :             hvq_band_end[k] = add( hvq_band_end[k_1], hvq_band_width[k] ); /*Q0*/
    1531         691 :             move16();
    1532             :         }
    1533             :         ELSE
    1534             :         {
    1535        4589 :             hvq_band_start[k] = extract_l( L_mult0( k, HVQ_PVQ_COEFS ) ); /*Q0*/
    1536        4589 :             move16();
    1537        4589 :             hvq_band_width[k] = HVQ_PVQ_COEFS; /*Q0*/
    1538        4589 :             move16();
    1539        4589 :             hvq_band_end[k] = add( hvq_band_start[k], HVQ_PVQ_COEFS ); /*Q0*/
    1540        4589 :             move16();
    1541             :         }
    1542             :     }
    1543             : 
    1544        2692 :     return;
    1545             : }
    1546             : /*--------------------------------------------------------------------------*
    1547             :  * noise_mix_fx()
    1548             :  *--------------------------------------------------------------------------*/
    1549             : 
    1550       12574 : void noise_mix_fx(
    1551             :     const Word16 *coeff_fine, /* i  : normalized fine structure spectrum     Qin */
    1552             :     const Word32 L_E,         /* i  : normalization factor                   Q17 */
    1553             :     const Word32 L_normq,     /* i  : quantized norm                         Q14 */
    1554             :     Word16 *seed,             /* i/o: random seed                            Q0  */
    1555             :     const Word16 istart,      /* i  : start coefficient                      Q0  */
    1556             :     const Word16 iend,        /* i  : end coefficient                        Q0  */
    1557             :     const Word16 noise_level, /* i  : noise_level                            Q0  */
    1558             :     Word32 *L_coeff_out,      /* o  : noise mixed spectrum                   Qout */
    1559             :     const Word16 qin,
    1560             :     const Word16 qout )
    1561             : {
    1562             :     Word16 i, tmp, n_c;
    1563             :     Word32 L_tmp0;
    1564             :     UWord16 lsb;
    1565             : 
    1566       12574 :     n_c = sub( MAX_16, noise_level ); /* Q15 */
    1567      607758 :     FOR( i = istart; i < iend; i++ )
    1568             :     {
    1569             :         /* L_coeff_out[i] = ((1.0f - noise_level)*coeff_fine[i]*L_E + noise_level*own_random(seed)/32768.0f)*normq; */
    1570      595184 :         Mpy_32_16_ss( L_E, coeff_fine[i], &L_tmp0, &lsb ); /* Qin+qL_E-15 (qL_E+qin+1-16) */
    1571      595184 :         Mpy_32_16_ss( L_tmp0, n_c, &L_tmp0, &lsb );        /* Qin+qL_E-15 (qin+qL_E-15+15+1-16) */
    1572             : 
    1573      595184 :         IF( L_tmp0 != 0 )
    1574             :         {
    1575             :             /* Normalize with 1 bit headroom for addition */
    1576      523086 :             tmp = sub( 30, add( qin, 2 ) ); /* Assuming fixed Q values */
    1577      523086 :             tmp = s_min( norm_l( L_tmp0 ), tmp );
    1578      523086 :             tmp = sub( tmp, 1 );
    1579             : 
    1580      523086 :             L_tmp0 = L_add( L_shl( L_tmp0, tmp ), L_shr( lsb, sub( 16, tmp ) ) );                                            /* Qin+2+tmp */
    1581      523086 :             L_tmp0 = L_add( L_tmp0, L_shr( L_mult0( noise_level, Random( seed ) ), sub( sub( 30, add( qin, 2 ) ), tmp ) ) ); /* Qin+2+tmp */
    1582             : 
    1583      523086 :             tmp = round_fx( L_shl( L_tmp0, sub( sub( 27, add( qin, 2 ) ), tmp ) ) );                              /* Q11 (Qin+2+tmp+27-qin-2-tmp-16) */
    1584      523086 :             Mpy_32_16_ss( L_normq, tmp, &L_tmp0, &lsb );                                                          /* Q10 (14+11+1-16) */
    1585      523086 :             L_coeff_out[i] = L_add( L_shl( L_tmp0, sub( qout, 10 ) ), L_shr( lsb, add( 10, sub( 16, qout ) ) ) ); /* Qout (10+qout-10) */
    1586      523086 :             move32();
    1587             :         }
    1588             :         ELSE
    1589             :         {
    1590       72098 :             L_tmp0 = L_mult0( noise_level, Random( seed ) );   /* Q30 (15+15) */
    1591       72098 :             tmp = round_fx( L_tmp0 );                          /* Q14 (30-16) */
    1592       72098 :             Mpy_32_16_ss( L_normq, tmp, &L_tmp0, &lsb );       /* Q13 (14+14+1-16) */
    1593       72098 :             L_coeff_out[i] = L_shr( L_tmp0, sub( 13, qout ) ); /* Qout (13-(13-qout)) */
    1594       72098 :             move32();
    1595             :         }
    1596             :     }
    1597       12574 : }
    1598             : 
    1599             : 
    1600             : /*--------------------------------------------------------------------------*
    1601             :  * hq_generic_fine_fx()
    1602             :  *
    1603             :  * Prepare HQ GENERIC HF fine structure
    1604             :  *--------------------------------------------------------------------------*/
    1605        2789 : void hq_generic_fine_fx(
    1606             :     Word16 *coeff,           /* i  : coded/noisefilled normalized spectrum   Q12*/
    1607             :     const Word16 last_sfm,   /* i  : Last coded band                         Q0*/
    1608             :     const Word16 *sfm_start, /* i  : Subband start coefficient               Q0*/
    1609             :     const Word16 *sfm_end,   /* i  : Subband end coefficient                 Q0*/
    1610             :     Word16 *bwe_seed,        /* i/o: random seed for generating BWE input    Q0*/
    1611             :     Word16 *coeff_out1       /* o  : HQ GENERIC input                        Q12*/
    1612             : )
    1613             : {
    1614             :     Word16 sfm;
    1615             :     Word16 i;
    1616             : 
    1617       78103 :     FOR( sfm = 0; sfm <= last_sfm; sfm++ )
    1618             :     {
    1619      990370 :         FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    1620             :         {
    1621      915056 :             IF( coeff[i] == 0 )
    1622             :             {
    1623      522084 :                 coeff_out1[i] = -2048; /*Q12*/
    1624      522084 :                 move16();
    1625      522084 :                 if ( Random( bwe_seed ) > 0 )
    1626             :                 {
    1627      261652 :                     coeff_out1[i] = 2048; /*Q12*/
    1628      261652 :                     move16();
    1629             :                 }
    1630             :             }
    1631             :             ELSE
    1632             :             {
    1633      392972 :                 coeff_out1[i] = coeff[i]; /*Q12*/
    1634      392972 :                 move16();
    1635             :             }
    1636             :         }
    1637             :     }
    1638             : 
    1639        2789 :     return;
    1640             : }
    1641             : 
    1642             : /*--------------------------------------------------------------------------*
    1643             :  * overlap_hq_bwe_fx()
    1644             :  *
    1645             :  * Overlapping at the boundary between HQ core and BWE
    1646             :  *--------------------------------------------------------------------------*/
    1647        2789 : static void overlap_hq_bwe_fx(
    1648             :     const Word32 *hq_swb_overlap_buf,  /* i  : spectrum from HQ core   Q12*/
    1649             :     Word32 *coeff_out,                 /* i/o: spectrum from BWE, overlapped output  Q12*/
    1650             :     const Word16 n_swb_overlap_offset, /* i  : starting offset of overlapping  Q0*/
    1651             :     const Word16 n_swb_overlap,        /* i  : length of overlapping  Q0*/
    1652             :     const Word16 *R,                   /*Q0*/
    1653             :     const Word16 num_env_bands,        /*Q0*/
    1654             :     const Word16 num_sfm,              /*Q0*/
    1655             :     const Word16 *sfm_end /*Q0*/ )
    1656             : {
    1657             :     Word16 i;
    1658             :     Word16 weighting;
    1659             :     Word16 step;
    1660             :     Word16 exp, tmp, n_band;
    1661             : 
    1662        2789 :     IF( R[( num_env_bands - 1 )] != 0 )
    1663             :     {
    1664        1518 :         Copy32( hq_swb_overlap_buf, &coeff_out[n_swb_overlap_offset], n_swb_overlap ); /*Q12*/
    1665             :     }
    1666             :     ELSE
    1667             :     {
    1668        1271 :         exp = norm_s( n_swb_overlap );
    1669        1271 :         tmp = div_s( 16384, shl( n_swb_overlap, exp ) ); /*15 + 14 - exp */
    1670        1271 :         tmp = shr( tmp, sub( 14, exp ) );                /*15 */
    1671        1271 :         step = mult_r( tmp, 32767 );                     /*15 */
    1672        1271 :         weighting = 32767;
    1673        1271 :         move16();
    1674       11439 :         FOR( i = 0; i < n_swb_overlap; i++ )
    1675             :         {
    1676       10168 :             coeff_out[( n_swb_overlap_offset + i )] = L_add( coeff_out[( n_swb_overlap_offset + i )],
    1677       10168 :                                                              Mult_32_16( L_sub( hq_swb_overlap_buf[i], coeff_out[( n_swb_overlap_offset + i )] ), weighting ) ); /*Q12*/
    1678       10168 :             move32();
    1679       10168 :             weighting = sub( weighting, step );
    1680             :         }
    1681             :     }
    1682             : 
    1683       46607 :     FOR( n_band = num_env_bands; n_band < num_sfm; n_band++ )
    1684             :     {
    1685       43818 :         IF( R[n_band] != 0 )
    1686             :         {
    1687         275 :             FOR( i = sfm_end[( n_band - 1 )]; i < sfm_end[n_band]; ++i )
    1688             :             {
    1689         264 :                 coeff_out[i] = hq_swb_overlap_buf[( i - n_swb_overlap_offset )]; /*Q12*/
    1690         264 :                 move32();
    1691             :             }
    1692             :         }
    1693             :     }
    1694        2789 :     return;
    1695             : }
    1696             : 
    1697             : /*--------------------------------------------------------------------------*
    1698             :  * map_hq_generic_fenv_norm()
    1699             :  *
    1700             :  * mapping high frequency envelope to high band norm
    1701             :  *--------------------------------------------------------------------------*/
    1702        5626 : void map_hq_generic_fenv_norm_fx(
    1703             :     const Word16 hqswb_clas,       /*Q0*/
    1704             :     const Word16 *hq_generic_fenv, /* Q1, frequency-domain BWE envelope */
    1705             :     Word16 *ynrm,                  /*Q0*/
    1706             :     Word16 *normqlg2,              /*Q0*/
    1707             :     const Word16 num_env_bands,    /*Q0*/
    1708             :     const Word16 nb_sfm,           /*Q0*/
    1709             :     const Word16 hq_generic_offset /*Q0*/ )
    1710             : {
    1711             :     Word32 env_fl[17]; /*Q8 */
    1712             :     Word16 i;
    1713             : 
    1714        5626 :     set32_fx( env_fl, 0, 17 );
    1715             : 
    1716        5626 :     IF( EQ_16( hq_generic_offset, 144 ) )
    1717             :     {
    1718           0 :         env_fl[0] = L_shl( hq_generic_fenv[1], 7 ); /*Q8*/
    1719           0 :         move32();
    1720           0 :         env_fl[1] = L_add( L_mult0( hq_generic_fenv[2], 85 ), L_mult0( hq_generic_fenv[3], 43 ) ); /*Q8*/
    1721           0 :         move32();
    1722           0 :         env_fl[2] = L_add( L_mult0( hq_generic_fenv[3], 85 ), L_mult0( hq_generic_fenv[4], 43 ) ); /*Q8*/
    1723           0 :         move32();
    1724           0 :         env_fl[3] = L_add( L_mult0( hq_generic_fenv[4], 43 ), L_mult0( hq_generic_fenv[5], 85 ) ); /*Q8*/
    1725           0 :         move32();
    1726           0 :         env_fl[4] = L_add( L_mult0( hq_generic_fenv[5], 43 ), L_mult0( hq_generic_fenv[6], 85 ) ); /*Q8*/
    1727           0 :         move32();
    1728           0 :         env_fl[5] = L_shl( hq_generic_fenv[7], 7 ); /*Q8*/
    1729           0 :         move32();
    1730           0 :         env_fl[6] = L_add( L_mult0( hq_generic_fenv[8], 96 ), L_mult0( hq_generic_fenv[9], 32 ) ); /*Q8*/
    1731           0 :         move32();
    1732           0 :         env_fl[7] = L_add( L_mult0( hq_generic_fenv[9], 96 ), L_mult0( hq_generic_fenv[10], 32 ) ); /*Q8*/
    1733           0 :         move32();
    1734           0 :         env_fl[8] = L_add( L_mult0( hq_generic_fenv[10], 32 ), L_mult0( hq_generic_fenv[11], 96 ) ); /*Q8*/
    1735           0 :         move32();
    1736             :     }
    1737             :     ELSE
    1738             :     {
    1739        5626 :         env_fl[0] = L_add( L_mult0( hq_generic_fenv[0], 43 ), L_mult0( hq_generic_fenv[1], 85 ) ); /*Q8*/
    1740        5626 :         move32();
    1741        5626 :         env_fl[1] = L_add( L_mult0( hq_generic_fenv[1], 43 ), L_mult0( hq_generic_fenv[2], 85 ) ); /*Q8*/
    1742        5626 :         move32();
    1743        5626 :         env_fl[2] = L_shl( hq_generic_fenv[3], 7 ); /*Q8*/
    1744        5626 :         move32();
    1745        5626 :         env_fl[3] = L_add( L_mult0( hq_generic_fenv[4], 85 ), L_mult0( hq_generic_fenv[5], 43 ) ); /*Q8*/
    1746        5626 :         move32();
    1747        5626 :         env_fl[4] = L_add( L_mult0( hq_generic_fenv[5], 85 ), L_mult0( hq_generic_fenv[6], 43 ) ); /*Q8*/
    1748        5626 :         move32();
    1749        5626 :         env_fl[5] = L_add( L_mult0( hq_generic_fenv[6], 43 ), L_mult0( hq_generic_fenv[7], 85 ) ); /*Q8*/
    1750        5626 :         move32();
    1751        5626 :         env_fl[6] = L_add( L_mult0( hq_generic_fenv[7], 43 ), L_mult0( hq_generic_fenv[8], 85 ) ); /*Q8*/
    1752        5626 :         move32();
    1753        5626 :         env_fl[7] = L_add( L_mult0( hq_generic_fenv[8], 43 ), L_mult0( hq_generic_fenv[9], 85 ) ); /*Q8*/
    1754        5626 :         move32();
    1755        5626 :         env_fl[8] = L_add( L_mult0( hq_generic_fenv[9], 43 ), L_mult0( hq_generic_fenv[10], 85 ) ); /*Q8*/
    1756        5626 :         move32();
    1757        5626 :         env_fl[9] = L_add( L_mult0( hq_generic_fenv[10], 32 ), L_mult0( hq_generic_fenv[11], 96 ) ); /*Q8*/
    1758        5626 :         move32();
    1759        5626 :         env_fl[10] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
    1760        5626 :         move32();
    1761        5626 :         env_fl[11] = L_shl( hq_generic_fenv[13], 7 ); /*Q8*/
    1762        5626 :         move32();
    1763             :     }
    1764             : 
    1765        5626 :     IF( EQ_16( hqswb_clas, HQ_GEN_FB ) )
    1766             :     {
    1767        4275 :         IF( EQ_16( hq_generic_offset, 144 ) )
    1768             :         {
    1769           0 :             env_fl[9] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
    1770           0 :             move32();
    1771           0 :             env_fl[10] = L_add( L_mult0( hq_generic_fenv[12], 32 ), L_mult0( hq_generic_fenv[13], 96 ) ); /*Q8*/
    1772           0 :             move32();
    1773           0 :             env_fl[11] = L_add( L_mult0( hq_generic_fenv[13], 64 ), L_mult0( hq_generic_fenv[14], 64 ) ); /*Q8*/
    1774           0 :             move32();
    1775           0 :             env_fl[12] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
    1776           0 :             move32();
    1777           0 :             env_fl[13] = env_fl[12]; /*Q8*/
    1778           0 :             move32();
    1779             :         }
    1780             :         ELSE
    1781             :         {
    1782        4275 :             env_fl[12] = L_shl( hq_generic_fenv[14], 7 ); /*Q8*/
    1783        4275 :             move32();
    1784        4275 :             env_fl[13] = L_add( L_mult0( hq_generic_fenv[14], 32 ), L_mult0( hq_generic_fenv[15], 96 ) ); /*Q8*/
    1785        4275 :             move32();
    1786        4275 :             env_fl[14] = L_add( L_mult0( hq_generic_fenv[15], 64 ), L_mult0( hq_generic_fenv[16], 64 ) ); /*Q8*/
    1787        4275 :             move32();
    1788        4275 :             env_fl[15] = L_shl( hq_generic_fenv[16], 7 ); /*Q8*/
    1789        4275 :             move32();
    1790        4275 :             env_fl[16] = env_fl[15]; /*Q8*/
    1791        4275 :             move32();
    1792             :         }
    1793             :     }
    1794             : 
    1795        5626 :     logqnorm_2_fx( env_fl, 40, num_env_bands, nb_sfm, ynrm + num_env_bands, normqlg2 + num_env_bands, thren_fx );
    1796             : 
    1797       94513 :     FOR( i = num_env_bands; i < nb_sfm; ++i )
    1798             :     {
    1799       88887 :         normqlg2[i] = dicnlg2[s_min( add( ynrm[i], 10 ), 39 )]; /*Q0*/
    1800       88887 :         move16();
    1801             :     }
    1802        5626 :     return;
    1803             : }
    1804             : 
    1805           4 : static void update_rsubband_fx( const Word16 nb_sfm, /*Q0*/
    1806             :                                 Word16 *Rsubband,    /* Q3 */
    1807             :                                 Word16 b_add_bits_denv /*Q0*/ )
    1808             : {
    1809             :     Word16 i;
    1810             : 
    1811             :     /* updating bit allocation */
    1812           8 :     WHILE( b_add_bits_denv > 0 )
    1813             :     {
    1814           4 :         i = sub( nb_sfm, 1 );
    1815           4 :         test();
    1816          76 :         WHILE( b_add_bits_denv > 0 && i >= 0 )
    1817             :         {
    1818          72 :             IF( GT_16( Rsubband[i], 24 ) )
    1819             :             {
    1820          40 :                 Rsubband[i] = sub( Rsubband[i], 8 ); /*Q3*/
    1821          40 :                 move16();
    1822          40 :                 b_add_bits_denv = sub( b_add_bits_denv, 1 ); /*Q0*/
    1823             :             }
    1824          72 :             i = sub( i, 1 );
    1825             :         }
    1826             :     }
    1827             : 
    1828           4 :     return;
    1829             : }
    1830             : 
    1831        2789 : Word16 get_nor_delta_hf_fx(
    1832             :     Decoder_State *st,
    1833             :     Word16 *ynrm,               /*Q0*/
    1834             :     Word16 *Rsubband,           /* Q3 */
    1835             :     const Word16 num_env_bands, /*Q0*/
    1836             :     const Word16 nb_sfm,        /*Q0*/
    1837             :     const Word16 core_sfm /*Q0*/ )
    1838             : {
    1839             :     Word16 i;
    1840             :     Word16 delta, bitsforDelta, add_bits_denv;
    1841             : 
    1842        2789 :     add_bits_denv = 0;
    1843        2789 :     move16();
    1844        2789 :     IF( GE_16( core_sfm, num_env_bands ) )
    1845             :     {
    1846           3 :         bitsforDelta = (Word16) get_next_indice_fx( st, 2 ); /*Q0*/
    1847           3 :         bitsforDelta = add( bitsforDelta, 2 );
    1848           3 :         add_bits_denv = add( add_bits_denv, 2 );
    1849             : 
    1850          39 :         FOR( i = num_env_bands; i < nb_sfm; ++i )
    1851             :         {
    1852          36 :             IF( Rsubband[i] != 0 )
    1853             :             {
    1854          11 :                 delta = (Word16) get_next_indice_fx( st, bitsforDelta );                      /*Q0*/
    1855          11 :                 ynrm[i] = add( ynrm[i], sub( delta, ( shl( 1, sub( bitsforDelta, 1 ) ) ) ) ); /*Q0*/
    1856          11 :                 move16();
    1857             : 
    1858             :                 /* safety check in case of bit errors */
    1859          11 :                 test();
    1860          11 :                 IF( ynrm[i] < 0 || GT_16( ynrm[i], 39 ) )
    1861             :                 {
    1862           0 :                     ynrm[i] = 39;
    1863           0 :                     move16();
    1864           0 :                     st->BER_detect = 1;
    1865           0 :                     move16();
    1866             :                 }
    1867             :                 /*ynrm[i] += delta - (1<<(bitsforDelta-1));*/
    1868          11 :                 add_bits_denv = add( add_bits_denv, bitsforDelta );
    1869             :             }
    1870             :         }
    1871           3 :         update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
    1872             :     }
    1873        2789 :     return add_bits_denv;
    1874             : }
    1875             : /*-------------------------------------------------------------------*
    1876             :  * calc_nor_delta_hf()
    1877             :  *
    1878             :  *
    1879             :  *--------------------------------------------------------------------------*/
    1880        2805 : Word16 calc_nor_delta_hf_ivas_fx(
    1881             :     BSTR_ENC_HANDLE hBstr,      /* i/o: encoder bitstream handle       */
    1882             :     const Word32 *t_audio,      /* i  : transform-domain coefficients Qx*/
    1883             :     Word16 *ynrm,               /* i/o: norm indices                   Q0*/
    1884             :     Word16 *Rsubband,           /* i/o: sub-band bit allocation        Q0*/
    1885             :     const Word16 num_env_bands, /* i  : Number coded envelope bands    Q0*/
    1886             :     const Word16 nb_sfm,        /* i  : Number of envelope bands       Q0*/
    1887             :     const Word16 *sfmsize,      /* i  : band length                    Q0*/
    1888             :     const Word16 *sfm_start,    /* i  : Start index of bands           Q0*/
    1889             :     const Word16 core_sfm       /* i  : index of the end band for core Q0*/
    1890             : )
    1891             : {
    1892             :     Word16 i;
    1893             :     Word16 ynrm_t[44], normqlg2_t[44];
    1894             :     Word16 delta, max_delta, min_delta, bitsforDelta, add_bits_denv;
    1895             : 
    1896        2805 :     max_delta = -100;
    1897        2805 :     move16();
    1898        2805 :     calc_norm_fx( t_audio, 12, ynrm_t, normqlg2_t, 0, nb_sfm, sfmsize, sfm_start );
    1899        2805 :     add_bits_denv = 0;
    1900        2805 :     move16();
    1901       47490 :     FOR( i = num_env_bands; i < nb_sfm; ++i )
    1902             :     {
    1903       44685 :         IF( Rsubband[i] != 0 )
    1904             :         {
    1905           0 :             delta = sub( ynrm_t[i], ynrm[i] ); /*Q0*/
    1906           0 :             IF( delta > 0 )
    1907             :             {
    1908           0 :                 delta = add( delta, 1 ); /*Q0*/
    1909             :             }
    1910             :             ELSE
    1911             :             {
    1912           0 :                 delta = negate( delta ); /*Q0*/
    1913             :             }
    1914           0 :             if ( GT_16( delta, max_delta ) )
    1915             :             {
    1916           0 :                 max_delta = delta; /*Q0*/
    1917           0 :                 move16();
    1918             :             }
    1919             :         }
    1920             :     }
    1921        2805 :     IF( GE_16( core_sfm, num_env_bands ) )
    1922             :     {
    1923           0 :         IF( LT_16( max_delta, 16 ) )
    1924             :         {
    1925           0 :             bitsforDelta = 2;
    1926           0 :             move16();
    1927           0 :             FOR( ; max_delta >= 2; max_delta >>= 1 )
    1928             :             {
    1929           0 :                 bitsforDelta = add( bitsforDelta, 1 ); /*Q0*/
    1930             :             }
    1931             :         }
    1932             :         ELSE
    1933             :         {
    1934           0 :             bitsforDelta = 5;
    1935           0 :             move16();
    1936             :         }
    1937           0 :         max_delta = sub( shl( 1, sub( bitsforDelta, 1 ) ), 1 ); /*Q0*/
    1938           0 :         min_delta = negate( add( max_delta, 1 ) );              /*Q0*/
    1939             : 
    1940             :         /* updating norm & storing delta norm */
    1941           0 :         add_bits_denv = 2;
    1942           0 :         move16();
    1943           0 :         push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 );
    1944           0 :         FOR( i = num_env_bands; i < nb_sfm; ++i )
    1945             :         {
    1946           0 :             IF( Rsubband[i] != 0 )
    1947             :             {
    1948           0 :                 delta = sub( ynrm_t[i], ynrm[i] );
    1949           0 :                 IF( GT_16( delta, max_delta ) )
    1950             :                 {
    1951           0 :                     delta = max_delta; /*Q0*/
    1952           0 :                     move16();
    1953             :                 }
    1954           0 :                 ELSE IF( LT_16( delta, min_delta ) )
    1955             :                 {
    1956           0 :                     delta = min_delta; /*Q0*/
    1957           0 :                     move16();
    1958             :                 }
    1959           0 :                 push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta );
    1960           0 :                 ynrm[i] = add( ynrm[i], delta ); /*Q0*/
    1961           0 :                 move16();
    1962           0 :                 add_bits_denv = add( add_bits_denv, bitsforDelta );
    1963             :             }
    1964             :         }
    1965             : 
    1966             :         /* updating bit allocation */
    1967           0 :         update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
    1968             :     }
    1969        2805 :     return add_bits_denv;
    1970             : }
    1971             : /*-------------------------------------------------------------------*
    1972             :  * calc_nor_delta_hf()
    1973             :  *
    1974             :  *
    1975             :  *--------------------------------------------------------------------------*/
    1976          32 : Word16 calc_nor_delta_hf_fx(
    1977             :     BSTR_ENC_HANDLE hBstr,      /* i/o: encoder bitstream handle       */
    1978             :     const Word32 *t_audio,      /* i  : transform-domain coefficients  Qx*/
    1979             :     Word16 *ynrm,               /* i/o: norm indices                   Q0*/
    1980             :     Word16 *Rsubband,           /* i/o: sub-band bit allocation        Q0*/
    1981             :     const Word16 num_env_bands, /* i  : Number coded envelope bands    Q0*/
    1982             :     const Word16 nb_sfm,        /* i  : Number of envelope bands       Q0*/
    1983             :     const Word16 *sfmsize,      /* i  : band length                    Q0*/
    1984             :     const Word16 *sfm_start,    /* i  : Start index of bands           Q0*/
    1985             :     const Word16 core_sfm       /* i  : index of the end band for core Q0*/
    1986             : )
    1987             : {
    1988             :     Word16 i;
    1989             :     Word16 ynrm_t[44], normqlg2_t[44];
    1990             :     Word16 delta, max_delta, min_delta, bitsforDelta, add_bits_denv;
    1991             : 
    1992          32 :     max_delta = -100;
    1993          32 :     move16();
    1994          32 :     calc_norm_fx( t_audio, 12, ynrm_t, normqlg2_t, 0, nb_sfm, sfmsize, sfm_start );
    1995          32 :     add_bits_denv = 0;
    1996          32 :     move16();
    1997         416 :     FOR( i = num_env_bands; i < nb_sfm; ++i )
    1998             :     {
    1999         384 :         IF( Rsubband[i] != 0 )
    2000             :         {
    2001           5 :             delta = sub( ynrm_t[i], ynrm[i] );
    2002           5 :             IF( delta > 0 )
    2003             :             {
    2004           0 :                 delta = add( delta, 1 ); /*Q0*/
    2005             :             }
    2006             :             ELSE
    2007             :             {
    2008           5 :                 delta = negate( delta ); /*Q0*/
    2009             :             }
    2010           5 :             if ( GT_16( delta, max_delta ) )
    2011             :             {
    2012           1 :                 max_delta = delta; /*Q0*/
    2013           1 :                 move16();
    2014             :             }
    2015             :         }
    2016             :     }
    2017          32 :     IF( GE_16( core_sfm, num_env_bands ) )
    2018             :     {
    2019           1 :         IF( LT_16( max_delta, 16 ) )
    2020             :         {
    2021           1 :             bitsforDelta = 2;
    2022           1 :             move16();
    2023           1 :             FOR( ; max_delta >= 2; max_delta >>= 1 )
    2024             :             {
    2025           0 :                 bitsforDelta = add( bitsforDelta, 1 ); /*Q0*/
    2026             :             }
    2027             :         }
    2028             :         ELSE
    2029             :         {
    2030           0 :             bitsforDelta = 5;
    2031           0 :             move16();
    2032             :         }
    2033           1 :         max_delta = sub( shl( 1, sub( bitsforDelta, 1 ) ), 1 ); /*Q0*/
    2034           1 :         min_delta = negate( add( max_delta, 1 ) );              /*Q0*/
    2035             : 
    2036             :         /* updating norm & storing delta norm */
    2037           1 :         add_bits_denv = 2;
    2038           1 :         move16();
    2039           1 :         push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 );
    2040          13 :         FOR( i = num_env_bands; i < nb_sfm; ++i )
    2041             :         {
    2042          12 :             IF( Rsubband[i] != 0 )
    2043             :             {
    2044           5 :                 delta = sub( ynrm_t[i], ynrm[i] ); /*Q0*/
    2045           5 :                 IF( GT_16( delta, max_delta ) )
    2046             :                 {
    2047           0 :                     delta = max_delta; /*Q0*/
    2048           0 :                     move16();
    2049             :                 }
    2050           5 :                 ELSE IF( LT_16( delta, min_delta ) )
    2051             :                 {
    2052           0 :                     delta = min_delta; /*Q0*/
    2053           0 :                     move16();
    2054             :                 }
    2055           5 :                 push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta );
    2056           5 :                 ynrm[i] = add( ynrm[i], delta ); /*Q0*/
    2057           5 :                 move16();
    2058           5 :                 add_bits_denv = add( add_bits_denv, bitsforDelta );
    2059             :             }
    2060             :         }
    2061             : 
    2062             :         /* updating bit allocation */
    2063           1 :         update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
    2064             :     }
    2065          32 :     return add_bits_denv;
    2066             : }
    2067             : 
    2068             : 
    2069             : /*-------------------------------------------------------------------*
    2070             :  * hq_bwe_fx()
    2071             :  *
    2072             :  * HQ GENERIC
    2073             :  *--------------------------------------------------------------------------*/
    2074          46 : void hq_bwe_fx(
    2075             :     const Word16 HQ_mode,             /* i  : HQ mode                                     Q0*/
    2076             :     Word32 *coeff_out1,               /* i/o: BWE input & temporary buffer                Q12*/
    2077             :     const Word16 *hq_generic_fenv,    /* i  : SWB frequency envelopes                     Q1*/
    2078             :     Word32 *coeff_out,                /* o  : SWB signal in MDCT domain                   Q12*/
    2079             :     const Word16 hq_generic_offset,   /* i  : frequency offset for representing hq generic Q0*/
    2080             :     Word16 *prev_L_swb_norm,          /* i/o: last normalize length                       Q0*/
    2081             :     const Word16 hq_generic_exc_clas, /* i  : hq generic hf excitation class              Q0*/
    2082             :     const Word16 *sfm_end,            /* i  : End of bands                                Q0*/
    2083             :     const Word16 num_sfm,             /* i  : Number of bands                             Q0*/
    2084             :     const Word16 num_env_bands,       /* i  : Number of coded envelope bands              Q0*/
    2085             :     const Word16 *R                   /* i  : Bit allocation                              Q0*/
    2086             : )
    2087             : {
    2088             :     Word16 n_swb_overlap_offset, n_swb_overlap;
    2089             :     Word32 hq_swb_overlap_buf_fx[L_FRAME32k];
    2090             : 
    2091          46 :     n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset );
    2092          46 :     n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/
    2093             : 
    2094             : 
    2095          46 :     Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/
    2096             : 
    2097          46 :     hq_generic_decoding_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R );
    2098             : 
    2099          46 :     overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end );
    2100             : 
    2101          46 :     return;
    2102             : }
    2103             : 
    2104        2743 : void hq_bwe_ivas_fx(
    2105             :     const Word16 HQ_mode,             /* i  : HQ mode                                     Q0*/
    2106             :     Word32 *coeff_out1,               /* i/o: BWE input & temporary buffer                Q12*/
    2107             :     const Word16 *hq_generic_fenv,    /* i  : SWB frequency envelopes                     Q1*/
    2108             :     Word32 *coeff_out,                /* o  : SWB signal in MDCT domain                   Q12*/
    2109             :     const Word16 hq_generic_offset,   /* i  : frequency offset for representing hq generic Q0*/
    2110             :     Word16 *prev_L_swb_norm,          /* i/o: last normalize length                       Q0*/
    2111             :     const Word16 hq_generic_exc_clas, /* i  : hq generic hf excitation class              Q0*/
    2112             :     const Word16 *sfm_end,            /* i  : End of bands                                Q0*/
    2113             :     const Word16 num_sfm,             /* i  : Number of bands                             Q0*/
    2114             :     const Word16 num_env_bands,       /* i  : Number of coded envelope bands              Q0*/
    2115             :     const Word16 *R                   /* i  : Bit allocation                              Q0*/
    2116             : )
    2117             : {
    2118             :     Word16 n_swb_overlap_offset, n_swb_overlap;
    2119             :     Word32 hq_swb_overlap_buf_fx[L_FRAME32k];
    2120             : 
    2121        2743 :     n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset );
    2122        2743 :     n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/
    2123             : 
    2124             : 
    2125        2743 :     Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/
    2126             : 
    2127        2743 :     hq_generic_decoding_ivas_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R );
    2128             : 
    2129        2743 :     overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end );
    2130             : 
    2131        2743 :     return;
    2132             : }
    2133             : 
    2134             : /*--------------------------------------------------------------------------*
    2135             :  * hq_wb_nf_bwe()
    2136             :  *
    2137             :  * HQ WB noisefill and BWE
    2138             :  *--------------------------------------------------------------------------*/
    2139             : 
    2140         476 : void hq_wb_nf_bwe_fx(
    2141             :     const Word16 *coeff_fx,         /* i  : coded/noisefilled normalized spectrum Q12*/
    2142             :     const Word16 is_transient,      /*Q0*/
    2143             :     const Word16 prev_bfi,          /* i  : previous bad frame indicator    Q0*/
    2144             :     const Word32 *L_normq_v,        /*Q14*/
    2145             :     const Word16 num_sfm,           /* i  : Number of subbands              Q0*/
    2146             :     const Word16 *sfm_start,        /* i  : Subband start coefficient       Q0*/
    2147             :     const Word16 *sfm_end,          /* i  : Subband end coefficient         Q0*/
    2148             :     const Word16 *sfmsize,          /* i  : Subband band width              Q0*/
    2149             :     const Word16 last_sfm,          /* i  : last coded subband              Q0*/
    2150             :     const Word16 *R,                /* i  : bit allocation                  Q0*/
    2151             :     const Word16 prev_is_transient, /* i  : previous transient flag         Q0*/
    2152             :     Word32 *prev_normq_fx,          /* i/o: previous norms                  Q14*/
    2153             :     Word32 *prev_env_fx,            /* i/o: previous noise envelopes        prev_env_Q*/
    2154             :     Word16 *bwe_seed,               /* i/o: random seed for generating BWE input Q0*/
    2155             :     Word32 *prev_coeff_out_fx,      /* i/o: decoded spectrum in previous frame Q12*/
    2156             :     Word16 *prev_R,                 /* i/o: bit allocation info. in previous frame Q0*/
    2157             :     Word32 *L_coeff_out,            /* o  : coded/noisefilled spectrum      Q12*/
    2158             :     Word16 *prev_env_Q )
    2159             : {
    2160             :     Word16 i;
    2161             :     Word16 sfm;
    2162             :     Word16 total_bit;
    2163             :     Word16 num;
    2164             :     Word32 env_fx, peak_fx, fabs_coeff_out_fx, min_coef_fx;
    2165         476 :     Word32 L_tmp1, L_tmp2 = 0, L_tmp3, L_tmp4;
    2166         476 :     move32();
    2167         476 :     Word16 tmp1, exp = 0, exp1, exp2, exp3, harm_para_fx, sharp_fx, step_fx, alfa_fx = 4096;
    2168         476 :     move16();
    2169         476 :     move16();
    2170             :     Word32 avrg_norm_fx, prev_avrg_norm_fx;
    2171             :     Word16 bitalloc_var_fx;
    2172             :     Word16 tmp;
    2173             :     Word32 L_tmp;
    2174             :     Word32 mean_fx;
    2175             : 
    2176         476 :     IF( is_transient == 0 )
    2177             :     {
    2178         465 :         IF( EQ_16( prev_bfi, 1 ) )
    2179             :         {
    2180           4 :             Copy32( L_normq_v, prev_normq_fx, SFM_N_WB ); /*Q14*/
    2181             :         }
    2182             : 
    2183             :         /* the variance of bit allocation */
    2184         465 :         total_bit = 0;
    2185         465 :         bitalloc_var_fx = 0;
    2186         465 :         move16();
    2187         465 :         move16();
    2188             : 
    2189        8117 :         FOR( sfm = 8; sfm <= last_sfm; sfm++ )
    2190             :         {
    2191        7652 :             tmp = abs_s( sub( R[sfm], R[( sfm - 1 )] ) ); /*Q0*/
    2192        7652 :             bitalloc_var_fx = add( bitalloc_var_fx, tmp );
    2193        7652 :             total_bit = add( total_bit, R[sfm] ); /*Q0*/
    2194             :         }
    2195         465 :         test();
    2196         465 :         IF( GT_16( last_sfm, 8 ) && total_bit > 0 )
    2197             :         {
    2198         458 :             exp = norm_s( total_bit );
    2199         458 :             tmp = shl( total_bit, exp );                               /*Q(exp) */
    2200         458 :             tmp = div_s( 16384, tmp );                                 /*Q(15+14-exp) */
    2201         458 :             L_tmp = L_mult( tmp, bitalloc_var_fx );                    /*Q(29-exp+1) */
    2202         458 :             bitalloc_var_fx = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q14 */
    2203             :         }
    2204             :         ELSE
    2205             :         {
    2206           7 :             bitalloc_var_fx = 0; /*Q14 */
    2207           7 :             move16();
    2208             :         }
    2209             :         /* calculate the peak-average ratio of saturable subbands */
    2210         465 :         num = 0;
    2211         465 :         move16();
    2212         465 :         sharp_fx = 0;
    2213         465 :         move16();
    2214        8117 :         FOR( sfm = last_sfm; sfm >= 8; sfm-- )
    2215             :         {
    2216        7652 :             tmp = shl( sfmsize[sfm], 9 );   /*Q9 */
    2217        7652 :             tmp = mult( rat_fx[sfm], tmp ); /*Q(14+9-15=8) */
    2218        7652 :             IF( GE_16( shl_sat( R[sfm], 8 ), tmp ) )
    2219             :             {
    2220        2407 :                 peak_fx = 0;
    2221        2407 :                 move16();
    2222        2407 :                 mean_fx = 0;
    2223        2407 :                 move16();
    2224       27703 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2225             :                 {
    2226       25296 :                     fabs_coeff_out_fx = L_abs( L_coeff_out[i] );       /*Q12*/
    2227       25296 :                     mean_fx = L_add_sat( mean_fx, fabs_coeff_out_fx ); /*Q12 */
    2228       25296 :                     if ( GT_32( fabs_coeff_out_fx, peak_fx ) )
    2229             :                     {
    2230        4470 :                         peak_fx = fabs_coeff_out_fx; /*Q12 */
    2231        4470 :                         move32();
    2232             :                     }
    2233             :                 }
    2234             : 
    2235        2407 :                 IF( mean_fx != 0 )
    2236             :                 {
    2237        2407 :                     exp = norm_l( mean_fx );
    2238        2407 :                     mean_fx = L_shl_sat( mean_fx, exp );   /*Q(exp+12) */
    2239        2407 :                     tmp = round_fx_sat( mean_fx );         /*Q(exp-4) */
    2240        2407 :                     tmp = div_s( 16384, tmp );             /*Q(15+14-exp+4 = 33-exp) */
    2241        2407 :                     L_tmp = Mult_32_16( peak_fx, tmp );    /*Q(12+33-exp-15 = 30-exp) */
    2242        2407 :                     tmp = shl( sfmsize[sfm], 9 );          /*Q9 */
    2243        2407 :                     L_tmp = Mult_32_16( L_tmp, tmp );      /*Q(30-exp+9-15 = 24-exp) */
    2244        2407 :                     tmp = round_fx( L_shl( L_tmp, exp ) ); /*Q8   */
    2245        2407 :                     sharp_fx = add( sharp_fx, tmp );
    2246             :                 }
    2247        2407 :                 num = add( num, 1 );
    2248             :             }
    2249             :         }
    2250         465 :         test();
    2251         465 :         IF( num != 0 && sharp_fx != 0 )
    2252             :         {
    2253         448 :             num = add( num, num );
    2254         448 :             exp = norm_s( sharp_fx );
    2255         448 :             sharp_fx = shl( sharp_fx, exp );                      /*Q(8+exp) */
    2256         448 :             tmp = div_s( 16384, sharp_fx );                       /*Q(21-exp) */
    2257         448 :             L_tmp = L_mult( num, tmp );                           /*Q(22-exp) */
    2258         448 :             sharp_fx = round_fx( L_shl( L_tmp, add( 8, exp ) ) ); /*Q14 */
    2259             :         }
    2260             :         ELSE
    2261             :         {
    2262          17 :             sharp_fx = 16384; /*Q14 = 1 */
    2263          17 :             move16();
    2264             :         }
    2265         465 :         harm_para_fx = sharp_fx; /*Q14 */
    2266         465 :         move16();
    2267             : 
    2268         465 :         IF( last_sfm == 0 )
    2269             :         {
    2270           0 :             tmp = 0;
    2271           0 :             move16();
    2272             :         }
    2273             :         ELSE
    2274             :         {
    2275         465 :             tmp = div_s( 1, last_sfm ); /*Q15 */
    2276             :         }
    2277             : 
    2278         465 :         L_tmp = L_mult( 5, sharp_fx );                    /*Q15 */
    2279         465 :         L_tmp = Mult_32_16( L_tmp, tmp );                 /*Q15 */
    2280         465 :         step_fx = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Q15  */
    2281         465 :         alfa_fx = 20480;                                  /*Q13 = 2.5 */
    2282         465 :         move16();
    2283             :         /* fill noise for the insaturable subbands */
    2284       12555 :         FOR( sfm = 0; sfm < num_sfm; sfm++ )
    2285             :         {
    2286       12090 :             env_fx = L_deposit_l( 0 );
    2287       12090 :             L_tmp2 = L_deposit_l( 0 );
    2288       12090 :             exp = 0;
    2289       12090 :             move16();
    2290       12090 :             test();
    2291       12090 :             IF( R[sfm] != 0 && LT_16( R[sfm], shl( mult( 24756, sfmsize[sfm] ), 1 ) ) )
    2292             :             {
    2293             :                 /* calculate the energy of the undecoded coefficients */
    2294        5497 :                 env_fx = L_deposit_l( 0 );
    2295        5497 :                 exp1 = norm_l( L_normq_v[sfm] );
    2296        5497 :                 L_tmp4 = L_shl( L_normq_v[sfm], exp1 ); /*14+exp1 */
    2297        5497 :                 L_tmp1 = Mult_32_32( L_tmp4, L_tmp4 );  /*2*exp1-3   14+exp1+14+exp1 -31  */
    2298        5497 :                 L_tmp2 = L_deposit_l( 0 );
    2299        5497 :                 peak_fx = L_deposit_l( 0 );
    2300        5497 :                 min_coef_fx = 0x7fffffff; /*Q31*/
    2301        5497 :                 move32();
    2302             : 
    2303       84305 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2304             :                 {
    2305       78808 :                     fabs_coeff_out_fx = L_abs( L_coeff_out[i] ); /*Q12*/
    2306       78808 :                     test();
    2307       78808 :                     if ( LT_32( fabs_coeff_out_fx, min_coef_fx ) && L_coeff_out[i] != 0 )
    2308             :                     {
    2309        7539 :                         min_coef_fx = fabs_coeff_out_fx; /*Q12*/
    2310        7539 :                         move32();
    2311             :                     }
    2312       78808 :                     if ( GT_32( fabs_coeff_out_fx, peak_fx ) )
    2313             :                     {
    2314        7441 :                         peak_fx = fabs_coeff_out_fx; /*Q12*/
    2315        7441 :                         move32();
    2316             :                     }
    2317             :                 }
    2318             : 
    2319        5497 :                 exp2 = norm_l( peak_fx );
    2320       84305 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2321             :                 {
    2322       78808 :                     L_tmp4 = L_shl( L_coeff_out[i], exp2 );            /*12+exp2 */
    2323       78808 :                     L_tmp3 = L_shr( Mult_32_32( L_tmp4, L_tmp4 ), 4 ); /*2*exp2-7-4    12+exp2+12+exp2-31-4   */
    2324       78808 :                     L_tmp2 = L_add( L_tmp2, L_tmp3 );                  /*2*exp2-11 */
    2325             :                 }
    2326             : 
    2327        5497 :                 tmp1 = div_s( 1, sfmsize[sfm] );     /*15  */
    2328        5497 :                 L_tmp4 = Mult_32_16( L_tmp2, tmp1 ); /*2*exp2-11   2*exp2-7+15+1-16              */
    2329             : 
    2330        5497 :                 exp = norm_l( L_tmp1 );
    2331        5497 :                 L_tmp1 = L_shl( L_tmp1, exp ); /*exp + 2*exp1 - 3 */
    2332        5497 :                 exp1 = sub( add( exp, shl( exp1, 1 ) ), 3 );
    2333             : 
    2334        5497 :                 exp = norm_l( L_tmp4 );
    2335        5497 :                 L_tmp4 = L_shl( L_tmp4, exp ); /*exp + 2*exp1 - 3 */
    2336        5497 :                 exp2 = sub( add( exp, shl( exp2, 1 ) ), 11 );
    2337        5497 :                 exp = s_min( exp1, exp2 );
    2338             : 
    2339        5497 :                 L_tmp1 = L_shl( L_tmp1, sub( exp, exp1 ) );
    2340        5497 :                 L_tmp4 = L_shl( L_tmp4, sub( exp, exp2 ) );
    2341        5497 :                 env_fx = L_sub( L_tmp1, L_tmp4 ); /*exp */
    2342        5497 :                 exp1 = norm_l( env_fx );
    2343        5497 :                 env_fx = L_shl( env_fx, exp1 ); /*exp + exp1 */
    2344        5497 :                 exp = add( exp, exp1 );
    2345             : 
    2346        5497 :                 IF( env_fx > 0 )
    2347             :                 {
    2348        5497 :                     IF( sfm == 0 )
    2349             :                     {
    2350         160 :                         avrg_norm_fx = L_add( L_shr( L_normq_v[0], 1 ), L_shr( L_normq_v[1], 1 ) );              /*13 */
    2351         160 :                         avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[2], 1 ) );                          /*13                      */
    2352         160 :                         prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[0], 1 ), L_shr( prev_normq_fx[1], 1 ) ); /*13 */
    2353         160 :                         prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[2], 1 ) );            /*13 */
    2354             :                     }
    2355        5337 :                     ELSE IF( EQ_16( sfm, 25 ) )
    2356             :                     {
    2357         299 :                         avrg_norm_fx = L_add( L_shr( L_normq_v[23], 1 ), L_shr( L_normq_v[24], 1 ) );              /*13 */
    2358         299 :                         avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[25], 1 ) );                           /*13 */
    2359         299 :                         prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[23], 1 ), L_shr( prev_normq_fx[24], 1 ) ); /*13 */
    2360         299 :                         prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[25], 1 ) );             /*13 */
    2361             :                     }
    2362             :                     ELSE
    2363             :                     {
    2364        5038 :                         avrg_norm_fx = L_add( L_shr( L_normq_v[( sfm - 1 )], 1 ), L_shr( L_normq_v[sfm], 1 ) );              /*13 */
    2365        5038 :                         avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[sfm + 1], 1 ) );                                /*13 */
    2366        5038 :                         prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[( sfm - 1 )], 1 ), L_shr( prev_normq_fx[sfm], 1 ) ); /*13 */
    2367        5038 :                         prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[( sfm + 1 )], 1 ) );              /*13 */
    2368             :                     }
    2369             : 
    2370        5497 :                     test();
    2371        5497 :                     test();
    2372        5497 :                     IF( ( GT_16( bitalloc_var_fx, 4915 ) || LT_32( L_normq_v[sfm], peak_fx ) ) && peak_fx != 0 )
    2373        5401 :                     {
    2374             :                         Word16 exp_p;
    2375        5401 :                         exp_p = norm_l( peak_fx );
    2376        5401 :                         exp = sub( 31, exp );
    2377        5401 :                         env_fx = Isqrt_lc( env_fx, &exp );                      /*Q31 - exp*/
    2378        5401 :                         L_tmp1 = Mult_32_32( env_fx, L_shl( peak_fx, exp_p ) ); /*12+exp2-exp  31-exp+12+exp1-31  */
    2379        5401 :                         L_tmp2 = Mult_32_16( avrg_norm_fx, harm_para_fx );      /*12 13 + 14 + 1 -16 */
    2380        5401 :                         exp1 = norm_l( L_tmp1 );
    2381        5401 :                         L_tmp1 = L_shl( L_tmp1, exp1 ); /* 12+exp2-exp+exp1 */
    2382        5401 :                         exp = add( sub( 12, exp ), add( exp1, exp_p ) );
    2383        5401 :                         L_tmp2 = Div_32( L_tmp2, extract_h( L_tmp1 ), extract_l( L_tmp1 ) ); /*Q31 - (43-exp)*/
    2384        5401 :                         exp = sub( 43, exp );
    2385             :                     }
    2386             :                     ELSE
    2387             :                     {
    2388          96 :                         L_tmp1 = Mult_32_16( L_normq_v[sfm], alfa_fx ); /*12 13 + 14 + 1 -16 */
    2389          96 :                         IF( LT_32( L_tmp1, peak_fx ) )
    2390             :                         {
    2391           1 :                             exp = sub( 31, exp );
    2392           1 :                             env_fx = Isqrt_lc( env_fx, &exp ); /*Q31 - exp*/
    2393           1 :                             exp1 = norm_l( env_fx );
    2394           1 :                             env_fx = L_shl( env_fx, exp1 ); /* 31-exp+exp1 */
    2395           1 :                             exp = add( sub( 31, exp ), exp1 );
    2396           1 :                             L_tmp1 = L_deposit_l( sharp_fx );                                    /*Q14*/
    2397           1 :                             L_tmp2 = Div_32( L_tmp1, extract_h( env_fx ), extract_l( env_fx ) ); /* 45-exp 14 - exp + 31 //39-exp 8 - exp + 31 */
    2398           1 :                             exp = sub( 45, exp );
    2399           1 :                             exp1 = norm_l( peak_fx );
    2400           1 :                             L_tmp1 = L_shl( peak_fx, exp1 );                                     /*12 + exp1 */
    2401           1 :                             L_tmp1 = Div_32( L_tmp2, extract_h( L_tmp1 ), extract_l( L_tmp1 ) ); /*  exp - (12 + exp1) +31 */
    2402           1 :                             L_tmp2 = Mult_32_32( L_tmp2, L_tmp1 );                               /*2*exp+exp1-12    exp +exp - (12 + exp1) +31 - 31 */
    2403           1 :                             exp = sub( add( shl( exp, 1 ), exp1 ), 12 );
    2404             :                         }
    2405             :                         ELSE
    2406             :                         {
    2407          95 :                             exp = sub( 31, exp );
    2408          95 :                             env_fx = Isqrt_lc( env_fx, &exp ); /*Q31 - exp*/
    2409          95 :                             exp1 = norm_l( env_fx );
    2410          95 :                             env_fx = L_shl( env_fx, exp1 ); /* 31-exp+exp1 */
    2411          95 :                             exp = add( sub( 31, exp ), exp1 );
    2412          95 :                             L_tmp1 = L_deposit_l( sharp_fx );                                    /*Q14*/
    2413          95 :                             L_tmp2 = Div_32( L_tmp1, extract_h( env_fx ), extract_l( env_fx ) ); /* 45-exp 14 - exp + 31  //39-exp 8 - exp + 31  */
    2414          95 :                             exp = sub( 45, exp );
    2415             :                         }
    2416             : 
    2417          96 :                         sharp_fx = add_sat( sharp_fx, shr( step_fx, 1 ) ); /*Q14*/
    2418             :                     }
    2419             : 
    2420        5497 :                     IF( GT_32( L_tmp2, L_shl_sat( min_coef_fx, sub( exp, 13 ) ) ) ) /*exp  */
    2421             :                     {
    2422        2380 :                         L_tmp2 = L_shr( min_coef_fx, 1 );
    2423        2380 :                         exp = 12;
    2424        2380 :                         move16();
    2425             :                     }
    2426             : 
    2427        5497 :                     IF( EQ_16( prev_bfi, 1 ) )
    2428             :                     {
    2429          45 :                         prev_env_Q[sfm] = exp;
    2430          45 :                         move16();
    2431          45 :                         prev_env_fx[sfm] = L_tmp2;
    2432          45 :                         move32();
    2433             :                     }
    2434             :                     /* smooth the noise magnitudes between inter-frame */
    2435        5497 :                     test();
    2436        5497 :                     test();
    2437        5497 :                     IF( GT_32( prev_avrg_norm_fx, L_shr( avrg_norm_fx, 1 ) ) && LT_32( prev_avrg_norm_fx, L_shl_sat( avrg_norm_fx, 1 ) ) && prev_is_transient == 0 )
    2438             :                     {
    2439        3100 :                         exp1 = norm_l( prev_env_fx[sfm] );
    2440        3100 :                         L_tmp1 = L_shl( prev_env_fx[sfm], exp1 ); /* prev_env_Q[sfm] +exp1 */
    2441             : 
    2442        3100 :                         exp2 = norm_l( L_tmp2 );
    2443        3100 :                         L_tmp3 = L_shl( L_tmp2, exp2 ); /* exp +exp2 */
    2444        3100 :                         exp3 = s_min( add( prev_env_Q[sfm], exp1 ), add( exp, exp2 ) );
    2445             : 
    2446        3100 :                         L_tmp1 = L_shl( L_tmp1, sub( sub( exp3, prev_env_Q[sfm] ), exp1 ) ); /*exp3 */
    2447        3100 :                         L_tmp3 = L_shl( L_tmp3, sub( sub( exp3, exp ), exp2 ) );             /*exp3 */
    2448        3100 :                         L_tmp2 = L_add( L_shr( L_tmp1, 1 ), L_shr( L_tmp3, 1 ) );            /*exp3 */
    2449        3100 :                         exp = exp3;
    2450        3100 :                         move16();
    2451             :                     }
    2452       84305 :                     FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2453             :                     {
    2454       78808 :                         IF( coeff_fx[i] == 0 )
    2455             :                         {
    2456       65593 :                             tmp1 = Random( bwe_seed );                /*Q15 */
    2457       65593 :                             L_tmp1 = Mult_32_16( L_tmp2, tmp1 );      /*exp   exp+15+1 -16 */
    2458       65593 :                             L_tmp1 = L_shl( L_tmp1, sub( 12, exp ) ); /*Q12*/
    2459       65593 :                             L_coeff_out[i] = L_tmp1;                  /*Q12*/
    2460       65593 :                             move32();
    2461             :                         }
    2462             :                     }
    2463             :                 }
    2464             :                 ELSE
    2465             :                 {
    2466           0 :                     exp = 0;
    2467           0 :                     move16();
    2468           0 :                     L_tmp2 = L_deposit_l( 0 );
    2469             :                 }
    2470             :             }
    2471        6593 :             ELSE IF( R[sfm] == 0 )
    2472             :             {
    2473             :                 /* fill random noise for 0 bit subbands */
    2474       36188 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2475             :                 {
    2476       34008 :                     IF( coeff_fx[i] == 0 )
    2477             :                     {
    2478       16919 :                         tmp1 = Random( bwe_seed );                   /*Q15 */
    2479       16919 :                         L_tmp1 = Mult_32_16( L_normq_v[sfm], tmp1 ); /*14   14+15+1 -16 */
    2480       16919 :                         L_tmp1 = L_shr( L_tmp1, 2 );                 /*Q12 */
    2481       16919 :                         L_coeff_out[i] = L_tmp1;                     /*Q12*/
    2482       16919 :                         move32();
    2483             :                     }
    2484             :                 }
    2485        2180 :                 L_tmp2 = L_normq_v[sfm]; /*Q14*/
    2486        2180 :                 move32();
    2487        2180 :                 exp = 14;
    2488        2180 :                 move16();
    2489             :             }
    2490             : 
    2491       12090 :             test();
    2492       12090 :             test();
    2493       12090 :             test();
    2494       12090 :             test();
    2495       12090 :             IF( EQ_16( sfm, sub( SFM_N_WB, 1 ) ) && prev_is_transient == 0 && GT_32( prev_normq_fx[sfm], L_shr( L_normq_v[sfm], 1 ) ) && LT_32( prev_normq_fx[sfm], L_shl_sat( L_normq_v[sfm], 1 ) ) && LE_16( bitalloc_var_fx, 4915 ) )
    2496             :             {
    2497           0 :                 Word32 *p_prev_coeff_out = prev_coeff_out_fx; /*Q12*/
    2498           0 :                 FOR( i = add( sfm_start[sfm], 12 ); i < sfm_end[sfm]; i++ )
    2499             :                 {
    2500           0 :                     test();
    2501           0 :                     test();
    2502           0 :                     test();
    2503           0 :                     test();
    2504           0 :                     IF( GT_32( L_abs( L_coeff_out[i] ), L_shl_sat( L_abs( *p_prev_coeff_out ), 2 ) ) || LT_32( L_abs( L_coeff_out[i] ), L_shr( L_abs( *p_prev_coeff_out ), 2 ) ) || ( ( R[sfm] == 0 || *prev_R == 0 ) && add_sat( R[sfm], *prev_R ) != 0 ) )
    2505             :                     {
    2506           0 :                         L_tmp = L_add_sat( L_shr( L_abs( L_coeff_out[i] ), 1 ), L_shr( L_abs( *p_prev_coeff_out ), 1 ) ); /*Q12*/
    2507           0 :                         if ( L_coeff_out[i] <= 0 )
    2508             :                         {
    2509           0 :                             L_tmp = L_negate( L_tmp ); /*Q12*/
    2510             :                         }
    2511           0 :                         L_coeff_out[i] = L_tmp; /*Q12*/
    2512           0 :                         move32();
    2513             :                     }
    2514           0 :                     p_prev_coeff_out++; /*Q12*/
    2515             :                 }
    2516             :             }
    2517       12090 :             prev_env_Q[sfm] = exp;
    2518       12090 :             move16();
    2519       12090 :             prev_env_fx[sfm] = L_tmp2;
    2520       12090 :             move32();
    2521             :         }
    2522             :     }
    2523             :     ELSE
    2524             :     {
    2525             :         /* fill random noise for 0 bit subbands of transient frame */
    2526         297 :         FOR( sfm = 0; sfm < num_sfm; sfm++ )
    2527             :         {
    2528         286 :             IF( R[sfm] == 0 )
    2529             :             {
    2530        1507 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2531             :                 {
    2532        1392 :                     tmp1 = Random( bwe_seed );                   /*Q15 */
    2533        1392 :                     L_tmp1 = Mult_32_16( L_normq_v[sfm], tmp1 ); /*14   14+15+1 -16 */
    2534        1392 :                     L_tmp1 = L_shr( L_tmp1, 2 );                 /*Q12*/
    2535        1392 :                     L_coeff_out[i] = L_tmp1;                     /*Q12*/
    2536        1392 :                     move32();
    2537             :                 }
    2538             :             }
    2539             :         }
    2540          11 :         set16_fx( prev_env_Q, 0, SFM_N_WB );
    2541          11 :         set32_fx( prev_env_fx, 0, SFM_N_WB );
    2542             :     }
    2543             : 
    2544         476 :     Copy32( L_normq_v, prev_normq_fx, SFM_N_WB );                                     /*Q14*/
    2545         476 :     Copy32( L_coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out_fx, L_HQ_WB_BWE ); /*Q12*/
    2546         476 :     *prev_R = R[SFM_N_WB - 1];                                                        /*Q0*/
    2547         476 :     move16();
    2548             : 
    2549         476 :     return;
    2550             : }
    2551             : 
    2552             : /*--------------------------------------------------------------------------*
    2553             :  * enforce_zero_for_min_envelope_fx()
    2554             :  *
    2555             :  * Detect minimum level of envelope and set corresponding bands to zero
    2556             :  *--------------------------------------------------------------------------*/
    2557             : 
    2558        7728 : void enforce_zero_for_min_envelope_fx(
    2559             :     const Word16 hqswb_clas, /* i  : HQ coding mode                     Q0  */
    2560             :     const Word16 *ynrm,      /* i  : Envelope indices                   Q0  */
    2561             :     Word32 *L_coefsq,        /* i/o: Quantized spectrum/zeroed spectrum Q12 */
    2562             :     const Word16 nb_sfm,     /* i  : Number of coded sub bands          Q0  */
    2563             :     const Word16 *sfm_start, /* i  : Sub band start indices             Q0  */
    2564             :     const Word16 *sfm_end    /* i  : Sub band end indices               Q0  */
    2565             : )
    2566             : {
    2567             :     Word16 i, j;
    2568             : 
    2569             :     /* prevent non-zero output for all-zero input */
    2570        7728 :     IF( NE_16( hqswb_clas, HQ_HVQ ) )
    2571             :     {
    2572        6499 :         IF( EQ_16( ynrm[0], 31 ) )
    2573             :         {
    2574          36 :             FOR( j = sfm_start[0]; j < sfm_end[0]; j++ )
    2575             :             {
    2576          32 :                 L_coefsq[j] = L_deposit_l( 0 ); /*Q12*/
    2577          32 :                 move32();
    2578             :             }
    2579             :         }
    2580             : 
    2581      260385 :         FOR( i = 1; i < nb_sfm; i++ )
    2582             :         {
    2583      253886 :             IF( EQ_16( ynrm[i], 39 ) )
    2584             :             {
    2585      162935 :                 FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
    2586             :                 {
    2587      157320 :                     L_coefsq[j] = L_deposit_l( 0 ); /*Q12*/
    2588      157320 :                     move32();
    2589             :                 }
    2590             :             }
    2591             :         }
    2592             :     }
    2593             : 
    2594        7728 :     return;
    2595             : }
    2596             : /*--------------------------------------------------------------------------*
    2597             :  * apply_envelope()
    2598             :  *
    2599             :  * Apply spectral envelope with envelope adjustments
    2600             :  *--------------------------------------------------------------------------*/
    2601             : 
    2602        6352 : void apply_envelope_enc_ivas_fx(
    2603             :     const Word16 *coeff,     /* i/o: Coded/noisefilled normalized spectrum  Q12 */
    2604             :     const Word16 *norm,      /* i  : Envelope                               Q0  */
    2605             :     const Word16 num_sfm,    /* i  : Total number of bands                  Q0  */
    2606             :     const Word16 *sfm_start, /* i  : Sub band start indices                 Q0  */
    2607             :     const Word16 *sfm_end,   /* i  : Sub band end indices                   Q0  */
    2608             :     Word32 *coeff_out        /* o  : coded/noisefilled spectrum             Q12 */
    2609             : )
    2610             : {
    2611             :     Word16 i;
    2612             :     Word16 sfm;
    2613             :     UWord16 lsb;
    2614             :     Word32 normq;
    2615             :     Word32 L_tmp;
    2616             : 
    2617      263750 :     FOR( sfm = 0; sfm < num_sfm; sfm++ )
    2618             :     {
    2619      257398 :         normq = dicn_fx[norm[sfm]]; /*Q14*/
    2620      257398 :         move16();
    2621             : 
    2622     4978838 :         FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2623             :         {
    2624             :             /*coeff_out[i] = coeff[i]*normq; */
    2625     4721440 :             Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
    2626     4721440 :             coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /*Q12*/
    2627     4721440 :             move32();
    2628             :         }
    2629             :     }
    2630             : 
    2631             : 
    2632        6352 :     return;
    2633             : }
    2634             : 
    2635             : /*--------------------------------------------------------------------------*
    2636             :  * apply_envelope()
    2637             :  *
    2638             :  * Apply spectral envelope with envelope adjustments
    2639             :  *--------------------------------------------------------------------------*/
    2640             : 
    2641        5771 : void apply_envelope_fx(
    2642             :     const Word16 *coeff,     /* i/o: Coded/noisefilled normalized spectrum  Q12 */
    2643             :     const Word16 *norm,      /* i  : Envelope                               Q0  */
    2644             :     const Word16 *norm_adj,  /* i  : Envelope adjustment                    Q15 */
    2645             :     const Word16 num_sfm,    /* i  : Total number of bands                  Q0  */
    2646             :     const Word16 last_sfm,   /* i  : Last coded band                        Q0  */
    2647             :     const Word16 HQ_mode,    /* i  : HQ mode                                Q0  */
    2648             :     const Word16 length,     /* i  : Frame length                           Q0  */
    2649             :     const Word16 *sfm_start, /* i  : Sub band start indices                 Q0  */
    2650             :     const Word16 *sfm_end,   /* i  : Sub band end indices                   Q0  */
    2651             :     Word32 *normq_v,         /* o  : Envelope with adjustment               Q14 */
    2652             :     Word32 *coeff_out,       /* o  : coded/noisefilled spectrum             Q12 */
    2653             :     const Word16 *coeff1,    /* i  : coded/noisefilled spectrum             Q12 */
    2654             :     Word32 *coeff_out1       /* o  : coded/noisefilled spectrum             Q12 */
    2655             : )
    2656             : {
    2657             :     Word16 i;
    2658             :     Word16 sfm;
    2659             :     UWord16 lsb;
    2660             :     Word32 normq;
    2661             :     Word32 L_tmp;
    2662             :     Word16 len;
    2663             : 
    2664        5771 :     len = num_sfm;
    2665        5771 :     move16();
    2666        5771 :     test();
    2667        5771 :     if ( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    2668             :     {
    2669        2789 :         len = add( last_sfm, 1 ); /*Q0*/
    2670             :     }
    2671             : 
    2672        5771 :     IF( EQ_16( length, L_FRAME16k ) )
    2673             :     {
    2674       16092 :         FOR( sfm = 0; sfm < num_sfm; sfm++ )
    2675             :         {
    2676       15496 :             normq_v[sfm] = dicn_fx[norm[sfm]]; /*Q14*/
    2677       15496 :             move16();
    2678       15496 :             move32();
    2679             :             /*normq = normq_v[sfm] * norm_adj[sfm];               */
    2680       15496 :             Mpy_32_16_ss( normq_v[sfm], norm_adj[sfm], &normq, &lsb ); /* Q14 (14+15+1-16) */
    2681             : 
    2682      206216 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2683             :             {
    2684             :                 /*coeff_out[i] = coeff[i]*normq; */
    2685      190720 :                 Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
    2686      190720 :                 coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
    2687      190720 :                 move32();
    2688             :             }
    2689             :         }
    2690             :     }
    2691             :     ELSE
    2692             :     {
    2693      182419 :         FOR( sfm = 0; sfm < len; sfm++ )
    2694             :         {
    2695      177244 :             normq_v[sfm] = dicn_fx[norm[sfm]]; /*Q14*/
    2696      177244 :             move16();
    2697      177244 :             move32();
    2698             :             /*normq_v[sfm] *= norm_adj[sfm];               */
    2699      177244 :             Mpy_32_16_ss( normq_v[sfm], norm_adj[sfm], &normq_v[sfm], &lsb ); /* Q14 (14+15+1-16) */
    2700      177244 :             move32();
    2701             : 
    2702      177244 :             normq = normq_v[sfm]; /*Q14*/
    2703      177244 :             move32();
    2704     2926980 :             FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2705             :             {
    2706             :                 /*coeff_out[i] = coeff[i]*normq; */
    2707     2749736 :                 Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
    2708     2749736 :                 coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
    2709     2749736 :                 move32();
    2710             :             }
    2711             :         }
    2712             : 
    2713        5175 :         test();
    2714        5175 :         IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
    2715             :         {
    2716       78103 :             FOR( sfm = 0; sfm <= last_sfm; sfm++ )
    2717             :             {
    2718       75314 :                 normq = normq_v[sfm];
    2719       75314 :                 move32();
    2720      990370 :                 FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
    2721             :                 {
    2722             :                     /*coeff_out1[i] = coeff_out1[i]*normq; */
    2723      915056 :                     Mpy_32_16_ss( normq, coeff1[i], &L_tmp, &lsb );
    2724      915056 :                     coeff_out1[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
    2725      915056 :                     move32();
    2726             :                 }
    2727             :             }
    2728             :         }
    2729             :     }
    2730             : 
    2731             : 
    2732        5771 :     return;
    2733             : }

Generated by: LCOV version 1.14