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

Generated by: LCOV version 1.14