LCOV - code coverage report
Current view: top level - lib_enc - enc_higher_acelp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 318 378 84.1 %
Date: 2025-05-03 01:55:50 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"    /* Compilation switches                   */
       6             : #include "cnst.h"       /* Common constants                       */
       7             : #include "prot_fx.h"    /* Function prototypes                    */
       8             : #include "rom_com_fx.h" /* Static table prototypes                */
       9             : #include "rom_com.h"    /* Static table prototypes                */
      10             : #include "prot_fx_enc.h"
      11             : 
      12             : /*---------------------------------------------------------------------*
      13             :  * Local function prototype
      14             :  *---------------------------------------------------------------------*/
      15             : static void find_cn_fx( const Word16 xn[], const Word16 Ap[], const Word16 *p_Aq, Word16 cn[] );
      16             : 
      17             : /*-----------------------------------------------------------------*
      18             :  * Transform domain contribution encoding
      19             :  *-----------------------------------------------------------------*/
      20             : #define Q_MINUS 4
      21        3370 : void transf_cdbk_enc_fx(
      22             :     Encoder_State *st_fx,         /* i/o: encoder state structure                         */
      23             :     const Word16 harm_flag_acelp, /* i  : harmonic flag for higher rates ACELP            Q0*/
      24             :     const Word16 i_subfr,         /* i  : subframe index                                  Q0*/
      25             :     Word16 cn[],                  /* i/o: target vector in residual domain                Q_new*/
      26             :     Word16 exc[],                 /* i/o: pointer to excitation signal frame              Q_new*/
      27             :     const Word16 *p_Aq,           /* i  : 12k8 Lp coefficient                             Q12*/
      28             :     const Word16 Ap[],            /* i  : weighted LP filter coefficients                 Q12*/
      29             :     const Word16 h1[],            /* i  : weighted filter input response                  Q15*/
      30             :     Word16 xn[],                  /* i/o: target vector                                   Q_new + shift -1*/
      31             :     Word16 xn2[],                 /* i/o: target vector for innovation search             Q_new + shift -1*/
      32             :     Word16 y1[],                  /* i/o: zero-memory filtered adaptive excitation        Q_new + shift -1*/
      33             :     const Word16 y2[],            /* i  : zero-memory filtered innovative excitation      Q9*/
      34             :     const Word16 Es_pred,         /* i  : predicited scaled innovation energy             Q8*/
      35             :     Word16 *gain_pit,             /* i/o: adaptive excitation gain                        Q14*/
      36             :     const Word32 gain_code,       /* i  : innovative excitation gain                      Q16*/
      37             :     Word16 g_corr[],              /* o  : ACELP correlation values                        Q15*/
      38             :     const Word16 clip_gain,       /* i  : adaptive gain clipping flag                     Q0*/
      39             :     Word16 *gain_preQ,            /* o  : prequantizer excitation gain                    Q2*/
      40             :     Word16 code_preQ[],           /* o  : prequantizer excitation                         Q_AVQ_OUT_DEC*/
      41             :     Word16 *unbits,               /* o  : number of AVQ unused bits                       Q0*/
      42             :     const Word16 Q_new,           /* i  : Current frame scaling                           */
      43             :     const Word16 shift            /* i  : shifting applied to y1, xn,...                  */
      44             : )
      45             : {
      46             :     Word16 i, index, nBits, Nsv, Es_pred_loc;
      47             :     Word16 x_in[L_SUBFR], x_tran[L_SUBFR], gcode16, stmp;
      48             :     Word16 e_corr, m_corr, e_ener, m_ener, m_den, e_den;
      49             :     Word16 x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND];
      50             :     Word32 L_corr, L_ener, Ltmp, Ltmp1;
      51             :     Word16 nq[L_SUBFR / WIDTH_BAND];
      52             :     Word32 out32[L_SUBFR];
      53             :     Word16 Qdct;
      54             :     Word16 avq_bit_sFlag;
      55             :     Word16 trgtSvPos;
      56             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      57        3370 :     Flag Overflow = 0;
      58        3370 :     move32();
      59             : #endif
      60             : 
      61        3370 :     avq_bit_sFlag = 0;
      62        3370 :     move16();
      63        3370 :     if ( st_fx->element_mode > EVS_MONO )
      64             :     {
      65           0 :         avq_bit_sFlag = 1;
      66           0 :         move16();
      67             :     }
      68             : 
      69             :     /*--------------------------------------------------------------*
      70             :      * Set bit-allocation
      71             :      *--------------------------------------------------------------*/
      72             : 
      73        3370 :     Nsv = 8;
      74        3370 :     move16();
      75        3370 :     nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; /* Q0 */
      76        3370 :     move16();
      77             : 
      78             :     /* increase # of AVQ allocated bits by unused bits from the previous subframe */
      79        3370 :     nBits = add( nBits, *unbits );
      80             : 
      81             :     /*--------------------------------------------------------------*
      82             :      * Compute/Update target
      83             :      * For inactive frame, find target in residual domain
      84             :      * Deemphasis
      85             :      *--------------------------------------------------------------*/
      86        3370 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
      87             :     {
      88           0 :         gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow );
      89           0 :         FOR( i = 0; i < L_SUBFR; i++ )
      90             :         {
      91             :             /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/
      92           0 :             Ltmp = L_mult( gcode16, y2[i] );
      93           0 :             Ltmp = L_shl( Ltmp, add( 5, shift ) );
      94           0 :             Ltmp = L_negate( Ltmp );
      95           0 :             Ltmp = L_mac( Ltmp, xn[i], 16384 );
      96           0 :             Ltmp = L_msu( Ltmp, y1[i], *gain_pit );    /* Q_new + 14 + shift */
      97           0 :             Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */
      98           0 :             x_tran[i] = round_fx_sat( Ltmp );          /*Q_new-1  */
      99           0 :             move16();
     100             :         }
     101           0 :         find_cn_fx( x_tran, Ap, p_Aq, x_in );
     102             :     }
     103             :     ELSE
     104             :     {
     105        3370 :         updt_tar_fx( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR );
     106             :     }
     107        3370 :     Deemph2( x_in, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_deemp_preQ_fx ) );
     108             : 
     109             :     /*--------------------------------------------------------------*
     110             :      * DCT-II
     111             :      *--------------------------------------------------------------*/
     112             : 
     113        3370 :     test();
     114        3370 :     test();
     115        3370 :     test();
     116        3370 :     IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
     117             :     {
     118           0 :         Copy_Scale_sig( x_in, x_tran, L_SUBFR, -Q_MINUS + 1 ); /*Q_new-1 -> Q_new-4*/
     119             :         /*Copy( x_in, x_tran, L_SUBFR );*/
     120           0 :         Qdct = sub( Q_new, Q_MINUS );
     121             :     }
     122             :     ELSE
     123             :     {
     124        3370 :         Qdct = 0;
     125        3370 :         move16();
     126        3370 :         edct2_fx( L_SUBFR, -1, x_in, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
     127        3370 :         Qdct = negate( Qdct );
     128        3370 :         Copy_Scale_sig_32_16( out32, x_tran, L_SUBFR, sub( Qdct, Q_MINUS - 1 ) ); /* Output in Q_new-4 */
     129        3370 :         Qdct = sub( Q_new, Q_MINUS );
     130             :     }
     131             : 
     132             :     /*--------------------------------------------------------------*
     133             :      * Split algebraic vector quantizer based on RE8 lattice
     134             :      *--------------------------------------------------------------*/
     135        3370 :     AVQ_cod_fx( x_tran, x_norm, nBits, Nsv, 0 );
     136             : 
     137             :     /*--------------------------------------------------------------*
     138             :      * Find prequantizer excitation gain
     139             :      * Quantize the gain
     140             :      *--------------------------------------------------------------*/
     141        3370 :     L_corr = L_deposit_l( 0 );
     142        3370 :     L_ener = L_deposit_l( 0 );
     143      219050 :     FOR( i = 0; i < Nsv * 8; i++ )
     144             :     {
     145             :         /*fcorr += fx_tran[i]*(float)ix_norm[i];*/
     146             :         /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/
     147      215680 :         stmp = shl_sat( x_norm[i], Q_AVQ_OUT );
     148      215680 :         L_corr = L_mac_sat( L_corr, x_tran[i], stmp );
     149      215680 :         L_ener = L_mac_sat( L_ener, stmp, stmp );
     150             :     }
     151        3370 :     L_ener = L_max( L_ener, 1 );
     152             : 
     153             :     /* No negative gains allowed in the quantizer*/
     154        3370 :     L_corr = L_max( L_corr, 0 );
     155             : 
     156        3370 :     e_corr = norm_l( L_corr );
     157        3370 :     m_corr = extract_h( L_shl( L_corr, e_corr ) );
     158        3370 :     e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) );
     159        3370 :     e_ener = norm_l( L_ener );
     160        3370 :     m_ener = extract_h( L_shl( L_ener, e_ener ) );
     161        3370 :     e_ener = sub( 30, e_ener );
     162             : 
     163        3370 :     IF( GT_16( m_corr, m_ener ) )
     164             :     {
     165        2319 :         m_corr = shr( m_corr, 1 );
     166        2319 :         e_corr = add( e_corr, 1 );
     167             :     }
     168        3370 :     m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */
     169        3370 :     e_corr = sub( e_corr, e_ener );
     170        3370 :     Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */
     171        3370 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
     172             :     {
     173           0 :         Ltmp1 = L_max( gain_code, 1 );
     174           0 :         e_den = norm_l( Ltmp1 );
     175           0 :         m_den = extract_h( L_shl_sat( Ltmp1, e_den ) );
     176             :         /* ensure m_corr < m_den */
     177           0 :         test();
     178           0 :         IF( m_corr > 0 && m_den > 0 )
     179             :         {
     180           0 :             m_corr = div_s( 16384, m_den );
     181           0 :             e_corr = sub( 14 + 4, e_den );
     182           0 :             Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr );             /*Q12*/
     183           0 :             stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */
     184             :         }
     185             :         ELSE
     186             :         {
     187           0 :             stmp = 0;
     188           0 :             move16();
     189             :         }
     190           0 :         IF( GT_32( st_fx->core_brate, 56000 ) )
     191             :         {
     192           0 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     193             :         }
     194           0 :         ELSE IF( GT_32( st_fx->core_brate, 42000 ) )
     195             :         {
     196           0 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     197             :         }
     198             :         ELSE
     199             :         {
     200           0 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     201             :         }
     202           0 :         Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/
     203           0 :         Ltmp = L_shl_sat( Ltmp, 5 );          /* Q13 -> Q18*/
     204           0 :         *gain_preQ = round_fx_sat( Ltmp );    /* Q2*/
     205             :     }
     206             :     ELSE
     207             :     {
     208        3370 :         IF( Es_pred < 0 )
     209             :         {
     210          35 :             Es_pred_loc = shr( negate( Es_pred ), 2 ); /* Q8 */
     211             :         }
     212             :         ELSE
     213             :         {
     214        3335 :             Es_pred_loc = Es_pred; /* Q8 */
     215        3335 :             move16();
     216             :         }
     217             : 
     218        3370 :         e_den = norm_s( Es_pred_loc );
     219        3370 :         m_den = shl( Es_pred_loc, e_den );
     220             :         /* ensure m_corr < m_den */
     221        3370 :         test();
     222        3370 :         IF( m_corr > 0 && m_den > 0 )
     223             :         {
     224        3369 :             m_corr = div_s( 16384, m_den ); /* 14 - 8 - e_den */
     225        3369 :             e_corr = sub( 14 - 8, e_den );
     226        3369 :             Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q18 */
     227             :         }
     228             :         ELSE
     229             :         {
     230           1 :             Ltmp = L_deposit_l( 0 );
     231             :         }
     232        3370 :         test();
     233        3370 :         IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) )
     234             :         {
     235           0 :             index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
     236             :         }
     237             :         ELSE
     238             :         {
     239        3370 :             index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
     240             :         }
     241        3370 :         Ltmp = L_mult( stmp, Es_pred_loc );    /* Q0*Q8 -> Q9*/
     242        3370 :         Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/
     243        3370 :         *gain_preQ = round_fx( Ltmp );         /* Q2*/
     244             :     }
     245        3370 :     push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS );
     246             : 
     247             :     /*--------------------------------------------------------------*
     248             :      * Encode and multiplex subvectors into bit-stream
     249             :      *--------------------------------------------------------------*/
     250        3370 :     trgtSvPos = Nsv - 1;
     251        3370 :     move16();
     252        3370 :     test();
     253        3370 :     test();
     254        3370 :     test();
     255        3370 :     test();
     256        3370 :     test();
     257        3370 :     IF( avq_bit_sFlag && GT_16( nBits, 85 ) && !harm_flag_acelp && ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, TRANSITION ) || EQ_16( st_fx->coder_type, INACTIVE ) ) )
     258             :     {
     259           0 :         trgtSvPos = 2;
     260           0 :         avq_bit_sFlag = 2;
     261           0 :         move16();
     262           0 :         move16();
     263             :     }
     264             : 
     265        3370 :     AVQ_encmux_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos );
     266             : 
     267             :     /* save # of AVQ unused bits for next subframe */
     268        3370 :     *unbits = nBits; /* Q0 */
     269        3370 :     move16();
     270             : 
     271             :     /* at the last subframe, write AVQ unused bits */
     272        3370 :     test();
     273        3370 :     test();
     274        3370 :     IF( EQ_16( i_subfr, 4 * L_SUBFR ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) )
     275             :     {
     276           0 :         WHILE( *unbits > 0 )
     277             :         {
     278           0 :             i = s_min( *unbits, 16 );
     279           0 :             push_indice( st_fx->hBstr, IND_UNUSED, 0, i );
     280           0 :             *unbits -= i;
     281             :         }
     282             :     }
     283             : 
     284             :     /*--------------------------------------------------------------*
     285             :      * DCT transform
     286             :      *--------------------------------------------------------------*/
     287             : 
     288      219050 :     FOR( i = 0; i < Nsv * WIDTH_BAND; i++ )
     289             :     {
     290      215680 :         x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow );
     291      215680 :         move16();
     292             :     }
     293        3370 :     set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) );
     294             : 
     295        3370 :     test();
     296        3370 :     test();
     297        3370 :     test();
     298        3370 :     IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
     299             :     {
     300           0 :         Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */
     301             :     }
     302             :     ELSE
     303             :     {
     304        3370 :         Qdct = 0;
     305        3370 :         move16();
     306        3370 :         edct2_fx( L_SUBFR, 1, x_tran, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
     307             :         /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/
     308        3370 :         Qdct = negate( Qdct );
     309        3370 :         Copy_Scale_sig_32_16( out32, code_preQ, L_SUBFR, Qdct ); /* Output in Q_AVQ_OUT_DEC */
     310             :         /*qdct = Q_AVQ_OUT_DEC;*/
     311             :     }
     312             : 
     313             :     /*--------------------------------------------------------------*
     314             :      * Preemphasise
     315             :      *--------------------------------------------------------------*/
     316             :     /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
     317        3370 :     test();
     318        3370 :     if ( ( nq[7] != 0 ) && ( GT_16( sub( st_fx->last_nq_preQ, nq[0] ), 7 ) ) )
     319             :     {
     320             :         /* *mem_preemp /= 16; */
     321           0 :         st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
     322           0 :         move16();
     323             :     }
     324        3370 :     st_fx->last_nq_preQ = nq[7];
     325        3370 :     move16();
     326             : 
     327        3370 :     PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) );
     328             : 
     329             :     /*--------------------------------------------------------------*
     330             :      * For inactive segments
     331             :      * - Zero-memory filtered pre-filter excitation
     332             :      * - Update of targets and gain_pit
     333             :      * For inactive segments
     334             :      * - Update xn[L_subfr-1] for updating the memory of the weighting filter
     335             :      *--------------------------------------------------------------*/
     336             : 
     337        3370 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
     338             :     {
     339             :         /*ftemp = fcode_preQ[0] *fh1[L_SUBFR-1];*/
     340           0 :         Ltmp = L_mult( code_preQ[0], h1[L_SUBFR - 1] ); /*1+14+shift + Q_AVQ_OUT */
     341           0 :         FOR( i = 1; i < L_SUBFR; i++ )
     342             :         {
     343             :             /*ftemp += fcode_preQ[i] * fh1[L_SUBFR-1-i];*/
     344           0 :             Ltmp = L_mac( Ltmp, code_preQ[i], h1[L_SUBFR - 1 - i] );
     345             :         }
     346             :         /*fxn[L_SUBFR-1] -= *fgain_preQ * ftemp;*/
     347           0 :         Ltmp = L_shr( Mult_32_16( Ltmp, *gain_preQ ), sub( add( Q_AVQ_OUT_DEC, 2 ), Q_new ) ); /* (2 + 1 + 14 +shift+Q_AVQ_OUT)-(Q_AVQ_OUT+2-Q_new) = 15 + Q_new + shift */
     348           0 :         xn[L_SUBFR - 1] = round_fx( L_sub( L_mult( xn[L_SUBFR - 1], 32767 ), Ltmp ) );         /* -> Q_new + shift -1 */
     349             :     }
     350             :     ELSE
     351             :     {
     352        3370 :         conv_fx( code_preQ, h1, x_tran, L_SUBFR );
     353        3370 :         updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
     354             : 
     355        3370 :         updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
     356        3370 :         *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */
     357             :         /* clip gain if necessary to avoid problems at decoder */
     358        3370 :         test();
     359        3370 :         if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) )
     360             :         {
     361          37 :             *gain_pit = 15565; /* 0.95 in Q15 */
     362          37 :             move16();
     363             :         }
     364        3370 :         updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR );
     365             :     }
     366             : 
     367        3370 :     st_fx->use_acelp_preq = 1;
     368        3370 :     move16();
     369             : 
     370        3370 :     return;
     371             : }
     372       70770 : void transf_cdbk_enc_ivas_fx(
     373             :     Encoder_State *st_fx,         /* i/o: encoder state structure                         */
     374             :     const Word16 harm_flag_acelp, /* i  : harmonic flag for higher rates ACELP            Q0*/
     375             :     const Word16 i_subfr,         /* i  : subframe index                                  Q0*/
     376             :     Word16 cn[],                  /* i/o: target vector in residual domain                Q_new*/
     377             :     Word16 exc[],                 /* i/o: pointer to excitation signal frame              Q_new*/
     378             :     const Word16 *p_Aq,           /* i  : 12k8 Lp coefficient                             Q12*/
     379             :     const Word16 Ap[],            /* i  : weighted LP filter coefficients                 Q12*/
     380             :     const Word16 h1[],            /* i  : weighted filter input response                  Q15*/
     381             :     Word16 xn[],                  /* i/o: target vector                                   Q_new + shift -1*/
     382             :     Word16 xn2[],                 /* i/o: target vector for innovation search             Q_new + shift -1*/
     383             :     Word16 y1[],                  /* i/o: zero-memory filtered adaptive excitation        Q_new + shift -1*/
     384             :     const Word16 y2[],            /* i  : zero-memory filtered innovative excitation      Q9*/
     385             :     const Word16 Es_pred,         /* i  : predicited scaled innovation energy             Q8*/
     386             :     Word16 *gain_pit,             /* i/o: adaptive excitation gain                        Q14*/
     387             :     const Word32 gain_code,       /* i  : innovative excitation gain                      Q16*/
     388             :     Word16 g_corr[],              /* o  : ACELP correlation values                        Q15*/
     389             :     const Word16 clip_gain,       /* i  : adaptive gain clipping flag                     Q0*/
     390             :     Word16 *gain_preQ,            /* o  : prequantizer excitation gain                    Q2*/
     391             :     Word16 code_preQ[],           /* o  : prequantizer excitation                         Q_AVQ_OUT_DEC*/
     392             :     Word16 *unbits,               /* o  : number of AVQ unused bits                       Q0*/
     393             :     const Word16 Q_new,           /* i  : Current frame scaling                           */
     394             :     const Word16 shift            /* i  : shifting applied to y1, xn,...                  */
     395             : )
     396             : {
     397             :     Word16 i, index, nBits, Nsv, Es_pred_loc;
     398             :     Word16 x_in[L_SUBFR], x_tran[L_SUBFR], gcode16, stmp;
     399             :     Word16 e_corr, m_corr, e_ener, m_ener, m_den, e_den;
     400             :     Word16 x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND];
     401             :     Word32 L_corr, L_ener, Ltmp, Ltmp1;
     402             :     Word16 nq[L_SUBFR / WIDTH_BAND];
     403             :     Word32 out32[L_SUBFR];
     404             :     Word16 Qdct;
     405             :     Word16 avq_bit_sFlag;
     406             :     Word16 trgtSvPos;
     407             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     408       70770 :     Flag Overflow = 0;
     409       70770 :     move32();
     410             : #endif
     411             : 
     412       70770 :     avq_bit_sFlag = 0;
     413       70770 :     move16();
     414       70770 :     if ( st_fx->element_mode > EVS_MONO )
     415             :     {
     416       70770 :         avq_bit_sFlag = 1;
     417       70770 :         move16();
     418             :     }
     419             : 
     420             :     /*--------------------------------------------------------------*
     421             :      * Set bit-allocation
     422             :      *--------------------------------------------------------------*/
     423             : 
     424       70770 :     Nsv = 8;
     425       70770 :     move16();
     426       70770 :     nBits = st_fx->acelp_cfg.AVQ_cdk_bits[i_subfr >> 6]; /* Q0 */
     427       70770 :     move16();
     428             : 
     429             :     /* increase # of AVQ allocated bits by unused bits from the previous subframe */
     430       70770 :     nBits = add( nBits, *unbits );
     431             : 
     432             :     /*--------------------------------------------------------------*
     433             :      * Compute/Update target
     434             :      * For inactive frame, find target in residual domain
     435             :      * Deemphasis
     436             :      *--------------------------------------------------------------*/
     437       70770 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
     438             :     {
     439       13015 :         gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow );
     440      845975 :         FOR( i = 0; i < L_SUBFR; i++ )
     441             :         {
     442             :             /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/
     443      832960 :             Ltmp = L_mult( gcode16, y2[i] );
     444      832960 :             Ltmp = L_shl( Ltmp, add( 5, shift ) );
     445      832960 :             Ltmp = L_negate( Ltmp );
     446      832960 :             Ltmp = L_mac( Ltmp, xn[i], 16384 );
     447      832960 :             Ltmp = L_msu( Ltmp, y1[i], *gain_pit );    /* Q_new + 14 + shift */
     448      832960 :             Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */
     449      832960 :             x_tran[i] = round_fx_sat( Ltmp );          /*Q_new-1  */
     450             :         }
     451       13015 :         find_cn_fx( x_tran, Ap, p_Aq, x_in );
     452             :     }
     453             :     ELSE
     454             :     {
     455       57755 :         updt_tar_fx( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR );
     456             :     }
     457       70770 :     Deemph2( x_in, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_deemp_preQ_fx ) );
     458             : 
     459             :     /*--------------------------------------------------------------*
     460             :      * DCT-II
     461             :      *--------------------------------------------------------------*/
     462             : 
     463       70770 :     test();
     464       70770 :     test();
     465       70770 :     test();
     466       70770 :     IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
     467             :     {
     468       41265 :         Copy_Scale_sig( x_in, x_tran, L_SUBFR, -Q_MINUS + 1 ); /*Q_new-1 -> Q_new-4*/
     469             :         /*Copy( x_in, x_tran, L_SUBFR );*/
     470       41265 :         Qdct = sub( Q_new, Q_MINUS );
     471             :     }
     472             :     ELSE
     473             :     {
     474       29505 :         Qdct = 0;
     475       29505 :         move16();
     476       29505 :         edct2_fx( L_SUBFR, -1, x_in, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
     477       29505 :         Qdct = negate( Qdct );
     478       29505 :         Copy_Scale_sig_32_16( out32, x_tran, L_SUBFR, sub( Qdct, Q_MINUS - 1 ) ); /* Output in Q_new-4 */
     479       29505 :         Qdct = sub( Q_new, Q_MINUS );
     480             :     }
     481             : 
     482             :     /*--------------------------------------------------------------*
     483             :      * Split algebraic vector quantizer based on RE8 lattice
     484             :      *--------------------------------------------------------------*/
     485       70770 :     AVQ_cod_fx( x_tran, x_norm, nBits, Nsv, 0 );
     486             : 
     487             :     /*--------------------------------------------------------------*
     488             :      * Find prequantizer excitation gain
     489             :      * Quantize the gain
     490             :      *--------------------------------------------------------------*/
     491       70770 :     L_corr = L_deposit_l( 0 );
     492       70770 :     L_ener = L_deposit_l( 0 );
     493     4600050 :     FOR( i = 0; i < Nsv * 8; i++ )
     494             :     {
     495             :         /*fcorr += fx_tran[i]*(float)ix_norm[i];*/
     496             :         /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/
     497     4529280 :         stmp = shl_sat( x_norm[i], Q_AVQ_OUT );
     498     4529280 :         L_corr = L_mac_sat( L_corr, x_tran[i], stmp );
     499     4529280 :         L_ener = L_mac_sat( L_ener, stmp, stmp );
     500             :     }
     501       70770 :     L_ener = L_max( L_ener, 1 );
     502             : 
     503             :     /* No negative gains allowed in the quantizer*/
     504       70770 :     L_corr = L_max( L_corr, 0 );
     505             : 
     506       70770 :     e_corr = norm_l( L_corr );
     507       70770 :     m_corr = extract_h( L_shl( L_corr, e_corr ) );
     508       70770 :     e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) );
     509       70770 :     e_ener = norm_l( L_ener );
     510       70770 :     m_ener = extract_h( L_shl( L_ener, e_ener ) ); /* 30 - e-ener */
     511       70770 :     e_ener = sub( 30, e_ener );
     512             : 
     513       70770 :     IF( GT_16( m_corr, m_ener ) )
     514             :     {
     515       40866 :         m_corr = shr( m_corr, 1 ); /* e_corr + 1 */
     516       40866 :         e_corr = add( e_corr, 1 );
     517             :     }
     518       70770 :     m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */
     519       70770 :     e_corr = sub( e_corr, e_ener );
     520       70770 :     Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */
     521       70770 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
     522             :     {
     523       13015 :         Ltmp1 = L_max( gain_code, 1 );
     524       13015 :         e_den = norm_l( Ltmp1 );
     525       13015 :         m_den = extract_h( L_shl_sat( Ltmp1, e_den ) );
     526             :         /* ensure m_corr < m_den */
     527       13015 :         test();
     528       13015 :         IF( m_corr > 0 && m_den > 0 )
     529             :         {
     530       13015 :             m_corr = div_s( 16384, m_den );
     531       13015 :             e_corr = sub( 14 + 4, e_den );
     532       13015 :             Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr );             /*Q12*/
     533       13015 :             stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */
     534             :         }
     535             :         ELSE
     536             :         {
     537           0 :             stmp = 0;
     538           0 :             move16();
     539             :         }
     540       13015 :         IF( GT_32( st_fx->core_brate, 56000 ) )
     541             :         {
     542           0 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     543             :         }
     544       13015 :         ELSE IF( GT_32( st_fx->core_brate, 42000 ) )
     545             :         {
     546        1570 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     547             :         }
     548             :         ELSE
     549             :         {
     550       11445 :             index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
     551             :         }
     552       13015 :         Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/
     553       13015 :         Ltmp = L_shl_sat( Ltmp, 5 );          /* Q13 -> Q18*/
     554       13015 :         *gain_preQ = round_fx_sat( Ltmp );    /* Q2*/
     555       13015 :         move16();
     556             :     }
     557             :     ELSE
     558             :     {
     559       57755 :         IF( Es_pred < 0 )
     560             :         {
     561         160 :             Es_pred_loc = shr( negate( Es_pred ), 2 );
     562             :         }
     563             :         ELSE
     564             :         {
     565       57595 :             Es_pred_loc = Es_pred;
     566       57595 :             move16();
     567             :         }
     568             : 
     569       57755 :         e_den = norm_s( Es_pred_loc );
     570       57755 :         m_den = shl( Es_pred_loc, e_den );
     571             :         /* ensure m_corr < m_den */
     572       57755 :         test();
     573       57755 :         IF( m_corr > 0 && m_den > 0 )
     574             :         {
     575       56948 :             m_corr = div_s( 16384, m_den );
     576       56948 :             e_corr = sub( 14 - 8, e_den );
     577       56948 :             Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q16 */
     578             :         }
     579             :         ELSE
     580             :         {
     581         807 :             Ltmp = L_deposit_l( 0 );
     582             :         }
     583       57755 :         test();
     584       57755 :         IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) )
     585             :         {
     586       52040 :             index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
     587             :         }
     588             :         ELSE
     589             :         {
     590        5715 :             index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
     591             :         }
     592       57755 :         Ltmp = L_mult( stmp, Es_pred_loc );    /* Q0*Q8 -> Q9*/
     593       57755 :         Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/
     594       57755 :         *gain_preQ = round_fx( Ltmp );         /* Q2*/
     595       57755 :         move16();
     596             :     }
     597       70770 :     push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS );
     598             : 
     599             :     /*--------------------------------------------------------------*
     600             :      * Encode and multiplex subvectors into bit-stream
     601             :      *--------------------------------------------------------------*/
     602       70770 :     trgtSvPos = sub( Nsv, 1 );
     603       70770 :     move16();
     604       70770 :     test();
     605       70770 :     test();
     606       70770 :     test();
     607       70770 :     test();
     608       70770 :     test();
     609       70770 :     IF( avq_bit_sFlag && GT_16( nBits, 85 ) && !harm_flag_acelp && ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, TRANSITION ) || EQ_16( st_fx->coder_type, INACTIVE ) ) )
     610             :     {
     611       20080 :         trgtSvPos = 2;
     612       20080 :         avq_bit_sFlag = 2;
     613       20080 :         move16();
     614       20080 :         move16();
     615             :     }
     616             : 
     617       70770 :     AVQ_encmux_ivas_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos );
     618             : 
     619             :     /* save # of AVQ unused bits for next subframe */
     620       70770 :     *unbits = nBits;
     621       70770 :     move16();
     622             : 
     623             :     /* at the last subframe, write AVQ unused bits */
     624       70770 :     test();
     625       70770 :     test();
     626       70770 :     IF( EQ_16( i_subfr, 4 * L_SUBFR ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) )
     627             :     {
     628       26622 :         WHILE( *unbits > 0 )
     629             :         {
     630       12468 :             i = s_min( *unbits, 16 );
     631       12468 :             push_indice( st_fx->hBstr, IND_UNUSED, 0, i );
     632       12468 :             *unbits = sub( *unbits, i );
     633       12468 :             move16();
     634             :         }
     635             :     }
     636             : 
     637             :     /*--------------------------------------------------------------*
     638             :      * DCT transform
     639             :      *--------------------------------------------------------------*/
     640             : 
     641     4600050 :     FOR( i = 0; i < Nsv * WIDTH_BAND; i++ )
     642             :     {
     643     4529280 :         x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow );
     644     4529280 :         move16();
     645             :     }
     646       70770 :     set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) );
     647             : 
     648       70770 :     test();
     649       70770 :     test();
     650       70770 :     test();
     651       70770 :     IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
     652             :     {
     653       41265 :         Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */
     654             :     }
     655             :     ELSE
     656             :     {
     657       29505 :         Qdct = 0;
     658       29505 :         move16();
     659       29505 :         edct2_fx( L_SUBFR, 1, x_tran, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
     660             :         /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/
     661       29505 :         Qdct = negate( Qdct );
     662       29505 :         Copy_Scale_sig_32_16( out32, code_preQ, L_SUBFR, Qdct ); /* Output in Q_AVQ_OUT_DEC */
     663             :         /*qdct = Q_AVQ_OUT_DEC;*/
     664             :     }
     665             : 
     666             :     /*--------------------------------------------------------------*
     667             :      * Preemphasise
     668             :      *--------------------------------------------------------------*/
     669             :     /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
     670       70770 :     test();
     671       70770 :     if ( ( nq[7] != 0 ) && ( GT_16( sub( st_fx->last_nq_preQ, nq[0] ), 7 ) ) )
     672             :     {
     673             :         /* *mem_preemp /= 16; */
     674           1 :         st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
     675           1 :         move16();
     676             :     }
     677       70770 :     st_fx->last_nq_preQ = nq[7];
     678       70770 :     move16();
     679             : 
     680             :     /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
     681       70770 :     test();
     682       70770 :     test();
     683       70770 :     test();
     684       70770 :     test();
     685       70770 :     test();
     686       70770 :     IF( GT_16( st_fx->element_mode, EVS_MONO ) && NE_16( st_fx->coder_type, INACTIVE ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && !harm_flag_acelp && code_preQ[0] != 0 )
     687             :     {
     688       18410 :         IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 4 ) ) )
     689             :         {
     690           0 :             st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
     691           0 :             move16();
     692             :         }
     693       18410 :         ELSE IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 3 ) ) )
     694             :         {
     695           0 :             st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 3 );
     696           0 :             move16();
     697             :         }
     698             :     }
     699             : 
     700       70770 :     st_fx->last_code_preq = shr( code_preQ[L_SUBFR - 1], 9 ); // Q0
     701       70770 :     move16();
     702             : 
     703       70770 :     PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) );
     704             : 
     705             :     /*--------------------------------------------------------------*
     706             :      * For inactive segments
     707             :      * - Zero-memory filtered pre-filter excitation
     708             :      * - Update of targets and gain_pit
     709             :      * For inactive segments
     710             :      * - Update xn[L_subfr-1] for updating the memory of the weighting filter
     711             :      *--------------------------------------------------------------*/
     712             : 
     713       70770 :     IF( EQ_16( st_fx->coder_type, INACTIVE ) )
     714             :     {
     715             :         /*ftemp = fcode_preQ[0] *fh1[L_SUBFR-1];*/
     716       13015 :         Ltmp = L_mult( code_preQ[0], h1[L_SUBFR - 1] ); /*1+14+shift + Q_AVQ_OUT */
     717      832960 :         FOR( i = 1; i < L_SUBFR; i++ )
     718             :         {
     719             :             /*ftemp += fcode_preQ[i] * fh1[L_SUBFR-1-i];*/
     720      819945 :             Ltmp = L_mac( Ltmp, code_preQ[i], h1[L_SUBFR - 1 - i] );
     721             :         }
     722             :         /*fxn[L_SUBFR-1] -= *fgain_preQ * ftemp;*/
     723       13015 :         Ltmp = L_shr( Mult_32_16( Ltmp, *gain_preQ ), sub( add( Q_AVQ_OUT_DEC, 2 ), Q_new ) ); /* (2 + 1 + 14 +shift+Q_AVQ_OUT)-(Q_AVQ_OUT+2-Q_new) = 15 + Q_new + shift */
     724       13015 :         xn[L_SUBFR - 1] = round_fx( L_sub( L_mult( xn[L_SUBFR - 1], 32767 ), Ltmp ) );         /* -> Q_new + shift -1 */
     725             :     }
     726             :     ELSE
     727             :     {
     728       57755 :         conv_fx( code_preQ, h1, x_tran, L_SUBFR );
     729       57755 :         updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
     730             : 
     731       57755 :         updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
     732       57755 :         *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */
     733       57755 :         move16();
     734             :         /* clip gain if necessary to avoid problems at decoder */
     735       57755 :         test();
     736       57755 :         if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) )
     737             :         {
     738          50 :             *gain_pit = 15565; /* 0.95 in Q14 */
     739          50 :             move16();
     740             :         }
     741       57755 :         updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR );
     742             :     }
     743             : 
     744       70770 :     st_fx->use_acelp_preq = 1;
     745       70770 :     move16();
     746             : 
     747       70770 :     return;
     748             : }
     749             : /*-------------------------------------------------------------------*
     750             :  * Find target in residual domain - cn[]
     751             :  *-------------------------------------------------------------------*/
     752             : 
     753       13015 : static void find_cn_fx(
     754             :     const Word16 xn[],  /* i  : target signal                                   Qx*/
     755             :     const Word16 Ap[],  /* i  : weighted LP filter coefficients                 Q12*/
     756             :     const Word16 *p_Aq, /* i  : 12k8 LP coefficients                            Q12*/
     757             :     Word16 cn[]         /* o  : target signal in residual domain                Qx*/
     758             : )
     759             : {
     760             :     Word16 tmp, tmp_fl[L_SUBFR + M];
     761             : 
     762       13015 :     set16_fx( tmp_fl, 0, M );
     763       13015 :     Copy( xn, tmp_fl + M, L_SUBFR ); /* Qx */
     764       13015 :     tmp = 0;
     765       13015 :     move16();
     766       13015 :     PREEMPH_FX( tmp_fl + M, PREEMPH_FAC_16k, L_SUBFR, &tmp );
     767       13015 :     syn_filt_s_lc_fx( 0, Ap, tmp_fl + M, tmp_fl + M, L_SUBFR );
     768       13015 :     Residu3_lc_fx( p_Aq, M, tmp_fl + M, cn, L_SUBFR, 1 );
     769             : 
     770       13015 :     return;
     771             : }
     772             : 
     773             : 
     774             : /*-----------------------------------------------------------------*
     775             :  * Transform domain contribution encoding
     776             :  *-----------------------------------------------------------------*/
     777      114293 : Word16 gain_quant_fx(                     /* o:  quantization index                             Q0*/
     778             :                       Word32 *gain,       /* i:  quantized gain                                 Q16*/
     779             :                       Word16 *gain16,     /* o:  quantized gain                                 expg*/
     780             :                       const Word16 c_min, /* i:  log10 of lower limit in                Q14*/
     781             :                       const Word16 c_max, /* i:  log10 of upper limit in                Q13*/
     782             :                       const Word16 bits,  /* i:   number of bits to quantize    Q0*/
     783             :                       Word16 *expg        /* o:  output exponent of gain16      */
     784             : )
     785             : {
     786             :     Word16 index, levels;
     787             :     Word16 c_gain;
     788             :     Word16 e_tmp, f_tmp, exp;
     789             :     Word16 tmp, tmp1, tmp2, frac;
     790             :     Word32 L_tmp;
     791             : 
     792      114293 :     levels = shl( 1, bits );
     793             :     /* Prevent gain to be smaller than 0.0003.                       */
     794             :     /* This is to avoid an overflow when the gain is very small      */
     795             :     /* the log10 give a high negative value in Q13 that overflow     */
     796             :     /* on this code (the resulting value of 'index' is not affected. */
     797             :     /*   tmp2 = msu_r(L_deposit_h(c_gain),c_min,16384)               */
     798      114293 :     L_tmp = L_max( *gain, 20 );
     799             : 
     800             :     /*c_min = (float)log10(min);*/
     801             :     /*c_mult = (float) ((levels-1)/(log10(max)-c_min));*/
     802             : 
     803             :     /*tmp = c_mult * ((float)log10(*gain) - c_min);
     804             :         = ((levels-1)/(log10(max)-log10(min)))*((float)log10(*gain) - log10(min));*/
     805             : 
     806      114293 :     e_tmp = norm_l( L_tmp );
     807      114293 :     f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
     808      114293 :     e_tmp = sub( 30 - 16, e_tmp );                     /*Q(min)=16*/
     809      114293 :     L_tmp = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ /*log10(2) in Q15*/
     810      114293 :     c_gain = round_fx( L_shl( L_tmp, 13 ) );           /* Q13 */
     811             : 
     812             :     /*tmp1 = sub(c_max,c_min); Q14*/
     813             :     /*tmp2 = sub(c_gain,c_min); Q14*/
     814             : 
     815      114293 :     tmp1 = msu_r_sat( L_deposit_h( c_max /*in Q13 already*/ ), c_min, 16384 );  /*Q13*/
     816      114293 :     tmp2 = msu_r_sat( L_deposit_h( c_gain /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/
     817      114293 :     IF( tmp1 != 0 )
     818             :     {
     819      114293 :         exp = norm_s( tmp1 );
     820      114293 :         frac = div_s( shl( 1, sub( 14, exp ) ), tmp1 );                                    /*Q(15-exp)*/
     821      114293 :         L_tmp = L_mult( tmp2, frac );                                                      /*Q(30-exp)*/
     822      114293 :         L_tmp = Mult_32_16( L_tmp, sub( levels, 1 ) );                                     /*Q(15-exp)*/
     823      114293 :         index = extract_l( L_shr( L_add( L_tmp, shr( 1 << 14, exp ) ), sub( 15, exp ) ) ); /* Q0 */
     824             :     }
     825             :     ELSE
     826             :     {
     827           0 :         L_tmp = L_mult( tmp2, sub( levels, 1 ) );                  /*Q15*/
     828           0 :         index = extract_l( L_shr( L_add( L_tmp, 1 << 14 ), 15 ) ); /* Q0 */
     829             :     }
     830             : 
     831      114293 :     index = s_max( index, 0 );
     832      114293 :     index = s_min( index, sub( levels, 1 ) );
     833             : 
     834             :     /**gain = (float)pow( 10.0, (((float)index)/c_mult) + c_min );
     835             :     y = index/c_mult + c_min;
     836             :       = (index/(levels-1))*(log10(max) - log10(min)) + log10(min);
     837             :       = z*log10(max) + (1-z)*log10(min)
     838             :       z = (index/(levels-1))*/
     839      114293 :     tmp = div_s( index, sub( levels, 1 ) );            /*Q15*/
     840      114293 :     L_tmp = L_mult( tmp, c_max );                      /*Q29*/
     841      114293 :     L_tmp = L_mac0( L_tmp, sub( 32767, tmp ), c_min ); /*Q29*/
     842             : 
     843      114293 :     L_tmp = Mult_32_16( L_tmp, 27213 ); /*Q27, 3.321928 in Q13*/
     844      114293 :     L_tmp = L_shr( L_tmp, 11 );         /*Q27->Q16*/
     845             : 
     846      114293 :     frac = L_Extract_lc( L_tmp, expg ); /* Extract exponent of gcode0 */
     847             : 
     848      114293 :     *gain16 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     849             :     /* output of Pow2() will be: */
     850             :     /* 16384 < Pow2() <= 32767 */
     851      114293 :     *expg = sub( *expg, 14 );
     852      114293 :     move16();
     853             : 
     854      114293 :     return ( index );
     855             : }

Generated by: LCOV version 1.14