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

Generated by: LCOV version 1.14