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

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : /*VERSIONINFO: File up to date with trunk rev. 39929*/
       6             : 
       7             : 
       8             : #include <stdint.h>
       9             : #include "options.h"
      10             : #include <assert.h>
      11             : #include "prot_fx.h"
      12             : #include "basop_util.h"
      13             : #include "rom_dec.h"
      14             : extern const Word16 T_DIV_L_Frame[]; /*0Q15 * 2^-7 */
      15             : 
      16             : /*Table 2^7 * 1/L_frame */
      17             : 
      18             : #define L_SYN_BUF M + L_DIV_MAX + L_DIV_MAX
      19             : #define L_EXC_BUF OLD_EXC_SIZE_DEC_16k + L_DIV_MAX + L_SUBFR + 1 + L_DIV_MAX / 2
      20             : 
      21             : /*LOCAL FUNCTIONS*/
      22             : static void memsynPrecission_fx( Word16 nbLostCmpt, Word16 *mem_syn, Word16 *exc, Word16 len, Word16 *s_16 );
      23             : 
      24             : 
      25             : /***************************************************************
      26             :  *  \brief Main concealment function for ACELP
      27             :  *
      28             :  *
      29             :  ****************************************************************/
      30             : 
      31           0 : void con_acelp_fx(
      32             :     const Word16 A[],        /*<! i     Q12: coefficients NxAz[M+1]                                  */
      33             :     const Word16 coder_type, /*<! i     Q0 : ACELP coder type                                        */
      34             :     Word16 synth[],          /*<! i/o   Qx :   synthesis buffer,                 Headroom: 3 bits?   */
      35             :     Word16 *pT,              /*<! o     Q0 :   pitch for all subframe   [4]pit_min..pit_max          */
      36             :     Word16 *pgainT,          /*<! o     Q14:   pitch gain for all subfr [4] 0...1.3                  */
      37             :     const Word16 stab_fac,   /*<! i     Q15: stability of isf                                        */
      38             :     Decoder_State *st,
      39             :     const Word16 *Qf_exc,  /*<! i       :  Q format for excitation buffer                          */
      40             :     Word16 *Qf_mem_syn,    /*<! i/o     :  Q format for st->mem_syn            >rescaling done     */
      41             :     Word16 *pitch_buffer,  /* Q0 */
      42             :     Word16 *voice_factors, /* Q6 */
      43             :     Word16 *bwe_exc /* Qx */ )
      44             : {
      45             : 
      46             :     Word16 i_subfr, i, T0; /*Q0*/
      47             :     Word16 tmp, tmp2, tmp_deemph;
      48             :     Word16 mem_syn[M], mem_syn2[M], *syn;
      49             :     Word16 *noise_buf;
      50             :     Word16 *exc, *harmonic_exc_buf, buf[L_EXC_MEM_DEC + M + L_FRAME_16k + L_FRAME_16k / 2]; /*Qf_exc*/
      51             :     const Word16 *p_A;
      52             :     Word32 pitch_buf[NB_SUBFR16k] /*15Q16*/;
      53             :     Word16 alpha; /*Q14*/
      54             :     Word16 step, gain, gainCNG, ftmp;
      55             :     Word16 *pt_exc;
      56             :     Word16 gain_inov;
      57             :     Word16 gainCNG_e; /*scaling Factor (exponent) of gainCNG*/
      58             :     Word16 Qf_syn;    /*Q format and exponent of new synthesis*/
      59             :     Word16 *pt1_exc;
      60             :     Word32 tmp_tc; /*15Q16*/
      61             :     Word16 extrapolationFailed;
      62             :     Word32 predPitchLag;          /*15Q16*/
      63             :     Word32 pc;                    /*float 15Q16*/
      64             :     Word16 fUseExtrapolatedPitch; /*int*/
      65             :     Word16 tmpSeed, Tc;           /*Q0*/
      66             :     Word16 s_32;
      67             :     Word16 synthScaling;
      68           0 :     PWord16 const *w = st->hTcxCfg->tcx_mdct_window;
      69             :     Word16 W1, W2;
      70             :     Word16 nSubframes;
      71             :     Word16 s_16, s_gain_inov, s2;
      72             :     Word16 tmp_16, gain_16;
      73             :     Word32 tmp_32, gain_32, step_32;
      74             :     Word16 l_fir_fer;
      75             :     Word16 lpFiltAdapt[3];
      76             :     Word16 hp_filt[3];
      77             :     Word16 Qf_syn_new;
      78             :     Word16 exc_unv[L_FRAME_16k + L_FRAME_16k / 2];
      79             :     Word16 syn_unv[L_FRAME_16k + L_FRAME_16k / 2];
      80             :     Word16 mem_syn_unv[M];
      81             :     Word16 gain_lpc[NB_SUBFR16k];
      82             :     Word16 gain_lpc_e[NB_SUBFR16k];
      83             :     Word16 mem[M];
      84             :     Word16 h1[L_FRAME_16k / 4 + 1];
      85             :     Word16 gainSynthDeemph;
      86             :     Word16 gainSynthDeemph_e;
      87             :     Word16 l;
      88             :     Word16 g, g_e;
      89             :     Word16 n;
      90           0 :     const Word16 scale_h1 = 5;
      91             :     HQ_DEC_HANDLE hHQ_core;
      92             :     TCX_DEC_HANDLE hTcxDec;
      93           0 :     move16();
      94             : 
      95           0 :     hHQ_core = st->hHQ_core;
      96           0 :     hTcxDec = st->hTcxDec;
      97             : 
      98             :     /*Inits*/
      99           0 :     l_fir_fer = L_FIR_FER;
     100           0 :     move16();
     101             : 
     102           0 :     fUseExtrapolatedPitch = 0;
     103           0 :     move16();
     104           0 :     extrapolationFailed = 1;
     105           0 :     move16();
     106             : 
     107           0 :     alpha = 0;
     108           0 :     move16();
     109             :     /*st->Mode2_lp_gainc    = L_shl(st->Mode2_lp_gainc,7);*/ /*rudiment, could be changed in the whole file but should work also*/
     110           0 :     pc = L_deposit_l( 0 );
     111             : 
     112             :     /*------------------------------------------------------------------------*
     113             :      * Initialize buffers                                                     *
     114             :      *------------------------------------------------------------------------*/
     115             : 
     116             :     /* set ACELP synthesis memory */
     117           0 :     Copy( st->mem_syn2_fx, mem_syn, M ); /* Q_syn */
     118             : 
     119             :     /* set excitation memory*/
     120           0 :     harmonic_exc_buf = buf + M;                              /*Qf_exc*/
     121           0 :     exc = harmonic_exc_buf + L_EXC_MEM_DEC;                  /*Qf_exc*/
     122           0 :     Copy( st->old_exc_fx, harmonic_exc_buf, L_EXC_MEM_DEC ); /*Q_exc*/
     123           0 :     exc[st->L_frame] = 0;
     124           0 :     move16();
     125             : 
     126             :     /*------------------------------------------------------------------------*
     127             :      * PLC: [ACELP:Extrapolate Pitch Lag]
     128             :      *------------------------------------------------------------------------*/
     129             : 
     130           0 :     if ( EQ_16( st->flagGuidedAcelp, 1 ) )
     131             :     {
     132           0 :         T0 = st->guidedT0;
     133           0 :         move16();
     134             :     }
     135             : 
     136           0 :     pitch_pred_linear_fit( st->nbLostCmpt, st->last_good,
     137           0 :                            st->old_pitch_buf_fx,
     138             :                            &st->old_fpitch,
     139           0 :                            &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain, 0,
     140           0 :                            st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr );
     141           0 :     T0 = round_fx( predPitchLag ); /*Q0*/
     142             : 
     143           0 :     IF( extrapolationFailed != 0 )
     144             :     {
     145             :         /*------------------------------------------------------------------------*
     146             :          * - Construct adaptive codebook from side information                    *
     147             :          *------------------------------------------------------------------------*/
     148             : 
     149           0 :         IF( st->flagGuidedAcelp == 0 )
     150             :         {
     151           0 :             nSubframes = 0;
     152           0 :             move16();
     153             :         }
     154             :         ELSE
     155             :         {
     156           0 :             nSubframes = 2;
     157           0 :             move16();
     158             :             /* Construct adaptive codebook with T0, T0_frac, T0_res, gain_pit for 2 sub-frames */
     159           0 :             l = shl( L_SUBFR, 1 );
     160           0 :             FOR( i = 0; i < l; i++ )
     161             :             {
     162           0 :                 exc[i] = exc[( i - st->guidedT0 )]; /*Qf_exc*/
     163           0 :                 move16();
     164             :             }
     165             :         }
     166             :     }
     167             :     ELSE
     168             :     {
     169           0 :         nSubframes = 0;
     170           0 :         move16();
     171             :     }
     172             : 
     173           0 :     tmp_tc = st->old_fpitch; /*15Q16*/
     174           0 :     move32();                /* take the previous frame last pitch*/
     175           0 :     if ( nSubframes > 0 )
     176             :     {
     177           0 :         tmp_tc = L_deposit_h( st->guidedT0 ); /* take the transmit pitch*/ /* Q16 */
     178             :     }
     179             : 
     180             :     /* PLC: [ACELP: Fade-out]
     181             :      * PLC: calculate damping factor */
     182           0 :     alpha = Damping_fact_fx( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
     183           0 :     st->cummulative_damping = shl( mult( st->cummulative_damping, alpha ), 1 );                                 /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
     184           0 :     move16();
     185           0 :     if ( EQ_16( st->nbLostCmpt, 1 ) )
     186             :     {
     187           0 :         st->cummulative_damping = 32767 /*1.f Q15*/; /*Q15*/
     188           0 :         move16();
     189             :     }
     190             : 
     191             :     /*-----------------------------------------------------------------*
     192             :      * PLC: [ACELP: adaptive codebook]
     193             :      * PLC: Construct the harmonic part of excitation
     194             :      *-----------------------------------------------------------------*/
     195             : 
     196           0 :     IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
     197             :     {
     198             : 
     199             :         /*---------------------------------------------------------------*
     200             :          *  Last pitch cycle of the previous frame is repeatedly copied. *
     201             :          *---------------------------------------------------------------*/
     202             : 
     203           0 :         Tc = round_fx( tmp_tc );       /* Q0 */
     204             :         BASOP_SATURATE_WARNING_OFF_EVS /*if this ever saturates, it doesn't matter*/
     205           0 :             tmp = sub( shl_sat( abs_s( sub( T0, Tc ) ), 6 ), mult( 19661 /*0.15f Q17*/, shl_sat( Tc, 4 ) ) /*Q6*/ );
     206             :         BASOP_SATURATE_WARNING_ON_EVS
     207           0 :         test();
     208           0 :         test();
     209           0 :         test();
     210           0 :         if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( tmp < 0 ) && extrapolationFailed == 0 )
     211             :         {
     212           0 :             fUseExtrapolatedPitch = 1;
     213           0 :             move16();
     214             :         }
     215             : 
     216           0 :         pt_exc = exc;
     217           0 :         if ( st->enableGplc != 0 )
     218             :         {
     219           0 :             pt_exc = &exc[( nSubframes * L_SUBFR )]; /*Qf_exc*/
     220             :         }
     221           0 :         pt1_exc = pt_exc - Tc; /*Qf_exc*/
     222             : 
     223           0 :         IF( fUseExtrapolatedPitch != 0 )
     224             :         {
     225             :             /* Required because later pt1_exc[1] used in filtering points to exc[0]. To make it safe also for GPL pt_exc is used instead of exc */
     226           0 :             pt_exc[0] = 0;
     227           0 :             move16();
     228           0 :             pt_exc = harmonic_exc_buf; /*Qf_exc*/
     229           0 :             assert( pt_exc < pt1_exc - 1 );
     230             :         }
     231             : 
     232           0 :         IF( EQ_16( st->nbLostCmpt, 1 ) )
     233             :         {
     234             :             /* pitch cycle is first low-pass filtered */
     235             : 
     236             :             /*get filter coefficients*/
     237           0 :             genPlcFiltBWAdap_fx(
     238             :                 st->sr_core, /*W32 Q0*/
     239             :                 &lpFiltAdapt[0] /*Q15*/,
     240             :                 0,
     241           0 :                 st->cummulative_damping /*Q15*/
     242             :             );
     243           0 :             FOR( i = 0; i < Tc; i++ )
     244             :             {
     245             : 
     246             :                 /* *pt_exc++ = ( lpFiltAdapt[0] * pt1_exc[-1] + lpFiltAdapt[1] * pt1_exc[0] + lpFiltAdapt[2] * pt1_exc[1]);*/
     247           0 :                 tmp_32 = L_mult( lpFiltAdapt[0], pt1_exc[-1] );       /*Q16 + Qf_exc*/
     248           0 :                 tmp_32 = L_mac( tmp_32, lpFiltAdapt[1], pt1_exc[0] ); /*Q16 + Qf_exc*/
     249           0 :                 tmp_16 = mac_r( tmp_32, lpFiltAdapt[2], pt1_exc[1] ); /*Qf_exc*/
     250           0 :                 *pt_exc = tmp_16;                                     /*Qf_exc*/
     251           0 :                 move16();
     252           0 :                 pt_exc++;
     253           0 :                 pt1_exc++;
     254             :             }
     255             :         }
     256             :         ELSE
     257             :         {
     258             :             /* copy the first pitch cycle without low-pass filtering */
     259           0 :             FOR( i = 0; i < Tc; i++ )
     260             :             {
     261           0 :                 *pt_exc++ = *pt1_exc++; /*Qf_exc*/
     262           0 :                 move16();
     263             :             }
     264             :         }
     265             : 
     266           0 :         if ( fUseExtrapolatedPitch != 0 )
     267             :         {
     268           0 :             pt1_exc = harmonic_exc_buf; /*Qf_exc*/
     269             :         }
     270             : 
     271           0 :         l = add( st->L_frame, sub( imult1616( L_SUBFR, sub( 1, nSubframes ) ), Tc ) );
     272           0 :         FOR( i = 0; i < l; i++ )
     273             :         {
     274           0 :             *pt_exc++ = *pt1_exc++; /*Qf_exc*/
     275           0 :             move16();
     276             :         }
     277             : 
     278             :         /*-------------------------------------------------------*
     279             :          *  PLC: [ACELP: adaptive codebook]
     280             :          *  PLC: Resync pulse positions.
     281             :          *-------------------------------------------------------*/
     282             : 
     283           0 :         IF( nSubframes > 0 )
     284             :         {
     285           0 :             pitch_buf[0] = L_deposit_h( st->guidedT0 ); /*Q16*/
     286           0 :             move32();
     287           0 :             pitch_buf[1] = L_deposit_h( st->guidedT0 ); /*Q16*/
     288           0 :             move32();
     289             :         }
     290             : 
     291           0 :         IF( nSubframes > 0 )
     292             :         {
     293           0 :             pitch_buf[3] = pitch_buf[2] = pitch_buf[1]; /* do not resync on second half of frame */
     294           0 :             move32();
     295           0 :             move32();
     296           0 :             if ( EQ_16( st->nb_subfr, 5 ) )
     297             :             {
     298             :                 /* for guided acelp cases and nSubframes=2, set pitch_buf[4] to avoid memory_access issues in post_decoder() */
     299           0 :                 pitch_buf[4] = pitch_buf[3]; /*Q16*/
     300           0 :                 move32();
     301             :             }
     302             :         }
     303             :         ELSE
     304             :         {
     305           0 :             IF( fUseExtrapolatedPitch != 0 )
     306             :             {
     307             : 
     308           0 :                 get_subframe_pitch( st->nb_subfr, st->old_fpitch, predPitchLag, pitch_buf );
     309           0 :                 PulseResynchronization_fx( harmonic_exc_buf, exc, st->L_frame, st->nb_subfr, st->old_fpitch, predPitchLag );
     310             :             }
     311             :             ELSE
     312             :             {
     313           0 :                 set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr ); /*15Q16*/
     314             :             }
     315             :         }
     316             : 
     317             :         /*------------------------------------------------------------*
     318             :          *  PLC: [ACELP: adaptive codebook]
     319             :          *  PLC: Create the harmonic part needed for the overlap-add.
     320             :          *------------------------------------------------------------*/
     321           0 :         pt_exc = exc + st->L_frame; /*Qf_exc*/
     322           0 :         pt1_exc = pt_exc - T0;      /*Qf_exc*/
     323           0 :         if ( T0 == 0 )
     324             :         {
     325           0 :             pt1_exc = pt_exc - Tc;
     326             :         }
     327           0 :         l = shr( st->L_frame, 1 );
     328           0 :         FOR( i = 0; i < l; i++ )
     329             :         {
     330           0 :             *pt_exc++ = *pt1_exc++;
     331           0 :             move16();
     332             :         }
     333             : 
     334             :         /*-------------------------------------------------------*
     335             :          *  PLC: [ACELP: adaptive codebook]
     336             :          *  PLC: update the floating point pitch for consecutive loss
     337             :          *-------------------------------------------------------*/
     338             : 
     339           0 :         IF( fUseExtrapolatedPitch != 0 )
     340             :         {
     341           0 :             st->old_fpitch = predPitchLag; /*Q16*/
     342           0 :             move32();
     343           0 :             if ( EQ_16( st->flagGuidedAcelp, 1 ) )
     344             :             {
     345           0 :                 st->old_fpitch = L_deposit_h( T0 ); /*Q16*/
     346           0 :                 move32();
     347             :             }
     348             :         }
     349             : 
     350             :         /*-------------------------------------------------------*
     351             :          *  PLC: [ACELP: adaptive BPF]
     352             :          *  PLC: Accommodate the BPF
     353             :          *-------------------------------------------------------*/
     354             : 
     355           0 :         st->bpf_gain_param = 3; /*full BPF*/
     356           0 :         move16();
     357             : 
     358             :         /*-------------------------------------------------------*
     359             :          *  PLC: [ACELP: adaptive codebook]
     360             :          *  PLC: Calculate the initial gain and fade out step.
     361             :          *-------------------------------------------------------*/
     362             : 
     363             :         /* Compute pitch coherence (copied from decoder classifier)*/
     364             : 
     365           0 :         pc = L_abs( L_sub( L_add( pitch_buf[3], L_sub( pitch_buf[2], pitch_buf[1] ) ), pitch_buf[0] ) ); /*9Q6*/ /*> 15Q16*/
     366             : 
     367             :         /*                         mapping: floor(( 0.824[15Q15]-x[15Q0]*0.0733[0Q15] )*4)  */
     368             : 
     369           0 :         pc = Mpy_32_16_1( L_shl( pc, 1 ) /*precompensate Q14 from table*/,                                   /*15Q16*/
     370           0 :                           T_256DIV_L_Frame[L_shr( L_msu0( 54000, shr( st->L_frame, 5 ), 2402 ), 15 - 2 )] ); /*Q16*/
     371             : 
     372           0 :         test();
     373           0 :         test();                                                                                                                        /*test();*/
     374           0 :         IF( LE_16( st->last_good, UNVOICED_TRANSITION ) && ( EQ_16( coder_type, GENERIC ) ) && GT_32( pc, 6 * 2 * 32768 /*6(15Q16)*/ ) /*&& (stab_fac <= 0.5f)*/
     375             :         )
     376             :         {
     377           0 :             gain = 0;
     378           0 :             move16();
     379           0 :             st->Mode2_lp_gainp = L_deposit_l( 0 );
     380             :         }
     381             :         ELSE
     382             :         {
     383           0 :             gain = 0x4000 /*1 (1Q14)*/; /* start-of-the-frame gain */
     384           0 :             move16();
     385           0 :             st->Mode2_lp_gainp = L_shl( L_deposit_l( alpha ), 15 ); /*1Q14->2Q29*/
     386           0 :             move32();
     387             :         }
     388             : 
     389           0 :         tmp_16 = extract_l( L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 ) );
     390           0 :         tmp_16 = T_DIV_L_Frame[tmp_16];
     391           0 :         move16();
     392           0 :         tmp_32 = L_mult0( tmp_16, sub( gain, alpha ) ); /* 0Q15 * 2^-7  * 1Q14  -> 2Q29 * 2^-7*/
     393           0 :         tmp_32 = L_shr( tmp_32, 6 );                    /*-> 1Q30*/
     394           0 :         step = round_fx( tmp_32 );                      /*->1Q14*/
     395             : 
     396             :         /*FLC: step: 6.25e-5 .. 0.0045*/ /*-> s_step = -7*/
     397             :         /*lp_gainp : 0..0.2856..0.98*/
     398             : 
     399             :         /*-------------------------------------------------------*
     400             :          *  PLC: [ACELP: Fade-out]
     401             :          *  Apply fade out
     402             :          *-------------------------------------------------------*/
     403             : 
     404           0 :         tmp_16 = 0;
     405           0 :         move16();
     406           0 :         l = 0;
     407           0 :         move16();
     408           0 :         FOR( i_subfr = 0; i_subfr < st->nb_subfr; i_subfr++ )
     409             :         {
     410           0 :             pgainT[i_subfr] = gain; /*Q14*/
     411           0 :             move16();
     412           0 :             i = l;
     413           0 :             move16();
     414           0 :             l = add( l, L_SUBFR );
     415           0 :             FOR( ; i < l; i++ )
     416             :             {
     417             :                 BASOP_SATURATE_WARNING_OFF_EVS
     418           0 :                 exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may be 1 after shift*/ /*Qf_exc*/
     419             :                 BASOP_SATURATE_WARNING_ON_EVS
     420           0 :                 move16();
     421           0 :                 gain = sub( gain, step );
     422             :             }
     423             :         }
     424             : 
     425           0 :         l = add( st->L_frame, shr( st->L_frame, 1 ) );
     426           0 :         FOR( ; i < l; i++ )
     427             :         {
     428             :             BASOP_SATURATE_WARNING_OFF_EVS
     429           0 :             exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may become 1 due to shift*/ /*Qf_exc*/
     430             :             BASOP_SATURATE_WARNING_ON_EVS
     431           0 :             move16();
     432           0 :             gain = sub( gain, step );
     433             :         }
     434             : 
     435           0 :         FOR( i = 0; i < st->nb_subfr; i++ )
     436             :         {
     437           0 :             pT[i] = round_fx( pitch_buf[i] ); /*Q0*/
     438           0 :             move16();
     439           0 :             pitch_buffer[i] = round_fx( pitch_buf[i] ); /*Q0*/
     440           0 :             move16();
     441             :         }
     442             : 
     443             :         /* update old exc without random part*/
     444           0 :         Copy( harmonic_exc_buf + st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC ); /*Qf_exc*/
     445             :     }
     446             :     ELSE
     447             :     {
     448             :         /* No harmonic part */
     449           0 :         assert( (Word32) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 );
     450           0 :         set16_fx( &exc[0], 0, add( st->L_frame, shr( st->L_frame, 1 ) ) );
     451             : 
     452           0 :         FOR( i = 0; i < st->nb_subfr; i++ )
     453             :         {
     454           0 :             pitch_buf[i] = L_deposit_h( st->pit_max ); /*15Q16*/
     455           0 :             move32();
     456           0 :             pgainT[i] = 0;
     457           0 :             move16();
     458           0 :             pT[i] = L_SUBFR; /*Q0*/
     459           0 :             move16();
     460           0 :             pitch_buffer[i] = L_SUBFR; /*Q0*/
     461           0 :             move16();
     462             :         }
     463             : 
     464           0 :         st->bpf_gain_param = 0; /*no BPF*/
     465           0 :         move16();
     466             :     }
     467             : 
     468             :     /*-----------------------------------------------------------------*
     469             :      * Construct the random part of excitation (5/2 st->L_frame + 2L_FIR_FER - 2)
     470             :      *
     471             :      * This is done in Q0 and will be corrected to current Q format of excitation
     472             :      * when doing "non-causal ringing of the FIR filter"
     473             :      *
     474             :      * search for "Scale from randomized buffer to excitation buffer"
     475             :      *-----------------------------------------------------------------*/
     476           0 :     noise_buf = buf; /*Qf_exc*/
     477           0 :     tmpSeed = st->seed_acelp;
     478           0 :     move16();
     479           0 :     l = add( st->L_frame, sub( l_fir_fer, 1 ) );
     480           0 :     FOR( i = 0; i < l; i++ )
     481             :     {
     482           0 :         Random( &tmpSeed );
     483           0 :         noise_buf[i] = tmpSeed; /*Q0*/
     484           0 :         move16();
     485             :     }
     486             : 
     487           0 :     st->seed_acelp = tmpSeed;
     488           0 :     move16();
     489           0 :     l = add( add( st->L_frame, shr( st->L_frame, 1 ) ), sub( l_fir_fer, 1 ) );
     490           0 :     FOR( ; i < l; i++ )
     491             :     {
     492           0 :         Random( &tmpSeed );
     493           0 :         noise_buf[i] = tmpSeed; /*Q0*/
     494           0 :         move16();
     495             :     }
     496             : 
     497             :     /*get filter coefficients*/
     498           0 :     genPlcFiltBWAdap_fx( st->sr_core, /*W32 Q0*/
     499             :                          &hp_filt[0], /*Q15*/
     500             :                          1,
     501           0 :                          st->cummulative_damping ); /*Q15*/
     502             : 
     503             :     /* PLC: [ACELP: Fade-out]
     504             :      * PLC: retrieve background level */
     505             : 
     506           0 :     tmp2 = shl( div_s( st->L_frame, shl( L_SUBFR, 3 ) ), 3 - 15 ); /*Q0*/
     507             : 
     508             : 
     509           0 :     tmp = 32767 /*1.0f Q15*/;
     510           0 :     move16();
     511           0 :     gainSynthDeemph = getLevelSynDeemph_fx( &( tmp ),
     512             :                                             A,
     513             :                                             M,
     514             :                                             L_SUBFR,
     515           0 :                                             st->preemph_fac,
     516             :                                             tmp2,
     517             :                                             &gainSynthDeemph_e );
     518             : 
     519             : 
     520             :     /*gainCNG=st->cngTDLevel/gainSynthDeemph;*/
     521           0 :     BASOP_Util_Divide_MantExp( st->cngTDLevel, st->cngTDLevel_e, gainSynthDeemph, gainSynthDeemph_e, &gainCNG, &gainCNG_e );
     522           0 :     gainCNG_e = sub( gainCNG_e, 15 - 5 ); /*Q15->Q5*/
     523           0 :     if ( gainCNG == 0 )
     524             :     {
     525           0 :         gainCNG_e = 0;
     526           0 :         move16();
     527             :     }
     528             : 
     529           0 :     gain_32 = st->Mode2_lp_gainc; /*15Q16 */ /* start-of-the-frame gain */
     530           0 :     move32();
     531             : 
     532           0 :     ftmp = round_fx_sat( L_shl_sat( gain_32, 1 ) ); /*Q0*/
     533             :     BASOP_SATURATE_WARNING_OFF_EVS
     534           0 :     tmp_16 = sub( shl_sat( gainCNG, sub( gainCNG_e, 5 /*Q5*/ ) ), ftmp ); /*Q0*/
     535             :     /*in case of overflow:*/
     536           0 :     test();
     537           0 :     if ( ( EQ_16( shl_sat( ftmp, sub( gainCNG_e, 1 ) ), MAXVAL_WORD16 ) ) && EQ_16( gainCNG, MAXVAL_WORD16 ) )
     538             :     {
     539           0 :         tmp_16 = 1;
     540           0 :         move16();
     541             :     }
     542             :     BASOP_SATURATE_WARNING_ON_EVS
     543             : 
     544           0 :     IF( tmp_16 > 0 )
     545             :     {
     546           0 :         gainCNG = ftmp /*Q0*/;
     547           0 :         move16();
     548           0 :         gainCNG_e = 5; /*-> Q5*/
     549           0 :         move16();
     550           0 :         s_16 = norm_s( gainCNG );
     551           0 :         gainCNG = shl( gainCNG, s_16 );
     552           0 :         gainCNG_e = sub( gainCNG_e, s_16 );
     553             :     }
     554             : 
     555             :     /* end-of-the-frame gain */
     556             :     /* st->Mode2_lp_gainc = alpha * st->Mode2_lp_gainc + (1.0f - alpha) * gainCNG;*/
     557           0 :     tmp_32 = Mpy_32_16_1( st->Mode2_lp_gainc /*Q16*/, alpha /*Q14*/ ); /*Q31-16 = Q15*/
     558           0 :     s_32 = norm_l( tmp_32 );
     559           0 :     tmp_32 = L_shl( tmp_32, s_32 );
     560           0 :     tmp_16 = round_fx( tmp_32 );
     561           0 :     s_16 = negate( s_32 );
     562           0 :     s_16 = sub( s_16, -1 - 15 ); /*->Q15*/
     563             : 
     564           0 :     tmp2 = sub( 16384 /*1 in Q14*/, alpha ); /*Q14*/
     565           0 :     tmp2 = mult( tmp2, gainCNG );            /*Q14+Q5 +1 -16 = Q4*/
     566           0 :     s2 = norm_s( tmp2 );
     567           0 :     tmp2 = shl( tmp2, s2 );
     568           0 :     s2 = add( negate( s2 ), gainCNG_e );
     569           0 :     s2 = sub( s2, 4 - 15 ); /*->Q15*/
     570             : 
     571           0 :     s_16 = BASOP_Util_Add_MantExp( tmp_16, s_16, tmp2, s2, &tmp_16 );
     572           0 :     st->Mode2_lp_gainc = L_shl( L_deposit_l( tmp_16 ), add( s_16, 1 ) ); /*Q16*/
     573           0 :     move32();
     574           0 :     test();
     575           0 :     IF( ( EQ_16( st->last_good, UNVOICED_TRANSITION ) ) && ( EQ_16( coder_type, GENERIC ) ) )
     576             :     {
     577           0 :         st->Mode2_lp_gainc = L_deposit_h( gainCNG );                           /*Q21*/
     578           0 :         st->Mode2_lp_gainc = L_shr( st->Mode2_lp_gainc, sub( 5, gainCNG_e ) ); /*15Q16, no scaling*/
     579           0 :         move32();
     580           0 :         move32();
     581             :     }
     582             : 
     583           0 :     highPassFiltering_fx( st->last_good, add( st->L_frame, shr( l_fir_fer, 1 ) ), noise_buf, hp_filt, l_fir_fer );
     584             : 
     585           0 :     pt_exc = noise_buf + shr( l_fir_fer, 1 ); /*Qf_exc*/
     586             : 
     587             :     /*** Find energy normalization factor ***/
     588             :     /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, st->L_frame ) / st->L_frame );*/ /* normalize energy */ /*<--- FLC*/
     589             : 
     590             :     BASOP_SATURATE_WARNING_OFF_EVS                                   /*norm_llQ31 at the end of Dot_productSq16HQ may throw an overflow, but result is okay*/
     591           0 :         tmp_32 = Dot_productSq16HQ( 0, pt_exc, st->L_frame, &s_32 ); /*Q31*/
     592             :     BASOP_SATURATE_WARNING_ON_EVS
     593           0 :     s_32 = add( s_32, 31 - 1 );
     594             :     /*scalingfactor is twice the headroom (at noise insertion onto the buffer), -1 (because of mult) +31 (Result is Q31) +s_32 (output scalingfactor of dot_product)*/
     595             : 
     596           0 :     tmp_16 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )];
     597           0 :     move16();
     598           0 :     tmp_32 = Mpy_32_16_1( tmp_32, tmp_16 ); /* Q31 * 2^s_32  * 0Q15 * 2^-7 */
     599             : 
     600           0 :     s_32 = sub( s_32, 7 ); /*tmp_32 is Q31 * 2^s_32 */
     601             : 
     602             :     /*assure doing Isqrt not for 0*/
     603           0 :     IF( tmp_32 != 0 )
     604             :     {
     605           0 :         s_gain_inov = s_32;
     606           0 :         move16();
     607           0 :         tmp_32 = ISqrt32( tmp_32, &s_gain_inov ); /* Q31 - s_gain_inov */
     608             :     }
     609             :     ELSE
     610             :     {
     611           0 :         s_gain_inov = 0;
     612           0 :         move16();
     613           0 :         tmp_32 = 0;
     614           0 :         move16();
     615             :     }
     616             : 
     617             : 
     618           0 :     gain_inov = round_fx( tmp_32 ); /*Inverse sqrt*/ /* Q15 * 2^s_gain_inov */ /* Q15 - s_gain_inov */
     619             : 
     620             :     /* PLC: [ACELP: Fade-out]
     621             :      * PLC: Linearly attenuate the gain through the frame */
     622             : 
     623           0 :     step_32 = L_sub( gain_32, st->Mode2_lp_gainc ); /* 15Q16 */
     624           0 :     tmp_16 = extract_l( L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 ) );
     625           0 :     step_32 = Mpy_32_16_1( step_32, T_DIV_L_Frame[tmp_16] ); /* 15Q16 * 2^-7 = 15Q16 * Q15 * 2^-7 */
     626           0 :     step_32 = L_shr( step_32, 7 );                           /* 15Q16 */
     627             : 
     628           0 :     test();
     629           0 :     if ( ( EQ_16( st->last_good, UNVOICED_CLAS ) ) && ( NE_16( coder_type, UNVOICED ) ) ) /* Attenuate somewhat on unstable unvoiced */
     630             :     {
     631           0 :         gain_inov = mult_r( gain_inov, 26214 /*0.8f Q15*/ ); /*Q15 * 2^s_gain_inov*/
     632             :     }
     633             : 
     634           0 :     IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
     635             :     {
     636             :         Word16 tilt_code;
     637             : 
     638             :         /*tilt_code = (float)(0.10f*(1.0f + st->voice_fac));*/
     639           0 :         tilt_code = mac_r( 214748368l /*0.1f Q31*/, 3277 /*0.1f Q15*/, st->voice_fac ); /*Q15*/
     640             : 
     641           0 :         gain_inov = mult_r( gain_inov, sub( 32767 /*1.0f Q15*/, tilt_code ) ); /* Q15 * 2^s_gain_inov */
     642             :     }
     643             : 
     644           0 :     pt_exc = noise_buf; /*Qf_exc*/
     645             : 
     646             :     /* non-causal ringing of the FIR filter   */
     647             : 
     648             :     /* gain_16 = gain_32 = gain_inov * gain */
     649           0 :     gain_32 = Mpy_32_16_1( gain_32, gain_inov );            /* 15Q16 * Q15 * 2^s_gain_inov */
     650           0 :     gain_32 = L_shl_sat( gain_32, add( 15, s_gain_inov ) ); /* Q31 */
     651           0 :     gain_16 = round_fx_sat( gain_32 );                      /* Q15 */
     652             : 
     653             :     /* step_32 = gain_inov * step */
     654           0 :     step_32 = Mpy_32_16_1( step_32, gain_inov );        /* 15Q16 * Q15 * 2^s_gain_inov */
     655           0 :     step_32 = L_shl( step_32, add( 15, s_gain_inov ) ); /* Q31 */
     656             : 
     657           0 :     g_e = norm_s( round_fx_sat( L_shl_sat( Mpy_32_16_1( st->Mode2_lp_gainc, gain_inov ), add( 15, s_gain_inov ) ) ) ); /* norm_s for gain*gain_inov at the end of the following loops */
     658           0 :     g_e = s_min( norm_s( gain_16 ), g_e );
     659           0 :     gain_16 = shl( gain_16, g_e );   /*Q15 + g_e*/
     660           0 :     gain_32 = L_shl( gain_32, g_e ); /*Q31 + g_e*/
     661           0 :     step_32 = L_shl( step_32, g_e ); /*Q31 + g_e*/
     662           0 :     l = shr( l_fir_fer, 1 );
     663           0 :     FOR( i = 0; i < l; i++ )
     664             :     {
     665             :         /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
     666           0 :         *pt_exc = mult_r( *pt_exc, gain_16 );                            /* Q0 = Q0 * Q15 */
     667           0 :         move16();
     668           0 :         pt_exc++;
     669             :     }
     670             : 
     671             :     /* gain -= step; gain is updated after the loop and inside the loop gain_16 = gain_inov * gain is modified using gain_inov * (gain-step) =  gain_inov * gain - gain_inov * step */ /*<-- FLC*/
     672           0 :     FOR( i = 0; i < st->L_frame; i++ )
     673             :     {
     674             :         /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
     675           0 :         *pt_exc = mult_r( *pt_exc, gain_16 );                            /* Q0 = Q0 * Q15 */
     676           0 :         move16();
     677           0 :         pt_exc++;
     678             : 
     679           0 :         gain_32 = L_sub( gain_32, step_32 );
     680           0 :         gain_16 = round_fx( gain_32 ); /*Q15*/
     681             :     }
     682             : 
     683           0 :     l = add( shr( st->L_frame, 1 ), shr( l_fir_fer, 1 ) );
     684           0 :     FOR( i = 0; i < l; i++ )
     685             :     {
     686             :         /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
     687           0 :         *pt_exc = mult_r( *pt_exc, gain_16 );                            /* Q0 = Q0 * Q15 */
     688           0 :         move16();
     689           0 :         pt_exc++;
     690             :     }
     691             : 
     692             :     /*store st->past_gcode*/
     693             :     /* at this point gain is equal to st->Mode2_lp_gainc, so we don't need to calculate gain at all */
     694           0 :     st->past_gcode = st->Mode2_lp_gainc; /*15Q16 */
     695           0 :     move32();
     696             : 
     697             :     /*-----------------------------------------------------------------*
     698             :      * PLC: [ACELP: general]
     699             :      * PLC: Construct the total excitation
     700             :      *-----------------------------------------------------------------*/
     701             : 
     702           0 :     IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
     703             :     {
     704           0 :         bufferCopyFx( noise_buf + shr( l_fir_fer, 1 ), exc, add( st->L_frame, shr( st->L_frame, 1 ) ), 0, *Qf_exc, negate( g_e ), 0 ); /*copy between different formats*/ /*Qf_exc*/
     705           0 :         Copy( harmonic_exc_buf + st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC );                                                                                            /*Qf_exc*/
     706           0 :         Copy( exc, exc_unv, add( st->L_frame, shr( st->L_frame, 1 ) ) ); /* Update exc_unv */                                                                             /*Qf_exc*/
     707             :     }
     708             :     ELSE
     709             :     {
     710             :         /* Update exc_unv */
     711           0 :         bufferCopyFx( noise_buf + shr( l_fir_fer, 1 ), exc_unv, add( st->L_frame, shr( st->L_frame, 1 ) ), 0, *Qf_exc, negate( g_e ), 0 ); /*copy between different formats*/ /*Qf_exc*/
     712             :     }
     713             : 
     714             :     /* Compute total excitation in noisebuffer to save memories */
     715           0 :     IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
     716             :     {
     717           0 :         Vr_add( exc, exc_unv, noise_buf, add( st->L_frame, 1 ) ); /*Qf_exc*/
     718             :     }
     719             :     ELSE
     720             :     {
     721           0 :         noise_buf = exc_unv; /*Qf_exc*/
     722             :     }
     723           0 :     IF( st->hBWE_TD != NULL )
     724             :     {
     725           0 :         IF( EQ_16( st->L_frame, L_FRAME ) )
     726             :         {
     727           0 :             interp_code_5over2_fx( noise_buf, bwe_exc, st->L_frame );
     728           0 :             set16_fx( voice_factors, st->last_voice_factor_fx, NB_SUBFR ); /* Q6 */
     729             :         }
     730             :         ELSE
     731             :         {
     732           0 :             interp_code_4over2_fx( noise_buf, bwe_exc, st->L_frame );
     733           0 :             set16_fx( voice_factors, st->last_voice_factor_fx, NB_SUBFR16k ); /* Q6 */
     734             :         }
     735             :     }
     736             :     /*----------------------------------------------------------*
     737             :      * - compute the synthesis speech                           *
     738             :      *----------------------------------------------------------*/
     739             : 
     740             :     /* Init syn buffer */
     741           0 :     syn = buf + M;
     742           0 :     Copy( st->mem_syn2_fx, buf, M ); /*Q_syn*/
     743             : 
     744           0 :     IF( EQ_16( st->nbLostCmpt, 1 ) )
     745             :     {
     746           0 :         IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
     747             :         {
     748           0 :             Copy( st->mem_syn2_fx, mem_syn_unv, M ); /*Q_syn*/
     749             :         }
     750             :         ELSE
     751             :         {
     752           0 :             set16_fx( mem_syn_unv, 0, M );
     753             :         }
     754             :     }
     755             :     ELSE
     756             :     {
     757           0 :         Copy( st->mem_syn_unv_back, mem_syn_unv, M ); /*Q_syn*/
     758             :     }
     759             : 
     760             :     /* voiced synth */
     761           0 :     IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
     762             :     {
     763           0 :         p_A = A;
     764           0 :         FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     765             :         {
     766           0 :             tmp = 0;
     767           0 :             move16();
     768           0 :             set16_fx( h1, 0, L_SUBFR + 1 );
     769           0 :             set16_fx( mem, 0, M );
     770           0 :             h1[0] = 1024 /*1.0f/((float)(1 << scale_h1)) Q15*/;
     771           0 :             move16();
     772           0 :             E_UTIL_synthesis( 0, p_A, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC     */
     773           0 :             deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp );        /* impulse response of deemph  */
     774             : 
     775             :             /* impulse response level = gain introduced by synthesis+deemphasis */
     776             :             /* i_subfr / L_SUBFR */
     777           0 :             tmp_16 = shr( i_subfr, Q6 );
     778             :             /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */
     779           0 :             tmp_32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gain_lpc_e[tmp_16] ); /*Q31*/
     780           0 :             tmp_32 = L_max( tmp_32, 1 );
     781           0 :             gain_lpc_e[tmp_16] = add( gain_lpc_e[tmp_16], shl( scale_h1, 1 ) );
     782           0 :             move16();
     783           0 :             gain_lpc[tmp_16] = round_fx( ISqrt32( tmp_32, &gain_lpc_e[tmp_16] ) ); /* Q15 - gain_lpc_e[tmp_16] */
     784           0 :             move16();
     785             : 
     786           0 :             p_A += ( M + 1 ); /* Pointer move */
     787             :         }
     788             : 
     789           0 :         g = 0;
     790           0 :         move16();
     791           0 :         FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     792             :         {
     793             :             /* i_subfr / L_SUBFR */
     794           0 :             tmp_16 = shr( i_subfr, Q6 );
     795           0 :             g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */
     796           0 :             g_e = add_sat( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] );
     797           0 :             g = shl_sat( g, g_e ); /* Q15 */
     798             : 
     799           0 :             FOR( i = 0; i < L_SUBFR; i++ )
     800             :             {
     801             :                 /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */
     802           0 :                 exc[i_subfr + i] = mult_r( exc[( i_subfr + i )], g ); /*Qf_exc*/
     803           0 :                 move16();
     804             :             }
     805             :         }
     806           0 :         l = add( st->L_frame, shr( st->L_frame, 1 ) );
     807           0 :         FOR( i = st->L_frame; i < l; i++ )
     808             :         {
     809           0 :             exc[i] = mult_r( exc[i], g ); /*Qf_exc*/
     810           0 :             move16();
     811             :         }
     812             : 
     813             :         /*Rescale the synthesis memory*/
     814           0 :         Qf_syn_new = *Qf_mem_syn;
     815           0 :         move16();
     816           0 :         Qf_syn = *Qf_mem_syn;
     817           0 :         move16();
     818           0 :         rescale_mem( Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn, NULL, M, st->L_frame );
     819           0 :         synthScaling = sub( *Qf_exc, Qf_syn );
     820             : 
     821           0 :         p_A = A;
     822             : 
     823             :         /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/
     824           0 :         memsynPrecission_fx( st->nbLostCmpt, mem_syn, exc, st->L_frame, &s_16 );
     825           0 :         FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     826             :         {
     827           0 :             E_UTIL_synthesis( synthScaling, p_A, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M );
     828           0 :             p_A += ( M + 1 );
     829             :         }
     830           0 :         Copy( mem_syn, mem_syn2, M ); /*Qf_syn + s_16*/
     831             :         /* synthesize ola*/
     832           0 :         E_UTIL_synthesis( synthScaling, p_A - ( M + 1 ), &exc[i_subfr], &syn[i_subfr], shr( st->L_frame, 1 ), mem_syn2, 0, M );
     833             :     }
     834             : 
     835           0 :     test();
     836           0 :     IF( GT_16( st->nbLostCmpt, 5 ) && ( s_16 > 0 ) )
     837             :     {
     838             :         /*scale back mem_syn, exc and synthesis*/
     839           0 :         Scale_sig( mem_syn, M, negate( s_16 ) );                                     /* Qf_syn */
     840           0 :         Scale_sig( syn, add( shr( st->L_frame, 1 ), st->L_frame ), negate( s_16 ) ); /* Qf_syn */
     841             :         /*Scale_sig(exc, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/
     842             :     }
     843             : 
     844             : 
     845             :     /* unvoiced synth */
     846             : 
     847           0 :     tmp = 0;
     848           0 :     move16();
     849           0 :     p_A = st->Aq_cng;
     850             : 
     851           0 :     FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     852             :     {
     853           0 :         set16_fx( h1, 0, L_SUBFR + 1 );
     854           0 :         set16_fx( mem, 0, M );
     855           0 :         h1[0] = 1024 /*1.0f/((float)(1 << scale_h1)) Q15*/;
     856           0 :         move16();
     857           0 :         E_UTIL_synthesis( 0, p_A, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC     */
     858           0 :         deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp );        /* impulse response of deemph  */
     859             : 
     860             :         /* impulse response level = gain introduced by synthesis+deemphasis */
     861             :         /* i_subfr / L_SUBFR */
     862           0 :         tmp_16 = shr( i_subfr, Q6 );
     863             :         /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */
     864           0 :         tmp_32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gain_lpc_e[tmp_16] ); /*Q31*/
     865           0 :         tmp_32 = L_max( tmp_32, 1 );
     866           0 :         gain_lpc_e[tmp_16] = add( gain_lpc_e[tmp_16], shl( scale_h1, 1 ) );
     867           0 :         move16();
     868           0 :         gain_lpc[tmp_16] = round_fx( ISqrt32( tmp_32, &gain_lpc_e[tmp_16] ) ); /* Q15 - gain_lpc_e[tmp_16] */
     869           0 :         move16();
     870             : 
     871           0 :         p_A += ( M + 1 ); /* Pointer move */
     872             :     }
     873             : 
     874           0 :     g = 0;
     875           0 :     move16();
     876           0 :     FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     877             :     {
     878             :         /* i_subfr / L_SUBFR */
     879           0 :         tmp_16 = shr( i_subfr, Q6 );
     880           0 :         g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */
     881           0 :         g_e = add( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] );
     882           0 :         g = shl_sat( g, g_e ); /*Q15*/
     883           0 :         FOR( i = 0; i < L_SUBFR; i++ )
     884             :         {
     885             :             /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */
     886           0 :             exc_unv[( i_subfr + i )] = mult_r( exc_unv[add( i_subfr, i )], g ); /*Qf_exc*/
     887           0 :             move16();
     888             :         }
     889             :     }
     890           0 :     l = add( st->L_frame, shr( st->L_frame, 1 ) );
     891           0 :     FOR( i = st->L_frame; i < l; i++ )
     892             :     {
     893           0 :         exc_unv[i] = mult_r( exc_unv[i], g ); /*Qf_exc*/
     894           0 :         move16();
     895             :     }
     896             : 
     897             :     /* Update Qf_syn */
     898           0 :     Qf_syn_new = *Qf_mem_syn;
     899           0 :     move16();
     900           0 :     Qf_syn = *Qf_mem_syn;
     901           0 :     move16();
     902           0 :     rescale_mem( Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn_unv, NULL, M, st->L_frame );
     903           0 :     synthScaling = sub( *Qf_exc, Qf_syn );
     904           0 :     *Qf_mem_syn = Qf_syn;
     905           0 :     move16();
     906             : 
     907           0 :     p_A = st->Aq_cng;
     908             : 
     909             :     /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/
     910           0 :     memsynPrecission_fx( st->nbLostCmpt, mem_syn_unv, exc_unv, st->L_frame, &s_16 ); /*Qf_syn + s_16*/
     911             : 
     912           0 :     FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
     913             :     {
     914           0 :         E_UTIL_synthesis( synthScaling, p_A, &exc_unv[i_subfr], &syn_unv[i_subfr], L_SUBFR, mem_syn_unv, 1, M );
     915           0 :         p_A += ( M + 1 );
     916             :     }
     917           0 :     Copy( mem_syn_unv, st->mem_syn_unv_back, M ); /*Qf_syn + s_16*/
     918             : 
     919           0 :     IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
     920             :     {
     921           0 :         Copy( mem_syn_unv, mem_syn, M ); /*Qf_syn + s_16*/
     922             :         /* unvoiced for ola */
     923           0 :         E_UTIL_synthesis( synthScaling, p_A - ( M + 1 ), &exc_unv[i_subfr], &syn_unv[i_subfr], shr( st->L_frame, 1 ), mem_syn_unv, 0, M );
     924             :     }
     925             : 
     926           0 :     test();
     927           0 :     IF( GT_16( st->nbLostCmpt, 5 ) && ( s_16 > 0 ) )
     928             :     {
     929             :         /*scale back mem_syn_unv, exc_unv and synthesis*/
     930           0 :         Scale_sig( mem_syn_unv, M, negate( s_16 ) ); /*Qf_syn*/
     931           0 :         IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
     932             :         {
     933           0 :             Scale_sig( mem_syn, M, negate( s_16 ) );                                         /*Qf_syn*/
     934           0 :             Scale_sig( syn_unv, add( shr( st->L_frame, 1 ), st->L_frame ), negate( s_16 ) ); /*Qf_syn*/
     935             :         }
     936             :         ELSE
     937             :         {
     938           0 :             Scale_sig( syn_unv, st->L_frame, negate( s_16 ) ); /*Qf_syn*/
     939             :         }
     940             : 
     941           0 :         Scale_sig( st->mem_syn_unv_back, M, negate( s_16 ) ); /*Qf_syn*/
     942             : 
     943             :         /*Scale_sig(exc_unv, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/
     944             :     }
     945             : 
     946             :     /* add separate synthesis buffers */
     947           0 :     IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
     948             :     {
     949           0 :         FOR( i = 0; i < st->L_frame; i++ )
     950             :         {
     951           0 :             syn[i] = add_sat( syn[i], syn_unv[i] ); /*Qf_syn*/
     952           0 :             move16();
     953             :         }
     954             :     }
     955             :     ELSE
     956             :     {
     957           0 :         Copy( syn_unv, syn, add( st->L_frame, shr( st->L_frame, 1 ) ) ); /*Qf_syn*/
     958             :     }
     959             : 
     960             : 
     961             :     /* update buffer for the classification */
     962             :     {
     963             :         Word16 pit16[NB_SUBFR16k];
     964             :         Word16 k;
     965           0 :         FOR( k = 0; k < st->nb_subfr; k++ )
     966             :         {
     967           0 :             pit16[k] = shl( extract_h( pitch_buf[k] ), 6 ); /*Q6*/
     968           0 :             move16();
     969             :         }
     970             : 
     971           0 :         FEC_clas_estim_fx(
     972             :             st,
     973             :             /*Opt_AMR_WB*/ 0, /*A*/
     974           0 :             st->L_frame,
     975             :             &( st->clas_dec ),
     976             :             coder_type,
     977             :             pit16,
     978             :             syn,
     979             :             &st->lp_ener_FER_fx,
     980             :             /**decision_hyst*/ NULL,   /* i/o: hysteresis of the music/speech decision                           */
     981             :             /**UV_cnt*/ NULL,          /* i/o: number of consecutives frames classified as UV                    */
     982             :             /**LT_UV_cnt*/ NULL,       /* i/o: long term consecutives frames classified as UV                    */
     983             :             /**Last_ener*/ NULL,       /* i/o: last_energy frame                                                 */
     984             :             /**locattack*/ NULL,       /* i/o: detection of attack (mainly to localized speech burst)            */
     985             :             /**lt_diff_etot*/ NULL,    /* i/o: long-term total energy variation                                  */
     986             :             /**amr_io_class*/ NULL,    /* i/o: classification for AMR-WB IO mode                                 */
     987             :             Qf_syn,                    /* i  : Synthesis scaling                                                 */
     988             :             /**class_para*/ NULL,      /* o  : classification para. fmerit1                                      */
     989           0 :             st->mem_syn_clas_estim_fx, /* i/o: memory of the synthesis signal for frame class estimation         */
     990             :             &st->classifier_Q_mem_syn, /*i/o : exponent for memory of synthesis signal for frame class estimation */
     991             :             -32768 /*-1.f Q15*/,       /* i  : LTP Gain                                                          */
     992             :             0 /*CLASSIFIER_ACELP*/,    /* i  : signal classifier mode                                            */
     993             :             1 /*bfi*/,                 /* i  : bad frame indicator                                               */
     994             :             st->last_core_brate,       /* i  : bitrate of previous frame                                         */
     995             :             -1 );
     996             :     }
     997             : 
     998             :     /* Update Pitch Lag memory */
     999           0 :     Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); /*15Q16*/
    1000           0 :     Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr );            /*15Q16*/
    1001             : 
    1002             :     /*updating enr_old parameters*/
    1003           0 :     frame_ener_fx( st->L_frame, st->last_good, syn, round_fx( tmp_tc ), &( st->enr_old_fx ), 1, 0, 0, 0 );
    1004             : 
    1005           0 :     st->enr_old_fx = L_shl_sat( st->enr_old_fx, shl( negate( Qf_syn ), 1 ) ); /*Q0*/
    1006           0 :     move32();
    1007             :     /* update ACELP synthesis memory */
    1008           0 :     Copy( mem_syn, st->mem_syn2_fx, M );                             /*Qf_syn*/
    1009           0 :     Copy( syn + st->L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); /*Qf_syn*/
    1010             : 
    1011             :     /*Q_mem_syn_new = Q_mem_syn;*/ /*NOT "+synthScaling", cause mem_syn format is not changed*/
    1012             :     /* Deemphasis and output synth */
    1013           0 :     tmp_deemph = st->syn[M];
    1014           0 :     move16();
    1015             : 
    1016           0 :     E_UTIL_deemph2( *Qf_mem_syn, syn, st->preemph_fac, add( st->L_frame, shr( st->L_frame, 1 ) ), &tmp_deemph );
    1017             : 
    1018           0 :     Copy( syn, synth, st->L_frame );
    1019             : 
    1020           0 :     bufferCopyFx( syn + sub( st->L_frame, shr( st->L_frame, 1 ) ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/ );
    1021             : 
    1022             :     /* save last half frame if next frame is TCX */
    1023           0 :     bufferCopyFx( syn + st->L_frame, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/ );
    1024           0 :     hTcxDec->Q_syn_Overl_TDAC = add( st->Q_syn, -1 );
    1025           0 :     move16();
    1026           0 :     Copy( syn + sub( st->L_frame, M + 1 ), st->syn, 1 + M ); /*Qf_syn*/
    1027             : 
    1028             :     /* update old_Aq */
    1029           0 :     Copy( p_A - ( M + 1 ), st->old_Aq_12_8_fx, M + 1 ); /*Q12*/
    1030             : 
    1031             : 
    1032           0 :     Copy( syn + st->L_frame, hTcxDec->syn_Overl, shr( st->L_frame, 1 ) ); /*Qf_syn*/
    1033             : 
    1034             :     /* create aliasing and windowing */
    1035             : 
    1036           0 :     W1 = st->hTcxCfg->tcx_mdct_window_length;
    1037           0 :     move16();
    1038           0 :     W2 = shr( W1, 1 );
    1039           0 :     st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
    1040           0 :     move16();
    1041             : 
    1042           0 :     n = extract_h( L_mult( st->L_frame, 9216 /*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/ ) ); /*Q0*/
    1043             : 
    1044           0 :     hHQ_core->Q_old_wtda_LB = getScaleFactor16( syn + sub( st->L_frame, n ),
    1045           0 :                                                 sub( st->L_frame, n ) );
    1046           0 :     move16();
    1047             : 
    1048           0 :     bufferCopyFx( syn + sub( st->L_frame, n ), hHQ_core->old_out_LB_fx, sub( st->L_frame, n ), 0, 0, hHQ_core->Q_old_wtda_LB, 0 );
    1049           0 :     FOR( i = 0; i < W2; i++ )
    1050             :     {
    1051           0 :         hHQ_core->old_out_LB_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[i].v.re, w[i].v.re ), hHQ_core->old_out_LB_fx[( i + n )] ) ); /* hHQ_core->q_old_outLB_fx */
    1052           0 :         move16();
    1053             :     }
    1054           0 :     FOR( ; i < W1; i++ )
    1055             :     {
    1056           0 :         hHQ_core->old_out_LB_fx[i + n] = round_fx( Mpy_32_16_1( L_mult( w[( W2 - ( 1 + ( i - W2 ) ) )].v.im, w[( W2 - ( 1 + ( i - W2 ) ) )].v.im ), hHQ_core->old_out_LB_fx[( i + n )] ) ); /* hHQ_core->q_old_outLB_fx */
    1057           0 :         move16();
    1058             :     }
    1059           0 :     set16_fx( &hHQ_core->old_out_LB_fx[( W1 + n )], 0, n );
    1060             : 
    1061           0 :     hHQ_core->Q_old_wtda = hHQ_core->Q_old_wtda_LB;
    1062           0 :     move16();
    1063             : 
    1064             : 
    1065           0 :     FOR( i = 0; i < W2; i++ )
    1066             :     {
    1067           0 :         buf[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDAC*/
    1068           0 :         move16();
    1069             :     }
    1070           0 :     FOR( ; i < W1; i++ )
    1071             :     {
    1072           0 :         buf[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[( ( W1 - 1 ) - i )].v.im ); /*hTcxDec->Q_syn_Overl_TDAC*/
    1073           0 :         move16();
    1074             :     }
    1075             : 
    1076             : 
    1077           0 :     FOR( i = 0; i < W2; i++ )
    1078             :     {
    1079           0 :         hTcxDec->syn_Overl_TDAC[i] = add( buf[i], buf[( ( W1 - 1 ) - i )] ); /* A-D */ /*hTcxDec->Q_syn_Overl_TDAC*/
    1080           0 :         move16();
    1081             :     }
    1082             :     /*-2*/
    1083           0 :     FOR( i = 0; i < W2; i++ )
    1084             :     {
    1085           0 :         hTcxDec->syn_Overl_TDAC[( W2 + i )] = add( buf[( W2 + i )], buf[( ( ( W1 - 1 ) - W2 ) - i )] ); /* B-C */ /*hTcxDec->Q_syn_Overl_TDAC*/
    1086           0 :         move16();
    1087             :     }
    1088             : 
    1089             : 
    1090           0 :     FOR( i = 0; i < W2; i++ )
    1091             :     {
    1092           0 :         hTcxDec->syn_Overl_TDAC[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDAC*/
    1093           0 :         move16();
    1094             :     }
    1095             : 
    1096           0 :     FOR( ; i < W1; i++ )
    1097             :     {
    1098           0 :         hTcxDec->syn_Overl_TDAC[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[( ( W1 - 1 ) - i )].v.im ); /*hTcxDec->Q_syn_Overl_TDAC*/
    1099           0 :         move16();
    1100             :     }
    1101             : 
    1102             :     /* update memory for full band */
    1103           0 :     lerp( hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDACFB, shr( hTcxDec->L_frameTCX, 1 ), shr( st->L_frame, 1 ) );
    1104           0 :     st->hTcxDec->Q_syn_Overl_TDACFB = st->hTcxDec->Q_syn_Overl_TDAC;
    1105           0 :     move16();
    1106           0 :     lerp( hTcxDec->syn_Overl, hTcxDec->syn_OverlFB, shr( hTcxDec->L_frameTCX, 1 ), shr( st->L_frame, 1 ) );
    1107           0 :     lerp( hHQ_core->old_out_LB_fx, hHQ_core->old_out_fx, hTcxDec->L_frameTCX, st->L_frame );
    1108             : 
    1109             :     /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */
    1110           0 :     IF( st->hWIDec != NULL )
    1111             :     {
    1112           0 :         lerp( exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, st->L_frame );
    1113           0 :         lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, st->L_frame );
    1114             :     }
    1115           0 :     st->bfi_pitch_fx = shl( round_fx( pitch_buf[( st->nb_subfr - 1 )] ), 6 ); /*Q6*/
    1116           0 :     st->bfi_pitch_frame = st->L_frame;
    1117           0 :     move16();
    1118           0 :     move16();
    1119             : 
    1120           0 :     return;
    1121             : }
    1122             : 
    1123           0 : static void memsynPrecission_fx( Word16 nbLostCmpt, Word16 *mem_syn /*Qx*/, Word16 *exc /*Qx*/, Word16 len, Word16 *s_16 )
    1124             : {
    1125           0 :     IF( GT_16( nbLostCmpt, 5 ) )
    1126             :     {
    1127             :         Word16 sf_mem_syn, sf_exc, k, tmp_loop, max, tmp, i;
    1128           0 :         tmp = 0;
    1129           0 :         move16();
    1130           0 :         *s_16 = 0;
    1131           0 :         move16();
    1132           0 :         max = 0;
    1133           0 :         move16();
    1134             : 
    1135             :         /*check energy of mem_syn*/
    1136           0 :         FOR( i = 0; i < M; i++ )
    1137             :         {
    1138             :             /*saturation doesn't matter*/
    1139             :             BASOP_SATURATE_WARNING_OFF_EVS
    1140           0 :             tmp = add_sat( tmp, abs_s( mem_syn[i] ) );
    1141             :             BASOP_SATURATE_WARNING_ON_EVS
    1142             :         }
    1143             :         /*if there is energy in scale_syn, then increase precision*/
    1144           0 :         IF( abs_s( tmp ) > 0 )
    1145             :         {
    1146           0 :             sf_mem_syn = getScaleFactor16( mem_syn, M );
    1147             :             /*sf_exc = getScaleFactor16(exc, add(shr(len,1),len));*/ /*this returns 0 if signal is 0*/
    1148           0 :             tmp_loop = add( shr( len, 1 ), len );
    1149           0 :             FOR( k = 0; k < tmp_loop; k++ )
    1150             :             {
    1151           0 :                 max = s_max( max, abs_s( exc[k] ) );
    1152             :             }
    1153           0 :             sf_exc = norm_s( max );
    1154           0 :             if ( max == 0 )
    1155             :             {
    1156           0 :                 sf_exc = 16;
    1157           0 :                 move16();
    1158             :             }
    1159           0 :             *s_16 = s_max( sub( s_min( sf_exc, sf_mem_syn ), 5 ), 0 ) /*5 bits of headroom, scaling not smaller than 0*/;
    1160           0 :             move16();
    1161           0 :             Scale_sig( mem_syn, M, *s_16 );                     /*Qx + s_16*/
    1162           0 :             Scale_sig( exc, add( shr( len, 1 ), len ), *s_16 ); /*Qx + s_16*/
    1163             :         }
    1164             :     }
    1165           0 : }

Generated by: LCOV version 1.14