LCOV - code coverage report
Current view: top level - lib_com - gs_gains_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 5cb54858cb3178c8db39c9c2163d829984772878 Lines: 431 679 63.5 %
Date: 2025-11-05 02:09:30 Functions: 13 13 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             : 
      37             : #include <stdint.h>
      38             : #include <math.h>
      39             : #include "options.h" /* Compilation switches                   */
      40             : #include "cnst.h"    /* Common constants                       */
      41             : #include "rom_com.h" /* Static table prototypes                */
      42             : #include "prot_fx.h"
      43             : #include "stl.h"
      44             : #include "wmc_auto.h"
      45             : 
      46             : /*-------------------------------------------------------------------*
      47             :  * Local constants
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50             : static Word16 VDQ_vec_fx( Word16 *Qvec_out_fx, const Word16 *mean_dic_fx, const Word16 *dic_fx, const Word16 index_fx, const Word16 vec_en_fx );
      51             : 
      52             : /*========================================================================*/
      53             : /* FUNCTION : void Comp_and_apply_gain_enc_fx                                                 */
      54             : /*------------------------------------------------------------------------*/
      55             : /* PURPOSE :  Compute and apply the quantized per band gain               */
      56             : /*------------------------------------------------------------------------*/
      57             : /* INPUT ARGUMENTS :                                                                                                      */
      58             : /* _ (Word16[]) Ener_per_bd_iQ     : Target ener per band             Q12 */
      59             : /*------------------------------------------------------------------------*/
      60             : /* INPUT/OUTPUT ARGUMENTS :                                                                                               */
      61             : /* _ (Word16[]) exc_diffQ      : Quantized excitation     Qexc                */
      62             : /* _ (Word16[]) Ener_per_bd_yQ : Ener per band for norm vectori->Q12/o->Q2*/
      63             : /*------------------------------------------------------------------------*/
      64             : /* OUTPUT ARGUMENTS :                                                                                                     */
      65             : /* _ None                                                                 */
      66             : /*------------------------------------------------------------------------*/
      67             : 
      68             : /*------------------------------------------------------------------------*/
      69             : /* RETURN ARGUMENTS :                                                                                                     */
      70             : /* _ None                                                                                                                                 */
      71             : /*========================================================================*/
      72             : 
      73          32 : void Comp_and_apply_gain_fx(
      74             :     Word16 exc_diffQ[],      /* i/o: Quantized excitation                  */
      75             :     Word16 Ener_per_bd_iQ[], /* i  : Target ener per band              Q13 */
      76             :     Word16 Ener_per_bd_yQ[], /* i/o  : Ener per band for norm vector     i->Q13/o->Q13 */
      77             :     Word16 Mbands_gn,        /* i  : number of bands                  */
      78             :     const Word16 ReUseGain,  /* i  : Reuse the gain in Ener_per_bd_yQ  */
      79             :     Word16 Qexc_diff,
      80             :     Word16 Q_exc )
      81             : {
      82             :     Word16 i, i_band;
      83             :     Word16 StartBin, NB_Qbins;
      84             :     Word16 y_gain;
      85             :     Word16 L16, frac, exp1, tmp_exp;
      86             :     Word32 L32;
      87             : 
      88             :     /* Recreate excitation for local synthesis and decoder */
      89          32 :     StartBin = 0;
      90          32 :     move16();
      91          32 :     NB_Qbins = 0;
      92          32 :     move16();
      93             : 
      94          32 :     tmp_exp = add( 14, sub( Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
      95         544 :     FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
      96             :     {
      97         512 :         StartBin = add( StartBin, NB_Qbins );
      98         512 :         NB_Qbins = mfreq_bindiv_loc[i_band];
      99         512 :         move16();
     100         512 :         IF( EQ_16( ReUseGain, 1 ) )
     101             :         {
     102         256 :             y_gain = Ener_per_bd_yQ[i_band];
     103         256 :             move16();
     104             : 
     105        4352 :             FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
     106             :             {
     107        4096 :                 L32 = L_shl_sat( L_mult( exc_diffQ[i], y_gain ), tmp_exp ); /*Q_exc+16 */
     108        4096 :                 exc_diffQ[i] = round_fx_sat( L32 );                         /*Q_exc */
     109        4096 :                 move16();
     110             :             }
     111             :         }
     112             :         ELSE
     113             :         {
     114             :             /*-----------------------------------------------------------------*
     115             :              * y_gain  = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
     116             :              * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
     117             :              *-----------------------------------------------------------------*/
     118         256 :             L16 = sub( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
     119         256 :             L32 = L_mult( L16, 27213 );                                  /* 3.321928 in Q13 -> Q26 */
     120         256 :             L32 = L_shr( L32, 10 );                                      /* From Q26 to Q16 */
     121         256 :             frac = L_Extract_lc( L32, &exp1 );                           /* Extract exponent of gcode0 */
     122         256 :             y_gain = extract_l( Pow2( 14, frac ) );                      /* Put 14 as exponent so that */
     123             :                                                                          /* output of Pow2() will be: */
     124             :                                                                          /* 16384 < Pow2() <= 32767 */
     125         256 :             Ener_per_bd_yQ[i_band] = shl_sat( y_gain, sub( exp1, 13 ) );
     126         256 :             move16(); /*Q1     */
     127         256 :             tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) );
     128             : 
     129        4352 :             FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
     130             :             {
     131        4096 :                 L32 = L_mult( exc_diffQ[i], y_gain );                     /*Qexc_diff+15 */
     132        4096 :                 exc_diffQ[i] = round_fx_sat( L_shl_sat( L32, tmp_exp ) ); /*Q_exc */
     133        4096 :                 move16();
     134             :             }
     135             :         }
     136             :     }
     137             : 
     138          32 :     return;
     139             : }
     140             : 
     141       90734 : void Comp_and_apply_gain_ivas_fx(
     142             :     Word16 exc_diffQ[],      /* i/o: Quantized excitation                  */
     143             :     Word16 Ener_per_bd_iQ[], /* i  : Target ener per band              Q13 */
     144             :     Word16 Ener_per_bd_yQ[], /* i/o  : Ener per band for norm vector     i->Q13/o->Q13 */
     145             :     Word16 Mbands_gn,        /* i  : number of bands                  */
     146             :     const Word16 ReUseGain,  /* i  : Reuse the gain in Ener_per_bd_yQ  */
     147             :     Word16 Qexc_diff,
     148             :     Word16 *Q_exc )
     149             : {
     150             :     Word16 i, i_band;
     151             :     Word16 StartBin, NB_Qbins;
     152             :     Word16 y_gain;
     153             :     Word16 L16, frac, exp1, tmp_exp;
     154             :     Word32 L32;
     155             :     Word16 Q_exc_diffQ[L_FRAME16k];
     156             : 
     157             :     /* Recreate excitation for local synthesis and decoder */
     158       90734 :     StartBin = 0;
     159       90734 :     move16();
     160       90734 :     NB_Qbins = 0;
     161       90734 :     move16();
     162             : 
     163       90734 :     tmp_exp = add( 14, sub( *Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
     164     1563300 :     FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
     165             :     {
     166     1472566 :         StartBin = add( StartBin, NB_Qbins );
     167     1472566 :         NB_Qbins = mfreq_bindiv_loc[i_band];
     168     1472566 :         move16();
     169     1472566 :         IF( EQ_16( ReUseGain, 1 ) )
     170             :         {
     171      732107 :             y_gain = Ener_per_bd_yQ[i_band]; /*Q13*/
     172      732107 :             move16();
     173             : 
     174    12614891 :             FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
     175             :             {
     176    11882784 :                 L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16-tmp_exp */
     177    11882784 :                 exc_diffQ[i] = round_fx_sat( L32 );   /*Q_exc-tmp_exp */
     178    11882784 :                 move16();
     179    11882784 :                 IF( exc_diffQ[i] )
     180             :                 {
     181      912167 :                     Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
     182             :                 }
     183             :                 ELSE
     184             :                 {
     185    10970617 :                     Q_exc_diffQ[i] = *Q_exc;
     186             :                 }
     187    11882784 :                 move16();
     188             :             }
     189             :         }
     190             :         ELSE
     191             :         {
     192             :             /*-----------------------------------------------------------------*
     193             :              * y_gain  = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
     194             :              * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
     195             :              *-----------------------------------------------------------------*/
     196      740459 :             L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
     197      740459 :             L32 = L_mult( L16, 27213 );                                      /* 3.321928 in Q13 -> Q26 */
     198      740459 :             L32 = L_shr( L32, 10 );                                          /* From Q26 to Q16 */
     199      740459 :             frac = L_Extract_lc( L32, &exp1 );                               /* Extract exponent of gcode0 */
     200      740459 :             y_gain = extract_l( Pow2( 14, frac ) );                          /* Put 14 as exponent so that */
     201             :                                                                              /* output of Pow2() will be: */
     202             :                                                                              /* 16384 < Pow2() <= 32767 */
     203      740459 :             Ener_per_bd_yQ[i_band] = shl_sat( y_gain, sub( exp1, 13 ) );     /*Q13*/
     204      740459 :             move16();                                                        /*Q1     */
     205      740459 :             tmp_exp = add( add( exp1, 1 ), sub( *Q_exc, Qexc_diff ) );
     206             : 
     207    12757899 :             FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
     208             :             {
     209    12017440 :                 L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
     210    12017440 :                 exc_diffQ[i] = round_fx_sat( L32 );   /*Q_exc-tmp_exp */
     211    12017440 :                 move16();
     212    12017440 :                 IF( exc_diffQ[i] )
     213             :                 {
     214    10672688 :                     Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
     215             :                 }
     216             :                 ELSE
     217             :                 {
     218     1344752 :                     Q_exc_diffQ[i] = *Q_exc;
     219             :                 }
     220    12017440 :                 move16();
     221             :             }
     222             :         }
     223             :     }
     224             : 
     225    23990958 :     FOR( i = 0; i < StartBin + NB_Qbins; i++ )
     226             :     {
     227    23900224 :         *Q_exc = s_min( *Q_exc, add( Q_exc_diffQ[i], norm_s( exc_diffQ[i] ) ) );
     228    23900224 :         move16();
     229             :     }
     230    23990958 :     FOR( i = 0; i < StartBin + NB_Qbins; i++ )
     231             :     {
     232    23900224 :         exc_diffQ[i] = shl( exc_diffQ[i], sub( *Q_exc, Q_exc_diffQ[i] ) ); /*Q_exc*/
     233    23900224 :         move16();
     234             :     }
     235             : 
     236       90734 :     return;
     237             : }
     238             : 
     239             : 
     240             : /*========================================================================*/
     241             : /* FUNCTION : Ener_per_band_comp_fx()                                                                     */
     242             : /*------------------------------------------------------------------------*/
     243             : /* PURPOSE : Compute the energy per band in log domain for quantization   */
     244             : /*                       purposes.                                                                                                        */
     245             : /*           Loops are decomposed to accomodate the PVQ quantization      */
     246             : /*------------------------------------------------------------------------*/
     247             : /* INPUT ARGUMENTS :                                                                                                      */
     248             : /* _ (Word16*) edct_table_128_fx  : edct table                       Q15  */
     249             : /* _ (Word16*) Q_exc_diff         : input format of exc_diff              */
     250             : /*------------------------------------------------------------------------*/
     251             : /* INPUT/OUTPUT ARGUMENTS :                                                                                               */
     252             : /*------------------------------------------------------------------------*/
     253             : /* OUTPUT ARGUMENTS :                                                                                                     */
     254             : /* _ (Word16[]) y_gain4 : Energy per band to quantize      Q12                    */
     255             : /* _ (Word32*) etmp14   : Energy band 14                                   Q_exc_diff*2+1 */
     256             : /* _ (Word32*) etmp15   : Energy band 15                                   Q_exc_diff*2+1 */
     257             : /*------------------------------------------------------------------------*/
     258             : 
     259             : /*------------------------------------------------------------------------*/
     260             : /* RETURN ARGUMENTS :                                                                                                     */
     261             : /* _ None                                                                                                                                 */
     262             : /*========================================================================*/
     263             : 
     264     3724399 : static Word16 Comp_band_log_ener(                      /* o  : Band gain Q12 */
     265             :                                   const Word16 *pt_fx, /* i  : Dct input Q_sc */
     266             :                                   const Word16 Len,    /* i  : Lenght en energy accumulation */
     267             :                                   const Word16 Q_sc,   /* i  : scaling of input    */
     268             :                                   const Word16 E_sc    /* i  : Additional scaling factor for energy */
     269             : )
     270             : {
     271             :     Word32 L_tmp;
     272             :     Word16 e_tmp, f_tmp, tmp16, ener_exp;
     273     3724399 :     L_tmp = Calc_Energy_Autoscaled( pt_fx, Q_sc, Len, &ener_exp );
     274     3724399 :     e_tmp = norm_l( L_tmp );
     275     3724399 :     f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
     276     3724399 :     e_tmp = sub( sub( add( 30, E_sc ), e_tmp ), ener_exp );
     277     3724399 :     L_tmp = Mpy_32_16( e_tmp, f_tmp, 19728 ); /* Q16 */ /*log10(2) in Q17 */
     278     3724399 :     tmp16 = round_fx( L_shl( L_tmp, 12 - 2 ) );         /* Q12 -1 is to compensate Q17 */
     279     3724399 :     return tmp16;
     280             : }
     281             : 
     282          16 : void Ener_per_band_comp_fx(
     283             :     const Word16 exc_diff_fx[], /* i  : target signal                     Q_exc_diff     */
     284             :     Word16 y_gain4_fx[],        /* o  : Energy per band to quantize              Q12            */
     285             :     const Word16 Q_exc,         /* i  : frame length                      */
     286             :     const Word16 Mband,         /* i  : Max band                          */
     287             :     const Word16 Eflag          /* i  : flag of highest band              */
     288             : )
     289             : {
     290             :     const Word16 *pt_fx;
     291             :     Word16 j;
     292             : 
     293          16 :     pt_fx = exc_diff_fx;
     294          48 :     FOR( j = 0; j < 2; j++ )
     295             :     {
     296          32 :         y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
     297          32 :         move16();
     298          32 :         pt_fx += 8;
     299             :     }
     300             : 
     301         224 :     FOR( j = 1; j < Mband - 2; j++ )
     302             :     {
     303         208 :         y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
     304         208 :         move16();
     305         208 :         pt_fx += 16;
     306             :     }
     307             : 
     308          16 :     IF( EQ_16( Eflag, 1 ) )
     309             :     {
     310          16 :         y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
     311          16 :         move16();
     312          16 :         pt_fx += 32;
     313             :     }
     314             : 
     315          16 :     return;
     316             : }
     317             : 
     318      222853 : void Ener_per_band_comp_ivas_fx(
     319             :     const Word16 exc_diff_fx[], /* i  : target signal                     Q_exc_diff     */
     320             :     Word16 y_gain4_fx[],        /* o  : Energy per band to quantize              Q12            */
     321             :     const Word16 Q_exc,         /* i  : frame length                      */
     322             :     const Word16 Mband,         /* i  : Max band                          */
     323             :     const Word16 Eflag,         /* i  : flag of highest band              */
     324             :     const Word16 L_frame        /* i  : frame length                */
     325             : )
     326             : {
     327             :     const Word16 *pt_fx;
     328             :     Word16 j;
     329             : 
     330      222853 :     pt_fx = exc_diff_fx;
     331      668559 :     FOR( j = 0; j < 2; j++ )
     332             :     {
     333      445706 :         y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
     334      445706 :         move16();
     335      445706 :         pt_fx += 8;
     336             :     }
     337             : 
     338     3119780 :     FOR( j = 1; j < Mband - 2; j++ )
     339             :     {
     340     2896927 :         y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
     341     2896927 :         move16();
     342     2896927 :         pt_fx += 16;
     343             :     }
     344             : 
     345      222853 :     IF( EQ_16( Eflag, 1 ) )
     346             :     {
     347      222760 :         y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
     348      222760 :         move16();
     349      222760 :         pt_fx += 32;
     350             :     }
     351             : 
     352      222853 :     IF( EQ_16( L_frame, L_FRAME16k ) )
     353             :     {
     354       79375 :         y_gain4_fx[j + 2] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
     355       79375 :         move16();
     356       79375 :         y_gain4_fx[j + 3] = Comp_band_log_ener( pt_fx, 64, Q_exc, -1 ); /*Q12*/
     357       79375 :         move16();
     358       79375 :         pt_fx += 64;
     359             :     }
     360             : 
     361      222853 :     return;
     362             : }
     363             : 
     364             : 
     365             : /*-------------------------------------------------------------------*
     366             :  * gsc_gainQ()
     367             :  *
     368             :  * Quantization of the energy per band
     369             :  *-------------------------------------------------------------------*/
     370             : 
     371          16 : static void GSC_gain_adj(
     372             :     const Word16 coder_type,  /* i  : Coder type        */
     373             :     const Word32 core_brate,  /* i  : Bit rate          */
     374             :     const Word16 mean_g,      /* i  : Average gain Q12  */
     375             :     Word16 *old_y_gain,       /* i/o: Previous frame dequantized vector */
     376             :     const Word16 *y_gain_tmp, /* i  : Dequantized gains */
     377             :     Word16 *y_gainQ           /* i/o: Output gains Q12  */
     378             : )
     379             : {
     380             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
     381             :     Word16 Gain_off, i;
     382             : 
     383          16 :     IF( coder_type != INACTIVE )
     384             :     {
     385           0 :         FOR( i = 0; i < MBANDS_GN; i++ )
     386             :         {
     387           0 :             old_y_gain[i] = y_gain_tmp[i];
     388           0 :             move16();
     389           0 :             y_gainQ[i] = add( y_gain_tmp[i], mean_g );
     390           0 :             move16();
     391             :         }
     392             :     }
     393             :     ELSE
     394             :     {
     395          16 :         Gain_off = 0;
     396          16 :         move16();
     397          16 :         IF( LE_32( core_brate, ACELP_7k20 ) )
     398             :         {
     399           0 :             Gain_off = 32767;
     400           0 :             move16(); /* 8 -> Q12 */
     401             :         }
     402          16 :         ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
     403             :         {
     404           0 :             Gain_off = 27034;
     405           0 :             move16(); /* 6.6f -> Q12 */
     406             :         }
     407          16 :         ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
     408             :         {
     409           0 :             Gain_off = 19661;
     410           0 :             move16(); /*4.8f-> Q12 */
     411             :         }
     412          16 :         ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
     413             :         {
     414          16 :             Gain_off = 14336;
     415          16 :             move16(); /* 3.5f -> Q12 */
     416             :         }
     417           0 :         ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
     418             :         {
     419           0 :             Gain_off = 12288;
     420           0 :             move16(); /* 3.0f -> Q12 dB */
     421             :         }
     422             : 
     423             :         /*mimic ACELP decay of energy for low rates*/
     424         272 :         FOR( i = 0; i < MBANDS_GN; i++ )
     425             :         {
     426         256 :             old_y_gain[i] = y_gain_tmp[i];
     427         256 :             move16();
     428             :             /*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
     429         256 :             y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 102 /* 20/MBANDS_GN in Q15 */ ) ) ) );
     430         256 :             move16();
     431             :         }
     432             :     }
     433             : 
     434          16 :     return;
     435             : }
     436             : 
     437             : 
     438             : /*-------------------------------------------------------------------*
     439             :  * GSC_gain_adj_ivas_fx()
     440             :  *
     441             :  * Quantization of the energy per band
     442             :  *-------------------------------------------------------------------*/
     443             : 
     444       22439 : static void GSC_gain_adj_ivas_fx(
     445             :     const Word16 coder_type,  /* i  : Coder type        */
     446             :     const Word16 Mbands_gn,   /* i  : Number of band                          */
     447             :     const Word32 core_brate,  /* i  : Bit rate          */
     448             :     const Word16 mean_g,      /* i  : Average gain Q12  */
     449             :     Word16 *old_y_gain,       /* i/o: Previous frame dequantized vector */
     450             :     const Word16 *y_gain_tmp, /* i  : Dequantized gains */
     451             :     Word16 *y_gainQ           /* i/o: Output gains Q12  */
     452             : )
     453             : {
     454             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
     455             :     Word16 Gain_off, i;
     456             : 
     457       22439 :     test();
     458       22439 :     IF( ( coder_type != INACTIVE ) && NE_16( coder_type, UNVOICED ) )
     459             :     {
     460      183685 :         FOR( i = 0; i < Mbands_gn; i++ )
     461             :         {
     462      172880 :             old_y_gain[i] = y_gain_tmp[i];
     463      172880 :             move16();
     464      172880 :             y_gainQ[i] = add( y_gain_tmp[i], mean_g );
     465      172880 :             move16();
     466             :         }
     467             :     }
     468             :     ELSE
     469             :     {
     470       11634 :         Gain_off = 0;
     471       11634 :         move16();
     472             : 
     473       11634 :         test();
     474       11634 :         IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
     475             :         {
     476           0 :             Gain_off = 18432;
     477           0 :             move16(); /* 9 -> Q11 */
     478             :         }
     479       11634 :         IF( LE_32( core_brate, ACELP_7k20 ) )
     480             :         {
     481        7482 :             Gain_off = 16384;
     482        7482 :             move16(); /* 8 -> Q11 */
     483             :         }
     484        4152 :         ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
     485             :         {
     486          11 :             Gain_off = 13517;
     487          11 :             move16(); /* 6.6f -> Q11 */
     488             :         }
     489        4141 :         ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
     490             :         {
     491         324 :             Gain_off = 9830;
     492         324 :             move16(); /*4.8f-> Q11 */
     493             :         }
     494        3817 :         ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
     495             :         {
     496         171 :             Gain_off = 7168;
     497         171 :             move16(); /* 3.5f -> Q11 */
     498             :         }
     499        3646 :         ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
     500             :         {
     501         365 :             Gain_off = 6144;
     502         365 :             move16(); /* 3.0f -> Q11 dB */
     503             :         }
     504             : 
     505             :         /*mimic ACELP decay of energy for low rates*/
     506      203070 :         FOR( i = 0; i < Mbands_gn; i++ )
     507             :         {
     508      191436 :             old_y_gain[i] = y_gain_tmp[i];
     509      191436 :             move16();
     510      191436 :             y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 205 /* 20/MBANDS_GN in Q16 */ ) ) ) );
     511      191436 :             move16();
     512             :         }
     513             :     }
     514             : 
     515       22439 :     return;
     516             : }
     517             : 
     518             : 
     519             : /*-------------------------------------------------------------------*
     520             :  * GSC_gain_DQ()
     521             :  *
     522             :  * Form the final vector after gain quantization/Dequantization
     523             :  * Common to both encoder and decoder
     524             :  *-------------------------------------------------------------------*/
     525             : 
     526       22668 : static void GSC_gain_DQ_fx(
     527             :     const Word16 element_mode, /* i  : element mode                            */
     528             :     const Word16 enc_dec,      /* i  : encoder/decoder flag                    */
     529             :     const Word16 coder_type,   /* i  : Coder type                              */
     530             :     const Word16 Mbands_gn,    /* i  : Number of band                          */
     531             :     const Word32 core_brate,   /* i  : Core bitrate                            */
     532             :     const Word16 mean_g,       /* i  : Average gain Q12                            */
     533             :     const Word16 *Gain_in,     /* i  : Unquantized gain vector Q12                 */
     534             :     Word16 *Gain_out           /* o  : Level adjusted unquantized gain vector Q12  */
     535             : )
     536             : {
     537             :     Word16 Gain_off;
     538             :     Word16 i;
     539             : 
     540             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
     541       22668 :     Gain_off = 0;
     542       22668 :     move16();
     543             : 
     544       22668 :     test();
     545       22668 :     IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
     546             :     {
     547       11723 :         test();
     548       11723 :         IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
     549             :         {
     550           0 :             Gain_off = 1843; // 9/20 in Q12
     551           0 :             move16();
     552             :         }
     553       11723 :         ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
     554             :         {
     555        7541 :             Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
     556        7541 :             move16();
     557             :         }
     558        4182 :         ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
     559             :         {
     560          11 :             Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
     561          11 :             move16();
     562             :         }
     563        4171 :         ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
     564             :         {
     565         327 :             Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
     566         327 :             move16();
     567             :         }
     568        3844 :         ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
     569             :         {
     570         173 :             Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
     571         173 :             move16();
     572             :         }
     573        3671 :         ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
     574             :         {
     575         376 :             Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
     576         376 :             move16();
     577             :         }
     578             :     }
     579             : 
     580       22668 :     test();
     581       22668 :     IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
     582             :     {
     583      186065 :         FOR( i = 0; i < Mbands_gn; i++ )
     584             :         {
     585      175120 :             Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
     586      175120 :             move16();
     587             :         }
     588             :     }
     589             :     ELSE
     590             :     {
     591             :         /*mimic ACELP decay of energy for low rates*/
     592       11723 :         test();
     593       11723 :         IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
     594             :         {
     595             :             /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
     596           0 :             FOR( i = 0; i < Mbands_gn; i++ )
     597             :             {
     598           0 :                 Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
     599           0 :                 move16();
     600             :                 // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
     601             :             }
     602             :         }
     603             :         ELSE
     604             :         {
     605      204609 :             FOR( i = 0; i < Mbands_gn; i++ )
     606             :             {
     607      192886 :                 Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
     608      192886 :                 move16();
     609             :                 // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
     610             :             }
     611             :         }
     612             :     }
     613             : 
     614       22668 :     return;
     615             : }
     616             : 
     617             : 
     618             : /*-------------------------------------------------------------------*
     619             :  * gsc_gainQ()
     620             :  *
     621             :  * Quantization of the energy per band
     622             :  *-------------------------------------------------------------------*/
     623             : 
     624       22668 : Word16 gsc_gainQ_ivas_fx(
     625             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle     */
     626             :     const Word16 element_mode, /* i  : element mode                 */
     627             :     const Word16 idchan,       /* i  : channel ID                   */
     628             :     const Word16 y_gain4[],
     629             :     /* i  : Energy per band              */ // Q12
     630             :     Word16 y_gainQ[],
     631             :     /* o  : quantized energy per band    */ // Q12
     632             :     const Word32 core_brate,                /* i  : Core rate                    */
     633             :     const Word16 coder_type,                /* i  : coding type                  */
     634             :     const Word16 bwidth,                    /* i  : input signal bandwidth       */
     635             :     const Word16 L_frame,                   /* i  : frame length                 */
     636             :     const Word16 tdm_LRTD_flag,             /* i  : LRTD stereo mode flag        */
     637             :     const Word32 core_brate_inp             /* i  : true core bitrate            */
     638             : )
     639             : {
     640             :     Word16 y_gain_tmp[MBANDS_GN16k];
     641             :     Word16 y_gain_tmp2[MBANDS_GN16k];
     642       22668 :     Word16 i, idx_g = 0;
     643       22668 :     move16();
     644             :     Word16 mean_4g_fx[1], ftmp1_fx;
     645       22668 :     Word16 Mbands_gn = MBANDS_GN;
     646       22668 :     move16();
     647             :     Word16 y_gain_tmp3[MBANDS_GN];
     648             :     Word32 L_tmp;
     649             : 
     650       22668 :     if ( EQ_16( L_frame, L_FRAME16k ) )
     651             :     {
     652        2659 :         Mbands_gn = MBANDS_GN16k;
     653        2659 :         move16();
     654             :     }
     655             : 
     656       22668 :     mean_4g_fx[0] = 0;
     657       22668 :     move32();
     658             : 
     659       22668 :     test();
     660       22668 :     test();
     661       22668 :     IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
     662             :     {
     663           0 :         L_tmp = 0;
     664           0 :         move32();
     665           0 :         FOR( i = 0; i < 10; i++ )
     666             :         {
     667           0 :             L_tmp = L_add( L_tmp, y_gain4[i] );
     668             :         }
     669           0 :         L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
     670           0 :         ftmp1_fx = extract_l( L_tmp );
     671           0 :         FOR( i = 0; i < Mbands_gn; i++ )
     672             :         {
     673           0 :             IF( LT_16( y_gain4[i], ftmp1_fx ) )
     674             :             {
     675           0 :                 y_gain_tmp2[i] = ftmp1_fx; /*Q12*/
     676             :             }
     677             :             ELSE
     678             :             {
     679           0 :                 y_gain_tmp2[i] = y_gain4[i]; /*Q12*/
     680             :             }
     681           0 :             move16();
     682             :         }
     683             : 
     684             :         /* Quantized mean gain without clipping */
     685           0 :         L_tmp = 0;
     686           0 :         move32();
     687           0 :         FOR( i = 0; i < 10; i++ )
     688             :         {
     689           0 :             L_tmp = L_add( L_tmp, y_gain4[i] );
     690             :         }
     691           0 :         L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
     692           0 :         mean_4g_fx[0] = extract_l( L_tmp );                        // Q12
     693           0 :         move16();
     694           0 :         idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
     695           0 :         push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
     696             : 
     697           0 :         FOR( i = 0; i < Mbands_gn; i++ )
     698             :         {
     699           0 :             y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
     700           0 :             move16();
     701             :         }
     702             : 
     703           0 :         if ( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
     704             :         {
     705           0 :             y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
     706           0 :             move16();
     707             :         }
     708             : 
     709           0 :         set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
     710           0 :         idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
     711           0 :         push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     712             : 
     713           0 :         IF( LT_32( core_brate, ACELP_9k60 ) )
     714             :         {
     715           0 :             idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
     716           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     717             : 
     718           0 :             idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
     719           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
     720             :         }
     721             :         ELSE
     722             :         {
     723           0 :             idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
     724           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     725             : 
     726           0 :             idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
     727           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
     728             :         }
     729             : 
     730           0 :         test();
     731           0 :         IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
     732             :         {
     733             :             /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
     734           0 :             y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); /*Q12*/
     735           0 :             move16();
     736           0 :             y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); /*Q12*/
     737           0 :             move16();
     738           0 :             y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); /*Q12*/
     739           0 :             move16();
     740           0 :             y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); /*Q12*/
     741           0 :             move16();
     742           0 :             y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); /*Q12*/
     743           0 :             move16();
     744           0 :             y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); /*Q12*/
     745           0 :             move16();
     746             :         }
     747             :         ELSE
     748             :         {
     749           0 :             set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
     750             :         }
     751             :     }
     752             :     ELSE
     753             :     {
     754       22668 :         L_tmp = 0;
     755       22668 :         move32();
     756      385356 :         FOR( i = 0; i < 16; i++ )
     757             :         {
     758      362688 :             L_tmp = L_add( L_tmp, y_gain4[i] );
     759             :         }
     760       22668 :         L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
     761       22668 :         ftmp1_fx = extract_l( L_tmp );
     762      390674 :         FOR( i = 0; i < Mbands_gn; i++ )
     763             :         {
     764      368006 :             IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
     765             :             {
     766        2024 :                 y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
     767             :             }
     768      365982 :             ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
     769             :             {
     770         565 :                 y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
     771             :             }
     772             :             ELSE
     773             :             {
     774      365417 :                 y_gain_tmp2[i] = y_gain4[i];
     775             :             }
     776      368006 :             move16();
     777             :         }
     778             : 
     779       22668 :         L_tmp = 0;
     780       22668 :         move32();
     781      385356 :         FOR( i = 0; i < 16; i++ )
     782             :         {
     783      362688 :             L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
     784             :         }
     785       22668 :         L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
     786       22668 :         mean_4g_fx[0] = extract_l( L_tmp );                       // Q12
     787       22668 :         move16();
     788       22668 :         idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
     789       22668 :         push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
     790             : 
     791             :         /* Subtraction of the average gain */
     792      390674 :         FOR( i = 0; i < Mbands_gn; i++ )
     793             :         {
     794      368006 :             y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
     795      368006 :             move16();
     796             :         }
     797             : 
     798       22668 :         IF( LT_32( core_brate, ACELP_9k60 ) )
     799             :         {
     800             :             /* prediction and quantization of the average gain */
     801             : 
     802             :             /*--------------------------------------------------------------------------------------*
     803             :              * Quantization of the first 8 bands
     804             :              * Keep only 4 bands out of the last 8 bands
     805             :              *--------------------------------------------------------------------------------------*/
     806             : 
     807       14537 :             Copy( y_gain_tmp, y_gain_tmp2, 8 );
     808             : 
     809       14537 :             y_gain_tmp2[8] = y_gain_tmp[8];
     810       14537 :             move16();
     811       14537 :             y_gain_tmp2[9] = y_gain_tmp[10];
     812       14537 :             move16();
     813       14537 :             y_gain_tmp2[10] = y_gain_tmp[12];
     814       14537 :             move16();
     815       14537 :             y_gain_tmp2[11] = y_gain_tmp[14];
     816       14537 :             move16();
     817             : 
     818       14537 :             idx_g = 0;
     819       14537 :             move16();
     820       14537 :             idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
     821       14537 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     822             : 
     823       14537 :             test();
     824       14537 :             test();
     825       14537 :             test();
     826       14537 :             IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
     827             :             {
     828       14537 :                 idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
     829       14537 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     830             : 
     831             :                 /*----------------------------------------------------------------------*
     832             :                  * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
     833             :                  * Interpolation of the last 4 bands Q to create bands 8-16
     834             :                  *----------------------------------------------------------------------*/
     835             : 
     836       14537 :                 idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
     837       14537 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     838             : 
     839       14537 :                 set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
     840             : 
     841             :                 /* Update to quantized vector */
     842       14537 :                 Copy( y_gain_tmp2, y_gain_tmp, 8 );
     843             : 
     844       14537 :                 Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
     845       14537 :                 set16_fx( y_gain_tmp + 8, 0, 8 );
     846       14537 :                 fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
     847             : 
     848       14537 :                 Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
     849       14537 :                 y_gain_tmp[15] = y_gain_tmp2[11];
     850       14537 :                 move16();
     851       14537 :                 ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
     852             : 
     853      130833 :                 FOR( i = 8; i < 16; i++ )
     854             :                 {
     855      116296 :                     y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
     856      116296 :                     move16();
     857             :                 }
     858             : 
     859       14537 :                 y_gain_tmp[8] = y_gain_tmp3[0];
     860       14537 :                 move16();
     861       14537 :                 y_gain_tmp[10] = y_gain_tmp3[1];
     862       14537 :                 move16();
     863       14537 :                 y_gain_tmp[12] = y_gain_tmp3[2];
     864       14537 :                 move16();
     865       14537 :                 y_gain_tmp[14] = y_gain_tmp3[3];
     866       14537 :                 move16();
     867             :             }
     868             :             ELSE
     869             :             {
     870           0 :                 Copy( y_gain_tmp2, y_gain_tmp, 3 );
     871           0 :                 set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
     872             :             }
     873             :         }
     874             :         ELSE
     875             :         {
     876        8131 :             IF( EQ_16( L_frame, L_FRAME ) )
     877             :             {
     878        5472 :                 idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
     879        5472 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     880             : 
     881        5472 :                 idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
     882        5472 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     883             : 
     884        5472 :                 idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
     885        5472 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
     886             : 
     887        5472 :                 idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
     888        5472 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
     889             :             }
     890             :             ELSE
     891             :             {
     892        2659 :                 idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
     893        2659 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
     894             : 
     895        2659 :                 idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
     896        2659 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     897             : 
     898        2659 :                 idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
     899        2659 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     900             : 
     901        2659 :                 idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
     902        2659 :                 push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
     903             : 
     904        2659 :                 idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
     905        2659 :                 push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
     906             :             }
     907             :         }
     908             :     }
     909             : 
     910       22668 :     GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
     911             : 
     912       22668 :     return mean_4g_fx[0];
     913             : }
     914             : 
     915             : 
     916             : /*==========================================================================*/
     917             : /* FUNCTION : Word16 gsc_gaindec_fx     ()                                                                  */
     918             : /*--------------------------------------------------------------------------*/
     919             : /* PURPOSE  :  Generic signal frequency band decoding and application       */
     920             : /*--------------------------------------------------------------------------*/
     921             : /*    INPUT ARGUMENTS :                                                                                                 */
     922             : /* _ (Word16) pvq_bits_fx          : core used                                  Q0                          */
     923             : /* _ (Word16) coder_type    : coding type                               Q0                          */
     924             : /* _ (Word16) core_fx          : core used                  Q0              */
     925             : /* _ (Word16) bwidth_fx        : input signal bandwidth     Q0              */
     926             : /*--------------------------------------------------------------------------*/
     927             : /* OUTPUT ARGUMENTS :                                                                                                       */
     928             : /* _ (Word16[]) y_gainQ_fx         : quantized gain per band                    */
     929             : /*--------------------------------------------------------------------------*/
     930             : /* INPUT/OUTPUT ARGUMENTS :                                                                                         */
     931             : /* _ (Word16[]) old_y_gain_fx  : AR gain quantizer for low rate                 */
     932             : /*--------------------------------------------------------------------------*/
     933             : /* RETURN ARGUMENTS :                                                                                                       */
     934             : /* _ (Word16) :                                 average frequency gain                                      */
     935             : /*==========================================================================*/
     936             : 
     937           8 : Word16 gsc_gaindec_fx(                             /* o  : average frequency gain    */
     938             :                        Decoder_State *st_fx,       /* i/o: decoder state structure   */
     939             :                        Word16 y_gainQ_fx[],        /* o  : quantized gain per band   */
     940             :                        const Word32 core_brate_fx, /* i  : core used                 */
     941             :                        Word16 old_y_gain_fx[],     /* i/o: AR gain quantizer for low rate */
     942             :                        const Word16 coder_type,    /* i  : coding type               */
     943             :                        const Word16 bwidth_fx      /* i  : input signal bandwidth    */
     944             : )
     945             : {
     946             :     Word16 idx_g_fx, i;
     947             :     Word16 mean_4g_fx;
     948             :     Word16 y_gain_tmp3_fx[MBANDS_GN];
     949             : 
     950           8 :     test();
     951           8 :     test();
     952           8 :     IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
     953             :     {
     954           0 :         idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
     955           0 :         VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
     956             : 
     957           0 :         idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
     958           0 :         VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
     959             : 
     960           0 :         IF( LT_32( core_brate_fx, ACELP_9k60 ) )
     961             :         {
     962           0 :             idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 5 ) );
     963           0 :             VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
     964             : 
     965           0 :             idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 4 ) );
     966           0 :             VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
     967             :         }
     968             :         ELSE
     969             :         {
     970           0 :             idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
     971           0 :             VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
     972             : 
     973           0 :             idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 7 ) );
     974           0 :             VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
     975             :         }
     976           0 :         test();
     977           0 :         IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
     978             :         {
     979             :             /* Some energy is needed in high band for stat_noise_uv_enc
     980             :               to be functional in inactive speech */
     981           0 :             y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 );
     982           0 :             move16();
     983           0 :             y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 );
     984           0 :             move16();
     985           0 :             y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 );
     986           0 :             move16();
     987           0 :             y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 );
     988           0 :             move16();
     989           0 :             y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 );
     990           0 :             move16();
     991           0 :             y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 );
     992           0 :             move16();
     993             :         }
     994             :         ELSE
     995             :         {
     996           0 :             set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
     997             :         }
     998             :     }
     999             :     ELSE
    1000             :     {
    1001           8 :         idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1002             : 
    1003           8 :         VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
    1004             : 
    1005           8 :         IF( LE_32( core_brate_fx, ACELP_9k60 ) )
    1006             :         {
    1007             :             /*--------------------------------------------------------------------------------------*
    1008             :              * UQ of the first 8 bands and half of the last 8 bands
    1009             :              *--------------------------------------------------------------------------------------*/
    1010           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1011           0 :             VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
    1012             : 
    1013           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1014           0 :             VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
    1015             : 
    1016             :             /*----------------------------------------------------------------------*
    1017             :              * Interpolation of the last 4 Q bands to create bands 8-16
    1018             :              * And scaling
    1019             :              *----------------------------------------------------------------------*/
    1020             : 
    1021           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1022             : 
    1023           0 :             VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
    1024             : 
    1025           0 :             Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
    1026           0 :             set16_fx( y_gainQ_fx + 12, 0, 4 );
    1027             : 
    1028           0 :             fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
    1029             : 
    1030           0 :             y_gainQ_fx[15] = y_gainQ_fx[11];
    1031           0 :             move16();
    1032           0 :             y_gainQ_fx[11] = 0;
    1033           0 :             move16();
    1034           0 :             ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
    1035           0 :             FOR( i = 8; i < 16; i++ )
    1036             :             {
    1037           0 :                 y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
    1038           0 :                 move16();
    1039             :             }
    1040             :             /*----------------------------------------------------------------------*
    1041             :              * Copy the true Q values in the specific bands
    1042             :              *----------------------------------------------------------------------*/
    1043           0 :             y_gainQ_fx[8] = y_gain_tmp3_fx[0];
    1044           0 :             move16();
    1045           0 :             y_gainQ_fx[10] = y_gain_tmp3_fx[1];
    1046           0 :             move16();
    1047           0 :             y_gainQ_fx[12] = y_gain_tmp3_fx[2];
    1048           0 :             move16();
    1049           0 :             y_gainQ_fx[14] = y_gain_tmp3_fx[3];
    1050           0 :             move16();
    1051             :         }
    1052             :         ELSE
    1053             :         {
    1054           8 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1055           8 :             VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
    1056             : 
    1057           8 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1058           8 :             VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
    1059             : 
    1060           8 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1061           8 :             VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
    1062             : 
    1063           8 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
    1064           8 :             VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
    1065             :         }
    1066             :     }
    1067             : 
    1068             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
    1069           8 :     GSC_gain_adj( coder_type, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
    1070             : 
    1071           8 :     return mean_4g_fx;
    1072             : }
    1073             : 
    1074             : 
    1075             : /*==========================================================================*/
    1076             : /* FUNCTION : Word16 gsc_gaindec_ivas_fx        ()                                                                  */
    1077             : /*--------------------------------------------------------------------------*/
    1078             : /* PURPOSE  :  Generic signal frequency band decoding and application       */
    1079             : /*--------------------------------------------------------------------------*/
    1080             : /*    INPUT ARGUMENTS :                                                                                                 */
    1081             : /* _ (Word16) pvq_bits_fx          : core used                                  Q0                          */
    1082             : /* _ (Word16) coder_type    : coding type                               Q0                          */
    1083             : /* _ (Word16) core_fx          : core used                  Q0              */
    1084             : /* _ (Word16) bwidth_fx        : input signal bandwidth     Q0              */
    1085             : /*--------------------------------------------------------------------------*/
    1086             : /* OUTPUT ARGUMENTS :                                                                                                       */
    1087             : /* _ (Word16[]) y_gainQ_fx         : quantized gain per band                    */
    1088             : /*--------------------------------------------------------------------------*/
    1089             : /* INPUT/OUTPUT ARGUMENTS :                                                                                         */
    1090             : /* _ (Word16[]) old_y_gain_fx  : AR gain quantizer for low rate                 */
    1091             : /*--------------------------------------------------------------------------*/
    1092             : /* RETURN ARGUMENTS :                                                                                                       */
    1093             : /* _ (Word16) :                                 average frequency gain                                      */
    1094             : /*==========================================================================*/
    1095             : 
    1096       22439 : Word16 gsc_gaindec_ivas_fx(                             /* o  : average frequency gain    */
    1097             :                             Decoder_State *st_fx,       /* i/o: decoder state structure   */
    1098             :                             Word16 y_gainQ_fx[],        /* o  : quantized gain per band  Q12 */
    1099             :                             const Word32 core_brate_fx, /* i  : core used                 */
    1100             :                             Word16 old_y_gain_fx[],     /* i/o: AR gain quantizer for low rate */
    1101             :                             const Word16 coder_type,    /* i  : coding type               */
    1102             :                             const Word16 bwidth_fx      /* i  : input signal bandwidth    */
    1103             : )
    1104             : {
    1105             :     Word16 idx_g_fx, i;
    1106             :     Word16 mean_4g_fx;
    1107       22439 :     Word16 Mbands_gn = MBANDS_GN;
    1108       22439 :     move16();
    1109             :     Word16 y_gain_tmp3_fx[MBANDS_GN];
    1110       22439 :     if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
    1111             :     {
    1112        2646 :         Mbands_gn = MBANDS_GN16k;
    1113        2646 :         move16();
    1114             :     }
    1115             : 
    1116       22439 :     test();
    1117       22439 :     test();
    1118       22439 :     IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
    1119             :     {
    1120           0 :         idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1121           0 :         VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
    1122             : 
    1123           0 :         idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1124           0 :         VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
    1125             : 
    1126           0 :         IF( LT_32( core_brate_fx, ACELP_9k60 ) )
    1127             :         {
    1128           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1129           0 :             VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
    1130             : 
    1131           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
    1132           0 :             VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
    1133             :         }
    1134             :         ELSE
    1135             :         {
    1136           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1137           0 :             VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
    1138             : 
    1139           0 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
    1140           0 :             VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
    1141             :         }
    1142           0 :         test();
    1143           0 :         IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
    1144             :         {
    1145             :             /* Some energy is needed in high band for stat_noise_uv_enc
    1146             :               to be functional in inactive speech */
    1147           0 :             y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 ); /*Q12*/
    1148           0 :             move16();
    1149           0 :             y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 ); /*Q12*/
    1150           0 :             move16();
    1151           0 :             y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 ); /*Q12*/
    1152           0 :             move16();
    1153           0 :             y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 ); /*Q12*/
    1154           0 :             move16();
    1155           0 :             y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 ); /*Q12*/
    1156           0 :             move16();
    1157           0 :             y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 ); /*Q12*/
    1158           0 :             move16();
    1159             :         }
    1160             :         ELSE
    1161             :         {
    1162           0 :             set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
    1163             :         }
    1164             :     }
    1165             :     ELSE
    1166             :     {
    1167       22439 :         idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1168             : 
    1169       22439 :         VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
    1170             : 
    1171       22439 :         IF( LT_32( core_brate_fx, ACELP_9k60 ) )
    1172             :         {
    1173             :             /*--------------------------------------------------------------------------------------*
    1174             :              * UQ of the first 8 bands and half of the last 8 bands
    1175             :              *--------------------------------------------------------------------------------------*/
    1176       14414 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1177       14414 :             VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
    1178             : 
    1179       14414 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1180       14414 :             VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
    1181             : 
    1182             :             /*----------------------------------------------------------------------*
    1183             :              * Interpolation of the last 4 Q bands to create bands 8-16
    1184             :              * And scaling
    1185             :              *----------------------------------------------------------------------*/
    1186             : 
    1187       14414 :             idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1188             : 
    1189       14414 :             VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
    1190             : 
    1191       14414 :             Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
    1192       14414 :             set16_fx( y_gainQ_fx + 12, 0, 4 );
    1193             : 
    1194       14414 :             fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
    1195             : 
    1196       14414 :             y_gainQ_fx[15] = y_gainQ_fx[11];
    1197       14414 :             move16();
    1198       14414 :             y_gainQ_fx[11] = 0;
    1199       14414 :             move16();
    1200       14414 :             ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
    1201      129726 :             FOR( i = 8; i < 16; i++ )
    1202             :             {
    1203      115312 :                 y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
    1204      115312 :                 move16();
    1205             :             }
    1206             :             /*----------------------------------------------------------------------*
    1207             :              * Copy the true Q values in the specific bands
    1208             :              *----------------------------------------------------------------------*/
    1209       14414 :             y_gainQ_fx[8] = y_gain_tmp3_fx[0]; /*Q12*/
    1210       14414 :             move16();
    1211       14414 :             y_gainQ_fx[10] = y_gain_tmp3_fx[1]; /*Q12*/
    1212       14414 :             move16();
    1213       14414 :             y_gainQ_fx[12] = y_gain_tmp3_fx[2]; /*Q12*/
    1214       14414 :             move16();
    1215       14414 :             y_gainQ_fx[14] = y_gain_tmp3_fx[3]; /*Q12*/
    1216       14414 :             move16();
    1217             :         }
    1218             :         ELSE
    1219             :         {
    1220        8025 :             IF( EQ_16( st_fx->L_frame, L_FRAME ) )
    1221             :             {
    1222        5379 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1223        5379 :                 VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
    1224             : 
    1225        5379 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1226        5379 :                 VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
    1227             : 
    1228        5379 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
    1229        5379 :                 VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
    1230             : 
    1231        5379 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
    1232        5379 :                 VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
    1233             :             }
    1234             :             ELSE
    1235             :             {
    1236        2646 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
    1237        2646 :                 VDQ_vec_fx( y_gainQ_fx, YG_mean16HR_fx, YG_dicHR_1_fx, idx_g_fx, 4 );
    1238             : 
    1239        2646 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1240        2646 :                 VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16HR_fx + 4, YG_dicHR_2_fx, idx_g_fx, 4 );
    1241             : 
    1242        2646 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1243        2646 :                 VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16HR_fx + 8, YG_dicHR_3_fx, idx_g_fx, 4 );
    1244             : 
    1245        2646 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
    1246        2646 :                 VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16HR_16kHz_fx, YG_dicHR_4_16kHz_fx, idx_g_fx, 4 );
    1247             : 
    1248        2646 :                 idx_g_fx = (Word16) get_next_indice_fx( st_fx, 3 );
    1249        2646 :                 VDQ_vec_fx( y_gainQ_fx + 16, YG_meanL2G_16kHz_fx, YG_dicL2G_16kHz_fx, idx_g_fx, 2 );
    1250             :             }
    1251             :         }
    1252             :     }
    1253             : 
    1254             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
    1255       22439 :     GSC_gain_adj_ivas_fx( coder_type, Mbands_gn, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
    1256             : 
    1257       22439 :     return mean_4g_fx;
    1258             : }
    1259             : 
    1260             : 
    1261             : /*-------------------------------------------------------------------*
    1262             :  * gsc_gainQ()
    1263             :  *
    1264             :  * Quantization of the energy per band
    1265             :  *-------------------------------------------------------------------*/
    1266             : 
    1267           8 : Word16 gsc_gainQ_fx(                          /*Q12*/
    1268             :                      BSTR_ENC_HANDLE hBstr,   /* i/o: bitstream handle            */
    1269             :                      const Word16 y_gain4[],  /* i  : Energy per band              Q12 */
    1270             :                      Word16 y_gainQ[],        /* o  : quantized energy per band    Q12 */
    1271             :                      const Word32 core_brate, /* i  : Core rate                        */
    1272             :                      const Word16 coder_type, /* i  : coding type                      */
    1273             :                      const Word16 bwidth      /* i  : input signal bandwidth           */
    1274             : )
    1275             : {
    1276             :     Word16 y_gain_tmp[MBANDS_GN], y_gain_tmp2[MBANDS_GN];
    1277           8 :     Word16 i, idx_g = 0;
    1278           8 :     move16();
    1279           8 :     Word16 mean_4g[1] = { 0 }, tmp16, tmp1, tmp2;
    1280           8 :     move16();
    1281           8 :     Word16 Mbands_gn = MBANDS_GN;
    1282             :     Word16 y_gain_tmp3[MBANDS_GN];
    1283             :     Word16 cnt;
    1284             :     Word32 L_tmp;
    1285             : 
    1286           8 :     mean_4g[0] = 0;
    1287             : 
    1288           8 :     test();
    1289           8 :     test();
    1290           8 :     IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && ( bwidth == NB ) )
    1291             :     {
    1292             : 
    1293             :         /*ftmp1 =  mean(y_gain4, 10)-0.6f;*/
    1294           0 :         L_tmp = L_deposit_l( 0 );
    1295           0 :         FOR( cnt = 0; cnt < 10; cnt++ )
    1296             :         {
    1297           0 :             L_tmp = L_mac( L_tmp, y_gain4[cnt], 3277 /*0.1 in Q15*/ );
    1298             :         }
    1299           0 :         tmp16 = sub( round_fx( L_tmp ), 4915 );
    1300             : 
    1301           0 :         FOR( i = 0; i < Mbands_gn; i++ )
    1302             :         {
    1303           0 :             y_gain_tmp2[i] = y_gain4[i];
    1304           0 :             move16();
    1305             :             /*if(y_gain4[i] < ftmp1-0.6f)*/
    1306           0 :             y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp16 );
    1307           0 :             move16();
    1308             :         }
    1309             : 
    1310           0 :         L_tmp = L_deposit_l( 0 );
    1311           0 :         FOR( i = 0; i < 10; i++ )
    1312             :         {
    1313           0 :             L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 3277 /*0.1 in Q15*/ );
    1314             :         }
    1315             : 
    1316             :         /* Quantized mean gain without clipping */
    1317           0 :         mean_4g[0] = round_fx( L_tmp );
    1318           0 :         move16();
    1319           0 :         idx_g = vquant_fx( mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64 );
    1320           0 :         push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
    1321             : 
    1322           0 :         FOR( i = 0; i < Mbands_gn; i++ )
    1323             :         {
    1324           0 :             y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
    1325           0 :             move16();
    1326             :         }
    1327             :         /*if(y_gain_tmp[9] < -0.3f){y_gain_tmp[9] = -0.3f;}*/
    1328           0 :         y_gain_tmp[9] = s_max( y_gain_tmp[9], -1229 /*0.3 in Q12*/ );
    1329           0 :         move16();
    1330           0 :         set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
    1331           0 :         idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
    1332           0 :         push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
    1333             : 
    1334           0 :         IF( LT_32( core_brate, ACELP_9k60 ) )
    1335             :         {
    1336           0 :             idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
    1337           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1338           0 :             idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
    1339           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
    1340             :         }
    1341             :         ELSE
    1342             :         {
    1343           0 :             idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
    1344           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
    1345           0 :             idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
    1346           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
    1347             :         } /*add end */
    1348             : 
    1349           0 :         test();
    1350           0 :         IF( LE_32( core_brate, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
    1351             :         {
    1352             :             /* Some energy is needed in high band for stat_noise_uv_enc
    1353             :               to be functional in inactive speech */
    1354           0 :             y_gain_tmp[10] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[6], 8192 ), y_gain_tmp[7], 8192 ), y_gain_tmp[8], 8192 ) );
    1355           0 :             move16();
    1356           0 :             y_gain_tmp[11] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[7], 8192 ), y_gain_tmp[8], 8192 ), y_gain_tmp[9], 8192 ) );
    1357           0 :             move16();
    1358             : 
    1359           0 :             y_gain_tmp[12] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[8], 8192 ), y_gain_tmp[9], 8192 ), y_gain_tmp[10], 8192 ) );
    1360           0 :             move16();
    1361           0 :             y_gain_tmp[13] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[9], 8192 ), y_gain_tmp[10], 8192 ), y_gain_tmp[11], 8192 ) );
    1362           0 :             move16();
    1363           0 :             y_gain_tmp[14] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[10], 8192 ), y_gain_tmp[11], 8192 ), y_gain_tmp[12], 8192 ) );
    1364           0 :             move16();
    1365           0 :             y_gain_tmp[15] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[11], 8192 ), y_gain_tmp[12], 8192 ), y_gain_tmp[13], 8192 ) );
    1366           0 :             move16();
    1367             :         }
    1368             :         ELSE
    1369             :         {
    1370           0 :             set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
    1371             :         }
    1372             :     }
    1373             :     ELSE
    1374             :     {
    1375             :         /*ftmp1 =  mean(y_gain4, 16);*/
    1376             : 
    1377           8 :         L_tmp = 0;
    1378           8 :         move32();
    1379         136 :         FOR( cnt = 0; cnt < 16; cnt++ )
    1380             :         {
    1381         128 :             L_tmp = L_mac( L_tmp, y_gain4[cnt], 2048 );
    1382             :         }
    1383           8 :         tmp16 = round_fx( L_tmp );
    1384             : 
    1385           8 :         tmp1 = sub( tmp16, 4915 );
    1386           8 :         tmp2 = add( tmp16, 4915 );
    1387           8 :         L_tmp = 0;
    1388           8 :         move32();
    1389         136 :         FOR( i = 0; i < 16; i++ )
    1390             :         {
    1391         128 :             y_gain_tmp2[i] = y_gain4[i];
    1392         128 :             move16();
    1393         128 :             y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 );
    1394         128 :             move16();
    1395         128 :             y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
    1396         128 :             move16();
    1397         128 :             L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 2048 );
    1398             :         }
    1399           8 :         FOR( ; i < Mbands_gn; i++ )
    1400             :         {
    1401           0 :             y_gain_tmp2[i] = y_gain4[i];
    1402           0 :             move16();
    1403           0 :             y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 ); /* Just the last move is needed, because s_max and s_min could be done in 1 line*/
    1404           0 :             move16();
    1405           0 :             y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
    1406           0 :             move16();
    1407             :         }
    1408             : 
    1409             :         /* Quantized mean gain without clipping */
    1410           8 :         mean_4g[0] = round_fx( L_tmp );
    1411           8 :         move16();
    1412             : 
    1413           8 :         idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 );
    1414           8 :         push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
    1415             : 
    1416         136 :         FOR( i = 0; i < Mbands_gn; i++ )
    1417             :         {
    1418         128 :             y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
    1419         128 :             move16();
    1420             :         }
    1421             : 
    1422           8 :         IF( LT_32( core_brate, ACELP_9k60 ) )
    1423             :         {
    1424             :             /*mvr2r(y_gain_tmp, y_gain_tmp2, 8); */
    1425           0 :             Copy( y_gain_tmp, y_gain_tmp2, 8 );
    1426             : 
    1427           0 :             y_gain_tmp2[8] = y_gain_tmp[8];
    1428           0 :             move16();
    1429           0 :             y_gain_tmp2[9] = y_gain_tmp[10];
    1430           0 :             move16();
    1431           0 :             y_gain_tmp2[10] = y_gain_tmp[12];
    1432           0 :             move16();
    1433           0 :             y_gain_tmp2[11] = y_gain_tmp[14];
    1434           0 :             move16();
    1435             : 
    1436           0 :             idx_g = 0;
    1437           0 :             move16();
    1438             : 
    1439           0 :             idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
    1440           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1441           0 :             idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
    1442           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1443           0 :             idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
    1444           0 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1445           0 :             set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
    1446             : 
    1447             :             /* Update to quantized vector */
    1448           0 :             Copy( y_gain_tmp2, y_gain_tmp, 8 );
    1449             : 
    1450           0 :             Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
    1451           0 :             set16_fx( y_gain_tmp + 8, 0, 8 );
    1452           0 :             fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
    1453             : 
    1454           0 :             Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
    1455           0 :             y_gain_tmp[15] = y_gain_tmp2[11];
    1456           0 :             move16();
    1457           0 :             ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
    1458             : 
    1459           0 :             FOR( i = 8; i < 16; i++ )
    1460             :             {
    1461           0 :                 y_gain_tmp[i] = shl( mult_r( y_gain_tmp[i], 23101 ), 1 );
    1462           0 :                 move16();
    1463             :             }
    1464             : 
    1465           0 :             y_gain_tmp[8] = y_gain_tmp3[0];
    1466           0 :             move16();
    1467           0 :             y_gain_tmp[10] = y_gain_tmp3[1];
    1468           0 :             move16();
    1469           0 :             y_gain_tmp[12] = y_gain_tmp3[2];
    1470           0 :             move16();
    1471           0 :             y_gain_tmp[14] = y_gain_tmp3[3];
    1472           0 :             move16();
    1473             :         }
    1474             :         ELSE
    1475             :         {
    1476           8 :             idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
    1477           8 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
    1478           8 :             idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
    1479           8 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1480           8 :             idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
    1481           8 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
    1482           8 :             idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
    1483           8 :             push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
    1484             :         }
    1485             :     }
    1486             : 
    1487             :     /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
    1488           8 :     GSC_gain_adj( coder_type, core_brate, mean_4g[0], y_gain_tmp2 /* dummy buffer */, y_gain_tmp, y_gainQ );
    1489             : 
    1490           8 :     return mean_4g[0]; /*Q12*/
    1491             : }
    1492             : 
    1493             : 
    1494             : /*-------------------------------------------------------------------*
    1495             :  * VDQ_vec()
    1496             :  *
    1497             :  * Return the dequantized vector of index
    1498             :  *-------------------------------------------------------------------*/
    1499             : 
    1500      100467 : static Word16 VDQ_vec_fx(
    1501             :     Word16 *Qvec_out_fx,       /* o:  Quanitzed vector */
    1502             :     const Word16 *mean_dic_fx, /* i:  average codebook */
    1503             :     const Word16 *dic_fx,      /* i:  codebook         */
    1504             :     const Word16 index_fx,     /* i:  index of codebook*/
    1505             :     const Word16 vec_en_fx     /* i:  vector length    */
    1506             : )
    1507             : {
    1508             :     Word16 i, j;
    1509             : 
    1510             :     /*j =  shr_r(extract_l(L_mult(index_fx,vec_en_fx)),1);*/
    1511      100467 :     j = i_mult2( index_fx, vec_en_fx );
    1512      429702 :     FOR( i = 0; i < vec_en_fx; i++ )
    1513             :     {
    1514      329235 :         Qvec_out_fx[i] = dic_fx[j++];
    1515      329235 :         move16();
    1516             :     }
    1517             : 
    1518      429702 :     FOR( i = 0; i < vec_en_fx; i++ )
    1519             :     {
    1520      329235 :         Qvec_out_fx[i] = add( Qvec_out_fx[i], mean_dic_fx[i] );
    1521      329235 :         move16();
    1522             :     }
    1523             : 
    1524      100467 :     return index_fx;
    1525             : }

Generated by: LCOV version 1.14