LCOV - code coverage report
Current view: top level - lib_dec - dec_post_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 230 689 33.4 %
Date: 2025-05-03 01:55:50 Functions: 9 17 52.9 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"
       6             : #include "prot_fx.h"
       7             : #include "basop_util.h"
       8             : #include "rom_dec.h"
       9             : #include "rom_com.h"
      10             : #include "cnst.h"
      11             : #define FORMAT_POST_FILT_G1     24576 /*0.75f Q15*/ /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/
      12             : #define FORMAT_POST_FILT_G2     22938 /*0.7f Q15*/ /*0.7f*/   /*numerator 0.75,0.7,0.1,0.7*/
      13             : #define FORMAT_POST_FILT_G1_MAX 26214 /*0.8f Q15*/            /*for low bit-rates on clean speech*/
      14             : #define FORMAT_POST_FILT_G1_MIN 24576 /*0.75f Q15*/           /*for high bit-rates on clean speech and noisy speech*/
      15             : 
      16             : /*--------------------------------------------------------------------------
      17             :  * Local function prototypes
      18             :  *--------------------------------------------------------------------------*/
      19             : 
      20             : static void Dec_postfilt_fx( PFSTAT_HANDLE hPFstat, const Word16 t0, const Word16 *signal_ptr, const Word16 *coeff, Word16 *sig_out, const Word16 gamma1, const Word16 gamma2, const Word16 Gain_factor, const Word16 disable_hpf );
      21             : 
      22             : static void pst_ltp_fx( Word16 t0, Word16 *ptr_sig_in, Word16 *ptr_sig_pst0, Word16 gain_factor );
      23             : 
      24             : static void search_del_fx( Word16 t0, Word16 *ptr_sig_in, Word16 *ltpdel, Word16 *phase, Word16 *num_gltp, Word16 *den_gltp, Word16 *sh_num_gltp, Word16 *sh_den_gltp, Word16 *y_up, Word16 *off_yup );
      25             : 
      26             : static void filt_plt_fx( Word16 *s_in, Word16 *s_ltp, Word16 *s_out, Word16 gain_plt );
      27             : 
      28             : static void compute_ltp_l_fx( Word16 *s_in, Word16 ltpdel, Word16 phase, Word16 *y_up, Word16 *num, Word16 *den, Word16 *sh_num, Word16 *sh_den );
      29             : 
      30             : static Word16 select_ltp_fx( Word16 num1, Word16 den1, Word16 sh_num1, Word16 sh_den1, Word16 num2, Word16 den2, Word16 sh_num2, Word16 sh_den2 );
      31             : 
      32             : static void calc_st_filt_local_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero );
      33             : 
      34             : static void modify_pst_param_fx( const Word16 lp_noise, Word16 *g1, Word16 *g2, const Word16 coder_type, Word16 *gain_factor );
      35             : 
      36             : #ifndef REMOVE_EVS_DUPLICATES
      37             : static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 );
      38             : #endif
      39             : static void Dec_formant_postfilt_ivas_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 );
      40             : 
      41             : static void calc_st_filt_ivas_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero, const Word16 extl );
      42             : 
      43             : 
      44             : /*--------------------------------------------------------------------------
      45             :  *  Init_post_filter_fx
      46             :  *
      47             :  *  post filter initialization
      48             :  *--------------------------------------------------------------------------*/
      49        3256 : void Init_post_filter_fx(
      50             :     PFSTAT_HANDLE hPFstat /* i : core decoder parameters */
      51             : )
      52             : {
      53             :     /* It is off by default */
      54        3256 :     hPFstat->on = 0;
      55        3256 :     move16();
      56             :     /* Reset */
      57        3256 :     hPFstat->reset = 0;
      58        3256 :     move16();
      59             :     /* Initialize arrays and pointers */
      60        3256 :     set16_fx( hPFstat->mem_pf_in, 0, L_SUBFR );
      61             : 
      62             :     /* res2 =  A(gamma2) residual */
      63        3256 :     set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
      64             : 
      65             :     /* 1/A(gamma1) memory */
      66        3256 :     set16_fx( hPFstat->mem_stp, 0, L_SUBFR );
      67             : 
      68             :     /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
      69        3256 :     set16_fx( hPFstat->mem_zero, 0, M );
      70             : 
      71             :     /* for gain adjustment */
      72        3256 :     hPFstat->gain_prec = 16384; /*Q14*/
      73        3256 :     move16();
      74             : 
      75        3256 :     return;
      76             : }
      77             : 
      78             : /*--------------------------------------------------------------------------
      79             :  *  NB_post_filt:
      80             :  *
      81             :  *  Main routine to perform post filtering on NB synthesis
      82             :  *--------------------------------------------------------------------------*/
      83        2076 : void nb_post_filt_fx(
      84             :     const Word16 L_frame,    /* i  : frame length                            */
      85             :     PFSTAT_HANDLE hPFstat,   /* i : core decoder parameters */
      86             :     Word16 *psf_lp_noise,    /* i  : Long term noise                   Q8    */
      87             :     const Word16 tmp_noise,  /* i  : noise energy                       Q0   */
      88             :     Word16 *Synth,           /* i  : 12k8 synthesis                    Qsyn  */
      89             :     const Word16 *Aq,        /* i  : LP filter coefficient             Q12   */
      90             :     const Word16 *Pitch_buf, /* i  : Fractionnal subframe pitch buffer Q0    */
      91             :     const Word16 coder_type, /* i  : coder_type                              */
      92             :     const Word16 BER_detect, /* i  : BER detect flag                         */
      93             :     const Word16 disable_hpf /* i  : flag to diabled HPF                     */
      94             : )
      95             : {
      96             :     Word16 i, j, Post_G1, Post_G2, Gain_factor;
      97             :     Word16 T0_first, *Pf_in;
      98             :     const Word16 *p_Aq;
      99             :     Word16 pf_in_buffer[M + L_FRAME16k];
     100             : 
     101        2076 :     IF( BER_detect == 0 )
     102             :     {
     103             :         /* update long-term background noise energy during inactive frames */
     104        2076 :         IF( EQ_16( coder_type, INACTIVE ) )
     105             :         {
     106           0 :             *psf_lp_noise = round_fx( L_mac( L_mult( 31130 /*0.95.Q15*/, *psf_lp_noise ), 26214 /*0.05 Q19*/, shl( tmp_noise, 4 ) ) ); /*Q8*Q15 + Q19*Q4 -> Q8 */
     107             :         }
     108             :     }
     109             : 
     110        2076 :     modify_pst_param_fx( *psf_lp_noise, &Post_G1, &Post_G2, coder_type, &Gain_factor );
     111             : 
     112        2076 :     IF( hPFstat->reset )
     113             :     {
     114        2076 :         set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
     115        2076 :         Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); // Qsyn
     116        2076 :         Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
     117        2076 :         hPFstat->gain_prec = 16384; // 1.Q14
     118        2076 :         move16();
     119        2076 :         hPFstat->reset = 0;
     120        2076 :         move16();
     121        2076 :         return;
     122             :     }
     123           0 :     Pf_in = &pf_in_buffer[M];
     124           0 :     Copy( hPFstat->mem_pf_in + L_SYN_MEM - M, &Pf_in[-M], M ); // Qsyn
     125           0 :     Copy( Synth, Pf_in, L_frame );                             // Qsyn
     126           0 :     Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
     127             :     /* deactivation of the post filter in case of AUDIO because it causes problems to singing sequences */
     128           0 :     IF( EQ_16( coder_type, AUDIO ) )
     129             :     {
     130           0 :         Post_G1 = 32767;
     131           0 :         move16();
     132           0 :         Post_G2 = 32767;
     133           0 :         move16();
     134           0 :         Gain_factor = 32767;
     135           0 :         move16();
     136             :     }
     137             : 
     138             : 
     139             :     /* run the post filter */
     140           0 :     p_Aq = Aq; // Q12
     141           0 :     move16();
     142           0 :     j = 0;
     143           0 :     move16();
     144           0 :     FOR( i = 0; i < L_frame; i += L_SUBFR )
     145             :     {
     146           0 :         T0_first = Pitch_buf[j]; // Q0
     147           0 :         move16();
     148           0 :         Dec_postfilt_fx( hPFstat, T0_first, &Pf_in[i], p_Aq, &Synth[i], Post_G1, Post_G2, Gain_factor, disable_hpf );
     149             : 
     150           0 :         p_Aq += ( M + 1 );
     151           0 :         j = add( j, 1 );
     152             :     }
     153             : 
     154             : 
     155           0 :     return;
     156             : }
     157             : 
     158             : /*----------------------------------------------------------------------------
     159             :  * Dec_postfilt()
     160             :  *
     161             :  * Post - adaptive postfilter main function
     162             :  *   Short term postfilter :
     163             :  *     Hst(z) = Hst0(z) Hst1(z)
     164             :  *     Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
     165             :  *     if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
     166             :  *     g0 = SUM(|hi|) if > 1
     167             :  *     g0 = 1. else
     168             :  *     Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
     169             :  *     with mu = k1 * gamma3
     170             :  *     k1 = 1st parcor calculated on {hi}
     171             :  *     gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
     172             :  *   Long term postfilter :
     173             :  *     harmonic postfilter :   H0(z) = gl * (1 + b * z-p)
     174             :  *       b = gamma_g * gain_ltp
     175             :  *       gl = 1 / 1 + b
     176             :  *     computation of delay p on A(gamma2)(z) s(z)
     177             :  *     sub optimal search
     178             :  *       1. search around 1st subframe delay (3 integer values)
     179             :  *       2. search around best integer with fract. delays (1/8)
     180             :  *----------------------------------------------------------------------------*/
     181           0 : static void Dec_postfilt_fx(
     182             :     PFSTAT_HANDLE hPFstat,    /* i : core decoder parameters */
     183             :     const Word16 t0,          /* i  : pitch delay given by coder Q0                   */
     184             :     const Word16 *signal_ptr, /* i  : input signal (pointer to current subframe Q0    */
     185             :     const Word16 *coeff,      /* i  : LPC coefficients for current subframe Q12        */
     186             :     Word16 *sig_out,          /* o  : postfiltered output                          Q15*/
     187             :     const Word16 gamma1,      /* i  : short term postfilt. den. weighting factor   Q15*/
     188             :     const Word16 gamma2,      /* i  : short term postfilt. num. weighting factor   Q15*/
     189             :     const Word16 Gain_factor, /* i  : Gain Factor (Q15)                            */
     190             :     const Word16 disable_hpf )
     191             : {
     192             :     /* Local variables and arrays */
     193             :     Word16 apond1[M + 1];        /* s.t. denominator coeff. Q12*/
     194             :     Word16 apond2[LONG_H_ST];    // Q12
     195             :     Word16 sig_ltp[L_SUBFR + 1]; /* H0 output signal  */
     196             :     Word16 res2[SIZ_RES2];       // Q0
     197             : 
     198             :     Word16 *sig_ltp_ptr;
     199             :     Word16 *res2_ptr;
     200             :     Word16 *ptr_mem_stp;
     201             : 
     202             :     Word16 parcor0; // Q15
     203             : 
     204             : 
     205             :     /* Init pointers and restore memories */
     206           0 :     res2_ptr = res2 + DECMEM_RES2;
     207           0 :     ptr_mem_stp = hPFstat->mem_stp + L_SYN_MEM - 1;
     208           0 :     Copy( hPFstat->mem_res2, res2, DECMEM_RES2 );
     209             : 
     210             :     /* Compute weighted LPC coefficients */
     211           0 :     weight_a_fx( coeff, apond1, gamma1, M );
     212           0 :     weight_a_fx( coeff, apond2, gamma2, M );
     213           0 :     set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
     214             : 
     215             :     /* Compute A(gamma2) residual */
     216           0 :     Residu3_fx( apond2, signal_ptr, res2_ptr, L_SUBFR, 1 );
     217             : 
     218             :     /* Harmonic filtering */
     219           0 :     sig_ltp_ptr = sig_ltp + 1;
     220             : 
     221           0 :     IF( disable_hpf == 0 )
     222             :     {
     223           0 :         pst_ltp_fx( t0, res2_ptr, sig_ltp_ptr, Gain_factor );
     224             :     }
     225             :     ELSE
     226             :     {
     227           0 :         Copy( res2_ptr, sig_ltp_ptr, L_SUBFR );
     228             :     }
     229             : 
     230             :     /* Save last output of 1/A(gamma1) */
     231             :     /* (from preceding subframe)       */
     232           0 :     sig_ltp[0] = *ptr_mem_stp;
     233           0 :     move16();
     234             : 
     235             :     /* Controls short term pst filter gain and compute parcor0 */
     236           0 :     calc_st_filt_local_fx( apond2, apond1, &parcor0, sig_ltp_ptr, hPFstat->mem_zero );
     237             : 
     238           0 :     E_UTIL_synthesis( 1, apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
     239           0 :     Copy( sig_ltp_ptr + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
     240             : 
     241             :     /* Tilt filtering */
     242           0 :     Filt_mu_fx( sig_ltp, sig_out, parcor0, L_SUBFR );
     243             : 
     244             :     /* Gain control */
     245           0 :     scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
     246             : 
     247             :     /* Update for next subframe */
     248           0 :     Copy( &res2[L_SUBFR], hPFstat->mem_res2, DECMEM_RES2 );
     249             : 
     250             : 
     251           0 :     return;
     252             : }
     253             : 
     254             : /*--------------------------------------------------------------------------
     255             :  *  formant_post_filt_fx:
     256             :  *
     257             :  *  Main routine to perform formant post filtering
     258             :  *--------------------------------------------------------------------------*/
     259             : 
     260             : #ifndef REMOVE_EVS_DUPLICATES
     261             : void formant_post_filt_fx(
     262             :     PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
     263             :     Word16 *synth_in,      /* i  : 12k8 synthesis                    */
     264             :     Word16 *Aq,            /* i  : LP filter coefficient Q12            */
     265             :     Word16 *synth_out,     /* i/o: input signal                      */
     266             :     Word16 L_frame,
     267             :     Word32 lp_noise,      /* (i) : background noise energy (15Q16) */
     268             :     Word32 brate,         /* (i) : bit-rate */
     269             :     const Word16 off_flag /* i  : off flag                        */
     270             : )
     271             : {
     272             :     Word16 i_subfr;
     273             :     Word16 *p_Aq;
     274             :     Word16 post_G1, post_G2; // Q15
     275             : 
     276             : 
     277             :     /*default parameter for noisy speech and high bit-rates*/
     278             :     IF( EQ_16( L_frame, L_FRAME ) )
     279             :     {
     280             :         post_G2 = 22938 /*0.7f Q15*/;
     281             :         move16();
     282             :         IF( LT_32( lp_noise, LP_NOISE_THRESH ) )
     283             :         {
     284             :             /*Clean speech*/
     285             :             IF( LT_32( brate, ACELP_13k20 ) )
     286             :             {
     287             :                 /*Low rates*/
     288             : 
     289             :                 post_G1 = 26214 /*0.8f Q15*/;
     290             :                 move16();
     291             :             }
     292             :             ELSE IF( LT_32( brate, ACELP_24k40 ) )
     293             :             {
     294             :                 /*Low rates*/
     295             : 
     296             :                 post_G1 = 24576 /*0.75f Q15*/;
     297             :                 move16();
     298             :             }
     299             :             ELSE
     300             :             {
     301             :                 post_G1 = 23593 /*0.72f Q15*/;
     302             :                 move16();
     303             :             }
     304             :         }
     305             :         ELSE /*Noisy speech*/
     306             :         {
     307             :             post_G1 = 22938 /*0.7f Q15*/;
     308             :             move16();
     309             :             if ( LT_32( brate, ACELP_15k85 ) )
     310             :             {
     311             :                 /*Low rates*/
     312             :                 post_G1 = 24576 /*0.75f Q15*/;
     313             :                 move16();
     314             :             }
     315             :         }
     316             :     }
     317             :     ELSE
     318             :     {
     319             :         post_G2 = 24904 /*0.76f Q15*/;
     320             :         move16();
     321             :         test();
     322             :         IF( GE_32( lp_noise, LP_NOISE_THRESH ) )
     323             :         {
     324             :             post_G1 = 24904 /*0.76f Q15*/;
     325             :         }
     326             :         ELSE IF( EQ_32( brate, ACELP_13k20 ) )
     327             :         {
     328             :             post_G1 = 26870 /*0.82f Q15*/;
     329             :             move16();
     330             :         }
     331             :         ELSE IF( EQ_32( brate, ACELP_16k40 ) )
     332             :         {
     333             :             post_G1 = 26214 /*0.80f Q15*/;
     334             :             move16();
     335             :         }
     336             :         ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) )
     337             :         {
     338             :             post_G1 = 25559 /*0.78f Q15*/;
     339             :             move16();
     340             :         }
     341             :         ELSE
     342             :         {
     343             :             post_G1 = 24904 /*0.76f Q15*/;
     344             :             move16();
     345             :         }
     346             :     }
     347             : 
     348             :     /* Switch off post-filter */
     349             :     if ( off_flag != 0 )
     350             :     {
     351             :         post_G1 = post_G2;
     352             :         move16();
     353             :     }
     354             : 
     355             :     /* Reset post filter */
     356             :     IF( hPFstat->reset != 0 )
     357             :     {
     358             :         post_G1 = MAX16B;
     359             :         move16();
     360             :         post_G2 = MAX16B;
     361             :         move16();
     362             :         hPFstat->reset = 0;
     363             :         move16();
     364             :         Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
     365             :         Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
     366             :         hPFstat->gain_prec = 16384; // 1.Q14
     367             :         move16();
     368             :         Copy( synth_in, synth_out, L_frame );
     369             : 
     370             :         return;
     371             :     }
     372             : 
     373             :     /* input memory*/
     374             :     Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
     375             :     Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
     376             : 
     377             :     move16();
     378             :     p_Aq = Aq; // Q12
     379             :     FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
     380             :     {
     381             :         Dec_formant_postfilt_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 );
     382             :         p_Aq += ( M + 1 );
     383             :     }
     384             : }
     385             : #endif
     386      258774 : void formant_post_filt_ivas_fx(
     387             :     PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
     388             :     Word16 *synth_in,      /* i  : 12k8 synthesis                    */
     389             :     Word16 *Aq,            /* i  : LP filter coefficient Q12             */
     390             :     Word16 *synth_out,     /* i/o: input signal                      */
     391             :     Word16 L_frame,
     392             :     Word32 lp_noise,      /* (i) : background noise energy (15Q16) */
     393             :     Word32 brate,         /* (i) : bit-rate */
     394             :     const Word16 off_flag /* i  : off flag                        */
     395             : )
     396             : {
     397             :     Word16 i_subfr;
     398             :     Word16 *p_Aq;
     399             :     Word16 post_G1, post_G2;
     400             : 
     401             : 
     402             :     /*default parameter for noisy speech and high bit-rates*/
     403      258774 :     IF( EQ_16( L_frame, L_FRAME ) )
     404             :     {
     405      126131 :         post_G2 = 22938 /*0.7f Q15*/;
     406      126131 :         move16();
     407      126131 :         IF( LT_32( lp_noise, LP_NOISE_THRESH ) )
     408             :         {
     409             :             /*Clean speech*/
     410      106298 :             IF( LT_32( brate, ACELP_13k20 ) )
     411             :             {
     412             :                 /*Low rates*/
     413             : 
     414       69539 :                 post_G1 = 26214 /*0.8f Q15*/;
     415       69539 :                 move16();
     416             :             }
     417       36759 :             ELSE IF( LT_32( brate, ACELP_24k40 ) )
     418             :             {
     419             :                 /*Low rates*/
     420             : 
     421       36759 :                 post_G1 = 24576 /*0.75f Q15*/;
     422       36759 :                 move16();
     423             :             }
     424             :             ELSE
     425             :             {
     426           0 :                 post_G1 = 23593 /*0.72f Q15*/;
     427           0 :                 move16();
     428             :             }
     429             :         }
     430             :         ELSE /*Noisy speech*/
     431             :         {
     432       19833 :             post_G1 = 22938 /*0.7f Q15*/;
     433       19833 :             move16();
     434       19833 :             if ( LT_32( brate, ACELP_15k85 ) )
     435             :             {
     436             :                 /*Low rates*/
     437       18557 :                 post_G1 = 24576 /*0.75f Q15*/;
     438       18557 :                 move16();
     439             :             }
     440             :         }
     441             :     }
     442             :     ELSE
     443             :     {
     444      132643 :         post_G2 = 24904 /*0.76f Q15*/;
     445      132643 :         move16();
     446      132643 :         test();
     447      132643 :         IF( GE_32( lp_noise, LP_NOISE_THRESH ) )
     448             :         {
     449       16152 :             post_G1 = 24904 /*0.76f Q15*/;
     450             :         }
     451      116491 :         ELSE IF( EQ_32( brate, ACELP_13k20 ) )
     452             :         {
     453           0 :             post_G1 = 26870 /*0.82f Q15*/;
     454           0 :             move16();
     455             :         }
     456      116491 :         ELSE IF( EQ_32( brate, ACELP_16k40 ) )
     457             :         {
     458         190 :             post_G1 = 26214 /*0.80f Q15*/;
     459         190 :             move16();
     460             :         }
     461      116301 :         ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) )
     462             :         {
     463        1454 :             post_G1 = 25559 /*0.78f Q15*/;
     464        1454 :             move16();
     465             :         }
     466             :         ELSE
     467             :         {
     468      114847 :             post_G1 = 24904 /*0.76f Q15*/;
     469      114847 :             move16();
     470             :         }
     471             :     }
     472             : 
     473             :     /* Switch off post-filter */
     474      258774 :     if ( off_flag != 0 )
     475             :     {
     476           0 :         post_G1 = post_G2;
     477           0 :         move16();
     478             :     }
     479             : 
     480             :     /* Reset post filter */
     481      258774 :     IF( hPFstat->reset != 0 )
     482             :     {
     483      108110 :         post_G1 = MAX16B;
     484      108110 :         move16();
     485      108110 :         post_G2 = MAX16B;
     486      108110 :         move16();
     487      108110 :         hPFstat->reset = 0;
     488      108110 :         move16();
     489      108110 :         Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
     490      108110 :         Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
     491      108110 :         hPFstat->gain_prec = 16384; // 1.Q14
     492      108110 :         move16();
     493      108110 :         Copy( synth_in, synth_out, L_frame );
     494             : 
     495      108110 :         return;
     496             :     }
     497             : 
     498             :     /* input memory*/
     499      150664 :     Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
     500      150664 :     Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
     501             : 
     502      150664 :     move16();
     503      150664 :     p_Aq = Aq; // Q12
     504      823504 :     FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
     505             :     {
     506      672840 :         Dec_formant_postfilt_ivas_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 );
     507      672840 :         p_Aq += ( M + 1 );
     508             :     }
     509             : }
     510             : /*----------------------------------------------------------------------------
     511             :  * Dec_formant_postfilt_fx
     512             :  *
     513             :  * Post - adaptive postfilter main function
     514             :  *   Short term postfilter :
     515             :  *     Hst(z) = Hst0(z) Hst1(z)
     516             :  *     Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
     517             :  *     if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
     518             :  *     g0 = SUM(|hi|) if > 1
     519             :  *     g0 = 1. else
     520             :  *     Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
     521             :  *     with mu = k1 * gamma3
     522             :  *     k1 = 1st parcor calculated on {hi}
     523             :  *     gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
     524             :  *----------------------------------------------------------------------------*/
     525             : #ifndef REMOVE_EVS_DUPLICATES
     526             : static void Dec_formant_postfilt_fx(
     527             :     PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
     528             :     Word16 *signal_ptr,    /* i  : input signal (pointer to current subframe Q14*/
     529             :     Word16 *coeff,         /* i  : LPC coefficients for current subframe Q12    */
     530             :     Word16 *sig_out,       /* o  : postfiltered output                       */
     531             :     Word16 gamma1,         /* i  : short term postfilt. den. weighting factor Q15*/
     532             :     Word16 gamma2          /* i  : short term postfilt. num. weighting factor Q15*/
     533             : )
     534             : {
     535             :     /* Local variables and arrays */
     536             :     Word16 apond1[M + 1];        /* s.t. denominator coeff. Q12*/
     537             :     Word16 apond2[LONG_H_ST];    // Q12
     538             :     Word16 res2[L_SUBFR];        // Q14
     539             :     Word16 resynth[L_SUBFR + 1]; // Qy
     540             :     Word16 parcor0;              // Q15
     541             :     Word16 i, max;
     542             :     Word16 scale_down;
     543             : 
     544             :     /* Compute weighted LPC coefficients */
     545             :     weight_a_fx( coeff, apond1, gamma1, M );
     546             :     weight_a_fx( coeff, apond2, gamma2, M );
     547             :     set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
     548             : 
     549             :     max = abs_s( signal_ptr[0] ); // Q14
     550             :     FOR( i = 1; i < L_SUBFR; i++ )
     551             :     {
     552             :         max = s_max( max, abs_s( signal_ptr[i] ) );
     553             :     }
     554             :     scale_down = 0;
     555             :     move16();
     556             :     if ( GT_16( max, 16384 /*1.Q14*/ ) )
     557             :     {
     558             :         scale_down = 1;
     559             :         move16();
     560             :     }
     561             : 
     562             :     /* Compute A(gamma2) residual */
     563             :     IF( !scale_down )
     564             :     {
     565             :         Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 1 );
     566             :     }
     567             :     ELSE
     568             :     {
     569             :         Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 0 );
     570             :         Scale_sig( hPFstat->mem_stp, L_SYN_MEM, -1 );
     571             :     }
     572             : 
     573             :     /* Controls short term pst filter gain and compute parcor0 */
     574             :     calc_st_filt_local_fx( apond2, apond1, &parcor0, res2, hPFstat->mem_zero );
     575             : 
     576             :     /* 1/A(gamma1) filtering, mem_stp is updated */
     577             :     resynth[0] = *( hPFstat->mem_stp + sub( L_SYN_MEM, 1 ) );
     578             :     move16();
     579             : 
     580             :     E_UTIL_synthesis( 1, apond1, res2, &( resynth[1] ), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
     581             : 
     582             :     IF( !scale_down )
     583             :     {
     584             :         Copy( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
     585             :     }
     586             :     ELSE
     587             :     {
     588             :         Copy_Scale_sig( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 );
     589             :     }
     590             : 
     591             :     /* Tilt filtering */
     592             :     Filt_mu_fx( resynth, sig_out, parcor0, L_SUBFR );
     593             :     IF( scale_down )
     594             :     {
     595             :         Scale_sig( sig_out, L_SUBFR, 1 );
     596             :     }
     597             : 
     598             :     /* Gain control */
     599             :     scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
     600             : 
     601             : 
     602             :     return;
     603             : }
     604             : #endif
     605      672840 : static void Dec_formant_postfilt_ivas_fx(
     606             :     PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
     607             :     Word16 *signal_ptr,    /* i  : input signal (pointer to current subframe Q14*/
     608             :     Word16 *coeff,         /* i  : LPC coefficients for current subframe Q12     */
     609             :     Word16 *sig_out,       /* o  : postfiltered output                       */
     610             :     Word16 gamma1,         /* i  : short term postfilt. den. weighting factor Q15*/
     611             :     Word16 gamma2          /* i  : short term postfilt. num. weighting factor Q15*/
     612             : )
     613             : {
     614             :     /* Local variables and arrays */
     615             :     Word16 apond1[M + 1];        /* s.t. denominator coeff. Q12*/
     616             :     Word16 apond2[LONG_H_ST];    // Q12
     617             :     Word16 res2[L_SUBFR];        // Q14
     618             :     Word16 resynth[L_SUBFR + 1]; // Qy
     619             :     Word16 parcor0;              // Q15
     620             :     Word16 i, max;
     621             :     Word16 scale_down;
     622             : 
     623             :     /* Compute weighted LPC coefficients */
     624      672840 :     weight_a_fx( coeff, apond1, gamma1, M );
     625      672840 :     weight_a_fx( coeff, apond2, gamma2, M );
     626      672840 :     set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
     627             : 
     628      672840 :     max = abs_s( signal_ptr[0] ); // Q14
     629    43061760 :     FOR( i = 1; i < L_SUBFR; i++ )
     630             :     {
     631    42388920 :         max = s_max( max, abs_s( signal_ptr[i] ) );
     632             :     }
     633      672840 :     scale_down = 0;
     634      672840 :     move16();
     635      672840 :     if ( GT_16( max, 16384 /*1.Q14*/ ) )
     636             :     {
     637         646 :         scale_down = 1;
     638         646 :         move16();
     639             :     }
     640             : 
     641             :     /* Compute A(gamma2) residual */
     642      672840 :     IF( !scale_down )
     643             :     {
     644      672194 :         Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 1 );
     645             :     }
     646             :     ELSE
     647             :     {
     648         646 :         Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 0 );
     649         646 :         Scale_sig( hPFstat->mem_stp, L_SYN_MEM, -1 );
     650             :     }
     651             : 
     652             :     /* Controls short term pst filter gain and compute parcor0 */
     653      672840 :     calc_st_filt_ivas_fx( apond2, apond1, &parcor0, res2, hPFstat->mem_zero, -1 );
     654             : 
     655             :     /* 1/A(gamma1) filtering, mem_stp is updated */
     656      672840 :     resynth[0] = *( hPFstat->mem_stp + sub( L_SYN_MEM, 1 ) );
     657      672840 :     move16();
     658             : 
     659      672840 :     E_UTIL_synthesis( 1, apond1, res2, &( resynth[1] ), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
     660             : 
     661      672840 :     IF( !scale_down )
     662             :     {
     663      672194 :         Copy( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
     664             :     }
     665             :     ELSE
     666             :     {
     667         646 :         Copy_Scale_sig( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 );
     668             :     }
     669             : 
     670             :     /* Tilt filtering */
     671      672840 :     Filt_mu_ivas_fx( resynth, sig_out, parcor0, L_SUBFR, -1 );
     672      672840 :     IF( scale_down )
     673             :     {
     674         646 :         Scale_sig( sig_out, L_SUBFR, 1 );
     675             :     }
     676             : 
     677             :     /* Gain control */
     678      672840 :     scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
     679             : 
     680             : 
     681      672840 :     return;
     682             : }
     683             : 
     684             : /*------------------------------------------------------------------------------------
     685             :  * modify_pst_param()
     686             :  *
     687             :  * Modify gamma1 and gamma2 values in function of the long term noise level
     688             :  *-----------------------------------------------------------------------------------*/
     689             : 
     690        2076 : static void modify_pst_param_fx(
     691             :     const Word16 lp_noise,   /* i  : Long term noise energy     Q8           */
     692             :     Word16 *g1,              /* o  : Gamma1 used in post filter Q15          */
     693             :     Word16 *g2,              /* o  : Gamma1 used in post filter Q15          */
     694             :     const Word16 coder_type, /* i  : Vad information decoded in UV frame     */
     695             :     Word16 *gain_factor      /* o  : Gain factor applied in post filtering Q15  */
     696             : )
     697             : {
     698             :     Word16 tmp;
     699             :     Word16 lp_noiseQ12;
     700             :     Word32 L_tmp;
     701             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     702        2076 :     Flag Overflow = 0;
     703        2076 :     move16();
     704             : #endif
     705             : 
     706             : 
     707        2076 :     test();
     708        2076 :     IF( NE_16( coder_type, INACTIVE ) && LT_16( lp_noise, LP_NOISE_THR_FX ) )
     709             :     {
     710        2076 :         lp_noiseQ12 = shl_o( lp_noise, 4, &Overflow ); /* to go from Q8 to Q12 */
     711             : 
     712             :         /* ftmp = lp_noise*BG1_FX + CG1_FX */
     713        2076 :         tmp = mac_r( CG1_FX * 65536L, lp_noiseQ12, BG1_FX * 8 ); /* x8 to go from Q12 to Q15 */
     714        2076 :         tmp = s_min( tmp, POST_G1_FX );
     715        2076 :         tmp = s_max( tmp, GAMMA1_PST12K_MIN_FX );
     716             : 
     717        2076 :         *g1 = tmp;
     718        2076 :         move16();
     719             : 
     720             :         /* ftmp = lp_noise*BG2_FX + CG2_FX */
     721        2076 :         L_tmp = L_mac0( CG2_FX / 2 * 65536L, lp_noiseQ12, BG2_FX * 8 ); /* L_mac0 and /2 to go from Q12 to Q14 */
     722             :         /* we go to Q30 to avoid overflow CG2_FX*/
     723             : 
     724        2076 :         L_tmp = L_min( L_tmp, POST_G2_FX * 65536L / 2 ); /* /2 because L_tmp is Q30 */
     725        2076 :         L_tmp = L_max( L_tmp, GAMMA2_PST12K_MIN_FX * 65536L / 2 );
     726             : 
     727        2076 :         *g2 = extract_h( L_shl( L_tmp, 1 ) ); /* Q30=>Q31=>Q15 */
     728             :     }
     729             :     ELSE
     730             :     {
     731           0 :         *g1 = GAMMA1_PST12K_NOIS_FX;
     732           0 :         move16();
     733           0 :         *g2 = GAMMA2_PST12K_NOIS_FX;
     734           0 :         move16();
     735             :     }
     736             : 
     737             :     /* Set gain_factor of the harmonic filtering*/
     738             :     /* ftmp = (lp_noise - K_LP_NOISE)*C_LP_NOISE_FX */
     739        2076 :     L_tmp = L_mac( -CK_LP_NOISE_FX, lp_noise, C_LP_NOISE_FX ); /* tmp is in Q24 (from Q8) */
     740             : 
     741        2076 :     L_tmp = L_min( L_tmp, 64 * 65536L ); /* 0.25 in Q24 */
     742        2076 :     L_tmp = L_max( L_tmp, 0 );
     743             : 
     744        2076 :     *gain_factor = extract_h( L_shl( L_tmp, 7 ) ); /* Q24=>Q31=>Q15 */
     745             : 
     746             : 
     747        2076 :     return;
     748             : }
     749             : 
     750             : /*----------------------------------------------------------------------------
     751             :  * pst_ltp_fx
     752             :  *
     753             :  * Perform harmonic postfilter
     754             :  *----------------------------------------------------------------------------*/
     755           0 : static void pst_ltp_fx(
     756             :     Word16 t0,            /* i  : pitch delay given by coder Q0       */
     757             :     Word16 *ptr_sig_in,   /* i  : postfilter i  filter (residu2) Qx   */
     758             :     Word16 *ptr_sig_pst0, /* o  : harmonic postfilter o Qx           */
     759             :     Word16 gain_factor    /* i  : Gain Factor (Q15)                */
     760             : )
     761             : {
     762             :     Word32 L_temp;
     763             : 
     764             :     Word16 y_up[SIZ_Y_UP];
     765             :     Word16 sig_cadr[SIZ_RES2];
     766             : 
     767             :     Word16 *ptr_y_up;
     768             :     Word16 *ptr_sig;
     769             :     Word16 *ptr_sig_cadr;
     770             : 
     771             :     Word16 i;
     772             :     Word16 temp;
     773             :     Word16 ltpdel, phase;
     774             :     Word16 num_gltp, den_gltp;
     775             :     Word16 num2_gltp, den2_gltp;
     776             :     Word16 sh_num, sh_den;
     777             :     Word16 sh_num2, sh_den2;
     778             :     Word16 gain_plt;
     779             :     Word16 off_yup;
     780             :     Word16 nb_sh_sig;
     781             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     782           0 :     Flag Overflow = 0;
     783           0 :     move16();
     784             : #endif
     785             : 
     786             : 
     787             :     /* i  signal justified on 13 bits */
     788           0 :     ptr_sig = ptr_sig_in - DECMEM_RES2; // Qx
     789           0 :     nb_sh_sig = getScaleFactor16( ptr_sig, DECMEM_RES2 + L_SUBFR );
     790           0 :     nb_sh_sig = sub( 3, nb_sh_sig );
     791             : 
     792           0 :     FOR( i = 0; i < DECMEM_RES2 + L_SUBFR; i++ )
     793             :     {
     794             :         /* nb_sh_sig may be >0, <0 or =0 */
     795           0 :         sig_cadr[i] = shr( ptr_sig[i], nb_sh_sig );
     796           0 :         move16();
     797             :     }
     798           0 :     ptr_sig_cadr = sig_cadr + DECMEM_RES2;
     799             : 
     800             :     /* Sub optimal delay search */
     801           0 :     search_del_fx( t0, ptr_sig_cadr, &ltpdel, &phase, &num_gltp, &den_gltp, &sh_num, &sh_den, y_up, &off_yup );
     802             : 
     803             : 
     804           0 :     IF( num_gltp == 0 )
     805             :     {
     806           0 :         Copy( ptr_sig_in, ptr_sig_pst0, L_SUBFR );
     807             :     }
     808             :     ELSE
     809             :     {
     810           0 :         IF( phase == 0 )
     811             :         {
     812           0 :             ptr_y_up = ptr_sig_in - ltpdel; // Qx
     813             :         }
     814             :         ELSE
     815             :         {
     816             :             /* Filtering with long filter */
     817           0 :             compute_ltp_l_fx( ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, &sh_num2, &sh_den2 );
     818             : 
     819             : 
     820           0 :             IF( EQ_16( select_ltp_fx( num_gltp, den_gltp, sh_num, sh_den, num2_gltp, den2_gltp, sh_num2, sh_den2 ), 1 ) )
     821             :             {
     822             :                 /* select short filter */
     823           0 :                 temp = sub( phase, 1 );
     824           0 :                 L_temp = L_mult0( temp, L_SUBFR + 1 );
     825           0 :                 temp = extract_l( L_temp );
     826           0 :                 temp = add( temp, off_yup );
     827             : 
     828             :                 /* ptr_y_up = y_up + (phase-1) * (L_SUBFR+1) + off_yup */
     829           0 :                 ptr_y_up = y_up + temp;
     830             :             }
     831             :             ELSE
     832             :             {
     833             :                 /* select long filter */
     834           0 :                 num_gltp = num2_gltp;
     835           0 :                 move16();
     836           0 :                 den_gltp = den2_gltp;
     837           0 :                 move16();
     838           0 :                 sh_num = sh_num2;
     839           0 :                 move16();
     840           0 :                 sh_den = sh_den2;
     841           0 :                 move16();
     842           0 :                 ptr_y_up = ptr_sig_pst0;
     843             :             }
     844             : 
     845             :             /* rescale y_up */
     846           0 :             FOR( i = 0; i < L_SUBFR; i++ )
     847             :             {
     848             :                 /* nb_sh_sig may be >0, <0 or =0 */
     849           0 :                 ptr_y_up[i] = shl_sat( ptr_y_up[i], nb_sh_sig );
     850           0 :                 move16();
     851             :             }
     852             :         }
     853             : 
     854           0 :         temp = sub( sh_num, sh_den );
     855           0 :         IF( temp >= 0 )
     856             :         {
     857           0 :             den_gltp = shr( den_gltp, temp );
     858             :         }
     859             :         ELSE
     860             :         {
     861           0 :             num_gltp = shl( num_gltp, temp ); /* >> (-temp) */
     862             :         }
     863           0 :         IF( GE_16( num_gltp, den_gltp ) )
     864             :         {
     865             :             /* beta bounded to 1 */
     866           0 :             gain_plt = MIN_GPLT_FX;
     867           0 :             move16();
     868             :         }
     869             :         ELSE
     870             :         {
     871             :             /* GAMMA_G = 0.5 */
     872             :             /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp) */
     873             :             /* shift 1 bit to avoid overflows in add */
     874           0 :             num_gltp = shr( num_gltp, 2 );
     875           0 :             den_gltp = shr( den_gltp, 1 );
     876           0 :             temp = add( den_gltp, num_gltp );
     877           0 :             gain_plt = div_s( den_gltp, temp ); /* Q15 */
     878             :         }
     879             : 
     880             :         /* decrease gain in noisy condition */
     881             :         /* gain_plt += (1.0f-gain_plt) * gain_factor */
     882             :         /* gain_plt = gain_plt + gain_factor - gain_plt*gain_factor */
     883           0 :         gain_plt = msu_ro( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor, &Overflow ); // Q15
     884             : 
     885             :         /** filtering by H0(z) = harmonic filter **/
     886           0 :         filt_plt_fx( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt );
     887             :     }
     888           0 : }
     889             : 
     890             : /*----------------------------------------------------------------------------
     891             :  * search_del_fx:
     892             :  *
     893             :  * Computes best (shortest) integer LTP delay + fine search
     894             :  *---------------------------------------------------------------------------*/
     895           0 : static void search_del_fx(
     896             :     Word16 t0,           /* i  : pitch delay given by coder Q0        */
     897             :     Word16 *ptr_sig_in,  /* i  : i  signal (with delay line)       */
     898             :     Word16 *ltpdel,      /* o  : delay = *ltpdel - *phase / f_up   */
     899             :     Word16 *phase,       /* o  : phase                             */
     900             :     Word16 *num_gltp,    /* o  : 16 bits numerator of LTP gain Q(sh_num_gltp)     */
     901             :     Word16 *den_gltp,    /* o  : 16 bits denominator of LTP gain Q(sh_den_gltp)  */
     902             :     Word16 *sh_num_gltp, /* o  : justification for num_gltp        */
     903             :     Word16 *sh_den_gltp, /* o  : justification for den_gltp        */
     904             :     Word16 *y_up,        /* o  : LT delayed signal if fract. delay */
     905             :     Word16 *off_yup      /* o  : offset in y_up                    */
     906             : )
     907             : {
     908             :     Word32 L_den0[F_UP_PST - 1];
     909             :     Word32 L_den1[F_UP_PST - 1];
     910             : 
     911             :     Word32 *ptr_L_den0, *ptr_L_den1;
     912             : 
     913             :     Word32 L_num_int, L_den_int, L_den_max;
     914             :     Word32 L_temp0, L_temp1;
     915             :     Word32 L_acc;
     916             :     Word32 L_temp;
     917             : 
     918             :     const Word16 *ptr_h;
     919             :     Word16 *ptr_sig_past, *ptr_sig_past0;
     920             :     Word16 *ptr1, *ptr_y_up;
     921             : 
     922             :     Word16 i, n;
     923             :     Word16 num /*Q(sh_num)*/, den0 /*Q(sh_den)*/, den1 /*Q(sh_den)*/;
     924             :     Word16 den_max, num_max;
     925             :     Word32 L_numsq_max;
     926             :     Word16 ener; // Q(sh_ener)
     927             :     Word16 sh_num, sh_den, sh_ener;
     928             :     Word16 i_max, lambda, phi, phi_max, ioff;
     929             :     Word16 temp;
     930             : 
     931             : 
     932             :     /*-------------------------------------
     933             :      * Computes energy of current signal
     934             :      *-------------------------------------*/
     935             : 
     936           0 :     L_acc = L_mult( ptr_sig_in[0], ptr_sig_in[0] );
     937           0 :     FOR( i = 1; i < L_SUBFR; i++ )
     938             :     {
     939           0 :         L_acc = L_mac_sat( L_acc, ptr_sig_in[i], ptr_sig_in[i] );
     940             :     }
     941           0 :     IF( L_acc == 0 )
     942             :     {
     943           0 :         *num_gltp = 0;
     944           0 :         move16();
     945           0 :         *den_gltp = 1;
     946           0 :         move16();
     947           0 :         *ltpdel = 0;
     948           0 :         move16();
     949           0 :         *phase = 0;
     950           0 :         move16();
     951             : 
     952           0 :         return;
     953             :     }
     954           0 :     sh_ener = sub( 16, norm_l( L_acc ) );
     955             :     /* save energy for final decision */
     956           0 :     sh_ener = s_max( 0, sh_ener );
     957           0 :     ener = extract_l( L_shr( L_acc, sh_ener ) );
     958             : 
     959             :     /*-------------------------------------
     960             :      * Selects best of 3 integer delays
     961             :      * Maximum of 3 numerators around t0
     962             :      *-------------------------------------*/
     963           0 :     lambda = sub( t0, 1 );
     964           0 :     ptr_sig_past = ptr_sig_in - lambda;
     965           0 :     L_num_int = L_deposit_l( -1 );
     966             : 
     967             :     /* initialization used only to suppress Microsoft Visual C++ warnings */
     968           0 :     i_max = (Word16) 0;
     969           0 :     move16();
     970             : 
     971           0 :     FOR( i = 0; i < 3; i++ )
     972             :     {
     973           0 :         L_acc = L_mult( ptr_sig_in[0], ptr_sig_past[0] );
     974           0 :         FOR( n = 1; n < L_SUBFR; n++ )
     975             :         {
     976           0 :             L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_sig_past[n] );
     977             :         }
     978             : 
     979             : 
     980           0 :         L_acc = L_max( L_acc, 0 );
     981           0 :         L_temp = L_sub_sat( L_acc, L_num_int );
     982           0 :         if ( L_temp > 0L )
     983             :         {
     984           0 :             i_max = (Word16) i;
     985           0 :             move16();
     986             :         }
     987           0 :         L_num_int = L_max( L_num_int, L_acc );
     988           0 :         ptr_sig_past--;
     989             :     }
     990             : 
     991           0 :     IF( L_num_int == 0 )
     992             :     {
     993           0 :         *num_gltp = 0;
     994           0 :         move16();
     995           0 :         *den_gltp = 1;
     996           0 :         move16();
     997           0 :         *ltpdel = 0;
     998           0 :         move16();
     999           0 :         *phase = 0;
    1000           0 :         move16();
    1001             : 
    1002           0 :         return;
    1003             :     }
    1004             : 
    1005             :     /* Compute den for i_max */
    1006           0 :     lambda = add( lambda, (Word16) i_max );
    1007           0 :     ptr_sig_past = ptr_sig_in - lambda;
    1008           0 :     temp = *ptr_sig_past++;
    1009           0 :     move16();
    1010           0 :     L_acc = L_mult( temp, temp );
    1011           0 :     FOR( i = 1; i < L_SUBFR; i++ )
    1012             :     {
    1013           0 :         temp = *ptr_sig_past++;
    1014           0 :         move16();
    1015           0 :         L_acc = L_mac_sat( L_acc, temp, temp );
    1016             :     }
    1017           0 :     IF( L_acc == 0L )
    1018             :     {
    1019           0 :         *num_gltp = 0;
    1020           0 :         move16();
    1021           0 :         *den_gltp = 1;
    1022           0 :         move16();
    1023           0 :         *ltpdel = 0;
    1024           0 :         move16();
    1025           0 :         *phase = 0;
    1026           0 :         move16();
    1027             : 
    1028           0 :         return;
    1029             :     }
    1030           0 :     L_den_int = L_acc; /* sets to 'L_acc' in 1 clock */
    1031           0 :     move32();
    1032             : 
    1033             :     /*----------------------------------
    1034             :      * Select best phase around lambda
    1035             :      *----------------------------------
    1036             :      * Compute y_up & denominators
    1037             :      *----------------------------------*/
    1038             : 
    1039           0 :     ptr_y_up = y_up;
    1040           0 :     L_den_max = L_den_int; /* sets to 'L_acc' in 1 clock */
    1041           0 :     move32();
    1042           0 :     ptr_L_den0 = L_den0;
    1043           0 :     ptr_L_den1 = L_den1;
    1044           0 :     ptr_h = tab_hup_s_fx;
    1045           0 :     temp = sub( lambda, LH_UP_S - 1 );
    1046           0 :     ptr_sig_past0 = ptr_sig_in - temp;
    1047             : 
    1048             :     /* Loop on phase */
    1049           0 :     FOR( phi = 1; phi < F_UP_PST; phi++ )
    1050             :     {
    1051             :         /* Compute y_up for lambda+1 - phi/F_UP_PST */
    1052             :         /* and lambda - phi/F_UP_PST */
    1053             : 
    1054           0 :         ptr_sig_past = ptr_sig_past0;
    1055           0 :         FOR( n = 0; n <= L_SUBFR; n++ )
    1056             :         {
    1057           0 :             ptr1 = ptr_sig_past++;
    1058             : 
    1059           0 :             L_acc = L_mult( ptr_h[0], ptr1[0] );
    1060           0 :             FOR( i = 1; i < LH2_S; i++ )
    1061             :             {
    1062           0 :                 L_acc = L_mac( L_acc, ptr_h[i], ptr1[-i] );
    1063             :             }
    1064           0 :             ptr_y_up[n] = round_fx( L_acc );
    1065             :         }
    1066             : 
    1067             :         /* compute den0 (lambda+1) and den1 (lambda) */
    1068             : 
    1069             :         /* part common to den0 and den1 */
    1070           0 :         L_acc = L_mult( ptr_y_up[1], ptr_y_up[1] );
    1071           0 :         FOR( n = 2; n < L_SUBFR; n++ )
    1072             :         {
    1073           0 :             L_acc = L_mac_sat( L_acc, ptr_y_up[n], ptr_y_up[n] );
    1074             :         }
    1075           0 :         L_temp0 = L_acc; /* sets to 'L_acc' in 1 clock (saved for den1) */
    1076           0 :         move32();
    1077             : 
    1078             :         /* den0 */
    1079           0 :         L_acc = L_mac_sat( L_acc, ptr_y_up[0], ptr_y_up[0] );
    1080           0 :         *ptr_L_den0 = L_acc;
    1081           0 :         move32();
    1082             : 
    1083             :         /* den1 */
    1084           0 :         L_acc = L_mac_sat( L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR] );
    1085           0 :         *ptr_L_den1 = L_acc;
    1086           0 :         move32();
    1087             : 
    1088           0 :         IF( GT_16( abs_s( ptr_y_up[0] ), abs_s( ptr_y_up[L_SUBFR] ) ) )
    1089             :         {
    1090           0 :             L_den_max = L_max( *ptr_L_den0, L_den_max );
    1091             :         }
    1092             :         ELSE
    1093             :         {
    1094           0 :             L_den_max = L_max( *ptr_L_den1, L_den_max );
    1095             :         }
    1096           0 :         ptr_L_den0++;
    1097           0 :         ptr_L_den1++;
    1098           0 :         ptr_y_up += ( L_SUBFR + 1 );
    1099           0 :         ptr_h += LH2_S;
    1100             :     }
    1101             : 
    1102           0 :     IF( L_den_max == 0 )
    1103             :     {
    1104           0 :         *num_gltp = 0;
    1105           0 :         move16();
    1106           0 :         *den_gltp = 1;
    1107           0 :         move16();
    1108           0 :         *ltpdel = 0;
    1109           0 :         move16();
    1110           0 :         *phase = 0;
    1111           0 :         move16();
    1112             : 
    1113           0 :         return;
    1114             :     }
    1115             : 
    1116           0 :     sh_den = sub( 16, norm_l( L_den_max ) );
    1117             :     /* if sh_den <= 0 : dynamic between current frame */
    1118             :     /* and delay line too high */
    1119           0 :     IF( sh_den <= 0 )
    1120             :     {
    1121           0 :         *num_gltp = 0;
    1122           0 :         move16();
    1123           0 :         *den_gltp = 1;
    1124           0 :         move16();
    1125           0 :         *ltpdel = 0;
    1126           0 :         move16();
    1127           0 :         *phase = 0;
    1128           0 :         move16();
    1129             : 
    1130           0 :         return;
    1131             :     }
    1132             : 
    1133             :     /* search sh_num to justify correlations */
    1134             :     /* sh_num = Max(sh_den, sh_ener) */
    1135           0 :     sh_num = sh_ener;
    1136           0 :     move16();
    1137           0 :     if ( GE_16( sh_den, sh_ener ) )
    1138             :     {
    1139           0 :         sh_num = sh_den;
    1140           0 :         move16();
    1141             :     }
    1142             : 
    1143             :     /* Computation of the numerators */
    1144             :     /* and selection of best num*num/den */
    1145             :     /* for non null phases */
    1146             : 
    1147             :     /* Initialize with null phase */
    1148           0 :     L_acc = L_shr( L_den_int, sh_den ); /* sh_den > 0 */
    1149           0 :     den_max = extract_l( L_acc );
    1150           0 :     L_acc = L_shr( L_num_int, sh_num ); /* sh_num > 0 */
    1151           0 :     num_max = extract_l( L_acc );
    1152           0 :     L_numsq_max = L_mult( num_max, num_max );
    1153             : 
    1154           0 :     phi_max = 0;
    1155           0 :     move16();
    1156           0 :     ioff = 1;
    1157           0 :     move16();
    1158             : 
    1159           0 :     ptr_L_den0 = L_den0;
    1160           0 :     ptr_L_den1 = L_den1;
    1161           0 :     ptr_y_up = y_up;
    1162             : 
    1163             : 
    1164             :     /* if den_max = 0 : will be selected and declared unvoiced */
    1165             :     /* if num!=0 & den=0 : will be selected and declared unvoiced */
    1166             :     /* degenerated seldom cases, switch off LT is OK */
    1167             : 
    1168             :     /* Loop on phase */
    1169           0 :     FOR( phi = 1; phi < F_UP_PST; phi++ )
    1170             :     {
    1171             :         /* compute num for lambda+1 - phi/F_UP_PST */
    1172           0 :         L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
    1173           0 :         FOR( n = 1; n < L_SUBFR; n++ )
    1174             :         {
    1175           0 :             L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
    1176             :         }
    1177           0 :         L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
    1178           0 :         L_acc = L_max( 0, L_acc );
    1179           0 :         num = extract_l( L_acc );
    1180             : 
    1181             :         /* selection if num**2/den0 max */
    1182           0 :         L_temp1 = L_mult( num, num );
    1183           0 :         L_temp0 = Mpy_32_16_1( L_temp1, den_max );
    1184           0 :         L_acc = L_add( *ptr_L_den0++, 0 );
    1185           0 :         L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
    1186           0 :         den0 = extract_l( L_acc );
    1187           0 :         L_temp = Msub_32_16( L_temp0, L_numsq_max, den0 );
    1188           0 :         IF( L_temp > 0L )
    1189             :         {
    1190           0 :             num_max = num;
    1191           0 :             move16();
    1192           0 :             L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
    1193           0 :             move32();
    1194           0 :             den_max = den0;
    1195           0 :             move16();
    1196           0 :             ioff = 0;
    1197           0 :             move16();
    1198           0 :             phi_max = phi;
    1199           0 :             move16();
    1200             :         }
    1201             : 
    1202             :         /* compute num for lambda - phi/F_UP_PST */
    1203           0 :         ptr_y_up++;
    1204             : 
    1205           0 :         L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
    1206           0 :         FOR( n = 1; n < L_SUBFR; n++ )
    1207             :         {
    1208           0 :             L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
    1209             :         }
    1210           0 :         L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
    1211           0 :         L_acc = L_max( 0, L_acc );
    1212           0 :         num = extract_l( L_acc );
    1213             : 
    1214             :         /* selection if num**2/den1 max */
    1215           0 :         L_temp1 = L_mult( num, num );
    1216           0 :         L_temp0 = Mpy_32_16_1( L_temp1, den_max );
    1217           0 :         L_acc = L_add( *ptr_L_den1++, 0 );
    1218           0 :         L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
    1219           0 :         den1 = extract_l( L_acc );
    1220           0 :         L_temp = Msub_32_16( L_temp0, L_numsq_max, den1 );
    1221           0 :         IF( L_temp > 0L )
    1222             :         {
    1223           0 :             num_max = num;
    1224           0 :             move16();
    1225           0 :             L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
    1226           0 :             move32();
    1227           0 :             den_max = den1;
    1228           0 :             move16();
    1229           0 :             ioff = 1;
    1230           0 :             move16();
    1231           0 :             phi_max = phi;
    1232           0 :             move16();
    1233             :         }
    1234             : 
    1235           0 :         ptr_y_up += L_SUBFR;
    1236             :     }
    1237             : 
    1238             :     /*---------------------------------------------------
    1239             :      * test if normalized crit0[iopt] > THRESHCRIT
    1240             :      *--------------------------------------------------*/
    1241           0 :     test();
    1242           0 :     IF( num_max == 0 || LE_16( den_max, 1 ) )
    1243             :     {
    1244           0 :         *num_gltp = 0;
    1245           0 :         move16();
    1246           0 :         *den_gltp = 1;
    1247           0 :         move16();
    1248           0 :         *ltpdel = 0;
    1249           0 :         move16();
    1250           0 :         *phase = 0;
    1251           0 :         move16();
    1252             : 
    1253           0 :         return;
    1254             :     }
    1255             : 
    1256             :     /* compare num**2 */
    1257             :     /* to ener * den * 0.5 */
    1258             :     /* (THRESHCRIT = 0.5) */
    1259           0 :     L_temp1 = L_mult( den_max, ener );
    1260             : 
    1261             :     /* temp = 2 * sh_num - sh_den - sh_ener + 1 */
    1262             :     /* 16 bits with no overflows */
    1263           0 :     temp = shl( sh_num, 1 );
    1264           0 :     temp = sub( temp, sh_den );
    1265           0 :     temp = sub( temp, sh_ener );
    1266           0 :     temp = add( temp, 1 );
    1267           0 :     IF( temp < 0 )
    1268             :     {
    1269           0 :         temp = negate( temp ); /* no overflow */
    1270           0 :         L_numsq_max = L_shr( L_numsq_max, temp );
    1271             :     }
    1272             :     ELSE
    1273             :     {
    1274           0 :         IF( temp > 0 )
    1275             :         {
    1276           0 :             L_temp1 = L_shr( L_temp1, temp );
    1277             :         }
    1278             :     }
    1279           0 :     L_temp = L_sub( L_numsq_max, L_temp1 );
    1280           0 :     IF( L_temp >= 0L )
    1281             :     {
    1282           0 :         temp = add( lambda, 1 );
    1283           0 :         *ltpdel = sub( temp, ioff );
    1284           0 :         *off_yup = ioff;
    1285           0 :         move16();
    1286           0 :         *phase = phi_max;
    1287           0 :         move16();
    1288           0 :         *num_gltp = num_max;
    1289           0 :         move16();
    1290           0 :         *den_gltp = den_max;
    1291           0 :         move16();
    1292           0 :         *sh_den_gltp = sh_den;
    1293           0 :         move16();
    1294           0 :         *sh_num_gltp = sh_num;
    1295           0 :         move16();
    1296             :     }
    1297             :     ELSE
    1298             :     {
    1299           0 :         *num_gltp = 0;
    1300           0 :         move16();
    1301           0 :         *den_gltp = 1;
    1302           0 :         move16();
    1303           0 :         *ltpdel = 0;
    1304           0 :         move16();
    1305           0 :         *phase = 0;
    1306           0 :         move16();
    1307             :     }
    1308             : 
    1309             : 
    1310           0 :     return;
    1311             : }
    1312             : 
    1313             : /*----------------------------------------------------------------------------
    1314             :  *  filt_plt_fx:
    1315             :  *
    1316             :  * Perform long term postfilter
    1317             :  *----------------------------------------------------------------------------*/
    1318           0 : static void filt_plt_fx(
    1319             :     Word16 *s_in,   /* i  : i  signal with past Qx        */
    1320             :     Word16 *s_ltp,  /* i  : filtered signal with gain 1 Qx*/
    1321             :     Word16 *s_out,  /* o  : signal Qx                     */
    1322             :     Word16 gain_plt /* i  : filter gain Q15                 */
    1323             : )
    1324             : {
    1325             : 
    1326             :     /* Local variables */
    1327             :     Word32 L_acc;
    1328             : 
    1329             :     Word16 n;
    1330             :     Word16 gain_plt_1;
    1331             : 
    1332             : 
    1333           0 :     gain_plt_1 = sub( 32767, gain_plt ); // Q15
    1334           0 :     gain_plt_1 = add( gain_plt_1, 1 );   /* 2**15 (1 - g) */
    1335             : 
    1336           0 :     FOR( n = 0; n < L_SUBFR; n++ )
    1337             :     {
    1338             :         /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */
    1339           0 :         L_acc = L_mult( gain_plt, s_in[n] );             // Qx + Q15 + 1
    1340           0 :         s_out[n] = mac_r( L_acc, gain_plt_1, s_ltp[n] ); // Qx
    1341           0 :         move16();                                        /* no overflow */
    1342             :     }
    1343             : 
    1344             : 
    1345           0 :     return;
    1346             : }
    1347             : 
    1348             : 
    1349             : /*----------------------------------------------------------------------------
    1350             :  * compute_ltp_l_fx :
    1351             :  *
    1352             :  * compute delayed signal, num & den of gain for fractional delay
    1353             :  * with long interpolation filter
    1354             :  *----------------------------------------------------------------------------*/
    1355           0 : static void compute_ltp_l_fx(
    1356             :     Word16 *s_in,   /* i/o: signal with past            */
    1357             :     Word16 ltpdel,  /* i  : delay factor                */
    1358             :     Word16 phase,   /* i  : phase factor                */
    1359             :     Word16 *y_up,   /* i  : delayed signal              */
    1360             :     Word16 *num,    /* i  : numerator of LTP gain Q(sh_num)       */
    1361             :     Word16 *den,    /* i  : denominator of LTP gain Q(sh_den)     */
    1362             :     Word16 *sh_num, /* i  : justification factor of num */
    1363             :     Word16 *sh_den  /* i  : justification factor of den */
    1364             : )
    1365             : {
    1366             :     Word32 L_acc;
    1367             :     Word16 *ptr2;
    1368             :     const Word16 *ptr_h;
    1369             :     Word16 n, i;
    1370             :     Word16 temp;
    1371             : 
    1372           0 :     temp = sub( phase, 1 );
    1373           0 :     temp = shl( temp, L2_LH2_L );
    1374           0 :     ptr_h = tab_hup_l_fx + temp; /* tab_hup_l_fx + LH2_L * (phase-1) */ // Q15
    1375             : 
    1376           0 :     temp = sub( LH_UP_L, ltpdel );
    1377           0 :     ptr2 = s_in + temp;
    1378             : 
    1379             :     /* Compute y_up */
    1380           0 :     FOR( n = 0; n < L_SUBFR; n++ )
    1381             :     {
    1382           0 :         L_acc = L_mult( ptr_h[0], *ptr2-- );
    1383             : 
    1384           0 :         FOR( i = 1; i < LH2_L; i++ )
    1385             :         {
    1386           0 :             L_acc = L_mac( L_acc, ptr_h[i], *ptr2-- );
    1387             :         }
    1388           0 :         y_up[n] = round_fx( L_acc );
    1389           0 :         ptr2 += LH2_L_P1;
    1390             :     }
    1391             : 
    1392             :     /* Compute num */
    1393           0 :     L_acc = L_mult( y_up[0], s_in[0] );
    1394           0 :     FOR( n = 1; n < L_SUBFR; n++ )
    1395             :     {
    1396           0 :         L_acc = L_mac( L_acc, y_up[n], s_in[n] );
    1397             :     }
    1398           0 :     IF( L_acc < 0L )
    1399             :     {
    1400           0 :         *num = 0;
    1401           0 :         move16();
    1402           0 :         *sh_num = 0;
    1403           0 :         move16();
    1404             :     }
    1405             :     ELSE
    1406             :     {
    1407           0 :         temp = sub( 16, norm_l( L_acc ) );
    1408           0 :         temp = s_max( temp, 0 );
    1409           0 :         L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
    1410           0 :         *num = extract_l( L_acc );
    1411           0 :         *sh_num = temp;
    1412           0 :         move16();
    1413           0 :         move16();
    1414             :     }
    1415             : 
    1416             :     /* Compute den */
    1417           0 :     L_acc = L_mult( y_up[0], y_up[0] );
    1418           0 :     FOR( n = 1; n < L_SUBFR; n++ )
    1419             :     {
    1420           0 :         L_acc = L_mac_sat( L_acc, y_up[n], y_up[n] );
    1421             :     }
    1422           0 :     temp = sub( 16, norm_l( L_acc ) );
    1423           0 :     temp = s_max( temp, 0 );
    1424           0 :     L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
    1425           0 :     *den = extract_l( L_acc );
    1426           0 :     *sh_den = temp;
    1427           0 :     move16();
    1428           0 :     move16();
    1429             : 
    1430             : 
    1431           0 :     return;
    1432             : }
    1433             : 
    1434             : /*----------------------------------------------------------------------------
    1435             :  *  select_ltp_fx:
    1436             :  *
    1437             :  *  selects best of (gain1, gain2)
    1438             :  *  with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
    1439             :  *  and  gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
    1440             :  *----------------------------------------------------------------------------*/
    1441           0 : static Word16 select_ltp_fx(                 /* o  : 1 = 1st gain, 2 = 2nd gain  */
    1442             :                              Word16 num1,    /* i  : numerator of gain1 Q(sh_num1)          */
    1443             :                              Word16 den1,    /* i  : denominator of gain1 Q(sh_den1)       */
    1444             :                              Word16 sh_num1, /* i  : just. factor for num1       */
    1445             :                              Word16 sh_den1, /* i  : just. factor for den1       */
    1446             :                              Word16 num2,    /* i  : numerator of gain2 Q(sh_num2)          */
    1447             :                              Word16 den2,    /* i  : denominator of gain2 Q(sh_den2)       */
    1448             :                              Word16 sh_num2, /* i  : just. factor for num2       */
    1449             :                              Word16 sh_den2  /* i  : just. factor for den2       */
    1450             : )
    1451             : {
    1452             :     Word32 L_temp1, L_temp2;
    1453             :     Word32 L_temp;
    1454             : 
    1455             :     Word16 temp1, temp2;
    1456             : 
    1457             : 
    1458           0 :     IF( den2 == 0 )
    1459             :     {
    1460           0 :         return 1;
    1461             :     }
    1462             : 
    1463             :     /* compares criteria = num**2/den */
    1464           0 :     L_temp1 = L_mult( num1, num1 );
    1465           0 :     L_temp1 = Mpy_32_16_1( L_temp1, den2 );
    1466             : 
    1467           0 :     L_temp2 = L_mult( num2, num2 );
    1468           0 :     L_temp2 = Mpy_32_16_1( L_temp2, den1 );
    1469             : 
    1470             :     /* temp1 = sh_den2 + 2 * sh_num1 */
    1471           0 :     temp1 = shl( sh_num1, 1 );
    1472           0 :     temp1 = add( temp1, sh_den2 );
    1473             :     /* temp2 = sh_den1 + 2 * sh_num2; */
    1474           0 :     temp2 = shl( sh_num2, 1 );
    1475           0 :     temp2 = add( temp2, sh_den1 );
    1476             : 
    1477           0 :     temp2 = sub( temp2, temp1 );
    1478           0 :     IF( temp2 > 0 )
    1479             :     {
    1480           0 :         L_temp1 = L_shr( L_temp1, temp2 ); /* temp2 > 0 */
    1481             :     }
    1482           0 :     IF( temp2 < 0 )
    1483             :     {
    1484           0 :         L_temp2 = L_shl( L_temp2, temp2 ); /* temp2 < 0 */
    1485             :     }
    1486             : 
    1487           0 :     L_temp = L_sub( L_temp2, L_temp1 );
    1488           0 :     temp1 = 1;
    1489           0 :     move16();
    1490           0 :     if ( L_temp > 0L )
    1491             :     {
    1492           0 :         temp1 = 2;
    1493           0 :         move16();
    1494             :     }
    1495             : 
    1496           0 :     return temp1;
    1497             : }
    1498             : 
    1499             : /*----------------------------------------------------------------------------
    1500             :  * calc_st_filt_local_fx
    1501             :  *
    1502             :  * computes impulse response of A(gamma2) / A(gamma1)
    1503             :  * controls gain : computation of energy impulse response as
    1504             :  *                 SUMn  (abs (h[n])) and computes parcor0
    1505             :  *---------------------------------------------------------------------------- */
    1506           0 : static void calc_st_filt_local_fx(
    1507             :     Word16 *apond2,      /* i  : coefficients of numerator Q12            */
    1508             :     Word16 *apond1,      /* i  : coefficients of denominator Q12           */
    1509             :     Word16 *parcor0,     /* o  : 1st parcor calcul. on composed filter Q15*/
    1510             :     Word16 *sig_ltp_ptr, /* i/o: i  of 1/A(gamma1) : scaled by 1/g0 Qx   */
    1511             :     Word16 *mem_zero     /* i  : All zero memory                       */
    1512             : )
    1513             : {
    1514             :     Word32 L_g0;
    1515             : 
    1516             :     Word16 h[LONG_H_ST];
    1517             : 
    1518             :     Word16 g0, temp;
    1519             :     Word16 i;
    1520             : 
    1521             : 
    1522           0 :     temp = sub( 2, norm_s( apond2[0] ) );
    1523             : 
    1524             :     /* compute i.r. of composed filter apond2 / apond1 */
    1525           0 :     E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
    1526             : 
    1527             :     /* compute 1st parcor */
    1528           0 :     Calc_rc0_h( h, parcor0 );
    1529             : 
    1530             :     /* compute g0 */
    1531           0 :     L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
    1532           0 :     FOR( i = 1; i < LONG_H_ST; i++ )
    1533             :     {
    1534           0 :         L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
    1535             :     }
    1536           0 :     g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
    1537             : 
    1538             :     /* Scale signal i  of 1/A(gamma1) */
    1539           0 :     IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
    1540             :     {
    1541           0 :         temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
    1542           0 :         FOR( i = 0; i < L_SUBFR; i++ )
    1543             :         {
    1544           0 :             sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
    1545           0 :             move16();
    1546             :         }
    1547             :     }
    1548             : 
    1549             : 
    1550           0 :     return;
    1551             : }
    1552             : 
    1553      672840 : static void calc_st_filt_ivas_fx(
    1554             :     Word16 *apond2,      /* i  : coefficients of numerator Q12             */
    1555             :     Word16 *apond1,      /* i  : coefficients of denominator Q12          */
    1556             :     Word16 *parcor0,     /* o  : 1st parcor calcul. on composed filter Q15 */
    1557             :     Word16 *sig_ltp_ptr, /* i/o: i  of 1/A(gamma1) : scaled by 1/g0    Qx*/
    1558             :     Word16 *mem_zero,    /* i  : All zero memory                       */
    1559             :     const Word16 extl    /* i  : extension layer info                  */
    1560             : )
    1561             : {
    1562             :     Word32 L_g0;
    1563             : 
    1564             :     Word16 h[LONG_H_ST]; // Q12
    1565             : 
    1566             :     Word16 g0, temp;
    1567             :     Word16 i;
    1568             : 
    1569             : 
    1570      672840 :     temp = sub( 2, norm_s( apond2[0] ) );
    1571             : 
    1572             :     /* compute i.r. of composed filter apond2 / apond1 */
    1573      672840 :     IF( EQ_16( extl, SWB_TBE ) )
    1574             :     {
    1575           0 :         E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, LPC_SHB_ORDER );
    1576             :     }
    1577             :     ELSE
    1578             :     {
    1579      672840 :         E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
    1580             :     }
    1581             : 
    1582             :     /* compute 1st parcor */
    1583      672840 :     Calc_rc0_h( h, parcor0 );
    1584             : 
    1585             :     /* compute g0 */
    1586      672840 :     L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
    1587    13456800 :     FOR( i = 1; i < LONG_H_ST; i++ )
    1588             :     {
    1589    12783960 :         L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
    1590             :     }
    1591      672840 :     g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
    1592             : 
    1593             :     /* Scale signal i  of 1/A(gamma1) */
    1594      672840 :     IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
    1595             :     {
    1596      323051 :         temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
    1597    20998315 :         FOR( i = 0; i < L_SUBFR; i++ )
    1598             :         {
    1599    20675264 :             sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
    1600    20675264 :             move16();
    1601             :         }
    1602             :     }
    1603             : 
    1604             : 
    1605      672840 :     return;
    1606             : }
    1607             : /*----------------------------------------------------------------------------
    1608             :  * filt_mu
    1609             :  *
    1610             :  * tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
    1611             :  *      computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
    1612             :  *---------------------------------------------------------------------------*/
    1613           0 : void Filt_mu_fx(
    1614             :     Word16 *sig_in,  /* i  : signal (beginning at sample -1)     */
    1615             :     Word16 *sig_out, /* o  : signal with tilt                    */
    1616             :     Word16 parcor0,  /* i  : parcor0 (mu = parcor0 * gamma3)     */
    1617             :     Word16 L_subfr   /* i  : the length of subframe              */
    1618             : )
    1619             : {
    1620             :     Word32 L_acc, L_temp, L_fact;
    1621             : 
    1622             :     Word16 *ptrs;
    1623             : 
    1624             :     Word16 n;
    1625             :     Word16 mu, mu2, ga, temp;
    1626             :     Word16 fact, sh_fact;
    1627             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1628           0 :     Flag Overflow = 0;
    1629           0 :     move16();
    1630             : #endif
    1631             : 
    1632             : 
    1633           0 :     IF( parcor0 > 0 )
    1634             :     {
    1635           0 :         mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
    1636             :         /* GAMMA3_PLUS_FX < 0.5 */
    1637           0 :         sh_fact = 14;
    1638           0 :         move16(); /* sh_fact */
    1639           0 :         fact = (Word16) 0x4000;
    1640           0 :         move16();                                /* Q(sh_fact) */
    1641           0 :         L_fact = (Word32) L_deposit_l( 0x2000 ); /* fact >> 1 */
    1642             :     }
    1643             :     ELSE
    1644             :     {
    1645           0 :         mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
    1646             :         /* GAMMA3_MINUS_FX < 0.9375 */
    1647           0 :         sh_fact = 11;
    1648           0 :         move16(); /* sh_fact */
    1649           0 :         fact = (Word16) 0x0800;
    1650           0 :         move16();                                /* Q(sh_fact) */
    1651           0 :         L_fact = (Word32) L_deposit_l( 0x0400 ); /* fact >> 1 */
    1652             :     }
    1653             : 
    1654           0 :     temp = sub( 1, abs_s( mu ) );
    1655             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1656           0 :     mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */
    1657             :     BASOP_SATURATE_WARNING_ON_EVS;
    1658           0 :     ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
    1659             : 
    1660           0 :     ptrs = sig_in; /* points on sig_in(-1) */
    1661             : 
    1662           0 :     sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
    1663             : 
    1664           0 :     FOR( n = 0; n < L_subfr; n++ )
    1665             :     {
    1666           0 :         L_acc = L_mult0( mu, *ptrs++ );
    1667           0 :         L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
    1668             : 
    1669           0 :         L_temp = Madd_32_16( L_fact, L_temp, ga );
    1670           0 :         L_temp = L_shr_sat( L_temp, sh_fact ); /* mult. temp x ga */
    1671             :         BASOP_SATURATE_WARNING_OFF_EVS;
    1672             :         /*sig_out[n] = saturate(L_temp); move16();*/
    1673           0 :         sig_out[n] = round_fx_sat( L_temp );
    1674           0 :         move16();
    1675             :         BASOP_SATURATE_WARNING_ON_EVS;
    1676             :     }
    1677             : 
    1678             : 
    1679           0 :     return;
    1680             : }
    1681             : 
    1682      672840 : void Filt_mu_ivas_fx(
    1683             :     Word16 *sig_in,  /* i  : signal (beginning at sample -1)     */
    1684             :     Word16 *sig_out, /* o  : signal with tilt                    */
    1685             :     Word16 parcor0,  /* i  : parcor0 (mu = parcor0 * gamma3) Q15     */
    1686             :     Word16 L_subfr,  /* i  : the length of subframe              */
    1687             :     const Word16 extl )
    1688             : {
    1689             :     Word32 L_acc, L_temp, L_fact;
    1690             : 
    1691             :     Word16 *ptrs;
    1692             : 
    1693             :     Word16 n;
    1694             :     Word16 mu, mu2, ga, temp;
    1695             :     Word16 fact, sh_fact;
    1696             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1697      672840 :     Flag Overflow = 0;
    1698      672840 :     move16();
    1699             : #endif
    1700             : 
    1701      672840 :     IF( EQ_16( extl, SWB_TBE ) )
    1702             :     {
    1703           0 :         IF( parcor0 > 0 )
    1704             :         {
    1705           0 :             mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); // Q15
    1706             :             /* GAMMA3_PLUS_FX < 0.5 */
    1707           0 :             sh_fact = 14;
    1708           0 :             move16(); /* sh_fact */
    1709           0 :             fact = (Word16) 0x4000;
    1710           0 :             move16();                       /* Q(sh_fact) */
    1711           0 :             L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
    1712             :         }
    1713             :         ELSE
    1714             :         {
    1715           0 :             mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); // Q15
    1716             :             /* GAMMA3_MINUS_FX < 0.9375 */
    1717           0 :             sh_fact = 11;
    1718           0 :             move16(); /* sh_fact */
    1719           0 :             fact = (Word16) 0x0800;
    1720           0 :             move16();                       /* Q(sh_fact) */
    1721           0 :             L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
    1722             :         }
    1723             :     }
    1724             :     ELSE
    1725             :     {
    1726      672840 :         IF( parcor0 > 0 )
    1727             :         {
    1728       49156 :             mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
    1729             :             /* GAMMA3_PLUS_FX < 0.5 */
    1730       49156 :             sh_fact = 14;
    1731       49156 :             move16(); /* sh_fact */
    1732       49156 :             fact = (Word16) 0x4000;
    1733       49156 :             move16();                       /* Q(sh_fact) */
    1734       49156 :             L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
    1735             :         }
    1736             :         ELSE
    1737             :         {
    1738      623684 :             mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
    1739             :             /* GAMMA3_MINUS_FX < 0.9375 */
    1740      623684 :             sh_fact = 11;
    1741      623684 :             move16(); /* sh_fact */
    1742      623684 :             fact = (Word16) 0x0800;
    1743      623684 :             move16();                       /* Q(sh_fact) */
    1744      623684 :             L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
    1745             :         }
    1746             :     }
    1747             : 
    1748      672840 :     temp = sub( 1, abs_s( mu ) );
    1749             :     BASOP_SATURATE_WARNING_OFF_EVS;
    1750      672840 :     mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */
    1751             :     BASOP_SATURATE_WARNING_ON_EVS;
    1752      672840 :     ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
    1753             : 
    1754      672840 :     ptrs = sig_in; /* points on sig_in(-1) */
    1755             : 
    1756      672840 :     sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
    1757             : 
    1758    43734600 :     FOR( n = 0; n < L_subfr; n++ )
    1759             :     {
    1760    43061760 :         L_acc = L_mult0( mu, *ptrs++ );
    1761    43061760 :         L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
    1762             : 
    1763    43061760 :         L_temp = Madd_32_16( L_fact, L_temp, ga );
    1764    43061760 :         L_temp = L_shr( L_temp, sh_fact ); /* mult. temp x ga */
    1765             : 
    1766             :         BASOP_SATURATE_WARNING_OFF_EVS;
    1767             :         /*sig_out[n] = saturate(L_temp); move16();*/
    1768    43061760 :         sig_out[n] = round_fx_sat( L_temp );
    1769             :         BASOP_SATURATE_WARNING_ON_EVS;
    1770             :     }
    1771             : 
    1772             : 
    1773      672840 :     return;
    1774             : }
    1775             : /*----------------------------------------------------------------------------
    1776             :  * scale_st_fx()
    1777             :  *
    1778             :  * control of the subframe gain
    1779             :  * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
    1780             :  *---------------------------------------------------------------------------*/
    1781      674040 : void scale_st_fx(
    1782             :     const Word16 *sig_in, /* i  : postfilter i signal Qx             */
    1783             :     Word16 *sig_out,      /* i/o: postfilter o signal Qx             */
    1784             :     Word16 *gain_prec,    /* i/o: last value of gain for subframe Q14*/
    1785             :     Word16 L_subfr )
    1786             : {
    1787             :     Word32 L_acc, L_temp;
    1788             : 
    1789             :     Word16 i;
    1790             :     Word16 scal_in, scal_out;
    1791             :     Word16 s_g_in, s_g_out, temp, sh_g0, g0;
    1792      674040 :     Word16 gain = 0;
    1793             : 
    1794             : 
    1795             :     /* compute i  gain */
    1796      674040 :     L_acc = L_deposit_l( 0 );
    1797    43812600 :     FOR( i = 0; i < L_subfr; i++ )
    1798             :     {
    1799    43138560 :         IF( sig_in[i] > 0 )
    1800             :         {
    1801    21400950 :             L_acc = L_mac0( L_acc, 1, sig_in[i] );
    1802             :         }
    1803    43138560 :         IF( sig_in[i] < 0 )
    1804             :         {
    1805    21309517 :             L_acc = L_msu0( L_acc, 1, sig_in[i] );
    1806             :         }
    1807             :     }
    1808             : 
    1809      674040 :     g0 = 0;
    1810      674040 :     move16();
    1811      674040 :     IF( L_acc != 0L )
    1812             :     {
    1813      670864 :         scal_in = norm_l( L_acc );
    1814      670864 :         L_acc = L_shl( L_acc, scal_in );
    1815      670864 :         s_g_in = extract_h( L_acc ); /* normalized */
    1816             : 
    1817             :         /* Compute o   gain */
    1818             :         {
    1819      670864 :             Word64 acc64 = 0;
    1820    43606160 :             FOR( i = 0; i < L_subfr; i++ )
    1821             :             {
    1822    42935296 :                 acc64 = W_mac0_16_16( acc64, 1, abs_s( sig_out[i] ) );
    1823             :             }
    1824      670864 :             L_acc = W_sat_l( acc64 );
    1825             :         }
    1826      670864 :         IF( L_acc == 0L )
    1827             :         {
    1828         919 :             *gain_prec = 0;
    1829         919 :             move16();
    1830             : 
    1831         919 :             return;
    1832             :         }
    1833      669945 :         scal_out = norm_l( L_acc );
    1834      669945 :         L_acc = L_shl( L_acc, scal_out );
    1835      669945 :         s_g_out = extract_h( L_acc ); /* normalized */
    1836             : 
    1837      669945 :         sh_g0 = add( scal_in, 1 );
    1838      669945 :         sh_g0 = sub( sh_g0, scal_out ); /* scal_in - scal_out + 1 */
    1839      669945 :         IF( LT_16( s_g_in, s_g_out ) )
    1840             :         {
    1841      210755 :             g0 = div_s( s_g_in, s_g_out ); /* s_g_in/s_g_out in Q15 */
    1842             :         }
    1843             :         ELSE
    1844             :         {
    1845      459190 :             temp = sub( s_g_in, s_g_out ); /* sufficient since normalized */
    1846      459190 :             g0 = shr( div_s( temp, s_g_out ), 1 );
    1847      459190 :             g0 = add( g0, (Word16) 0x4000 ); /* s_g_in/s_g_out in Q14 */
    1848      459190 :             sh_g0 = sub( sh_g0, 1 );
    1849             :         }
    1850             :         /* L_gain_in/L_gain_out in Q14 */
    1851             :         /* overflows if L_gain_in > 2 * L_gain_out */
    1852      669945 :         g0 = shr_sat( g0, sh_g0 );      /* sh_g0 may be >0, <0, or =0 */
    1853      669945 :         g0 = mult_r( g0, AGC_FAC1_FX ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */
    1854             :     }
    1855             : 
    1856             :     /* gain(n) = AGC_FAC gain(n-1) + AGC_FAC1 gain_in/gain_out */
    1857             :     /* sig_out(n) = gain(n) sig_out(n) */
    1858      673121 :     gain = *gain_prec;
    1859      673121 :     move16();
    1860    43752865 :     FOR( i = 0; i < L_subfr; i++ )
    1861             :     {
    1862    43079744 :         temp = mult_r( AGC_FAC_FX, gain );
    1863    43079744 :         gain = add( temp, g0 ); /* in Q14 */
    1864    43079744 :         L_temp = L_mult( gain, sig_out[i] );
    1865    43079744 :         L_temp = L_shl_sat( L_temp, 1 );
    1866    43079744 :         sig_out[i] = round_fx_sat( L_temp );
    1867    43079744 :         move16();
    1868             :     }
    1869      673121 :     *gain_prec = gain;
    1870      673121 :     move16();
    1871             : 
    1872             : 
    1873      673121 :     return;
    1874             : }
    1875             : 
    1876             : /*----------------------------------------------------------------------------
    1877             :  * blend_subfr2_fx()
    1878             :  *
    1879             :  *
    1880             :  *---------------------------------------------------------------------------*/
    1881             : 
    1882        1200 : void blend_subfr2_fx(
    1883             :     Word16 *sigIn1, // Qx
    1884             :     Word16 *sigIn2, // Qx
    1885             :     Word16 *sigOut  // Qx
    1886             : )
    1887             : {
    1888        1200 :     Word16 fac1 = 32768 - 512; // 1.Q15 - ( 1.Q15 / L_SUBFR );
    1889        1200 :     Word16 fac2 = 0 + 512;     // 0.Q15 + ( 1.Q15 / L_SUBFR );
    1890        1200 :     Word16 step = 1024;        // 1.Q15 / ( L_SUBFR / 2 );
    1891             :     Word16 i;
    1892             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1893        1200 :     Flag Overflow = 0;
    1894        1200 :     move16();
    1895             : #endif
    1896        1200 :     move16();
    1897        1200 :     move16();
    1898        1200 :     move16();
    1899       39600 :     FOR( i = 0; i < L_SUBFR / 2; i++ )
    1900             :     {
    1901       38400 :         sigOut[i] = mac_ro( L_mult_o( fac1, sigIn1[i], &Overflow ), fac2, sigIn2[i], &Overflow ); // Qx
    1902       38400 :         fac1 = sub_o( fac1, step, &Overflow );
    1903       38400 :         fac2 = add_o( fac2, step, &Overflow );
    1904       38400 :         move16();
    1905             :     }
    1906             : 
    1907        1200 :     return;
    1908             : }

Generated by: LCOV version 1.14