LCOV - code coverage report
Current view: top level - lib_dec - FEC_scale_syn_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 185 264 70.1 %
Date: 2025-05-17 01:59:02 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      140736 : void FEC_scale_syn_fx(
      54             :     const Word16 L_frame,          /* i  : length of the frame                     */
      55             :     Word16 *update_flg,            /* o: flag indicating re-synthesis after scaling*/
      56             :     Word16 clas,                   /* i/o: frame classification                    */
      57             :     const Word16 last_good,        /* i:   last good frame classification          */
      58             :     Word16 *synth,                 /* i/o: synthesized speech at Fs = 12k8 Hz      Q_syn*/
      59             :     const Word16 *pitch,           /* i:   pitch values for each subframe          Q0*/
      60             :     Word32 L_enr_old,              /* i:   energy at the end of previous frame     */
      61             :     Word32 L_enr_q,                /* i:   transmitted energy for current frame    */
      62             :     const Word16 coder_type,       /* i:   coder type                              */
      63             :     const Word16 LSF_Q_prediction, /* i  : LSF prediction mode                     */
      64             :     Word16 *scaling_flag,          /* i/o: flag to indicate energy control of syn  */
      65             :     Word32 *lp_ener_FEC_av,        /* i/o: averaged voiced signal energy           Q0*/
      66             :     Word32 *lp_ener_FEC_max,       /* i/o: averaged voiced signal energy           Q0*/
      67             :     const Word16 bfi,              /* i:   current  frame BFI                      */
      68             :     const Word32 total_brate,      /* i:   total bitrate                           */
      69             :     const Word16 prev_bfi,         /* i:   previous frame BFI                      */
      70             :     const Word32 last_core_brate,  /* i:   previous frame core bitrate             */
      71             :     Word16 *exc,                   /* i/o: excitation signal without enhancement   */
      72             :     Word16 *exc2,                  /* i/o: excitation signal with enhancement      */
      73             :     Word16 Aq[],                   /* i/o: LP filter coefs (can be modified if BR) Q12*/
      74             :     Word16 *old_enr_LP,            /* i/o: LP filter E of last good voiced frame   Q3*/
      75             :     const Word16 *mem_tmp,         /* i:   temp. initial synthesis filter states   Q_syn*/
      76             :     Word16 *mem_syn,               /* o:   initial synthesis filter states         Q_syn*/
      77             :     Word16 Q_exc,
      78             :     Word16 Q_syn,
      79             :     const Word16 element_mode,                /* i  : element mode                            */
      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      140736 :     enr_LP = 0;
      97      140736 :     move16();
      98      140736 :     gain2 = 0;
      99      140736 :     move16();
     100      140736 :     gain1 = 0;
     101      140736 :     move16();
     102      140736 :     *update_flg = 0;
     103      140736 :     move16();
     104      140736 :     L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */
     105      140736 :     scaling = 16384;
     106      140736 :     move16(); /* Q14*/
     107             : 
     108             :     /*-----------------------------------------------------------------*
     109             :      * Find the synthesis filter impulse response on voiced
     110             :      *-----------------------------------------------------------------*/
     111      140736 :     test();
     112      140736 :     IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     113             :     {
     114       81681 :         IF( EQ_16( L_frame, L_FRAME ) )
     115             :         {
     116       44333 :             enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR );
     117             :         }
     118             :         ELSE /* L_frame == L_FRAME16k */
     119             :         {
     120       37348 :             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      140736 :     IF( bfi )
     129             :     {
     130           0 :         *scaling_flag = 1;
     131           0 :         move16(); /* Always check synthesis on bad frames */
     132             :     }
     133      140736 :     ELSE IF( prev_bfi )
     134             :     {
     135        1602 :         test();
     136        1602 :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) )
     137             :         {
     138        1344 :             *scaling_flag = 2;
     139        1344 :             move16(); /* Decoded LSFs affected  */
     140             :         }
     141         258 :         ELSE IF( NE_16( coder_type, TRANSITION ) )
     142             :         {
     143         102 :             *scaling_flag = 1;
     144         102 :             move16(); /* SN, but not TC mode - LSF still affected by the interpolation */
     145             :         }
     146             :         ELSE
     147             :         {
     148         156 :             *scaling_flag = 0;
     149         156 :             move16(); /* LSF still possibly affected due to interpolation */
     150             :         }
     151        1602 :         scaling = 24576; /*1.5 Q14*/
     152        1602 :         move16();
     153             :     }
     154             :     ELSE
     155             :     {
     156      139134 :         test();
     157      139134 :         IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) )
     158             :         {
     159         550 :             *scaling_flag = 2;
     160         550 :             move16(); /* Continue with energy control till the end of AR prediction */
     161             :         }
     162      138584 :         ELSE IF( *scaling_flag > 0 )
     163             :         {
     164        1996 :             ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */
     165        1996 :             move16();
     166             :         }
     167      139134 :         scaling = 32767; /*2.0 Q14*/
     168      139134 :         move16();
     169             :     }
     170             : 
     171             :     /*-----------------------------------------------------------------*
     172             :      * Find the energy/gain at the end of the frame
     173             :      *-----------------------------------------------------------------*/
     174             : 
     175      140736 :     tmp = sub( 3, getScaleFactor16( synth, L_frame ) );
     176             : 
     177      140736 :     test();
     178      140736 :     IF( tmp > 0 && GT_16( element_mode, EVS_MONO ) )
     179        3804 :     {
     180             :         Word16 synth_tmp[L_FRAME16k];
     181        3804 :         Copy_Scale_sig( synth, synth_tmp, L_frame, -tmp ); // Q_synth - tmp
     182        3804 :         frame_ener_fx( L_frame, clas, synth_tmp, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, sub( Q_syn, tmp ), 3, 0 );
     183             :     }
     184             :     ELSE
     185             :     {
     186      136932 :         frame_ener_fx( L_frame, clas, synth, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 );
     187             :     }
     188             : 
     189      140736 :     test();
     190      140736 :     test();
     191      140736 :     IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) )
     192             :     {
     193             :         /* previous frame erased and no TC frame */
     194          55 :         IF( *scaling_flag > 0 )
     195             :         {
     196             :             /*enr2 += 0.01f;*/
     197           0 :             L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */
     198             : 
     199           0 :             IF( bfi ) /* In all bad frames, limit the gain to 1  */
     200             :             {
     201             :                 /* gain2 = (float)sqrt( enr_old / enr2 );*/
     202           0 :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 );
     203           0 :                 gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     204             : 
     205             :                 /*if( gain2 > 1.0f )gain2 = 1.0f;*/
     206           0 :                 gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /*Q14*/
     207             : 
     208             :                 /* find the energy/gain at the beginning of the frame */
     209           0 :                 frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     210             : 
     211             :                 /*enr1 += 0.1f;*/
     212           0 :                 L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */
     213             : 
     214             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
     215           0 :                 L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     216           0 :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     217             : 
     218             :                 /*if( gain1 > 1.0f )gain1 = 1.0f;*/
     219           0 :                 gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
     220             :             }
     221             :             ELSE /* good frame  */
     222             :             {
     223           0 :                 IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */
     224             :                 {
     225           0 :                     L_enr_q = L_enr2; /*Q0*/
     226           0 :                     set16_fx( h1, 0, L_FRAME / 2 );
     227           0 :                     h1[0] = 1024; /*1.0F in Q10*/
     228           0 :                     move16();
     229             :                     /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     230           0 :                     E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     231             : 
     232             :                     /*Compute tilt */
     233             :                     /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     234             :                     /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     235             :                     /*tilt = rr1 / rr0;*/
     236           0 :                     tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     237           0 :                     pitch_dist = 0;
     238           0 :                     move16();
     239           0 :                     L_mean_pitch = L_mult( pitch[0], 8192 ); /*Q14*/
     240           0 :                     FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ )
     241             :                     {
     242           0 :                         pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/
     243           0 :                         L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 );               /*Q14*/
     244             :                     }
     245             :                     /*pitch_dist /= (float)(NB_SUBFR-1);        */
     246           0 :                     pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/
     247             :                     /*mean_pitch /= (float)(NB_SUBFR);*/
     248           0 :                     mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/
     249             : 
     250             : 
     251           0 :                     test();
     252           0 :                     test();
     253           0 :                     test();
     254           0 :                     test();
     255           0 :                     test();
     256           0 :                     test();
     257           0 :                     IF( ( GT_16( tilt, 22938 ) ) &&                                                     /* HF resonnant filter */
     258             :                         ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short      */
     259             :                         ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) )
     260             :                     {
     261             :                         /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/
     262           0 :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     263             :                     }
     264             :                     ELSE
     265             :                     {
     266           0 :                         ener_max = *lp_ener_FEC_max; /*Q0*/
     267           0 :                         move32();
     268           0 :                         test();
     269           0 :                         if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) )
     270             :                         {
     271           0 :                             ener_max = *lp_ener_FEC_av; /*Q0*/
     272           0 :                             move32();
     273             :                         }
     274             :                         /*if( enr_old > ener_max )ener_max = enr_old;*/
     275           0 :                         ener_max = L_max( ener_max, L_enr_old );
     276             : 
     277             :                         /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/
     278           0 :                         L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/
     279             :                     }
     280             :                 }
     281             :                 /*gain2 = (float)sqrt( enr_q / enr2 );*/
     282           0 :                 L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */
     283           0 :                 L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 );
     284           0 :                 gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     285             : 
     286             :                 /*-----------------------------------------------------------------*
     287             :                  * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
     288             :                  *-----------------------------------------------------------------*/
     289             : 
     290           0 :                 test();
     291           0 :                 test();
     292           0 :                 test();
     293           0 :                 test();
     294           0 :                 test();
     295           0 :                 test();
     296           0 :                 IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) ||
     297             :                       EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) &&
     298             :                     prev_bfi )
     299             :                 {
     300             :                     /* voiced -> unvoiced signal transition */
     301             :                     /* CNG -> active signal transition */
     302           0 :                     gain1 = gain2; /*Q14*/
     303           0 :                     move16();
     304             :                 }
     305             :                 ELSE
     306             :                 {
     307             :                     /* find the energy at the beginning of the frame */
     308           0 :                     frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
     309             : 
     310             :                     /*enr1 += 0.1f;*/
     311           0 :                     L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */
     312             : 
     313             :                     /*gain1 = (float)sqrt( enr_old / enr1 );*/
     314           0 :                     L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
     315           0 :                     gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     316             : 
     317             :                     /*if( gain1 > 1.2f )gain1 = 1.2f;*/
     318             :                     /* prevent clipping */
     319           0 :                     gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ );
     320             : 
     321             :                     /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */
     322           0 :                     test();
     323           0 :                     test();
     324           0 :                     if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi )
     325             :                     {
     326           0 :                         gain1 = gain2; /*Q14*/
     327           0 :                         move16();
     328             :                     }
     329             :                 }
     330             : 
     331           0 :                 L_enr2 = L_enr_q; /*Q0*/
     332           0 :                 move32();         /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC  */
     333             :             }
     334             : 
     335             :             /*------------------------------------------------------------------------------*
     336             :              * Smooth the energy evolution by exponentially evolving from gain1 to gain2
     337             :              *------------------------------------------------------------------------------*/
     338             : 
     339             :             /*gain2 *= ( 1.0f - AGC );*/
     340           0 :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
     341           0 :             FOR( i = 0; i < L_frame; i++ )
     342             :             {
     343             :                 /*gain1 = gain1 * AGC + gain2;*/
     344           0 :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
     345             :                 /*exc[i] *= gain1;*/
     346           0 :                 exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 );
     347           0 :                 move16();
     348             :                 /*exc2[i] *= gain1;*/
     349           0 :                 exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 );
     350           0 :                 move16();
     351             :             }
     352             :             /* smoothing is done in excitation domain, so redo synthesis */
     353           0 :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
     354           0 :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
     355           0 :             *update_flg = 1;
     356           0 :             move16();
     357             :         }
     358             :     }
     359             :     ELSE
     360             :     {
     361             :         /* previous frame erased and no TC frame */
     362      140681 :         test();
     363      140681 :         IF( prev_bfi && NE_16( coder_type, TRANSITION ) )
     364             :         {
     365        1446 :             IF( L_enr_q == 0 )
     366             :             {
     367         488 :                 L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */
     368         488 :                 set16_fx( h1, 0, L_FRAME / 2 );
     369         488 :                 h1[0] = 1024; /*1.0f in Q10*/
     370         488 :                 move16();
     371             :                 /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
     372         488 :                 E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
     373             :                 /*Compute tilt */
     374             :                 /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
     375             :                 /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
     376             :                 /*tilt = rr1 / rr0;*/
     377         488 :                 tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
     378         488 :                 test();
     379         488 :                 test();
     380         488 :                 test();
     381         488 :                 test();
     382         488 :                 test();
     383         488 :                 test();
     384         488 :                 test();
     385         488 :                 test();
     386         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 ) ) ||
     387             :                         ( EQ_32( total_brate, ACELP_9k60 ) ) ) &&
     388             :                       ( GT_16( tilt, 22938 ) ) &&                                               /* HF resonnant filter */
     389             :                       ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */
     390             :                 {
     391             :                     /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/
     392           0 :                     L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
     393             :                 }
     394         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 ) )
     395             :                 {
     396             :                     /* Voiced-voiced recovery */
     397         262 :                     test();
     398         262 :                     IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) )
     399             :                     {
     400             :                         /* enr_q /= enr_LP */
     401          12 :                         exp = norm_l( L_enr_q );
     402          12 :                         tmp = extract_h( L_shl( L_enr_q, exp ) );
     403             : 
     404          12 :                         exp2 = norm_s( enr_LP );
     405          12 :                         tmp2 = shl( enr_LP, exp2 );
     406             : 
     407          12 :                         exp = sub( exp2, exp );
     408             : 
     409          12 :                         tmp3 = sub( tmp, tmp2 );
     410          12 :                         IF( tmp3 > 0 )
     411             :                         {
     412           4 :                             tmp = shr( tmp, 1 );
     413           4 :                             exp = add( exp, 1 );
     414             :                         }
     415          12 :                         tmp = div_s( tmp, tmp2 ); /*Q15*/
     416             : 
     417             :                         /* L_enr_q *= 2 * *old_enr_LP */
     418          12 :                         L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp ); /*Q0*/
     419             :                     }
     420             : 
     421             :                     ELSE
     422             :                     {
     423         250 :                         test();
     424         250 :                         IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) )
     425             :                         {
     426           3 :                             exp = norm_s( enr_LP );
     427           3 :                             tmp = shl( enr_LP, exp );
     428             : 
     429           3 :                             exp2 = 7;
     430           3 :                             move16();
     431           3 :                             tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */
     432           3 :                             move16();
     433           3 :                             exp = sub( exp2, exp );
     434             : 
     435           3 :                             IF( GT_16( tmp, tmp2 ) )
     436             :                             {
     437           3 :                                 tmp = shr( tmp, 1 );
     438           3 :                                 exp = add( exp, 1 );
     439             :                             }
     440           3 :                             tmp = div_s( tmp, tmp2 );                            /* tmp*2^exp = enr_LP/20.0 */
     441           3 :                             L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp );        /* L_tmp*2^exp = sqrt(20.0/enr_LP) */
     442           3 :                             L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp ); /*Q0*/
     443             :                         }
     444             :                     }
     445             :                 }
     446             : 
     447         488 :                 test();
     448         488 :                 test();
     449         488 :                 test();
     450         488 :                 test();
     451         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 )
     452             :                 {
     453             : 
     454         262 :                     IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */
     455             :                     {
     456          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*/
     457             :                     }
     458             :                 }
     459             :             }
     460             : 
     461        1446 :             L_enr_q = L_max( 1, L_enr_q );
     462             : 
     463             :             /* gain2 = (float)sqrt( enr_q / enr2 );*/
     464        1446 :             exp = norm_l( L_enr_q );
     465        1446 :             tmp = extract_h( L_shl( L_enr_q, exp ) );
     466             : 
     467        1446 :             exp2 = norm_l( L_enr2 );
     468        1446 :             tmp2 = extract_h( L_shl( L_enr2, exp2 ) );
     469             : 
     470        1446 :             exp2 = sub( exp, exp2 ); /* Denormalize and substract */
     471             : 
     472        1446 :             tmp3 = sub( tmp2, tmp );
     473        1446 :             IF( tmp3 > 0 )
     474             :             {
     475         139 :                 tmp2 = shr( tmp2, 1 );
     476         139 :                 exp2 = add( exp2, 1 );
     477             :             }
     478             : 
     479        1446 :             tmp = div_s( tmp2, tmp );
     480             : 
     481        1446 :             L_tmp = L_deposit_h( tmp );
     482        1446 :             L_tmp = Isqrt_lc( L_tmp, &exp2 );
     483        1446 :             gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     484             :             /*-----------------------------------------------------------------*
     485             :              * Clipping of the smoothing gain at the frame end
     486             :              *-----------------------------------------------------------------*/
     487             : 
     488        1446 :             gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */
     489        1446 :             if ( LT_32( L_enr_q, 2 ) )
     490             :             {
     491          21 :                 gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */
     492             :             }
     493             : 
     494             :             /*-----------------------------------------------------------------*
     495             :              * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
     496             :              *-----------------------------------------------------------------*/
     497             : 
     498        1446 :             test();
     499        1446 :             test();
     500        1446 :             test();
     501        1446 :             test();
     502        1446 :             test();
     503        1446 :             test();
     504        1446 :             IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */
     505             :             {
     506          19 :                 gain1 = shr( gain2, 1 );
     507             :             }
     508             :             /*------------------------------------------------------------*
     509             :              * voiced->unvoiced transition recovery
     510             :              *------------------------------------------------------------*/
     511        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 */
     512             :                      EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA )                                 /* CNG -> active signal transition */
     513             :             {
     514          90 :                 gain1 = gain2; /*Q14*/
     515          90 :                 move16();
     516             :             }
     517             :             ELSE
     518             :             {
     519             :                 /*--------------------------------------------------------*
     520             :                  * Find the energy at the beginning of the frame
     521             :                  *--------------------------------------------------------*/
     522        1337 :                 tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 );
     523             : 
     524             :                 /*gain1 = (float)sqrt( enr_old / enr1 );*/
     525        1337 :                 exp = norm_l( L_enr_old );
     526        1337 :                 tmp = extract_h( L_shl( L_enr_old, exp ) );
     527        1337 :                 exp2 = norm_l( L_enr1 );
     528        1337 :                 tmp2 = extract_h( L_shl( L_enr1, exp2 ) );
     529             : 
     530        1337 :                 exp2 = sub( exp, exp2 ); /* Denormalize and substract */
     531             : 
     532        1337 :                 tmp3 = sub( tmp2, tmp );
     533             : 
     534        1337 :                 IF( tmp3 > 0 )
     535             :                 {
     536         655 :                     tmp2 = shr( tmp2, 1 );
     537         655 :                     exp2 = add( exp2, 1 );
     538             :                 }
     539             : 
     540        1337 :                 tmp = div_s( tmp2, tmp );
     541             : 
     542        1337 :                 L_tmp = L_deposit_h( tmp );
     543        1337 :                 L_tmp = Isqrt_lc( L_tmp, &exp2 );
     544        1337 :                 gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
     545             :                 /* exp2 is always <= 1 */
     546             : 
     547        1337 :                 gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ ); /*Q14*/
     548             : 
     549        1337 :                 test();
     550        1337 :                 test();
     551        1337 :                 if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) )
     552             :                 {
     553           4 :                     gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
     554             :                 }
     555             : 
     556             :                 /*--------------------------------------------------------*
     557             :                  * Prevent a catastrophy in case of offset followed by onset
     558             :                  *--------------------------------------------------------*/
     559        1337 :                 test();
     560        1337 :                 if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) )
     561             :                 {
     562           5 :                     gain1 = gain2; /*Q14*/
     563           5 :                     move16();
     564             :                 }
     565             :             }
     566             :             /*-----------------------------------------------------------------*
     567             :              * Smooth the energy evolution by exponentially evolving from
     568             :              * gain1 to gain2
     569             :              *-----------------------------------------------------------------*/
     570             : 
     571        1446 :             L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
     572             : 
     573      434278 :             FOR( i = 0; i < L_frame; i++ )
     574             :             {
     575      432832 :                 gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
     576      432832 :                 exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 );
     577      432832 :                 move16();
     578      432832 :                 exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 );
     579      432832 :                 move16();
     580             :             }
     581             : 
     582        1446 :             Copy( mem_tmp, mem_syn, M ); /* Q_syn */
     583        1446 :             syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
     584        1446 :             *update_flg = 1;
     585        1446 :             move16();
     586             :         }
     587             :     }
     588             :     /*-----------------------------------------------------------------*
     589             :      * Update low-pass filtered energy for voiced frames
     590             :      *-----------------------------------------------------------------*/
     591             : 
     592      140736 :     test();
     593      140736 :     test();
     594      140736 :     IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) )
     595             :     {
     596       81681 :         IF( EQ_16( clas, VOICED_TRANSITION ) )
     597             :         {
     598        5822 :             L_enr2_av = L_enr2; /*Q0*/
     599        5822 :             move32();
     600        5822 :             frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 );
     601             :         }
     602             :         ELSE
     603             :         {
     604       75859 :             L_ener2_max = L_enr2; /*Q0*/
     605       75859 :             move32();
     606       75859 :             frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 );
     607             :         }
     608             : 
     609             :         /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av;      move32();*/
     610       81681 :         *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*/ );
     611       81681 :         move32();
     612             :         /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max;      move32();*/
     613       81681 :         *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*/ );
     614       81681 :         move32();
     615             :     }
     616             : 
     617             :     /*-----------------------------------------------------------------*
     618             :      * Update the LP filter energy for voiced frames
     619             :      *-----------------------------------------------------------------*/
     620      140736 :     test();
     621      140736 :     if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
     622             :     {
     623       81681 :         *old_enr_LP = enr_LP; /*Q3*/
     624       81681 :         move16();
     625             :     }
     626             : 
     627      140736 :     return;
     628             : }

Generated by: LCOV version 1.14