LCOV - code coverage report
Current view: top level - lib_dec - FEC_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 333 348 95.7 %
Date: 2025-09-16 02:47:18 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        5842 : 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        5842 :     hGSCDec = st_fx->hGSCDec;
      99             : 
     100             :     AMRWB_IO_DEC_HANDLE hAmrwb_IO;
     101        5842 :     hAmrwb_IO = st_fx->hAmrwb_IO;
     102             :     /* nb_subfr = L_frame/L_SUBFR */
     103        5842 :     nb_subfr = shr( L_frame, 6 );
     104        5842 :     Diff_len = 0; /* to avoid compilation flags */
     105        5842 :     move16();
     106        5842 :     set16_fx( exc_dct_in, 0, L_FRAME16k );
     107             : 
     108        5842 :     extrapolationFailed = 1;
     109        5842 :     move16();
     110             : 
     111        5842 :     gainCNG = 0;
     112        5842 :     move16();
     113        5842 :     IF( st_fx->lp_ener_fx != 0 )
     114             :     {
     115         472 :         exp = norm_l( st_fx->lp_ener_fx ); /*lp_ener in Q6*/
     116         472 :         tmp = extract_h( L_shl( st_fx->lp_ener_fx, exp ) );
     117         472 :         exp = sub( exp, 30 - 6 );
     118             : 
     119         472 :         tmp = div_s( 16384, tmp );
     120         472 :         L_tmp = L_deposit_h( tmp );
     121         472 :         L_tmp = Isqrt_lc( L_tmp, &exp );
     122             : 
     123         472 :         gainCNG = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */
     124             :     }
     125        5842 :     tmp1 = shl_sat( st_fx->lp_gainc_fx, 1 );
     126        5842 :     gainCNG = s_min( gainCNG, tmp1 );
     127        5842 :     set16_fx( exc_dct_in, 0, L_FRAME16k );
     128             : 
     129             :     /*-----------------------------------------------------------------*
     130             :      * pitch extrapolation
     131             :      *-----------------------------------------------------------------*/
     132             : 
     133             :     {
     134             :         Word32 *tmp_old_pitch /*15Q16*/;
     135             :         Word16 tmp_pitmin, tmp_pitmax;
     136             : 
     137             :         /*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];*/
     138             :         /*tmp_pitmin = L_frame == L_FRAME?PIT_MIN_DOUBLEEXTEND:PIT16k_MIN_EXTEND;*/
     139             :         /*tmp_pitmax = L_frame == L_FRAME?PIT_MAX:PIT16k_MAX;*/
     140             : 
     141        5842 :         tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1];
     142        5842 :         tmp_pitmin = PIT16k_MIN_EXTEND;
     143        5842 :         move16();
     144        5842 :         tmp_pitmax = PIT16k_MAX;
     145        5842 :         move16();
     146        5842 :         IF( EQ_16( L_frame, L_FRAME ) )
     147             :         {
     148        1358 :             tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1];
     149        1358 :             tmp_pitmin = PIT_MIN_DOUBLEEXTEND;
     150        1358 :             move16();
     151        1358 :             tmp_pitmax = PIT_MAX;
     152        1358 :             move16();
     153             :         }
     154             : 
     155             : 
     156        5842 :         pitch_pred_linear_fit(
     157        5842 :             st_fx->nbLostCmpt,
     158        5842 :             st_fx->last_good,
     159        5842 :             st_fx->old_pitch_buf_fx,
     160             :             tmp_old_pitch,
     161             :             &predPitchLag,
     162             :             tmp_pitmin,
     163             :             tmp_pitmax,
     164        5842 :             st_fx->mem_pitch_gain,
     165             :             0,
     166             :             0,
     167             :             &extrapolationFailed,
     168             :             nb_subfr );
     169             : 
     170        5842 :         new_pit /*Q0 int*/ = shl( round_fx( predPitchLag ), 0 );
     171             :     }
     172             : 
     173             : 
     174             :     /*-----------------------------------------------------------------*
     175             :      * estimate subframe pitch values for the FEC frame
     176             :      *-----------------------------------------------------------------*/
     177             : 
     178             :     /* initialize pitch to the long-term pitch */
     179             : 
     180        5842 :     *tmp_tc = st_fx->bfi_pitch_fx;
     181        5842 :     move16(); /*Q6*/
     182        5842 :     IF( EQ_16( L_frame, L_FRAME ) )
     183             :     {
     184        1358 :         test();
     185        1358 :         test();
     186        1358 :         IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl_sat( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) &&
     187             :               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  */
     188             :             GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) )                                                                                /* or last update too far in the past */
     189             :         {
     190             :             /* take the pitch value of last subframe of the previous frame */
     191        1330 :             *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) );
     192        1330 :             move16();
     193             :         }
     194             :     }
     195             :     ELSE /* L_frame == L_FRAME16k */
     196             :     {
     197        4484 :         test();
     198        4484 :         test();
     199        4484 :         IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl_sat( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) &&
     200             :               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  */
     201             :             GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) )                                                                                   /* or last update too far in the past */
     202             : 
     203             :         {
     204             :             /* take the pitch value of last subframe of the previous frame */
     205        4468 :             *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) );
     206        4468 :             move16();
     207             :         }
     208             :     }
     209             : 
     210             :     /* convert pitch period */
     211             :     /* Tc = (short)(tmp_tc + 0.5f) */
     212        5842 :     Tc = shr_r( *tmp_tc, 6 );
     213             : 
     214             :     /* estimate pitch values for all subframes */
     215             :     /*calculate conditions for Pulse resynchronization to take place*/
     216        5842 :     pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
     217             : 
     218        5842 :     test();
     219        5842 :     test();
     220        5842 :     test();
     221        5842 :     test();
     222        5842 :     IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
     223             :     {
     224         289 :         tmp16 = *tmp_tc; /*Q6*/
     225         289 :         move16();
     226         289 :         IF( EQ_16( nb_subfr, 4 ) )
     227             :         {
     228          79 :             delta = shr( sub( shl( new_pit, 6 ), *tmp_tc ), 2 ); /* 4 sub-frames */
     229             :         }
     230             :         ELSE
     231             :         {
     232         210 :             delta = mult_r( sub( shl( new_pit, 6 ), *tmp_tc ), 6554 ); /* 5 sub-frames */
     233             :         }
     234        1655 :         FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values */
     235             :         {
     236             :             /* fT0 += delta */
     237        1366 :             tmp16 = add( tmp16, delta );
     238             :             /* ptch_buf[i] = (short)(fT0 + 0.5) */
     239        1366 :             pitch_buf[i] = shl( mult_r( tmp16, 512 ), 6 );
     240        1366 :             move16();
     241             :         }
     242             :     }
     243             :     ELSE
     244             :     {
     245       32039 :         FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values for bass postfilter */
     246             :         {
     247       26486 :             pitch_buf[i] = *tmp_tc;
     248       26486 :             move16();
     249             :         }
     250             :     }
     251             : 
     252             :     /*-----------------------------------------------------------------*
     253             :      * estimate damping factor
     254             :      *-----------------------------------------------------------------*/
     255             : 
     256             :     /* rapid convergence to 0 */
     257        5842 :     alpha = _ALPHA_VT_FX;
     258        5842 :     move16();
     259        5842 :     test();
     260        5842 :     test();
     261        5842 :     test();
     262        5842 :     test();
     263        5842 :     test();
     264        5842 :     test();
     265        5842 :     test();
     266        5842 :     IF( EQ_16( st_fx->last_coder_type, UNVOICED ) && LE_16( st_fx->nbLostCmpt, 3 ) )
     267             :     {
     268             :         /* last good frame was clearly unvoiced */
     269         244 :         alpha = _ALPHA_UU_FX;
     270         244 :         move16();
     271             :     }
     272        5598 :     ELSE IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
     273             :     {
     274         126 :         test();
     275         126 :         IF( hGSCDec->Last_GSC_pit_band_idx > 0 && GT_16( st_fx->nbLostCmpt, 1 ) )
     276             :         {
     277          16 :             alpha = 26214;
     278          16 :             move16();
     279             :         }
     280         110 :         ELSE IF( LE_16( st_fx->nbLostCmpt, 5 ) )
     281             :         {
     282         110 :             alpha = 32604;
     283         110 :             move16();
     284             :         }
     285             :         ELSE
     286             :         {
     287           0 :             alpha = 31130;
     288           0 :             move16();
     289             :         }
     290             :     }
     291        5472 :     ELSE IF( EQ_16( st_fx->last_good, UNVOICED_CLAS ) )
     292             :     {
     293         960 :         IF( LE_16( st_fx->nbLostCmpt, 1 ) )
     294             :         {
     295             :             /* if stable, do not decrease the energy, pitch_gain = 0 */
     296         800 :             alpha = mac_r_sat( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX ); /*st_fx->stab_fac_fx in Q15*/
     297             :         }
     298         160 :         ELSE IF( EQ_16( st_fx->nbLostCmpt, 2 ) )
     299             :         {
     300         154 :             alpha = _ALPHA_S_FX;
     301         154 :             move16(); /* ALPHA_U*1.5f = 0.6 */
     302             :         }
     303             :         ELSE
     304             :         {
     305           6 :             alpha = _ALPHA_U_FX;
     306           6 :             move16(); /* 0.4 go rapidly to CNG gain, pitch gain = 0 */
     307             :         }
     308             :     }
     309        4512 :     ELSE IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) )
     310             :     {
     311          16 :         alpha = _ALPHA_UT_FX;
     312          16 :         move16();
     313             :     }
     314        4496 :     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 ) ) )
     315             :     {
     316         150 :         alpha = 26214;
     317         150 :         move16(); /* mild convergence to 0 for the first 3 erased frames 0.8 in Q15 */
     318             :     }
     319        4346 :     ELSE IF( ( EQ_16( st_fx->last_good, VOICED_CLAS ) || EQ_16( st_fx->last_good, ONSET ) ) && LE_16( st_fx->nbLostCmpt, 3 ) )
     320             :     {
     321        2326 :         alpha = _ALPHA_V_FX;
     322        2326 :         move16(); /* constant for the first 3 erased frames */
     323             :     }
     324        2020 :     ELSE IF( EQ_16( st_fx->last_good, SIN_ONSET ) )
     325             :     {
     326          12 :         alpha = _ALPHA_S_FX;
     327          12 :         move16();
     328             :     }
     329        5842 :     test();
     330        5842 :     test();
     331        5842 :     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 ) )
     332             :     {
     333        2632 :         IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) /* if first erased frame in a block, reset harmonic gain */
     334             :         {
     335             :             /* move pitch gain towards 1 for voiced to remove energy fluctuations */
     336             :             /*gain = (float)sqrt( st_fx->lp_gainp );*/
     337        1888 :             st_fx->lp_gainp_fx = s_max( st_fx->lp_gainp_fx, 1 );
     338        1888 :             move16();
     339        1888 :             exp = norm_s( st_fx->lp_gainp_fx );
     340        1888 :             tmp = shl( st_fx->lp_gainp_fx, exp );
     341        1888 :             tmp = div_s( 16384, tmp );
     342        1888 :             L_tmp = L_deposit_h( tmp );
     343        1888 :             L_tmp = Isqrt_lc( L_tmp, &exp );
     344             : 
     345        1888 :             gain = extract_h( L_shl_sat( L_tmp, exp ) );
     346             : 
     347        1888 :             gain = s_min( gain, 32113 ); /*0.98 */
     348        1888 :             gain = s_max( gain, 27853 ); /*0.85 */
     349             : 
     350        1888 :             alpha = mult_r( alpha, gain );
     351             :         }
     352             :         ELSE
     353             :         {
     354             :             /* st_fx->lp_gainp_fx is in Q14 when bfi_cnt > 1 to follow floating point because lp_gainp could be > than 1  */
     355         744 :             alpha = st_fx->lp_gainp_fx;
     356         744 :             move16();
     357             :         }
     358             :     }
     359             : 
     360             :     /*-----------------------------------------------------------------*
     361             :      * construct the harmonic part of excitation
     362             :      *-----------------------------------------------------------------*/
     363        5842 :     test();
     364        5842 :     test();
     365        5842 :     test();
     366        5842 :     test();
     367        5842 :     IF( ( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) ) ||
     368             :         ( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 ) )
     369             :     {
     370             : 
     371        4660 :         pt_exc = exc;
     372        4660 :         pt1_exc = pt_exc - Tc;
     373             : 
     374        4660 :         IF( EQ_16( st_fx->nbLostCmpt, 1 ) )
     375             :         {
     376             :             /* first pitch cycle is low-pass filtered */
     377             : 
     378      194087 :             FOR( i = 0; i < Tc; i++ ) /* pitch cycle is first low-pass filtered */
     379             :             {
     380             :                 /* *pt_exc++ = (0.18f * pt1_exc[-1] + 0.64f * pt1_exc[0] + 0.18f * pt1_exc[1]) */
     381      191943 :                 L_tmp = L_mult( 5898, pt1_exc[-1] );
     382      191943 :                 L_tmp = L_mac( L_tmp, 20972, pt1_exc[0] );
     383      191943 :                 *pt_exc++ = mac_r( L_tmp, 5898, pt1_exc[1] );
     384      191943 :                 move16();
     385      191943 :                 pt1_exc++;
     386             :             }
     387             :         }
     388             : 
     389             :         /* last pitch cycle of the previous frame is repeatedly copied up to an extra subframe */
     390             : 
     391        4660 :         tmp = extract_l( ( exc + add( L_frame, L_SUBFR ) ) - pt_exc );
     392     1551085 :         FOR( i = 0; i < tmp; i++ )
     393             :         {
     394     1546425 :             *pt_exc++ = *pt1_exc++;
     395     1546425 :             move16();
     396             :         }
     397             : 
     398        4660 :         IF( new_pit > 0 )
     399             :         {
     400             :             /*calculate conditions for Pulse resynchronization to take place*/
     401        3012 :             pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
     402             : 
     403        3012 :             test();
     404        3012 :             test();
     405        3012 :             test();
     406        3012 :             test();
     407        3012 :             IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
     408             :             {
     409         289 :                 Copy( exc, exc - add( L_frame, L_SUBFR ), add( L_frame, L_SUBFR ) );
     410         289 :                 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*/ );
     411             :             }
     412             :         }
     413        4660 :         test();
     414        4660 :         test();
     415        4660 :         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 ) ) )
     416             :         {
     417             :             /* start of the frame gain */
     418          16 :             gain = 0;
     419          16 :             move16();
     420             : 
     421             :             /* end of the frame gain */
     422          16 :             st_fx->lp_gainp_fx = 0;
     423          16 :             move16();
     424          16 :             step = 0;
     425          16 :             move16();
     426             :         }
     427             :         ELSE
     428             :         {
     429             : 
     430             :             /* start of the frame gain */
     431        4644 :             gain = 16384;
     432        4644 :             move16();
     433             : 
     434             :             /* end of the frame gain */
     435        4644 :             test();
     436        4644 :             test();
     437        4644 :             test();
     438        4644 :             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 ) ) )
     439             :             {
     440        3900 :                 st_fx->lp_gainp_fx = shr( alpha, 1 ); /* alpha in Q15 */
     441             :             }
     442             :             ELSE
     443             :             {
     444         744 :                 st_fx->lp_gainp_fx = alpha;
     445         744 :                 move16(); /* alpha in Q14 */
     446             :             }
     447             : 
     448        4644 :             IF( EQ_16( L_frame, L_FRAME ) )
     449             :             {
     450         792 :                 step = shr( sub( gain, st_fx->lp_gainp_fx ), 8 );
     451             :             }
     452             :             ELSE /*L_frame == L_FRAME16k*/
     453             :             {
     454             :                 /*step = (1.0f/L_frame) * (gain - st_fx->lp_gainp);*/
     455             : 
     456        3852 :                 step = shr( mult_r( 26214, sub( gain, st_fx->lp_gainp_fx ) ), 8 ); /*Q14*/
     457             :             }
     458             :         }
     459             : 
     460     1444788 :         FOR( i = 0; i < L_frame; i++ )
     461             :         {
     462             :             /* exc[i] *= gain */
     463     1440128 :             exc[i] = round_fx( L_shl( L_mult( exc[i], gain ), 1 ) ); /* in Q_exc */
     464     1440128 :             move16();
     465             :             /* gain -= step */
     466     1440128 :             gain = sub( gain, step );
     467             :         }
     468        4660 :         test();
     469        4660 :         test();
     470        4660 :         IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 )
     471             :         {
     472          94 :             Diff_len = mfreq_loc_div_25[hGSCDec->Last_GSC_pit_band_idx];
     473          94 :             move16();
     474             : 
     475             :             /* Transform to frequency domain */
     476          94 :             edct_16fx( exc, exc_dct_in, st_fx->L_frame, 5, st_fx->element_mode );
     477             : 
     478             :             /* Reset unvaluable part of the adaptive (pitch) excitation contribution */
     479          94 :             max_len = sub( st_fx->L_frame, Diff_len );
     480          94 :             Len = s_min( max_len, 80 );
     481             : 
     482          94 :             move16(); /*ptr init*/
     483        7070 :             FOR( i = 0; i < Len; i++ )
     484             :             {
     485        6976 :                 exc_dct_in[i + Diff_len] = mult_r( exc_dct_in[i + Diff_len], sm_table_fx[i] );
     486        6976 :                 move16();
     487             :             }
     488             : 
     489        3740 :             FOR( ; i < max_len; i++ )
     490             :             {
     491        3646 :                 exc_dct_in[i + Diff_len] = 0;
     492        3646 :                 move16();
     493             :             }
     494          94 :             Diff_len = add( Diff_len, 1 );
     495             :         }
     496             :     } /* end of "if st_fx->last_good >= VOICED_TRANSITION" */
     497             : 
     498             :     /*-----------------------------------------------------------------*
     499             :      * Replicate the last spectrum in case the last good frame was coded by GSC
     500             :      *-----------------------------------------------------------------*/
     501        5842 :     test();
     502        5842 :     test();
     503        5842 :     test();
     504        5842 :     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 ) )
     505             :     {
     506         204 :         st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag;
     507         204 :         move16();
     508             :         /* st_fx->L_frame / L_SUBFR */
     509         204 :         tmp = shr( st_fx->L_frame, 6 );
     510             : 
     511             :         /* Replication of the last spectrum, with a slight downscaling of its dynamic */
     512         204 :         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 );
     513             : 
     514         204 :         *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/
     515         204 :         move16();
     516             :         /* Transform back to time domain */
     517         204 :         edct_16fx( exc_dct_in, exc, st_fx->L_frame, 5, st_fx->element_mode );
     518             :     }
     519             :     ELSE
     520             :     {
     521             :         /*-----------------------------------------------------------------*
     522             :          * Construct the random part of excitation
     523             :          *-----------------------------------------------------------------*/
     524             : 
     525             :         /* generate the random part of the excitation */
     526     1758238 :         FOR( i = 0; i < L_frame + MODE1_L_FIR_FER - 1; i++ )
     527             :         {
     528             :             /*Q-3*/
     529     1752600 :             exc2_buf[i] = shr( Random( &st_fx->seed ), 3 );
     530     1752600 :             move16();
     531             :         }
     532             : 
     533             :         /* start of the frame gain */
     534        5638 :         gain = st_fx->lp_gainc_fx;
     535        5638 :         move16();
     536             : 
     537        5638 :         test();
     538        5638 :         test();
     539        5638 :         test();
     540        5638 :         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 ) ) )
     541             :         {
     542             :             /* Here alpha is in Q15 and lp_gainc_fx in Q3 */
     543             :             /*  st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
     544        4894 :             L_tmp = L_mult( alpha, st_fx->lp_gainc_fx );
     545             : 
     546        4894 :             st_fx->lp_gainc_fx = msu_r( L_tmp, add( alpha, -32768 ), gainCNG );
     547        4894 :             move16();
     548             :         }
     549             :         ELSE
     550             :         { /* Here alpha is in Q14, but lp_gainc still in Q3 */
     551             :             /*  st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
     552         744 :             L_tmp = L_mult( alpha, st_fx->lp_gainc_fx ); /* Q14*Q3->Q18 */
     553             : 
     554         744 :             st_fx->lp_gainc_fx = round_fx( L_shl( L_msu( L_tmp, add( alpha, -16384 ), gainCNG ), 1 ) ); /* (Q14*Q3<<1)>>16 ->Q3 */
     555         744 :             move16();
     556             :         }
     557             : 
     558        5638 :         test();
     559        5638 :         test();
     560        5638 :         test();
     561        5638 :         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 )
     562             :         {
     563           2 :             st_fx->lp_gainc_fx = gainCNG;
     564           2 :             move16();
     565             :         }
     566             : 
     567             :         /* linearly attenuate the gain throughout the frame */
     568             :         /* step = (1.0f/L_FRAME) * (gain - *lp_gainc); */
     569        5638 :         step = sub( gain, st_fx->lp_gainc_fx ); /* divide by L_FRAME done later */
     570        5638 :         test();
     571        5638 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     572             :         {
     573        4480 :             step = mult_r( step, 26214 ); /* L_frame16k-> L_frame and division by L_frame done later*/
     574             :         }
     575             : 
     576             :         /* calculate gain to normalize energy */
     577        5638 :         pt_exc = exc2_buf + MODE1_L_FIR_FER / 2;
     578        5638 :         move16();
     579             : 
     580             :         /* To avoid saturation split the L_frame dot product into (L_frame/L_SUBFR) dot products
     581             :            and scale down before adding */
     582             :         /*  gain_inov = 1.0f / (float)sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); */
     583             : 
     584        5638 :         L_tmp = L_deposit_l( 0 );
     585       16914 :         FOR( i = 0; i < 2; i++ )
     586             :         {
     587       11276 :             L_tmp2 = L_mult0( *pt_exc, *pt_exc );
     588       11276 :             pt_exc++;
     589     1730048 :             FOR( j = 1; j < shr( L_frame, 1 ); j++ )
     590             :             {
     591     1718772 :                 L_tmp2 = L_mac0( L_tmp2, *pt_exc, *pt_exc ); /* Q-5 */
     592     1718772 :                 pt_exc++;
     593             :             }
     594       11276 :             L_tmp = L_add( L_tmp, L_shr( L_tmp2, 1 ) ); /* Q-7 */
     595             :         }
     596        5638 :         test();
     597        5638 :         IF( EQ_16( L_frame, L_FRAME16k ) )
     598             :         {
     599        4480 :             L_tmp = Mult_32_16( L_tmp, 26214 ); /* x0.8 to normalize to 256 samples */
     600             :         }
     601        5638 :         exp = norm_l( L_tmp );
     602        5638 :         L_tmp = L_shl( L_tmp, exp );     /* Normalize                  */
     603        5638 :         exp = add( exp, 8 - 7 );         /* Q0, 8 ->divide by 256      */
     604        5638 :         exp = sub( 31, exp );            /* For Denormalization in Q31 */
     605        5638 :         L_tmp = Isqrt_lc( L_tmp, &exp ); /* in Q(31-exp)                     */
     606        5638 :         gain_inov = round_fx( L_tmp );
     607             : 
     608             :         /* attenuate somewhat on unstable unvoiced */
     609        5638 :         test();
     610        5638 :         test();
     611        5638 :         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 ) )
     612             :         {
     613         964 :             gain_inov = mult_r( gain_inov, 26214 );
     614             :         }
     615             : 
     616             :         /* scaling of the random part of excitation */
     617        5638 :         pt_exc = exc2_buf;
     618        5638 :         move16();
     619        5638 :         L_step = L_shr( L_mult( gain_inov, step ), 8 ); /* here is the divide by L_FRAME */
     620        5638 :         L_tmp2 = L_mult( gain_inov, gain );             /* Q15 * Q3 -> Q3 */
     621        5638 :         tmp = round_fx( L_tmp2 );
     622        5638 :         exp = add( add( exp, *Q_exc ), 15 ); /* 3+Q_exc+15 -> Q_exc+18 */
     623             : 
     624       16914 :         FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ )
     625             :         {
     626             :             /* non-causal ringing of the FIR filter */
     627             :             /**pt_exc++ *= (gain_inov * gain);*/
     628       11276 :             L_tmp = L_mult( tmp, *pt_exc ); /* Q_exc+18 * Q-3 -> Q_exc+16 */
     629       11276 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     630       11276 :             move16();
     631             :         }
     632             : 
     633     1735686 :         FOR( i = 0; i < L_frame; i++ )
     634             :         {
     635             :             /* the inner part of the FIR filter */
     636             :             /* *pt_exc++ *= (gain_inov * gain); */
     637     1730048 :             L_tmp = L_mult( tmp, *pt_exc );
     638     1730048 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     639     1730048 :             move16();
     640             :             /* gain -= step; */
     641     1730048 :             L_tmp2 = L_sub( L_tmp2, L_step );
     642     1730048 :             tmp = round_fx( L_tmp2 );
     643             :         }
     644             : 
     645       16914 :         FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ ) /* causal ringing of the FIR filter */
     646             :         {
     647             :             /* *pt_exc++ *= (gain_inov * gain) */
     648       11276 :             L_tmp = L_mult( tmp, *pt_exc );
     649       11276 :             *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     650       11276 :             move16();
     651             :         }
     652             :     }
     653             : 
     654             :     /*-----------------------------------------------------------------*
     655             :      * Total excitation
     656             :      *-----------------------------------------------------------------*/
     657        5842 :     test();
     658        5842 :     test();
     659        5842 :     test();
     660        5842 :     test();
     661        5842 :     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 ) )
     662             :     {
     663             :         /* For GSC - the excitation is already computed */
     664         204 :         Copy( exc, exc2, st_fx->L_frame );
     665             :     }
     666        5638 :     ELSE IF( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) )
     667             :     {
     668             :         /* For voiced and generic signals - prepare a HP filter for the random part of excitation */
     669             :         /* tmp = -(1-tilt_code) to correctly represent 1.0000 */
     670        4558 :         tmp = add( st_fx->tilt_code_fx, -32768 );
     671       27348 :         FOR( i = 0; i < MODE1_L_FIR_FER; i++ )
     672             :         {
     673       22790 :             hp_filt[i] = msu_r( 0, tmp, h_high_fx[i] );
     674       22790 :             move16();
     675             :         }
     676             : 
     677             :         /* HP filter the random part of the excitation and add the adaptive part */
     678        4558 :         pt_exc = exc2_buf;
     679     1418574 :         FOR( i = 0; i < L_frame; i++ )
     680             :         {
     681             :             /* exc2[i] = exc[i] + dotp( &exc2_buf[i], hp_filt, MODE1_L_FIR_FER );*/
     682     1414016 :             L_tmp = L_mult( hp_filt[0], pt_exc[0] );
     683     7070080 :             FOR( j = 1; j < MODE1_L_FIR_FER; j++ )
     684             :             {
     685     5656064 :                 L_tmp = L_mac_sat( L_tmp, hp_filt[j], pt_exc[j] );
     686             :             }
     687     1414016 :             exc2[i] = msu_r_sat( L_tmp, -32768, exc[i] );
     688     1414016 :             move16();
     689     1414016 :             pt_exc++;
     690             :         }
     691             :     }
     692             :     ELSE
     693             :     {
     694             :         /* For purely unvoiced signals - just copy the unfiltered random part of the excitation */
     695        1080 :         Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc, L_frame );
     696        1080 :         Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc2, L_frame );
     697             :     }
     698        5842 :     IF( st_fx->hBWE_TD != NULL )
     699             :     {
     700        5842 :         IF( EQ_16( L_frame, L_FRAME ) )
     701             :         {
     702        1358 :             interp_code_5over2_fx( exc, bwe_exc, L_frame );
     703             :         }
     704             :         ELSE
     705             :         {
     706        4484 :             interp_code_4over2_fx( exc, bwe_exc, L_frame );
     707             :         }
     708             :     }
     709        5842 :     test();
     710        5842 :     IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
     711             :     {
     712         208 :         IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     713             :         {
     714         200 :             set16_fx( voice_factors, 32767, NB_SUBFR );
     715             :         }
     716             :         ELSE
     717             :         {
     718           8 :             set16_fx( voice_factors, 32767, NB_SUBFR16k );
     719             :         }
     720             :     }
     721             :     ELSE
     722             :     {
     723        5634 :         IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     724             :         {
     725        1158 :             set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR ); /* The factor of the last subframe is propagated forward */
     726             :         }
     727             :         ELSE
     728             :         {
     729        4476 :             set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR16k ); /* The factor of the last subframe is propagated forward */
     730             :         }
     731             :     }
     732        5842 :     IF( st_fx->Opt_AMR_WB )
     733             :     {
     734           0 :         gain_dec_bfi_fx( hAmrwb_IO->past_qua_en_fx );
     735             :     }
     736             :     /* L_frame / L_SUBFR */
     737        5842 :     tmp = shr( L_frame, 6 );
     738        5842 :     st_fx->bfi_pitch_fx = pitch_buf[tmp - 1];
     739        5842 :     move16();
     740        5842 :     st_fx->bfi_pitch_frame = st_fx->L_frame;
     741        5842 :     move16();
     742        5842 :     return;
     743             : }
     744             : 
     745             : 
     746             : /*calculates some conditions for Pulse resynchronization to take place*/
     747        8854 : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame )
     748             : {
     749             :     Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e;
     750             :     Word32 tmp_pit2;
     751             : 
     752        8854 :     tmp_pit = BASOP_Util_Divide1616_Scale( new_pit /*Q0*/, Tc /*Q0*/, &tmp_pit_e ) /*Q15*/;
     753        8854 :     tmp_frame = add( extract_l( L_mult0( L_frame, 64 /*1.f/L_SUBFR Q12*/ ) /*Q12*/ ), 4096 /*1.f Q12*/ ); /*Q12*/
     754        8854 :     tmp_frame = BASOP_Util_Divide1616_Scale( 4096 /*1.f Q12*/, tmp_frame, &tmp_frame_e );                 /*Q15*/
     755        8854 :     tmp_frame = shl( tmp_frame, add( tmp_frame_e, 1 ) );
     756        8854 :     tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/
     757             :     BASOP_SATURATE_WARNING_OFF_EVS
     758             :     /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
     759        8854 :     tmp_pit = shl_sat( negate( tmp_pit ), tmp_pit_e );
     760             :     BASOP_SATURATE_WARNING_ON_EVS
     761        8854 :     *cond1 = sub( tmp_pit, negate( tmp_frame ) );
     762        8854 :     move16();
     763             : 
     764        8854 :     *cond2 = sub( Tc, new_pit );
     765        8854 :     move16();
     766             : 
     767        8854 :     tmp_pit_e = BASOP_Util_Add_MantExp( new_pit, 15 - 0, negate( Tc ), 15 - 0, &tmp_pit ); /*Q15*/
     768        8854 :     tmp_pit = abs_s( tmp_pit );
     769        8854 :     tmp_pit2 = L_mult( Tc, 4915 /*0.15f Q15*/ ); /*Q16*/
     770             :     BASOP_SATURATE_WARNING_OFF_EVS
     771             :     /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
     772        8854 :     tmp_pit2 = L_shl_sat( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) );
     773             :     BASOP_SATURATE_WARNING_ON_EVS
     774        8854 :     *cond3 = L_sub( L_mult0( -1, tmp_pit ), tmp_pit2 );
     775        8854 :     move32();
     776        8854 : }
     777             : 
     778             : /*-------------------------------------------------------------------*
     779             :  * gain_dec_bfi()
     780             :  *
     781             :  * Estimate past quantized gain prediction residual to be used in
     782             :  * next frame
     783             :  *-------------------------------------------------------------------*/
     784             : 
     785           0 : void gain_dec_bfi_fx(
     786             :     Word16 *past_qua_en /* i/o: gain quantization memory (4 words)  Qx*/
     787             : )
     788             : {
     789             :     Word16 i;
     790             :     Word16 av_pred_en;
     791             :     Word32 Lav_pred_en;
     792             : 
     793           0 :     Lav_pred_en = L_mult( past_qua_en[0], 8192 );
     794           0 :     FOR( i = 1; i < GAIN_PRED_ORDER; i++ )
     795             :     {
     796           0 :         Lav_pred_en = L_mac( Lav_pred_en, past_qua_en[i], 8192 );
     797             :     }
     798             : 
     799             :     /*av_pred_en = (float)(av_pred_en*(1.0f/(float)GAIN_PRED_ORDER)-3.0f);*/
     800           0 :     av_pred_en = sub( round_fx( Lav_pred_en ), 3 << 10 );
     801             : 
     802             :     /*if (av_pred_en < -14.0f)av_pred_en = -14.0f;*/
     803           0 :     av_pred_en = s_max( av_pred_en, -14 * ( 1 << 10 ) );
     804             : 
     805             : 
     806           0 :     FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
     807             :     {
     808           0 :         past_qua_en[i] = past_qua_en[i - 1];
     809           0 :         move16();
     810             :     }
     811             : 
     812           0 :     past_qua_en[0] = av_pred_en;
     813           0 :     move16();
     814             : 
     815           0 :     return;
     816             : }

Generated by: LCOV version 1.14