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

Generated by: LCOV version 1.14