LCOV - code coverage report
Current view: top level - lib_dec - FEC_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 337 352 95.7 %
Date: 2025-05-03 01:55:50 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "cnst.h"    /* Common constants                       */
       8             : #include "rom_com.h" /* Common static table prototypes        */
       9             : #include "rom_dec.h" /* Decoder static table prototypes        */
      10             : #include "prot_fx.h" /* Function prototypes                    */
      11             : #include "basop_util.h"
      12             : /*-------------------------------------------------------------------*
      13             :  * Local function prototypes
      14             :  *-------------------------------------------------------------------*/
      15             : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame );
      16             : void gain_dec_bfi_fx( Word16 *past_qua_en );
      17             : /*======================================================================*/
      18             : /* FUNCTION : FEC_exc_estim_fx()                    */
      19             : /*----------------------------------------------------------------------*/
      20             : /* PURPOSE :  Calculation of excitation signal                        */
      21             : /*                                    */
      22             : /*----------------------------------------------------------------------*/
      23             : /* GLOBAL INPUT ARGUMENTS :                        */
      24             : /* _ (Struct)  st_fx      : decoder static memory          */
      25             : /* _ (Word16) L_frame    : length of the frame        Q0  */
      26             : /* _ (Word16) st_fx->lp_ener_fx  :  FEC - low-pass filtered energy   Q6  */
      27             : /* _ (Word16) st_fx->lp_gainc_fx  : FEC - low-pass filtered code gain Q3  */
      28             : /* _ (Word16) st_fx->old_pitch_buf  : FEC buffer of old subframe pitch valuesQ6*/
      29             : /* _ (Word16) st_fx->last_good    : FEC - clas of last good received    */
      30             : /* _ (Word16) st_fx->bfi_pitch_fx  : LP filter coefficient          */
      31             : /* _ (Word16) st_fx->upd_cnt  : FEC counter of frames since last update*/
      32             : /* _ (Word16) st_fx->last_coder_type: previous coder type        */
      33             : /* _ (Word16) st_fx->Last_GSC_pit_band_idx: AC mode (GSC)Last pitch band index*/
      34             : /* _ (Word16) st_fx->stab_fac_fx    : LSF stability factor Q15      */
      35             : /* _ (Word16) st_fx->tilt_code    : tilt of code        Q15      */
      36             : /* _ (Word16) st_fx->last_voice_factor    : coding type        Q12  */
      37             : /* _ (Word16) st_fx->opt_AMR_WB_fx : coding type        Q12      */
      38             : /* _ (Word16) st_fx->lp_gainp_fx  : FEC -low-pass filtered pitch gain Q14  */
      39             : /* _ (Word16) st_fx->seed    :FEC-seed for random generator for excitation*/
      40             : /* _ (Word16) st_fx->opt_OMR_WB:flag indicating AMR-WB IO mode              */
      41             : /*-----------------------------------------------------------------------*/
      42             : /* OUTPUT ARGUMENTS :                                                      */
      43             : /* _ (Word16[]) exc_fx               : adapt. excitation exc (Q_exc)       */
      44             : /* _ (Word16[]) exc2_fx              : adapt. excitation/total exc (Q_exc)   */
      45             : /* _ (Word16[]) bwe_exc_fx           : excitation for SWB TBE (Q_exc)     */
      46             : /* _ (Word16[]) pitch_buf_fx         : floating pitch values for each subframe Q6*/
      47             : /* _ (Word16[])  voice_factors_fx    : frame error rate        Q15     */
      48             : /* _ (Word16[])  FEC_pitch_fx(tmp_tc):    FEC pitch  Q6                 */
      49             : /*-----------------------------------------------------------------------*/
      50             : 
      51             : /* _ (Word16) st_fx->lp_gainp_fx  : FEC -low-pass filtered pitch gain Q14   */
      52             : /* _ (Word16) st_fx->seed    :FEC-seed for random generator for excitation*/
      53             : /* _ (Word16) st_fx->bfi_pitch_fx  : LP filter coefficient          */
      54             : /* _ (Word16) st_fx->lp_gainc_fx  : FEC - low-pass filtered code gain Q3  */
      55             : /*-----------------------------------------------------------------------*/
      56             : /* RETURN ARGUMENTS :                           */
      57             : /* _ None                                 */
      58             : /*=======================================================================*/
      59             : 
      60             : 
      61        5822 : void FEC_exc_estim_fx(
      62             :     Decoder_State *st_fx,  /* i/o: Decoder static memory                        */
      63             :     const Word16 L_frame,  /* i  : length of the frame                          */
      64             :     Word16 *exc,           /* o  : pointer to excitation buffer (with past)     */
      65             :     Word16 *exc2,          /* o  : total excitation (for synthesis)             */
      66             :     Word16 exc_dct_in[],   /* o  : GSC excitation in DCT domain                 */
      67             :     Word16 *pitch_buf,     /* o  : Floating pitch   for each subframe           */
      68             :     Word16 *voice_factors, /* o  : voicing factors                              */
      69             :     Word16 *tmp_tc,        /* o  : FEC pitch  Q6                                */
      70             :     Word16 *bwe_exc,       /* o  : excitation for SWB TBE                       */
      71             :     Word16 *lsf_new,       /* i  : ISFs at the end of the frame                 */
      72             :     Word16 *Q_exc,
      73             :     Word16 *tmp_noise /* o  : long-term noise energy  Q0                   */
      74             : )
      75             : {
      76             : 
      77             :     Word16 exc2_buf[L_FRAME16k + MODE1_L_FIR_FER - 1];
      78             :     Word16 gainCNG, new_pit /*Q0*/; /* Q3*/
      79             :     Word16 exp;
      80             :     Word32 L_tmp, L_tmp2;
      81             :     Word16 tmp, tmp1, tmp16;
      82             :     Word16 delta;
      83             :     Word16 i, j;
      84             :     Word16 alpha;
      85             :     Word16 gain, gain_inov;
      86             :     Word16 Tc;
      87             :     Word16 *pt_exc, *pt1_exc;
      88             :     Word16 step;
      89             :     Word32 L_step;
      90             :     Word16 hp_filt[5];
      91             :     Word16 Diff_len, max_len, Len;
      92             :     Word16 last_bin_fx, nb_subfr;
      93             :     Word16 extrapolationFailed;
      94             :     Word16 cond1, cond2;
      95             :     Word32 cond3;
      96             :     Word32 predPitchLag;
      97             :     GSC_DEC_HANDLE hGSCDec;
      98             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      99        5822 :     Flag Overflow = 0;
     100        5822 :     move16();
     101             : #endif
     102        5822 :     hGSCDec = st_fx->hGSCDec;
     103             : 
     104             :     AMRWB_IO_DEC_HANDLE hAmrwb_IO;
     105        5822 :     hAmrwb_IO = st_fx->hAmrwb_IO;
     106             :     /* nb_subfr = L_frame/L_SUBFR */
     107        5822 :     nb_subfr = shr( L_frame, 6 );
     108        5822 :     Diff_len = 0; /* to avoid compilation flags */
     109        5822 :     move16();
     110        5822 :     set16_fx( exc_dct_in, 0, L_FRAME16k );
     111             : 
     112        5822 :     extrapolationFailed = 1;
     113        5822 :     move16();
     114             : 
     115        5822 :     gainCNG = 0;
     116        5822 :     move16();
     117        5822 :     IF( st_fx->lp_ener_fx != 0 )
     118             :     {
     119         490 :         exp = norm_l( st_fx->lp_ener_fx ); /*lp_ener in Q6*/
     120         490 :         tmp = extract_h( L_shl( st_fx->lp_ener_fx, exp ) );
     121         490 :         exp = sub( exp, 30 - 6 );
     122             : 
     123         490 :         tmp = div_s( 16384, tmp );
     124         490 :         L_tmp = L_deposit_h( tmp );
     125         490 :         L_tmp = Isqrt_lc( L_tmp, &exp );
     126             : 
     127         490 :         gainCNG = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */
     128             :     }
     129        5822 :     tmp1 = shl_o( st_fx->lp_gainc_fx, 1, &Overflow );
     130        5822 :     gainCNG = s_min( gainCNG, tmp1 );
     131        5822 :     set16_fx( exc_dct_in, 0, L_FRAME16k );
     132             : 
     133             :     /*-----------------------------------------------------------------*
     134             :      * pitch extrapolation
     135             :      *-----------------------------------------------------------------*/
     136             : 
     137             :     {
     138             :         Word32 *tmp_old_pitch /*15Q16*/;
     139             :         Word16 tmp_pitmin, tmp_pitmax;
     140             : 
     141             :         /*tmp_old_pitch = L_frame == L_FRAME ? &st_fx->old_pitch_buf_fx[2*NB_SUBFR-1] : &st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1];*/
     142             :         /*tmp_pitmin = L_frame == L_FRAME?PIT_MIN_DOUBLEEXTEND:PIT16k_MIN_EXTEND;*/
     143             :         /*tmp_pitmax = L_frame == L_FRAME?PIT_MAX:PIT16k_MAX;*/
     144             : 
     145        5822 :         tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1];
     146        5822 :         tmp_pitmin = PIT16k_MIN_EXTEND;
     147        5822 :         move16();
     148        5822 :         tmp_pitmax = PIT16k_MAX;
     149        5822 :         move16();
     150        5822 :         IF( EQ_16( L_frame, L_FRAME ) )
     151             :         {
     152        1310 :             tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1];
     153        1310 :             tmp_pitmin = PIT_MIN_DOUBLEEXTEND;
     154        1310 :             move16();
     155        1310 :             tmp_pitmax = PIT_MAX;
     156        1310 :             move16();
     157             :         }
     158             : 
     159             : 
     160        5822 :         pitch_pred_linear_fit(
     161        5822 :             st_fx->nbLostCmpt,
     162        5822 :             st_fx->last_good,
     163        5822 :             st_fx->old_pitch_buf_fx,
     164             :             tmp_old_pitch,
     165             :             &predPitchLag,
     166             :             tmp_pitmin,
     167             :             tmp_pitmax,
     168        5822 :             st_fx->mem_pitch_gain,
     169             :             0,
     170             :             0,
     171             :             &extrapolationFailed,
     172             :             nb_subfr );
     173             : 
     174        5822 :         new_pit /*Q0 int*/ = shl( round_fx( predPitchLag ), 0 );
     175             :     }
     176             : 
     177             : 
     178             :     /*-----------------------------------------------------------------*
     179             :      * estimate subframe pitch values for the FEC frame
     180             :      *-----------------------------------------------------------------*/
     181             : 
     182             :     /* initialize pitch to the long-term pitch */
     183             : 
     184        5822 :     *tmp_tc = st_fx->bfi_pitch_fx;
     185        5822 :     move16(); /*Q6*/
     186        5822 :     IF( EQ_16( L_frame, L_FRAME ) )
     187             :     {
     188        1310 :         test();
     189        1310 :         test();
     190        1310 :         IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) &&
     191             :               GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past  */
     192             :             GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) )                                                                                /* or last update too far in the past */
     193             :         {
     194             :             /* take the pitch value of last subframe of the previous frame */
     195        1287 :             *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) );
     196        1287 :             move16();
     197             :         }
     198             :     }
     199             :     ELSE /* L_frame == L_FRAME16k */
     200             :     {
     201        4512 :         test();
     202        4512 :         test();
     203        4512 :         IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) &&
     204             :               GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past  */
     205             :             GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) )                                                                                   /* or last update too far in the past */
     206             :         {
     207             :             /* take the pitch value of last subframe of the previous frame */
     208        4495 :             *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) );
     209        4495 :             move16();
     210             :         }
     211             :     }
     212             : 
     213             :     /* convert pitch period */
     214             :     /* Tc = (short)(tmp_tc + 0.5f) */
     215        5822 :     Tc = shr_r( *tmp_tc, 6 );
     216             : 
     217             :     /* estimate pitch values for all subframes */
     218             :     /*calculate conditions for Pulse resynchronization to take place*/
     219        5822 :     pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
     220             : 
     221        5822 :     test();
     222        5822 :     test();
     223        5822 :     test();
     224        5822 :     test();
     225        5822 :     IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
     226             :     {
     227         283 :         tmp16 = *tmp_tc; /*Q6*/
     228         283 :         move16();
     229         283 :         IF( EQ_16( nb_subfr, 4 ) )
     230             :         {
     231          74 :             delta = shr( sub( shl( new_pit, 6 ), *tmp_tc ), 2 ); /* 4 sub-frames */
     232             :         }
     233             :         ELSE
     234             :         {
     235         209 :             delta = mult_r( sub( shl( new_pit, 6 ), *tmp_tc ), 6554 ); /* 5 sub-frames */
     236             :         }
     237        1624 :         FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values */
     238             :         {
     239             :             /* fT0 += delta */
     240        1341 :             tmp16 = add( tmp16, delta );
     241             :             /* ptch_buf[i] = (short)(fT0 + 0.5) */
     242        1341 :             pitch_buf[i] = shl( mult_r( tmp16, 512 ), 6 );
     243        1341 :             move16();
     244             :         }
     245             :     }
     246             :     ELSE
     247             :     {
     248       31998 :         FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values for bass postfilter */
     249             :         {
     250       26459 :             pitch_buf[i] = *tmp_tc;
     251       26459 :             move16();
     252             :         }
     253             :     }
     254             : 
     255             :     /*-----------------------------------------------------------------*
     256             :      * estimate damping factor
     257             :      *-----------------------------------------------------------------*/
     258             : 
     259             :     /* rapid convergence to 0 */
     260        5822 :     alpha = _ALPHA_VT_FX;
     261        5822 :     move16();
     262        5822 :     test();
     263        5822 :     test();
     264        5822 :     test();
     265        5822 :     test();
     266        5822 :     test();
     267        5822 :     test();
     268        5822 :     test();
     269        5822 :     IF( EQ_16( st_fx->last_coder_type, UNVOICED ) && LE_16( st_fx->nbLostCmpt, 3 ) )
     270             :     {
     271             :         /* last good frame was clearly unvoiced */
     272         282 :         alpha = _ALPHA_UU_FX;
     273         282 :         move16();
     274             :     }
     275        5540 :     ELSE IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
     276             :     {
     277         124 :         test();
     278         124 :         IF( hGSCDec->Last_GSC_pit_band_idx > 0 && GT_16( st_fx->nbLostCmpt, 1 ) )
     279             :         {
     280          14 :             alpha = 26214;
     281          14 :             move16();
     282             :         }
     283         110 :         ELSE IF( LE_16( st_fx->nbLostCmpt, 5 ) )
     284             :         {
     285         110 :             alpha = 32604;
     286         110 :             move16();
     287             :         }
     288             :         ELSE
     289             :         {
     290           0 :             alpha = 31130;
     291           0 :             move16();
     292             :         }
     293             :     }
     294        5416 :     ELSE IF( EQ_16( st_fx->last_good, UNVOICED_CLAS ) )
     295             :     {
     296         948 :         IF( LE_16( st_fx->nbLostCmpt, 1 ) )
     297             :         {
     298             :             /* if stable, do not decrease the energy, pitch_gain = 0 */
     299         782 :             alpha = mac_ro( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX, &Overflow ); /*st_fx->stab_fac_fx in Q15*/
     300             :         }
     301         166 :         ELSE IF( EQ_16( st_fx->nbLostCmpt, 2 ) )
     302             :         {
     303         160 :             alpha = _ALPHA_S_FX;
     304         160 :             move16(); /* ALPHA_U*1.5f = 0.6 */
     305             :         }
     306             :         ELSE
     307             :         {
     308           6 :             alpha = _ALPHA_U_FX;
     309           6 :             move16(); /* 0.4 go rapidly to CNG gain, pitch gain = 0 */
     310             :         }
     311             :     }
     312        4468 :     ELSE IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) )
     313             :     {
     314          14 :         alpha = _ALPHA_UT_FX;
     315          14 :         move16();
     316             :     }
     317        4454 :     ELSE IF( EQ_16( st_fx->last_good, ONSET ) && LE_16( st_fx->nbLostCmpt, 3 ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) )
     318             :     {
     319         161 :         alpha = 26214;
     320         161 :         move16(); /* mild convergence to 0 for the first 3 erased frames 0.8 in Q15 */
     321             :     }
     322        4293 :     ELSE IF( ( EQ_16( st_fx->last_good, VOICED_CLAS ) || EQ_16( st_fx->last_good, ONSET ) ) && LE_16( st_fx->nbLostCmpt, 3 ) )
     323             :     {
     324        2255 :         alpha = _ALPHA_V_FX;
     325        2255 :         move16(); /* constant for the first 3 erased frames */
     326             :     }
     327        2038 :     ELSE IF( EQ_16( st_fx->last_good, SIN_ONSET ) )
     328             :     {
     329          12 :         alpha = _ALPHA_S_FX;
     330          12 :         move16();
     331             :     }
     332        5822 :     test();
     333        5822 :     test();
     334        5822 :     IF( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) )
     335             :     {
     336        2578 :         IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) /* if first erased frame in a block, reset harmonic gain */
     337             :         {
     338             :             /* move pitch gain towards 1 for voiced to remove energy fluctuations */
     339             :             /*gain = (float)sqrt( st_fx->lp_gainp );*/
     340        1860 :             st_fx->lp_gainp_fx = s_max( st_fx->lp_gainp_fx, 1 );
     341        1860 :             move16();
     342        1860 :             exp = norm_s( st_fx->lp_gainp_fx );
     343        1860 :             tmp = shl( st_fx->lp_gainp_fx, exp );
     344        1860 :             tmp = div_s( 16384, tmp );
     345        1860 :             L_tmp = L_deposit_h( tmp );
     346        1860 :             L_tmp = Isqrt_lc( L_tmp, &exp );
     347             : 
     348        1860 :             gain = extract_h( L_shl_o( L_tmp, exp, &Overflow ) );
     349             : 
     350        1860 :             gain = s_min( gain, 32113 ); /*0.98 */
     351        1860 :             gain = s_max( gain, 27853 ); /*0.85 */
     352             : 
     353        1860 :             alpha = mult_r( alpha, gain );
     354             :         }
     355             :         ELSE
     356             :         {
     357             :             /* st_fx->lp_gainp_fx is in Q14 when bfi_cnt > 1 to follow floating point because lp_gainp could be > than 1  */
     358         718 :             alpha = st_fx->lp_gainp_fx;
     359         718 :             move16();
     360             :         }
     361             :     }
     362             : 
     363             :     /*-----------------------------------------------------------------*
     364             :      * construct the harmonic part of excitation
     365             :      *-----------------------------------------------------------------*/
     366        5822 :     test();
     367        5822 :     test();
     368        5822 :     test();
     369        5822 :     test();
     370        5822 :     IF( ( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) ) ||
     371             :         ( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 ) )
     372             :     {
     373             : 
     374        4620 :         pt_exc = exc;
     375        4620 :         pt1_exc = pt_exc - Tc;
     376             : 
     377        4620 :         IF( EQ_16( st_fx->nbLostCmpt, 1 ) )
     378             :         {
     379             :             /* first pitch cycle is low-pass filtered */
     380             : 
     381      193753 :             FOR( i = 0; i < Tc; i++ ) /* pitch cycle is first low-pass filtered */
     382             :             {
     383             :                 /* *pt_exc++ = (0.18f * pt1_exc[-1] + 0.64f * pt1_exc[0] + 0.18f * pt1_exc[1]) */
     384      191625 :                 L_tmp = L_mult( 5898, pt1_exc[-1] );
     385      191625 :                 L_tmp = L_mac( L_tmp, 20972, pt1_exc[0] );
     386      191625 :                 *pt_exc++ = mac_r( L_tmp, 5898, pt1_exc[1] );
     387      191625 :                 move16();
     388      191625 :                 pt1_exc++;
     389             :             }
     390             :         }
     391             : 
     392             :         /* last pitch cycle of the previous frame is repeatedly copied up to an extra subframe */
     393             : 
     394        4620 :         tmp = extract_l( ( exc + add( L_frame, L_SUBFR ) ) - pt_exc );
     395     1538947 :         FOR( i = 0; i < tmp; i++ )
     396             :         {
     397     1534327 :             *pt_exc++ = *pt1_exc++;
     398     1534327 :             move16();
     399             :         }
     400             : 
     401        4620 :         IF( new_pit > 0 )
     402             :         {
     403             :             /*calculate conditions for Pulse resynchronization to take place*/
     404        3016 :             pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
     405             : 
     406        3016 :             test();
     407        3016 :             test();
     408        3016 :             test();
     409        3016 :             test();
     410        3016 :             IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
     411             :             {
     412         283 :                 Copy( exc, exc - add( L_frame, L_SUBFR ), add( L_frame, L_SUBFR ) );
     413         283 :                 PulseResynchronization_fx( exc - add( L_frame, L_SUBFR ), exc, L_frame, nb_subfr, L_deposit_h( Tc /*Q0*/ ) /*15Q16*/, L_deposit_h( new_pit /*Q0*/ ) /*15Q16*/ );
     414             :             }
     415             :         }
     416        4620 :         test();
     417        4620 :         test();
     418        4620 :         IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) )
     419             :         {
     420             :             /* start of the frame gain */
     421          14 :             gain = 0;
     422          14 :             move16();
     423             : 
     424             :             /* end of the frame gain */
     425          14 :             st_fx->lp_gainp_fx = 0;
     426          14 :             move16();
     427          14 :             step = 0;
     428          14 :             move16();
     429             :         }
     430             :         ELSE
     431             :         {
     432             : 
     433             :             /* start of the frame gain */
     434        4606 :             gain = 16384;
     435        4606 :             move16();
     436             : 
     437             :             /* end of the frame gain */
     438        4606 :             test();
     439        4606 :             test();
     440        4606 :             test();
     441        4606 :             IF( !( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) && GT_16( st_fx->nbLostCmpt, 1 ) ) )
     442             :             {
     443        3888 :                 st_fx->lp_gainp_fx = shr( alpha, 1 ); /* alpha in Q15 */
     444             :             }
     445             :             ELSE
     446             :             {
     447         718 :                 st_fx->lp_gainp_fx = alpha;
     448         718 :                 move16(); /* alpha in Q14 */
     449             :             }
     450             : 
     451        4606 :             IF( EQ_16( L_frame, L_FRAME ) )
     452             :             {
     453         748 :                 step = shr( sub( gain, st_fx->lp_gainp_fx ), 8 );
     454             :             }
     455             :             ELSE /*L_frame == L_FRAME16k*/
     456             :             {
     457             :                 /*step = (1.0f/L_frame) * (gain - st_fx->lp_gainp);*/
     458             : 
     459        3858 :                 step = shr( mult_r( 26214, sub( gain, st_fx->lp_gainp_fx ) ), 8 ); /*Q14*/
     460             :             }
     461             :         }
     462             : 
     463     1434892 :         FOR( i = 0; i < L_frame; i++ )
     464             :         {
     465             :             /* exc[i] *= gain */
     466     1430272 :             exc[i] = round_fx( L_shl( L_mult( exc[i], gain ), 1 ) ); /* in Q_exc */
     467     1430272 :             move16();
     468             :             /* gain -= step */
     469     1430272 :             gain = sub( gain, step );
     470             :         }
     471        4620 :         test();
     472        4620 :         test();
     473        4620 :         IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 )
     474             :         {
     475          91 :             Diff_len = mfreq_loc_div_25[hGSCDec->Last_GSC_pit_band_idx];
     476          91 :             move16();
     477             : 
     478             :             /* Transform to frequency domain */
     479          91 :             edct_16fx( exc, exc_dct_in, st_fx->L_frame, 5, st_fx->element_mode );
     480             : 
     481             :             /* Reset unvaluable part of the adaptive (pitch) excitation contribution */
     482          91 :             max_len = sub( st_fx->L_frame, Diff_len );
     483          91 :             Len = s_min( max_len, 80 );
     484             : 
     485          91 :             move16(); /*ptr init*/
     486        6763 :             FOR( i = 0; i < Len; i++ )
     487             :             {
     488        6672 :                 exc_dct_in[i + Diff_len] = mult_r( exc_dct_in[i + Diff_len], sm_table_fx[i] );
     489        6672 :                 move16();
     490             :             }
     491             : 
     492        3798 :             FOR( ; i < max_len; i++ )
     493             :             {
     494        3707 :                 exc_dct_in[i + Diff_len] = 0;
     495        3707 :                 move16();
     496             :             }
     497          91 :             Diff_len = add( Diff_len, 1 );
     498             :         }
     499             :     } /* end of "if st_fx->last_good >= VOICED_TRANSITION" */
     500             : 
     501             :     /*-----------------------------------------------------------------*
     502             :      * Replicate the last spectrum in case the last good frame was coded by GSC
     503             :      *-----------------------------------------------------------------*/
     504        5822 :     test();
     505        5822 :     test();
     506        5822 :     test();
     507        5822 :     IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) )
     508             :     {
     509         202 :         st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag;
     510         202 :         move16();
     511             :         /* st_fx->L_frame / L_SUBFR */
     512         202 :         tmp = shr( st_fx->L_frame, 6 );
     513             :         /* Replication of the last spectrum, with a slight downscaling of its dynamic */
     514             : #ifdef REMOVE_EVS_DUPLICATES
     515         202 :         gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc );
     516             : #else
     517             :         IF( st_fx->element_mode == EVS_MONO )
     518             :         {
     519             :             gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, st_fx->Q_exc );
     520             :         }
     521             :         ELSE
     522             :         {
     523             :             gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc );
     524             :         }
     525             : #endif
     526         202 :         *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/
     527         202 :         move16();
     528             :         /* Transform back to time domain */
     529         202 :         edct_16fx( exc_dct_in, exc, st_fx->L_frame, 5, st_fx->element_mode );
     530             :     }
     531             :     ELSE
     532             :     {
     533             :         /*-----------------------------------------------------------------*
     534             :          * Construct the random part of excitation
     535             :          *-----------------------------------------------------------------*/
     536             : 
     537             :         /* generate the random part of the excitation */
     538     1755332 :         FOR( i = 0; i < L_frame + MODE1_L_FIR_FER - 1; i++ )
     539             :         {
     540             :             /*Q-3*/
     541     1749712 :             exc2_buf[i] = shr( Random( &st_fx->seed ), 3 );
     542     1749712 :             move16();
     543             :         }
     544             : 
     545             :         /* start of the frame gain */
     546        5620 :         gain = st_fx->lp_gainc_fx;
     547        5620 :         move16();
     548             : 
     549        5620 :         test();
     550        5620 :         test();
     551        5620 :         test();
     552        5620 :         IF( !( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) && GT_16( st_fx->nbLostCmpt, 1 ) ) )
     553             :         {
     554             :             /* Here alpha is in Q15 and lp_gainc_fx in Q3 */
     555             :             /*  st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
     556        4902 :             L_tmp = L_mult( alpha, st_fx->lp_gainc_fx );
     557             : 
     558        4902 :             st_fx->lp_gainc_fx = msu_r( L_tmp, add( alpha, -32768 ), gainCNG );
     559        4902 :             move16();
     560             :         }
     561             :         ELSE
     562             :         { /* Here alpha is in Q14, but lp_gainc still in Q3 */
     563             :             /*  st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
     564         718 :             L_tmp = L_mult( alpha, st_fx->lp_gainc_fx ); /* Q14*Q3->Q18 */
     565             : 
     566         718 :             st_fx->lp_gainc_fx = round_fx( L_shl( L_msu( L_tmp, add( alpha, -16384 ), gainCNG ), 1 ) ); /* (Q14*Q3<<1)>>16 ->Q3 */
     567         718 :             move16();
     568             :         }
     569             : 
     570        5620 :         test();
     571        5620 :         test();
     572        5620 :         test();
     573        5620 :         if ( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) && gainCNG > 0 )
     574             :         {
     575           2 :             st_fx->lp_gainc_fx = gainCNG;
     576           2 :             move16();
     577             :         }
     578             : 
     579             :         /* linearly attenuate the gain throughout the frame */
     580             :         /* step = (1.0f/L_FRAME) * (gain - *lp_gainc); */
     581        5620 :         step = sub( gain, st_fx->lp_gainc_fx ); /* divide by L_FRAME done later */
     582        5620 :         test();
     583        5620 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     584             :         {
     585        4508 :             step = mult_r( step, 26214 ); /* L_frame16k-> L_frame and division by L_frame done later*/
     586             :         }
     587             : 
     588             :         /* calculate gain to normalize energy */
     589        5620 :         pt_exc = exc2_buf + MODE1_L_FIR_FER / 2;
     590        5620 :         move16();
     591             : 
     592             :         /* To avoid saturation split the L_frame dot product into (L_frame/L_SUBFR) dot products
     593             :            and scale down before adding */
     594             :         /*  gain_inov = 1.0f / (float)sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); */
     595             : 
     596        5620 :         L_tmp = L_deposit_l( 0 );
     597       16860 :         FOR( i = 0; i < 2; i++ )
     598             :         {
     599       11240 :             L_tmp2 = L_mult0( *pt_exc, *pt_exc );
     600       11240 :             pt_exc++;
     601     1727232 :             FOR( j = 1; j < shr( L_frame, 1 ); j++ )
     602             :             {
     603     1715992 :                 L_tmp2 = L_mac0( L_tmp2, *pt_exc, *pt_exc ); /* Q-5 */
     604     1715992 :                 pt_exc++;
     605             :             }
     606       11240 :             L_tmp = L_add( L_tmp, L_shr( L_tmp2, 1 ) ); /* Q-7 */
     607             :         }
     608        5620 :         test();
     609        5620 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     610             :         {
     611        4508 :             L_tmp = Mult_32_16( L_tmp, 26214 ); /* x0.8 to normalize to 256 samples */
     612             :         }
     613        5620 :         exp = norm_l( L_tmp );
     614        5620 :         L_tmp = L_shl( L_tmp, exp );     /* Normalize                  */
     615        5620 :         exp = add( exp, 8 - 7 );         /* Q0, 8 ->divide by 256      */
     616        5620 :         exp = sub( 31, exp );            /* For Denormalization in Q31 */
     617        5620 :         L_tmp = Isqrt_lc( L_tmp, &exp ); /* in Q(31-exp)                     */
     618        5620 :         gain_inov = round_fx( L_tmp );
     619             : 
     620             :         /* attenuate somewhat on unstable unvoiced */
     621        5620 :         test();
     622        5620 :         test();
     623        5620 :         IF( ( EQ_16( st_fx->last_good, UNVOICED_CLAS ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && NE_16( st_fx->last_coder_type, UNVOICED ) )
     624             :         {
     625         952 :             gain_inov = mult_r( gain_inov, 26214 );
     626             :         }
     627             : 
     628             :         /* scaling of the random part of excitation */
     629        5620 :         pt_exc = exc2_buf;
     630        5620 :         move16();
     631        5620 :         L_step = L_shr( L_mult( gain_inov, step ), 8 ); /* here is the divide by L_FRAME */
     632        5620 :         L_tmp2 = L_mult( gain_inov, gain );             /* Q15 * Q3 -> Q3 */
     633        5620 :         tmp = round_fx( L_tmp2 );
     634        5620 :         exp = add( add( exp, *Q_exc ), 15 ); /* 3+Q_exc+15 -> Q_exc+18 */
     635             : 
     636       16860 :         FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ )
     637             :         {
     638             :             /* non-causal ringing of the FIR filter */
     639             :             /**pt_exc++ *= (gain_inov * gain);*/
     640       11240 :             L_tmp = L_mult( tmp, *pt_exc ); /* Q_exc+18 * Q-3 -> Q_exc+16 */
     641       11240 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     642       11240 :             move16();
     643             :         }
     644             : 
     645     1732852 :         FOR( i = 0; i < L_frame; i++ )
     646             :         {
     647             :             /* the inner part of the FIR filter */
     648             :             /* *pt_exc++ *= (gain_inov * gain); */
     649     1727232 :             L_tmp = L_mult( tmp, *pt_exc );
     650     1727232 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     651     1727232 :             move16();
     652             :             /* gain -= step; */
     653     1727232 :             L_tmp2 = L_sub( L_tmp2, L_step );
     654     1727232 :             tmp = round_fx( L_tmp2 );
     655             :         }
     656             : 
     657       16860 :         FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ ) /* causal ringing of the FIR filter */
     658             :         {
     659             :             /* *pt_exc++ *= (gain_inov * gain) */
     660       11240 :             L_tmp = L_mult( tmp, *pt_exc );
     661       11240 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     662       11240 :             move16();
     663             :         }
     664             :     }
     665             : 
     666             :     /*-----------------------------------------------------------------*
     667             :      * Total excitation
     668             :      *-----------------------------------------------------------------*/
     669        5822 :     test();
     670        5822 :     test();
     671        5822 :     test();
     672        5822 :     test();
     673        5822 :     IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) )
     674             :     {
     675             :         /* For GSC - the excitation is already computed */
     676         202 :         Copy( exc, exc2, st_fx->L_frame );
     677             :     }
     678        5620 :     ELSE IF( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) )
     679             :     {
     680             :         /* For voiced and generic signals - prepare a HP filter for the random part of excitation */
     681             :         /* tmp = -(1-tilt_code) to correctly represent 1.0000 */
     682        4520 :         tmp = add( st_fx->tilt_code_fx, -32768 );
     683       27120 :         FOR( i = 0; i < MODE1_L_FIR_FER; i++ )
     684             :         {
     685       22600 :             hp_filt[i] = msu_r( 0, tmp, h_high_fx[i] );
     686       22600 :             move16();
     687             :         }
     688             : 
     689             :         /* HP filter the random part of the excitation and add the adaptive part */
     690        4520 :         pt_exc = exc2_buf;
     691     1409192 :         FOR( i = 0; i < L_frame; i++ )
     692             :         {
     693             :             /* exc2[i] = exc[i] + dotp( &exc2_buf[i], hp_filt, MODE1_L_FIR_FER );*/
     694     1404672 :             L_tmp = L_mult( hp_filt[0], pt_exc[0] );
     695     7023360 :             FOR( j = 1; j < MODE1_L_FIR_FER; j++ )
     696             :             {
     697     5618688 :                 L_tmp = L_mac_sat( L_tmp, hp_filt[j], pt_exc[j] );
     698             :             }
     699     1404672 :             exc2[i] = msu_r_sat( L_tmp, -32768, exc[i] );
     700     1404672 :             move16();
     701     1404672 :             pt_exc++;
     702             :         }
     703             :     }
     704             :     ELSE
     705             :     {
     706             :         /* For purely unvoiced signals - just copy the unfiltered random part of the excitation */
     707        1100 :         Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc, L_frame );
     708        1100 :         Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc2, L_frame );
     709             :     }
     710        5822 :     IF( st_fx->hBWE_TD != NULL )
     711             :     {
     712        5822 :         IF( EQ_16( L_frame, L_FRAME ) )
     713             :         {
     714        1310 :             interp_code_5over2_fx( exc, bwe_exc, L_frame );
     715             :         }
     716             :         ELSE
     717             :         {
     718        4512 :             interp_code_4over2_fx( exc, bwe_exc, L_frame );
     719             :         }
     720             :     }
     721        5822 :     test();
     722        5822 :     IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
     723             :     {
     724         206 :         IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     725             :         {
     726         198 :             set16_fx( voice_factors, 32767, NB_SUBFR );
     727             :         }
     728             :         ELSE
     729             :         {
     730           8 :             set16_fx( voice_factors, 32767, NB_SUBFR16k );
     731             :         }
     732             :     }
     733             :     ELSE
     734             :     {
     735        5616 :         IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     736             :         {
     737        1112 :             set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR ); /* The factor of the last subframe is propagated forward */
     738             :         }
     739             :         ELSE
     740             :         {
     741        4504 :             set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR16k ); /* The factor of the last subframe is propagated forward */
     742             :         }
     743             :     }
     744        5822 :     IF( st_fx->Opt_AMR_WB )
     745             :     {
     746           0 :         gain_dec_bfi_fx( hAmrwb_IO->past_qua_en_fx );
     747             :     }
     748             :     /* L_frame / L_SUBFR */
     749        5822 :     tmp = shr( L_frame, 6 );
     750        5822 :     st_fx->bfi_pitch_fx = pitch_buf[tmp - 1];
     751        5822 :     move16();
     752        5822 :     st_fx->bfi_pitch_frame = st_fx->L_frame;
     753        5822 :     move16();
     754        5822 :     return;
     755             : }
     756             : 
     757             : 
     758             : /*calculates some conditions for Pulse resynchronization to take place*/
     759        8838 : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame )
     760             : {
     761             :     Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e;
     762             :     Word32 tmp_pit2;
     763             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     764        8838 :     Flag Overflow = 0;
     765        8838 :     move32();
     766             : #endif
     767             : 
     768        8838 :     tmp_pit = BASOP_Util_Divide1616_Scale( new_pit /*Q0*/, Tc /*Q0*/, &tmp_pit_e ) /*Q15*/;
     769        8838 :     tmp_frame = add( extract_l( L_mult0( L_frame, 64 /*1.f/L_SUBFR Q12*/ ) /*Q12*/ ), 4096 /*1.f Q12*/ ); /*Q12*/
     770        8838 :     tmp_frame = BASOP_Util_Divide1616_Scale( 4096 /*1.f Q12*/, tmp_frame, &tmp_frame_e );                 /*Q15*/
     771        8838 :     tmp_frame = shl( tmp_frame, add( tmp_frame_e, 1 ) );
     772        8838 :     tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/
     773             :     BASOP_SATURATE_WARNING_OFF_EVS
     774             :     /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
     775        8838 :     tmp_pit = shl_o( negate( tmp_pit ), tmp_pit_e, &Overflow );
     776             :     BASOP_SATURATE_WARNING_ON_EVS
     777        8838 :     *cond1 = sub( tmp_pit, negate( tmp_frame ) );
     778        8838 :     move16();
     779             : 
     780        8838 :     *cond2 = sub( Tc, new_pit );
     781        8838 :     move16();
     782             : 
     783        8838 :     tmp_pit_e = BASOP_Util_Add_MantExp( new_pit, 15 - 0, negate( Tc ), 15 - 0, &tmp_pit ); /*Q15*/
     784        8838 :     tmp_pit = abs_s( tmp_pit );
     785        8838 :     tmp_pit2 = L_mult( Tc, 4915 /*0.15f Q15*/ ); /*Q16*/
     786             :     BASOP_SATURATE_WARNING_OFF_EVS
     787             :     /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
     788        8838 :     tmp_pit2 = L_shl_sat( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) );
     789             :     BASOP_SATURATE_WARNING_ON_EVS
     790        8838 :     *cond3 = L_sub( L_mult0( -1, tmp_pit ), tmp_pit2 );
     791        8838 :     move32();
     792        8838 : }
     793             : 
     794             : /*-------------------------------------------------------------------*
     795             :  * gain_dec_bfi()
     796             :  *
     797             :  * Estimate past quantized gain prediction residual to be used in
     798             :  * next frame
     799             :  *-------------------------------------------------------------------*/
     800             : 
     801           0 : void gain_dec_bfi_fx(
     802             :     Word16 *past_qua_en /* i/o: gain quantization memory (4 words)  Qx*/
     803             : )
     804             : {
     805             :     Word16 i;
     806             :     Word16 av_pred_en;
     807             :     Word32 Lav_pred_en;
     808             : 
     809           0 :     Lav_pred_en = L_mult( past_qua_en[0], 8192 );
     810           0 :     FOR( i = 1; i < GAIN_PRED_ORDER; i++ )
     811             :     {
     812           0 :         Lav_pred_en = L_mac( Lav_pred_en, past_qua_en[i], 8192 );
     813             :     }
     814             : 
     815             :     /*av_pred_en = (float)(av_pred_en*(1.0f/(float)GAIN_PRED_ORDER)-3.0f);*/
     816           0 :     av_pred_en = sub( round_fx( Lav_pred_en ), 3 << 10 );
     817             : 
     818             :     /*if (av_pred_en < -14.0f)av_pred_en = -14.0f;*/
     819           0 :     av_pred_en = s_max( av_pred_en, -14 * ( 1 << 10 ) );
     820             : 
     821             : 
     822           0 :     FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
     823             :     {
     824           0 :         past_qua_en[i] = past_qua_en[i - 1];
     825           0 :         move16();
     826             :     }
     827             : 
     828           0 :     past_qua_en[0] = av_pred_en;
     829           0 :     move16();
     830             : 
     831           0 :     return;
     832             : }

Generated by: LCOV version 1.14