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

Generated by: LCOV version 1.14