LCOV - code coverage report
Current view: top level - lib_dec - FEC_scale_syn_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 185 264 70.1 %
Date: 2025-05-03 01:55:50 Functions: 1 1 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             : 
       9             : /*-------------------------------------------------------------------*
      10             :  * Local constants
      11             :  *-------------------------------------------------------------------*/
      12             : #define AGC_FX        32113 /* 0.98f */
      13             : #define SCLSYN_LAMBDA ( 9830 /*0.3f Q15*/ )
      14             : 
      15             : /*========================================================================*/
      16             : /* FUNCTION : FEC_scale_syn_fx()                                                                                  */
      17             : /*------------------------------------------------------------------------*/
      18             : /* PURPOSE : Smooth the speech energy evolution when                                      */
      19             : /*                   recovering after a BAD frame                                                                 */
      20             : /*------------------------------------------------------------------------*/
      21             : /* INPUT ARGUMENTS :                                                                                                      */
      22             : /* _ (Word16) L_frame       :  length of the frame                                                */
      23             : /* _ (Word16) *update_flg   :  indication about resynthesis                               */
      24             : /* _ (Word16) st_fx->clas_dec: frame classification                                            */
      25             : /* _ (Word16) last_good     : last good frame classification                      */
      26             : /* _ (Word16[]) synth       : synthesized speech at Fs = 12k8 Hz   Q_syn  */
      27             : /* _ (Word16[])  pitch    : pitch values for each subframe          Q0    */
      28             : /* _ (Word32)  L_enr_old  :energy at the end of previous frame          Q0        */
      29             : /* _ (Word16) L_enr_q     : transmitted energy for current frame    Q0    */
      30             : /* _ (Word16) coder_type          : coder type                                */
      31             : /* _ (Word16) st_fx->prev_bfi_fx: previous frame BFI                      */
      32             : /* _ (Word16) st_fx->last_core_brate_fx: previous frame core bitrate      */
      33             : /* _ (Word16[]) mem_tmp   : temp. initial synthesis filter states   Q_syn */
      34             : /* _ (Word16) Q_exc       : quantized LSPs from frame end                     */
      35             : /* _ (Word16) Q_syn       : quantized LSPs from frame end                     */
      36             : /*------------------------------------------------------------------------*/
      37             : /* INPUT/OUTPUT ARGUMENTS :                                                                                               */
      38             : /* _ (Word16[]) exc       : excitation signal without enhancement      Q_exc  */
      39             : /* _ (Word16[]) exc2      : excitation signal with enhancement     Q_exc  */
      40             : /* _ (Word16[]) Aq        :  LP filter coefs (can be modified if BR)   Q12    */
      41             : /*------------------------------------------------------------------------*/
      42             : /* OUTPUT ARGUMENTS :                                                                                                     */
      43             : /*------------------------------------------------------------------------*/
      44             : 
      45             : /* _ (Word16[]) st_fx->mem_syn2        : initial synthesis filter states Q_syn */
      46             : /* _ (Word16) st_fx->old_enr_LP   : LP filter E of last            Q5     */
      47             : /*                                                                      good voiced frame                     */
      48             : /*------------------------------------------------------------------------*/
      49             : /* RETURN ARGUMENTS :                                                                                                     */
      50             : /* _ None                                                                                                                                 */
      51             : /*========================================================================*/
      52             : 
      53             : #ifndef REMOVE_EVS_DUPLICATES
      54             : void FEC_scale_syn_fx(
      55             :     const Word16 L_frame,          /* i  : length of the frame                     */
      56             :     Word16 *update_flg,            /* o: flag indicating re-synthesis after scaling*/
      57             :     Word16 clas,                   /* i/o: frame classification                    */
      58             :     const Word16 last_good,        /* i:   last good frame classification          */
      59             :     Word16 *synth,                 /* i/o: synthesized speech at Fs = 12k8 Hz      Q_syn*/
      60             :     const Word16 *pitch,           /* i:   pitch values for each subframe          Q0*/
      61             :     Word32 L_enr_old,              /* i:   energy at the end of previous frame     */
      62             :     Word32 L_enr_q,                /* i:   transmitted energy for current frame    */
      63             :     const Word16 coder_type,       /* i:   coder type                              */
      64             :     const Word16 LSF_Q_prediction, /* i  : LSF prediction mode                     */
      65             :     Word16 *scaling_flag,          /* i/o: flag to indicate energy control of syn  */
      66             :     Word32 *lp_ener_FEC_av,        /* i/o: averaged voiced signal energy           Q0*/
      67             :     Word32 *lp_ener_FEC_max,       /* i/o: averaged voiced signal energy           Q0*/
      68             :     const Word16 bfi,              /* i:   current  frame BFI                      */
      69             :     const Word32 total_brate,      /* i:   total bitrate                           */
      70             :     const Word16 prev_bfi,         /* i:   previous frame BFI                      */
      71             :     const Word32 last_core_brate,  /* i:   previous frame core bitrate             */
      72             :     Word16 *exc,                   /* i/o: excitation signal without enhancement   */
      73             :     Word16 *exc2,                  /* i/o: excitation signal with enhancement      */
      74             :     Word16 Aq[],                   /* i/o: LP filter coefs (can be modified if BR) Q12*/
      75             :     Word16 *old_enr_LP,            /* i/o: LP filter E of last good voiced frame   Q3*/
      76             :     const Word16 *mem_tmp,         /* i:   temp. initial synthesis filter states   Q_syn*/
      77             :     Word16 *mem_syn,               /* o:   initial synthesis filter states         Q_syn*/
      78             :     Word16 Q_exc,
      79             :     Word16 Q_syn,
      80             :     const Word16 avoid_lpc_burst_on_recovery, /* i  : if true the excitation energy is limited if LP has big gain */
      81             :     const Word16 force_scaling                /* i: force scaling                             */
      82             : )
      83             : {
      84             :     Word16 i;
      85             :     Word32 L_enr1, L_enr2;
      86             :     Word16 gain1, gain2, enr_LP;
      87             :     Word16 tmp, tmp2, exp, exp2;
      88             :     Word16 tmp3;
      89             :     Word32 L_tmp;
      90             :     Word16 scaling;
      91             :     Word32 ener_max, L_enr2_av, L_ener2_max;
      92             :     Word16 h1[L_FRAME / 2], tilt, pitch_dist, mean_pitch;
      93             :     Word16 k;
      94             :     Word32 L_mean_pitch;
      95             : 
      96             :     enr_LP = 0;
      97             :     move16();
      98             :     gain2 = 0;
      99             :     move16();
     100             :     gain1 = 0;
     101             :     move16();
     102             :     *update_flg = 0;
     103             :     move16();
     104             :     L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */
     105             :     scaling = 16384;
     106             :     move16(); /* Q14*/
     107             : 
     108             :     /*-----------------------------------------------------------------*
     109             :      * Find the synthesis filter impulse response on voiced
     110             :      *-----------------------------------------------------------------*/
     111             :     test();
     112             :     IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     113             :     {
     114             :         IF( EQ_16( L_frame, L_FRAME ) )
     115             :         {
     116             :             enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR );
     117             :         }
     118             :         ELSE /* L_frame == L_FRAME16k */
     119             :         {
     120             :             enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR16k - 1 ) * ( M + 1 ), L_SUBFR ); /*Q3*/
     121             :         }
     122             :     }
     123             : 
     124             :     /*-----------------------------------------------------------------*
     125             :      * Define when to scale the synthesis
     126             :      *-----------------------------------------------------------------*/
     127             : 
     128             :     IF( bfi )
     129             :     {
     130             :         *scaling_flag = 1;
     131             :         move16(); /* Always check synthesis on bad frames */
     132             :     }
     133             :     ELSE IF( prev_bfi )
     134             :     {
     135             :         test();
     136             :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) )
     137             :         {
     138             :             *scaling_flag = 2;
     139             :             move16(); /* Decoded LSFs affected  */
     140             :         }
     141             :         ELSE IF( NE_16( coder_type, TRANSITION ) )
     142             :         {
     143             :             *scaling_flag = 1;
     144             :             move16(); /* SN, but not TC mode - LSF still affected by the interpolation */
     145             :         }
     146             :         ELSE
     147             :         {
     148             :             *scaling_flag = 0;
     149             :             move16(); /* LSF still possibly affected due to interpolation */
     150             :         }
     151             :         scaling = 24576; /*1.5 Q14*/
     152             :         move16();
     153             :     }
     154             :     ELSE
     155             :     {
     156             :         test();
     157             :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) )
     158             :         {
     159             :             *scaling_flag = 2;
     160             :             move16(); /* Continue with energy control till the end of AR prediction */
     161             :         }
     162             :         ELSE IF( *scaling_flag > 0 )
     163             :         {
     164             :             ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */
     165             :             move16();
     166             :         }
     167             :         scaling = 32767; /*2.0 Q14*/
     168             :         move16();
     169             :     }
     170             : 
     171             :     /*-----------------------------------------------------------------*
     172             :      * Find the energy/gain at the end of the frame
     173             :      *-----------------------------------------------------------------*/
     174             : 
     175             :     frame_ener_fx( L_frame, clas, synth, pitch[( L_frame >> 6 ) - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 );
     176             : 
     177             : 
     178             :     test();
     179             :     test();
     180             :     IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) )
     181             :     {
     182             :         /* previous frame erased and no TC frame */
     183             :         IF( *scaling_flag > 0 )
     184             :         {
     185             :             /*enr2 += 0.01f;*/
     186             :             L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */
     187             : 
     188             :             IF( bfi ) /* In all bad frames, limit the gain to 1  */
     189             :             {
     190             :                 /* gain2 = (float)sqrt( enr_old / enr2 );*/
     191             :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 );
     192             :                 gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     193             : 
     194             :                 /*if( gain2 > 1.0f )gain2 = 1.0f;*/
     195             :                 gain2 = s_min( gain2, 16384 );
     196             : 
     197             :                 /* find the energy/gain at the beginning of the frame */
     198             :                 frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     199             : 
     200             :                 /*enr1 += 0.1f;*/
     201             :                 L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */
     202             : 
     203             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
     204             :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     205             :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     206             : 
     207             :                 /*if( gain1 > 1.0f )gain1 = 1.0f;*/
     208             :                 gain1 = s_min( gain1, 16384 ); /*Q14*/
     209             :             }
     210             :             ELSE /* good frame  */
     211             :             {
     212             :                 IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */
     213             :                 {
     214             :                     L_enr_q = L_enr2; /*Q0*/
     215             :                     set16_fx( h1, 0, L_FRAME / 2 );
     216             :                     h1[0] = 1024; /*1.0f in Q10*/
     217             :                     move16();
     218             :                     /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     219             :                     E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     220             : 
     221             :                     /*Compute tilt */
     222             :                     /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     223             :                     /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     224             :                     /*tilt = rr1 / rr0;*/
     225             :                     tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     226             :                     pitch_dist = 0;
     227             :                     move16();
     228             :                     L_mean_pitch = L_mult( pitch[0], 8192 /*1.0f in Q13*/ ); /*Q14*/
     229             :                     FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ )
     230             :                     {
     231             :                         pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/
     232             :                         L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 );               /*Q14*/
     233             :                     }
     234             :                     /*pitch_dist /= (float)(NB_SUBFR-1);        */
     235             :                     pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/
     236             :                     /*mean_pitch /= (float)(NB_SUBFR);*/
     237             :                     mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/
     238             : 
     239             : 
     240             :                     test();
     241             :                     test();
     242             :                     test();
     243             :                     test();
     244             :                     test();
     245             :                     test();
     246             :                     IF( ( GT_16( tilt, 22938 ) ) &&                                                     /* HF resonnant filter */
     247             :                         ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short      */
     248             :                         ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) )
     249             :                     {
     250             :                         /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/
     251             :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     252             :                     }
     253             :                     ELSE
     254             :                     {
     255             :                         ener_max = *lp_ener_FEC_max; /*Q0*/
     256             :                         move32();
     257             :                         test();
     258             :                         if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) )
     259             :                         {
     260             :                             ener_max = *lp_ener_FEC_av; /*Q0*/
     261             :                             move32();
     262             :                         }
     263             :                         /*if( enr_old > ener_max )ener_max = enr_old;*/
     264             :                         ener_max = L_max( ener_max, L_enr_old );
     265             : 
     266             :                         /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/
     267             :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/
     268             :                     }
     269             :                 }
     270             :                 /*gain2 = (float)sqrt( enr_q / enr2 );*/
     271             :                 L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */
     272             :                 L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 );
     273             :                 gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     274             : 
     275             :                 /*-----------------------------------------------------------------*
     276             :                  * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
     277             :                  *-----------------------------------------------------------------*/
     278             : 
     279             :                 test();
     280             :                 test();
     281             :                 test();
     282             :                 test();
     283             :                 test();
     284             :                 test();
     285             :                 IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) ||
     286             :                       EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) &&
     287             :                     prev_bfi )
     288             :                 {
     289             :                     /* voiced -> unvoiced signal transition */
     290             :                     /* CNG -> active signal transition */
     291             :                     gain1 = gain2; /*Q14*/
     292             :                     move16();
     293             :                 }
     294             :                 ELSE
     295             :                 {
     296             :                     /* find the energy at the beginning of the frame */
     297             :                     frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     298             : 
     299             :                     /*enr1 += 0.1f;*/
     300             :                     L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */
     301             : 
     302             :                     /*gain1 = (float)sqrt( enr_old / enr1 );*/
     303             :                     L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     304             :                     gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     305             : 
     306             :                     /*if( gain1 > 1.2f )gain1 = 1.2f;*/
     307             :                     /* prevent clipping */
     308             :                     gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ );
     309             : 
     310             :                     /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */
     311             :                     test();
     312             :                     test();
     313             :                     if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi )
     314             :                     {
     315             :                         gain1 = gain2; /*Q14*/
     316             :                         move16();
     317             :                     }
     318             :                 }
     319             : 
     320             :                 L_enr2 = L_enr_q; /*Q0*/
     321             :                 move32();         /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC  */
     322             :             }
     323             : 
     324             :             /*------------------------------------------------------------------------------*
     325             :              * Smooth the energy evolution by exponentially evolving from gain1 to gain2
     326             :              *------------------------------------------------------------------------------*/
     327             : 
     328             :             /*gain2 *= ( 1.0f - AGC );*/
     329             :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) ); /*Q30*/
     330             :             FOR( i = 0; i < L_frame; i++ )
     331             :             {
     332             :                 /*gain1 = gain1 * AGC + gain2;*/
     333             :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
     334             :                 /*exc[i] *= gain1;*/
     335             :                 exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 );
     336             :                 move16();
     337             :                 /*exc2[i] *= gain1;*/
     338             :                 exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 );
     339             :                 move16();
     340             :             }
     341             :             /* smoothing is done in excitation domain, so redo synthesis */
     342             :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
     343             :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
     344             :             *update_flg = 1;
     345             :             move16();
     346             :         }
     347             :     }
     348             :     ELSE
     349             :     {
     350             :         /* previous frame erased and no TC frame */
     351             :         test();
     352             :         IF( prev_bfi && NE_16( coder_type, TRANSITION ) )
     353             :         {
     354             :             IF( L_enr_q == 0 )
     355             :             {
     356             :                 L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */
     357             :                 set16_fx( h1, 0, L_FRAME / 2 );
     358             :                 h1[0] = 1024; /*1.0f in Q10*/
     359             :                 move16();
     360             :                 /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     361             :                 E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     362             :                 /*Compute tilt */
     363             :                 /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     364             :                 /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     365             :                 /*tilt = rr1 / rr0;*/
     366             :                 tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     367             :                 test();
     368             :                 test();
     369             :                 test();
     370             :                 test();
     371             :                 test();
     372             :                 test();
     373             :                 test();
     374             :                 test();
     375             :                 IF( ( ( ( EQ_32( total_brate, ACELP_13k20 ) ) || ( EQ_32( total_brate, ACELP_12k85 ) ) || ( EQ_32( total_brate, ACELP_12k15 ) ) || ( EQ_32( total_brate, ACELP_11k60 ) ) ||
     376             :                         ( EQ_32( total_brate, ACELP_9k60 ) ) ) &&
     377             :                       ( GT_16( tilt, 22938 ) ) &&                                               /* HF resonnant filter */
     378             :                       ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */
     379             :                 {
     380             :                     /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/
     381             :                     L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     382             :                 }
     383             :                 ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     384             :                 {
     385             :                     /* Voiced-voiced recovery */
     386             :                     test();
     387             :                     IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) )
     388             :                     {
     389             :                         /* enr_q /= enr_LP */
     390             :                         exp = norm_l( L_enr_q );
     391             :                         tmp = extract_h( L_shl( L_enr_q, exp ) );
     392             : 
     393             :                         exp2 = norm_s( enr_LP );
     394             :                         tmp2 = shl( enr_LP, exp2 );
     395             : 
     396             :                         exp = sub( exp2, exp );
     397             : 
     398             :                         tmp3 = sub( tmp, tmp2 );
     399             :                         IF( tmp3 > 0 )
     400             :                         {
     401             :                             tmp = shr( tmp, 1 );
     402             :                             exp = add( exp, 1 );
     403             :                         }
     404             :                         tmp = div_s( tmp, tmp2 );
     405             : 
     406             :                         /* L_enr_q *= 2 * *old_enr_LP */
     407             :                         L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp );
     408             :                     }
     409             : 
     410             :                     ELSE
     411             :                     {
     412             :                         test();
     413             :                         IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) )
     414             :                         {
     415             :                             exp = norm_s( enr_LP );
     416             :                             tmp = shl( enr_LP, exp );
     417             : 
     418             :                             exp2 = 7;
     419             :                             move16();
     420             :                             tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */
     421             :                             move16();
     422             :                             exp = sub( exp2, exp );
     423             : 
     424             :                             IF( GT_16( tmp, tmp2 ) )
     425             :                             {
     426             :                                 tmp = shr( tmp, 1 );
     427             :                                 exp = add( exp, 1 );
     428             :                             }
     429             :                             tmp = div_s( tmp, tmp2 );                     /* tmp*2^exp = enr_LP/20.0 */
     430             :                             L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* L_tmp*2^exp = sqrt(20.0/enr_LP) */
     431             :                             L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp );
     432             :                         }
     433             :                     }
     434             :                 }
     435             : 
     436             :                 test();
     437             :                 test();
     438             :                 test();
     439             :                 test();
     440             :                 IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) || force_scaling )
     441             :                 {
     442             : 
     443             :                     IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */
     444             :                     {
     445             :                         L_enr_q = L_add( Mpy_32_16_1( L_enr_old, 32767 - SCLSYN_LAMBDA ), Mpy_32_16_1( L_enr_q, SCLSYN_LAMBDA ) ); /*Q0*/
     446             :                     }
     447             :                 }
     448             :             }
     449             : 
     450             :             L_enr_q = L_max( 1, L_enr_q );
     451             : 
     452             :             /* gain2 = (float)sqrt( enr_q / enr2 );*/
     453             :             exp = norm_l( L_enr_q );
     454             :             tmp = extract_h( L_shl( L_enr_q, exp ) );
     455             : 
     456             :             exp2 = norm_l( L_enr2 );
     457             :             tmp2 = extract_h( L_shl( L_enr2, exp2 ) );
     458             : 
     459             :             exp2 = sub( exp, exp2 ); /* Denormalize and substract */
     460             : 
     461             :             tmp3 = sub( tmp2, tmp );
     462             :             IF( tmp3 > 0 )
     463             :             {
     464             :                 tmp2 = shr( tmp2, 1 );
     465             :                 exp2 = add( exp2, 1 );
     466             :             }
     467             : 
     468             :             tmp = div_s( tmp2, tmp );
     469             : 
     470             :             L_tmp = L_deposit_h( tmp );
     471             :             L_tmp = Isqrt_lc( L_tmp, &exp2 );
     472             :             gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     473             :             /*-----------------------------------------------------------------*
     474             :              * Clipping of the smoothing gain at the frame end
     475             :              *-----------------------------------------------------------------*/
     476             : 
     477             :             gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */
     478             :             if ( LT_32( L_enr_q, 2 ) )
     479             :             {
     480             :                 gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */
     481             :             }
     482             : 
     483             :             /*-----------------------------------------------------------------*
     484             :              * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
     485             :              *-----------------------------------------------------------------*/
     486             : 
     487             :             test();
     488             :             test();
     489             :             test();
     490             :             test();
     491             :             test();
     492             :             test();
     493             :             IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */
     494             :             {
     495             :                 gain1 = shr( gain2, 1 ); /*0.5f * gain2*/
     496             :             }
     497             :             /*------------------------------------------------------------*
     498             :              * voiced->unvoiced transition recovery
     499             :              *------------------------------------------------------------*/
     500             :             ELSE IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || /* voiced->unvoiced transition recovery */
     501             :                      EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA )                                 /* CNG -> active signal transition */
     502             :             {
     503             :                 gain1 = gain2; /*Q14*/
     504             :                 move16();
     505             :             }
     506             :             ELSE
     507             :             {
     508             :                 /*--------------------------------------------------------*
     509             :                  * Find the energy at the beginning of the frame
     510             :                  *--------------------------------------------------------*/
     511             :                 tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 );
     512             : 
     513             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
     514             :                 exp = norm_l( L_enr_old );
     515             :                 tmp = extract_h( L_shl( L_enr_old, exp ) );
     516             :                 exp2 = norm_l( L_enr1 );
     517             :                 tmp2 = extract_h( L_shl( L_enr1, exp2 ) );
     518             : 
     519             :                 exp2 = sub( exp, exp2 ); /* Denormalize and substract */
     520             : 
     521             :                 tmp3 = sub( tmp2, tmp );
     522             : 
     523             :                 IF( tmp3 > 0 )
     524             :                 {
     525             :                     tmp2 = shr( tmp2, 1 );
     526             :                     exp2 = add( exp2, 1 );
     527             :                 }
     528             : 
     529             :                 tmp = div_s( tmp2, tmp );
     530             : 
     531             :                 L_tmp = L_deposit_h( tmp );
     532             :                 L_tmp = Isqrt_lc( L_tmp, &exp2 );
     533             :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     534             :                 /* exp2 is always <= 1 */
     535             : 
     536             :                 gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ );
     537             : 
     538             :                 test();
     539             :                 test();
     540             :                 if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) )
     541             :                 {
     542             :                     gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ );
     543             :                 }
     544             : 
     545             :                 /*--------------------------------------------------------*
     546             :                  * Prevent a catastrophy in case of offset followed by onset
     547             :                  *--------------------------------------------------------*/
     548             :                 test();
     549             :                 if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) )
     550             :                 {
     551             :                     gain1 = gain2; /*Q14*/
     552             :                     move16();
     553             :                 }
     554             :             }
     555             :             /*-----------------------------------------------------------------*
     556             :              * Smooth the energy evolution by exponentially evolving from
     557             :              * gain1 to gain2
     558             :              *-----------------------------------------------------------------*/
     559             : 
     560             :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
     561             : 
     562             :             FOR( i = 0; i < L_frame; i++ )
     563             :             {
     564             :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
     565             :                 exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 );
     566             :                 move16();
     567             :                 exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 );
     568             :                 move16();
     569             :             }
     570             : 
     571             :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
     572             :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
     573             :             *update_flg = 1;
     574             :             move16();
     575             :         }
     576             :     }
     577             :     /*-----------------------------------------------------------------*
     578             :      * Update low-pass filtered energy for voiced frames
     579             :      *-----------------------------------------------------------------*/
     580             : 
     581             :     test();
     582             :     test();
     583             :     IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) )
     584             :     {
     585             :         IF( EQ_16( clas, VOICED_TRANSITION ) )
     586             :         {
     587             :             L_enr2_av = L_enr2; /*Q0*/
     588             :             move32();
     589             :             frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 );
     590             :         }
     591             :         ELSE
     592             :         {
     593             :             L_ener2_max = L_enr2; /*Q0*/
     594             :             move32();
     595             :             frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 );
     596             :         }
     597             : 
     598             :         /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av;      move32();*/
     599             :         *lp_ener_FEC_av = Madd_32_16( Mult_32_16( *lp_ener_FEC_av, 31130 /*0.95f in Q15*/ ), L_enr2_av, 1638 /*0.05F Q15*/ ); /*Q0*/
     600             :         move32();
     601             :         /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max;      move32();*/
     602             :         *lp_ener_FEC_max = Madd_32_16( Mult_32_16( *lp_ener_FEC_max, 31130 /*0.95f in Q15*/ ), L_ener2_max, 1638 /*0.05F Q15*/ ); /*Q0*/
     603             :         move32();
     604             :     }
     605             : 
     606             :     /*-----------------------------------------------------------------*
     607             :      * Update the LP filter energy for voiced frames
     608             :      *-----------------------------------------------------------------*/
     609             :     test();
     610             :     if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     611             :     {
     612             :         *old_enr_LP = enr_LP; /*Q3*/
     613             :         move16();
     614             :     }
     615             : 
     616             :     return;
     617             : }
     618             : #endif
     619      140736 : void FEC_scale_syn_ivas_fx(
     620             :     const Word16 L_frame,          /* i  : length of the frame                     */
     621             :     Word16 *update_flg,            /* o: flag indicating re-synthesis after scaling*/
     622             :     Word16 clas,                   /* i/o: frame classification                    */
     623             :     const Word16 last_good,        /* i:   last good frame classification          */
     624             :     Word16 *synth,                 /* i/o: synthesized speech at Fs = 12k8 Hz      Q_syn*/
     625             :     const Word16 *pitch,           /* i:   pitch values for each subframe          Q0*/
     626             :     Word32 L_enr_old,              /* i:   energy at the end of previous frame     */
     627             :     Word32 L_enr_q,                /* i:   transmitted energy for current frame    */
     628             :     const Word16 coder_type,       /* i:   coder type                              */
     629             :     const Word16 LSF_Q_prediction, /* i  : LSF prediction mode                     */
     630             :     Word16 *scaling_flag,          /* i/o: flag to indicate energy control of syn  */
     631             :     Word32 *lp_ener_FEC_av,        /* i/o: averaged voiced signal energy           Q0*/
     632             :     Word32 *lp_ener_FEC_max,       /* i/o: averaged voiced signal energy           Q0*/
     633             :     const Word16 bfi,              /* i:   current  frame BFI                      */
     634             :     const Word32 total_brate,      /* i:   total bitrate                           */
     635             :     const Word16 prev_bfi,         /* i:   previous frame BFI                      */
     636             :     const Word32 last_core_brate,  /* i:   previous frame core bitrate             */
     637             :     Word16 *exc,                   /* i/o: excitation signal without enhancement   */
     638             :     Word16 *exc2,                  /* i/o: excitation signal with enhancement      */
     639             :     Word16 Aq[],                   /* i/o: LP filter coefs (can be modified if BR) Q12*/
     640             :     Word16 *old_enr_LP,            /* i/o: LP filter E of last good voiced frame   Q3*/
     641             :     const Word16 *mem_tmp,         /* i:   temp. initial synthesis filter states   Q_syn*/
     642             :     Word16 *mem_syn,               /* o:   initial synthesis filter states         Q_syn*/
     643             :     Word16 Q_exc,
     644             :     Word16 Q_syn,
     645             : #ifdef REMOVE_EVS_DUPLICATES
     646             :     const Word16 element_mode, /* i  : element mode                            */
     647             : #endif
     648             :     const Word16 avoid_lpc_burst_on_recovery, /* i  : if true the excitation energy is limited if LP has big gain */
     649             :     const Word16 force_scaling                /* i: force scaling                             */
     650             : )
     651             : {
     652             :     Word16 i;
     653             :     Word32 L_enr1, L_enr2;
     654             :     Word16 gain1, gain2, enr_LP;
     655             :     Word16 tmp, tmp2, exp, exp2;
     656             :     Word16 tmp3;
     657             :     Word32 L_tmp;
     658             :     Word16 scaling;
     659             :     Word32 ener_max, L_enr2_av, L_ener2_max;
     660             :     Word16 h1[L_FRAME / 2], tilt, pitch_dist, mean_pitch;
     661             :     Word16 k;
     662             :     Word32 L_mean_pitch;
     663             : 
     664      140736 :     enr_LP = 0;
     665      140736 :     move16();
     666      140736 :     gain2 = 0;
     667      140736 :     move16();
     668      140736 :     gain1 = 0;
     669      140736 :     move16();
     670      140736 :     *update_flg = 0;
     671      140736 :     move16();
     672      140736 :     L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */
     673      140736 :     scaling = 16384;
     674      140736 :     move16(); /* Q14*/
     675             : 
     676             :     /*-----------------------------------------------------------------*
     677             :      * Find the synthesis filter impulse response on voiced
     678             :      *-----------------------------------------------------------------*/
     679      140736 :     test();
     680      140736 :     IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     681             :     {
     682       81679 :         IF( EQ_16( L_frame, L_FRAME ) )
     683             :         {
     684       44331 :             enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR );
     685             :         }
     686             :         ELSE /* L_frame == L_FRAME16k */
     687             :         {
     688       37348 :             enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR16k - 1 ) * ( M + 1 ), L_SUBFR ); /*Q3*/
     689             :         }
     690             :     }
     691             : 
     692             :     /*-----------------------------------------------------------------*
     693             :      * Define when to scale the synthesis
     694             :      *-----------------------------------------------------------------*/
     695             : 
     696      140736 :     IF( bfi )
     697             :     {
     698           0 :         *scaling_flag = 1;
     699           0 :         move16(); /* Always check synthesis on bad frames */
     700             :     }
     701      140736 :     ELSE IF( prev_bfi )
     702             :     {
     703        1602 :         test();
     704        1602 :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) )
     705             :         {
     706        1344 :             *scaling_flag = 2;
     707        1344 :             move16(); /* Decoded LSFs affected  */
     708             :         }
     709         258 :         ELSE IF( NE_16( coder_type, TRANSITION ) )
     710             :         {
     711         102 :             *scaling_flag = 1;
     712         102 :             move16(); /* SN, but not TC mode - LSF still affected by the interpolation */
     713             :         }
     714             :         ELSE
     715             :         {
     716         156 :             *scaling_flag = 0;
     717         156 :             move16(); /* LSF still possibly affected due to interpolation */
     718             :         }
     719        1602 :         scaling = 24576; /*1.5 Q14*/
     720        1602 :         move16();
     721             :     }
     722             :     ELSE
     723             :     {
     724      139134 :         test();
     725      139134 :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) )
     726             :         {
     727         550 :             *scaling_flag = 2;
     728         550 :             move16(); /* Continue with energy control till the end of AR prediction */
     729             :         }
     730      138584 :         ELSE IF( *scaling_flag > 0 )
     731             :         {
     732        1996 :             ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */
     733        1996 :             move16();
     734             :         }
     735      139134 :         scaling = 32767; /*2.0 Q14*/
     736      139134 :         move16();
     737             :     }
     738             : 
     739             :     /*-----------------------------------------------------------------*
     740             :      * Find the energy/gain at the end of the frame
     741             :      *-----------------------------------------------------------------*/
     742             : 
     743      140736 :     tmp = sub( 3, getScaleFactor16( synth, L_frame ) );
     744             : 
     745             : #ifdef REMOVE_EVS_DUPLICATES
     746      140736 :     test();
     747      140736 :     IF( tmp > 0 && GT_16( element_mode, EVS_MONO ) )
     748             : #else
     749             :     IF( tmp > 0 )
     750             : #endif
     751        3803 :     {
     752             :         Word16 synth_tmp[L_FRAME16k];
     753        3803 :         Copy_Scale_sig( synth, synth_tmp, L_frame, -tmp ); // Q_synth - tmp
     754        3803 :         frame_ener_fx( L_frame, clas, synth_tmp, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, sub( Q_syn, tmp ), 3, 0 );
     755             :     }
     756             :     ELSE
     757             :     {
     758      136933 :         frame_ener_fx( L_frame, clas, synth, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 );
     759             :     }
     760             : 
     761      140736 :     test();
     762      140736 :     test();
     763      140736 :     IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) )
     764             :     {
     765             :         /* previous frame erased and no TC frame */
     766          55 :         IF( *scaling_flag > 0 )
     767             :         {
     768             :             /*enr2 += 0.01f;*/
     769           0 :             L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */
     770             : 
     771           0 :             IF( bfi ) /* In all bad frames, limit the gain to 1  */
     772             :             {
     773             :                 /* gain2 = (float)sqrt( enr_old / enr2 );*/
     774           0 :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 );
     775           0 :                 gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     776             : 
     777             :                 /*if( gain2 > 1.0f )gain2 = 1.0f;*/
     778           0 :                 gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /*Q14*/
     779             : 
     780             :                 /* find the energy/gain at the beginning of the frame */
     781           0 :                 frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     782             : 
     783             :                 /*enr1 += 0.1f;*/
     784           0 :                 L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */
     785             : 
     786             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
     787           0 :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     788           0 :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     789             : 
     790             :                 /*if( gain1 > 1.0f )gain1 = 1.0f;*/
     791           0 :                 gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
     792             :             }
     793             :             ELSE /* good frame  */
     794             :             {
     795           0 :                 IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */
     796             :                 {
     797           0 :                     L_enr_q = L_enr2; /*Q0*/
     798           0 :                     set16_fx( h1, 0, L_FRAME / 2 );
     799           0 :                     h1[0] = 1024; /*1.0F in Q10*/
     800           0 :                     move16();
     801             :                     /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     802           0 :                     E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     803             : 
     804             :                     /*Compute tilt */
     805             :                     /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     806             :                     /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     807             :                     /*tilt = rr1 / rr0;*/
     808           0 :                     tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     809           0 :                     pitch_dist = 0;
     810           0 :                     move16();
     811           0 :                     L_mean_pitch = L_mult( pitch[0], 8192 ); /*Q14*/
     812           0 :                     FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ )
     813             :                     {
     814           0 :                         pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/
     815           0 :                         L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 );               /*Q14*/
     816             :                     }
     817             :                     /*pitch_dist /= (float)(NB_SUBFR-1);        */
     818           0 :                     pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/
     819             :                     /*mean_pitch /= (float)(NB_SUBFR);*/
     820           0 :                     mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/
     821             : 
     822             : 
     823           0 :                     test();
     824           0 :                     test();
     825           0 :                     test();
     826           0 :                     test();
     827           0 :                     test();
     828           0 :                     test();
     829           0 :                     IF( ( GT_16( tilt, 22938 ) ) &&                                                     /* HF resonnant filter */
     830             :                         ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short      */
     831             :                         ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) )
     832             :                     {
     833             :                         /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/
     834           0 :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     835             :                     }
     836             :                     ELSE
     837             :                     {
     838           0 :                         ener_max = *lp_ener_FEC_max; /*Q0*/
     839           0 :                         move32();
     840           0 :                         test();
     841           0 :                         if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) )
     842             :                         {
     843           0 :                             ener_max = *lp_ener_FEC_av; /*Q0*/
     844           0 :                             move32();
     845             :                         }
     846             :                         /*if( enr_old > ener_max )ener_max = enr_old;*/
     847           0 :                         ener_max = L_max( ener_max, L_enr_old );
     848             : 
     849             :                         /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/
     850           0 :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/
     851             :                     }
     852             :                 }
     853             :                 /*gain2 = (float)sqrt( enr_q / enr2 );*/
     854           0 :                 L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */
     855           0 :                 L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 );
     856           0 :                 gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     857             : 
     858             :                 /*-----------------------------------------------------------------*
     859             :                  * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
     860             :                  *-----------------------------------------------------------------*/
     861             : 
     862           0 :                 test();
     863           0 :                 test();
     864           0 :                 test();
     865           0 :                 test();
     866           0 :                 test();
     867           0 :                 test();
     868           0 :                 IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) ||
     869             :                       EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) &&
     870             :                     prev_bfi )
     871             :                 {
     872             :                     /* voiced -> unvoiced signal transition */
     873             :                     /* CNG -> active signal transition */
     874           0 :                     gain1 = gain2; /*Q14*/
     875           0 :                     move16();
     876             :                 }
     877             :                 ELSE
     878             :                 {
     879             :                     /* find the energy at the beginning of the frame */
     880           0 :                     frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     881             : 
     882             :                     /*enr1 += 0.1f;*/
     883           0 :                     L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */
     884             : 
     885             :                     /*gain1 = (float)sqrt( enr_old / enr1 );*/
     886           0 :                     L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     887           0 :                     gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     888             : 
     889             :                     /*if( gain1 > 1.2f )gain1 = 1.2f;*/
     890             :                     /* prevent clipping */
     891           0 :                     gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ );
     892             : 
     893             :                     /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */
     894           0 :                     test();
     895           0 :                     test();
     896           0 :                     if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi )
     897             :                     {
     898           0 :                         gain1 = gain2; /*Q14*/
     899           0 :                         move16();
     900             :                     }
     901             :                 }
     902             : 
     903           0 :                 L_enr2 = L_enr_q; /*Q0*/
     904           0 :                 move32();         /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC  */
     905             :             }
     906             : 
     907             :             /*------------------------------------------------------------------------------*
     908             :              * Smooth the energy evolution by exponentially evolving from gain1 to gain2
     909             :              *------------------------------------------------------------------------------*/
     910             : 
     911             :             /*gain2 *= ( 1.0f - AGC );*/
     912           0 :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
     913           0 :             FOR( i = 0; i < L_frame; i++ )
     914             :             {
     915             :                 /*gain1 = gain1 * AGC + gain2;*/
     916           0 :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
     917             :                 /*exc[i] *= gain1;*/
     918           0 :                 exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 );
     919           0 :                 move16();
     920             :                 /*exc2[i] *= gain1;*/
     921           0 :                 exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 );
     922           0 :                 move16();
     923             :             }
     924             :             /* smoothing is done in excitation domain, so redo synthesis */
     925           0 :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
     926           0 :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
     927           0 :             *update_flg = 1;
     928           0 :             move16();
     929             :         }
     930             :     }
     931             :     ELSE
     932             :     {
     933             :         /* previous frame erased and no TC frame */
     934      140681 :         test();
     935      140681 :         IF( prev_bfi && NE_16( coder_type, TRANSITION ) )
     936             :         {
     937        1446 :             IF( L_enr_q == 0 )
     938             :             {
     939         488 :                 L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */
     940         488 :                 set16_fx( h1, 0, L_FRAME / 2 );
     941         488 :                 h1[0] = 1024; /*1.0f in Q10*/
     942         488 :                 move16();
     943             :                 /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     944         488 :                 E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     945             :                 /*Compute tilt */
     946             :                 /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     947             :                 /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     948             :                 /*tilt = rr1 / rr0;*/
     949         488 :                 tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     950         488 :                 test();
     951         488 :                 test();
     952         488 :                 test();
     953         488 :                 test();
     954         488 :                 test();
     955         488 :                 test();
     956         488 :                 test();
     957         488 :                 test();
     958         488 :                 IF( ( ( ( EQ_32( total_brate, ACELP_13k20 ) ) || ( EQ_32( total_brate, ACELP_12k85 ) ) || ( EQ_32( total_brate, ACELP_12k15 ) ) || ( EQ_32( total_brate, ACELP_11k60 ) ) ||
     959             :                         ( EQ_32( total_brate, ACELP_9k60 ) ) ) &&
     960             :                       ( GT_16( tilt, 22938 ) ) &&                                               /* HF resonnant filter */
     961             :                       ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */
     962             :                 {
     963             :                     /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/
     964           0 :                     L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     965             :                 }
     966         488 :                 ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     967             :                 {
     968             :                     /* Voiced-voiced recovery */
     969         262 :                     test();
     970         262 :                     IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) )
     971             :                     {
     972             :                         /* enr_q /= enr_LP */
     973          12 :                         exp = norm_l( L_enr_q );
     974          12 :                         tmp = extract_h( L_shl( L_enr_q, exp ) );
     975             : 
     976          12 :                         exp2 = norm_s( enr_LP );
     977          12 :                         tmp2 = shl( enr_LP, exp2 );
     978             : 
     979          12 :                         exp = sub( exp2, exp );
     980             : 
     981          12 :                         tmp3 = sub( tmp, tmp2 );
     982          12 :                         IF( tmp3 > 0 )
     983             :                         {
     984           4 :                             tmp = shr( tmp, 1 );
     985           4 :                             exp = add( exp, 1 );
     986             :                         }
     987          12 :                         tmp = div_s( tmp, tmp2 ); /*Q15*/
     988             : 
     989             :                         /* L_enr_q *= 2 * *old_enr_LP */
     990          12 :                         L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp ); /*Q0*/
     991             :                     }
     992             : 
     993             :                     ELSE
     994             :                     {
     995         250 :                         test();
     996         250 :                         IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) )
     997             :                         {
     998           3 :                             exp = norm_s( enr_LP );
     999           3 :                             tmp = shl( enr_LP, exp );
    1000             : 
    1001           3 :                             exp2 = 7;
    1002           3 :                             move16();
    1003           3 :                             tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */
    1004           3 :                             move16();
    1005           3 :                             exp = sub( exp2, exp );
    1006             : 
    1007           3 :                             IF( GT_16( tmp, tmp2 ) )
    1008             :                             {
    1009           3 :                                 tmp = shr( tmp, 1 );
    1010           3 :                                 exp = add( exp, 1 );
    1011             :                             }
    1012           3 :                             tmp = div_s( tmp, tmp2 );                            /* tmp*2^exp = enr_LP/20.0 */
    1013           3 :                             L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp );        /* L_tmp*2^exp = sqrt(20.0/enr_LP) */
    1014           3 :                             L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp ); /*Q0*/
    1015             :                         }
    1016             :                     }
    1017             :                 }
    1018             : 
    1019         488 :                 test();
    1020         488 :                 test();
    1021         488 :                 test();
    1022         488 :                 test();
    1023         488 :                 IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) || force_scaling )
    1024             :                 {
    1025             : 
    1026         262 :                     IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */
    1027             :                     {
    1028          97 :                         L_enr_q = L_add( Mpy_32_16_1( L_enr_old, 32767 - SCLSYN_LAMBDA ), Mpy_32_16_1( L_enr_q, SCLSYN_LAMBDA ) ); /*Q0*/
    1029             :                     }
    1030             :                 }
    1031             :             }
    1032             : 
    1033        1446 :             L_enr_q = L_max( 1, L_enr_q );
    1034             : 
    1035             :             /* gain2 = (float)sqrt( enr_q / enr2 );*/
    1036        1446 :             exp = norm_l( L_enr_q );
    1037        1446 :             tmp = extract_h( L_shl( L_enr_q, exp ) );
    1038             : 
    1039        1446 :             exp2 = norm_l( L_enr2 );
    1040        1446 :             tmp2 = extract_h( L_shl( L_enr2, exp2 ) );
    1041             : 
    1042        1446 :             exp2 = sub( exp, exp2 ); /* Denormalize and substract */
    1043             : 
    1044        1446 :             tmp3 = sub( tmp2, tmp );
    1045        1446 :             IF( tmp3 > 0 )
    1046             :             {
    1047         139 :                 tmp2 = shr( tmp2, 1 );
    1048         139 :                 exp2 = add( exp2, 1 );
    1049             :             }
    1050             : 
    1051        1446 :             tmp = div_s( tmp2, tmp );
    1052             : 
    1053        1446 :             L_tmp = L_deposit_h( tmp );
    1054        1446 :             L_tmp = Isqrt_lc( L_tmp, &exp2 );
    1055        1446 :             gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
    1056             :             /*-----------------------------------------------------------------*
    1057             :              * Clipping of the smoothing gain at the frame end
    1058             :              *-----------------------------------------------------------------*/
    1059             : 
    1060        1446 :             gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */
    1061        1446 :             if ( LT_32( L_enr_q, 2 ) )
    1062             :             {
    1063          21 :                 gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */
    1064             :             }
    1065             : 
    1066             :             /*-----------------------------------------------------------------*
    1067             :              * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
    1068             :              *-----------------------------------------------------------------*/
    1069             : 
    1070        1446 :             test();
    1071        1446 :             test();
    1072        1446 :             test();
    1073        1446 :             test();
    1074        1446 :             test();
    1075        1446 :             test();
    1076        1446 :             IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */
    1077             :             {
    1078          19 :                 gain1 = shr( gain2, 1 );
    1079             :             }
    1080             :             /*------------------------------------------------------------*
    1081             :              * voiced->unvoiced transition recovery
    1082             :              *------------------------------------------------------------*/
    1083        1427 :             ELSE IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || /* voiced->unvoiced transition recovery */
    1084             :                      EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA )                                 /* CNG -> active signal transition */
    1085             :             {
    1086          90 :                 gain1 = gain2; /*Q14*/
    1087          90 :                 move16();
    1088             :             }
    1089             :             ELSE
    1090             :             {
    1091             :                 /*--------------------------------------------------------*
    1092             :                  * Find the energy at the beginning of the frame
    1093             :                  *--------------------------------------------------------*/
    1094        1337 :                 tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 );
    1095             : 
    1096             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
    1097        1337 :                 exp = norm_l( L_enr_old );
    1098        1337 :                 tmp = extract_h( L_shl( L_enr_old, exp ) );
    1099        1337 :                 exp2 = norm_l( L_enr1 );
    1100        1337 :                 tmp2 = extract_h( L_shl( L_enr1, exp2 ) );
    1101             : 
    1102        1337 :                 exp2 = sub( exp, exp2 ); /* Denormalize and substract */
    1103             : 
    1104        1337 :                 tmp3 = sub( tmp2, tmp );
    1105             : 
    1106        1337 :                 IF( tmp3 > 0 )
    1107             :                 {
    1108         652 :                     tmp2 = shr( tmp2, 1 );
    1109         652 :                     exp2 = add( exp2, 1 );
    1110             :                 }
    1111             : 
    1112        1337 :                 tmp = div_s( tmp2, tmp );
    1113             : 
    1114        1337 :                 L_tmp = L_deposit_h( tmp );
    1115        1337 :                 L_tmp = Isqrt_lc( L_tmp, &exp2 );
    1116        1337 :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
    1117             :                 /* exp2 is always <= 1 */
    1118             : 
    1119        1337 :                 gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ ); /*Q14*/
    1120             : 
    1121        1337 :                 test();
    1122        1337 :                 test();
    1123        1337 :                 if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) )
    1124             :                 {
    1125           4 :                     gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
    1126             :                 }
    1127             : 
    1128             :                 /*--------------------------------------------------------*
    1129             :                  * Prevent a catastrophy in case of offset followed by onset
    1130             :                  *--------------------------------------------------------*/
    1131        1337 :                 test();
    1132        1337 :                 if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) )
    1133             :                 {
    1134           5 :                     gain1 = gain2; /*Q14*/
    1135           5 :                     move16();
    1136             :                 }
    1137             :             }
    1138             :             /*-----------------------------------------------------------------*
    1139             :              * Smooth the energy evolution by exponentially evolving from
    1140             :              * gain1 to gain2
    1141             :              *-----------------------------------------------------------------*/
    1142             : 
    1143        1446 :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
    1144             : 
    1145      434278 :             FOR( i = 0; i < L_frame; i++ )
    1146             :             {
    1147      432832 :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
    1148      432832 :                 exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 );
    1149      432832 :                 move16();
    1150      432832 :                 exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 );
    1151      432832 :                 move16();
    1152             :             }
    1153             : 
    1154        1446 :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
    1155        1446 :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
    1156        1446 :             *update_flg = 1;
    1157        1446 :             move16();
    1158             :         }
    1159             :     }
    1160             :     /*-----------------------------------------------------------------*
    1161             :      * Update low-pass filtered energy for voiced frames
    1162             :      *-----------------------------------------------------------------*/
    1163             : 
    1164      140736 :     test();
    1165      140736 :     test();
    1166      140736 :     IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) )
    1167             :     {
    1168       81679 :         IF( EQ_16( clas, VOICED_TRANSITION ) )
    1169             :         {
    1170        5824 :             L_enr2_av = L_enr2; /*Q0*/
    1171        5824 :             move32();
    1172        5824 :             frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 );
    1173             :         }
    1174             :         ELSE
    1175             :         {
    1176       75855 :             L_ener2_max = L_enr2; /*Q0*/
    1177       75855 :             move32();
    1178       75855 :             frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 );
    1179             :         }
    1180             : 
    1181             :         /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av;      move32();*/
    1182       81679 :         *lp_ener_FEC_av = Madd_32_16( Mult_32_16( *lp_ener_FEC_av, 31130 /*0.95F in Q15*/ ), L_enr2_av, 1638 /*0.05 in Q15*/ );
    1183       81679 :         move32();
    1184             :         /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max;      move32();*/
    1185       81679 :         *lp_ener_FEC_max = Madd_32_16( Mult_32_16( *lp_ener_FEC_max, 31130 /*0.95F in Q15*/ ), L_ener2_max, 1638 /*0.05 in Q15*/ );
    1186       81679 :         move32();
    1187             :     }
    1188             : 
    1189             :     /*-----------------------------------------------------------------*
    1190             :      * Update the LP filter energy for voiced frames
    1191             :      *-----------------------------------------------------------------*/
    1192      140736 :     test();
    1193      140736 :     if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
    1194             :     {
    1195       81679 :         *old_enr_LP = enr_LP; /*Q3*/
    1196       81679 :         move16();
    1197             :     }
    1198             : 
    1199      140736 :     return;
    1200             : }

Generated by: LCOV version 1.14