LCOV - code coverage report
Current view: top level - lib_com - wi_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 0 1946 0.0 %
Date: 2025-10-13 22:24:20 Functions: 0 37 0.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "prot_fx.h"
       8             : #include "rom_com.h"
       9             : #include "log2.h"
      10             : 
      11             : /*-------------------------------------------------------------------*
      12             :  * Local constants
      13             :  *-------------------------------------------------------------------*/
      14             : #define WARP_OS_RATE         8
      15             : #define LL                   256
      16             : #define LL_OS                ( WARP_OS_RATE * LL )
      17             : #define OSLENGTH             12
      18             : #define CUTFREE_ABS_RANGE    6
      19             : #define CUTFREE_REL_RANGE    0.25
      20             : #define CUTFREE_ABS_RANGE_Q3 48
      21             : #define CUTFREE_REL_RANGE_Q2 1
      22             : #define WI_THRESHLD          0.8
      23             : #define WI_SAMPLE_THLD       20
      24             : 
      25             : /*#define _POLY1(x, c)    ((c)[0] * (x) + (c)[1]) */
      26             : /*#define _POLY2(x, c)    (_POLY1((x), (c)) * (x) + (c)[2]) */
      27             : /*#define _POLY3(x, c)    (_POLY2((x), (c)) * (x) + (c)[3]) */
      28             : 
      29             : /*-------------------------------------------------------------------*
      30             :  * Local functions
      31             :  *--------------------------------------------------------------------*/
      32             : 
      33             : static Word32 DTFS_setEngy_fx( DTFS_STRUCTURE *X_DTFS_FX, Word32 en2_fx );
      34             : 
      35             : /*-------------------------------------------------------------------*
      36             :  * DTFS_new_fx()
      37             :  *
      38             :  * DTFS structure initialization.
      39             :  *-------------------------------------------------------------------*/
      40           0 : ivas_error DTFS_new_fx(
      41             :     DTFS_STRUCTURE **dtfs_out )
      42             : {
      43             : 
      44             :     Word16 i;
      45             : 
      46           0 :     DTFS_STRUCTURE *dtfs_fx = NULL;
      47           0 :     dtfs_fx = (DTFS_STRUCTURE *) calloc( 1, sizeof( DTFS_STRUCTURE ) );
      48             :     // PMT("verif mem alloc")
      49           0 :     IF( dtfs_fx == NULL )
      50             :     {
      51           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTFS (SC-VBR) structure\n" ) );
      52             :     }
      53             : 
      54           0 :     dtfs_fx->lag_fx = 0;
      55           0 :     move16();
      56           0 :     dtfs_fx->nH_fx = 0;
      57           0 :     move16();
      58           0 :     dtfs_fx->nH_4kHz_fx = 0;
      59           0 :     move16();
      60           0 :     dtfs_fx->upper_cut_off_freq_of_interest_fx = 3300; // Q0
      61           0 :     move16();
      62           0 :     dtfs_fx->upper_cut_off_freq_fx = 4000; // Q0
      63           0 :     move16();
      64           0 :     dtfs_fx->Q = 0;
      65           0 :     move16();
      66             : 
      67           0 :     FOR( i = 0; i < MAXLAG_WI; i++ )
      68             :     {
      69           0 :         dtfs_fx->a_fx[i] = 0; // dtfs_fx->Q
      70           0 :         move16();
      71           0 :         dtfs_fx->b_fx[i] = 0; // dtfs_fx->Q
      72           0 :         move16();
      73             :     }
      74           0 :     *dtfs_out = dtfs_fx;
      75           0 :     return IVAS_ERR_OK;
      76             : }
      77             : /*-------------------------------------------------------------------*
      78             :  * DTFS_copy_fx()
      79             :  *
      80             :  * Copy from one DTFS STRUCTURE to another.
      81             :  *-------------------------------------------------------------------*/
      82             : 
      83           0 : void DTFS_copy_fx(
      84             :     DTFS_STRUCTURE *Xout_fx, /* o: DTFS structure  */
      85             :     DTFS_STRUCTURE Xinp_fx   /* i: DTFS structure  */
      86             : )
      87             : 
      88             : {
      89             : 
      90             :     Word16 k;
      91           0 :     FOR( k = 0; k < MAXLAG_WI; k++ )
      92             :     {
      93           0 :         Xout_fx->a_fx[k] = Xinp_fx.a_fx[k]; /* Q(DTFS_STRUCTURE.Q) */
      94           0 :         move16();
      95             :     }
      96             : 
      97           0 :     FOR( k = 0; k < MAXLAG_WI; k++ )
      98             :     {
      99           0 :         Xout_fx->b_fx[k] = Xinp_fx.b_fx[k]; /* Q(DTFS_STRUCTURE.Q) */
     100           0 :         move16();
     101             :     }
     102             : 
     103           0 :     Xout_fx->lag_fx = Xinp_fx.lag_fx;
     104           0 :     move16();
     105           0 :     Xout_fx->nH_fx = Xinp_fx.nH_fx;
     106           0 :     move16();
     107           0 :     Xout_fx->nH_4kHz_fx = Xinp_fx.nH_4kHz_fx;
     108           0 :     move16();
     109           0 :     Xout_fx->upper_cut_off_freq_of_interest_fx = Xinp_fx.upper_cut_off_freq_of_interest_fx; // Q0
     110           0 :     move16();
     111           0 :     Xout_fx->upper_cut_off_freq_fx = Xinp_fx.upper_cut_off_freq_fx; // Q0
     112           0 :     move16();
     113           0 :     Xout_fx->Q = Xinp_fx.Q;
     114           0 :     move16();
     115           0 :     return;
     116             : }
     117             : 
     118             : 
     119             : /*-------------------------------------------------------------------*
     120             :  * DTFS_sub_fx()
     121             :  *
     122             :  * Subtract one DTFS STRUCTURE from another.
     123             :  *-------------------------------------------------------------------*/
     124           0 : void DTFS_sub_fx(
     125             :     DTFS_STRUCTURE *tmp, /* o: X1 - X2 */
     126             :     DTFS_STRUCTURE X1,   /* i: DTFS input 1 */
     127             :     DTFS_STRUCTURE X2    /* i: DTFS input 2 */
     128             : )
     129             : {
     130             :     Word16 i, sft, tmp_loop;
     131           0 :     sft = sub( X1.Q, X2.Q );
     132             : 
     133           0 :     IF( sft > 0 )
     134             :     {
     135           0 :         tmp_loop = shr( X1.lag_fx, 1 );
     136           0 :         FOR( i = 0; i <= tmp_loop; i++ )
     137             :         {
     138             : 
     139           0 :             tmp->a_fx[i] = sub( shr( X1.a_fx[i], sft ), X2.a_fx[i] );
     140           0 :             move16();
     141           0 :             tmp->b_fx[i] = sub( shr( X1.b_fx[i], sft ), X2.b_fx[i] );
     142           0 :             move16();
     143             :         }
     144           0 :         tmp->Q = X2.Q;
     145           0 :         move16();
     146             :     }
     147             :     ELSE
     148             :     {
     149           0 :         tmp_loop = shr( X1.lag_fx, 1 );
     150           0 :         FOR( i = 0; i <= tmp_loop; i++ )
     151             :         {
     152             : 
     153           0 :             tmp->a_fx[i] = sub( X1.a_fx[i], shl( X2.a_fx[i], sft ) );
     154           0 :             move16();
     155           0 :             tmp->b_fx[i] = sub( X1.b_fx[i], shl( X2.b_fx[i], sft ) );
     156           0 :             move16();
     157             :         }
     158           0 :         tmp->Q = X1.Q;
     159           0 :         move16();
     160             :     }
     161           0 :     tmp->lag_fx = s_max( X1.lag_fx, X2.lag_fx );
     162           0 :     move16();
     163           0 :     tmp->nH_fx = s_max( X1.nH_fx, X2.nH_fx );
     164           0 :     move16();
     165           0 :     tmp->nH_4kHz_fx = s_max( X1.nH_4kHz_fx, X2.nH_4kHz_fx );
     166           0 :     move16();
     167           0 :     tmp->upper_cut_off_freq_of_interest_fx = X1.upper_cut_off_freq_of_interest_fx;
     168           0 :     move16();
     169           0 :     tmp->upper_cut_off_freq_fx = X1.upper_cut_off_freq_fx;
     170           0 :     move16();
     171           0 :     return;
     172             : }
     173             : /*-------------------------------------------------------------------*
     174             :  * DTFS_fast_fs_inv()
     175             :  *
     176             :  * DTFS inverse.
     177             :  *-------------------------------------------------------------------*/
     178             : 
     179           0 : static void DTFS_fast_fs_inv_fx( DTFS_STRUCTURE *X_fx, Word16 *out_fx /* Q0 */, Word16 N_fx, Word16 LOG2N )
     180             : {
     181             :     Word16 i, M_2, N_2, s;
     182             :     Word16 dbuf_fx[256 + 1];
     183             : 
     184           0 :     M_2 = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
     185           0 :     N_2 = shr( N_fx, 1 );
     186           0 :     s = negate( X_fx->Q );
     187             : 
     188           0 :     dbuf_fx[0] = X_fx->a_fx[0];
     189           0 :     move16();
     190           0 :     dbuf_fx[1] = 0;
     191           0 :     move16();
     192             : 
     193           0 :     FOR( i = 1; i <= M_2; i++ )
     194             :     {
     195           0 :         dbuf_fx[2 * i] = shl_r( X_fx->a_fx[i], s );
     196           0 :         move16();
     197           0 :         dbuf_fx[( 2 * i + 1 )] = shl_r( X_fx->b_fx[i], s );
     198           0 :         move16();
     199             :     }
     200             : 
     201           0 :     FOR( ; i < N_2; i++ )
     202             :     {
     203           0 :         dbuf_fx[2 * i] = 0;
     204           0 :         move16();
     205           0 :         dbuf_fx[( 2 * i + 1 )] = 0;
     206           0 :         move16();
     207             :     }
     208             : 
     209             :     /*  do IFFT */
     210           0 :     r_fft_4_fx( dbuf_fx, N_fx, sub( LOG2N, 1 ), -1 );
     211             : 
     212           0 :     FOR( i = 0; i < N_fx; i++ )
     213             :     {
     214           0 :         out_fx[i] = dbuf_fx[i]; /* Q0 */
     215           0 :         move16();
     216             :     }
     217           0 : }
     218             : 
     219             : 
     220             : /*===================================================================*/
     221             : /* FUNCTION      :  DTFS_alignment_weight_fx ()                      */
     222             : /*-------------------------------------------------------------------*/
     223             : /* PURPOSE       :  search for alignment                             */
     224             : /*-------------------------------------------------------------------*/
     225             : /* INPUT ARGUMENTS  :                                                */
     226             : /*   _ (struct DTFS_STRUCTURE) X1_fx :  a/b in X1.Q               */
     227             : /*   _ (struct DTFS_STRUCTURE) X2_fx :  a/b in X2.Q               */
     228             : /*   _ (Word16) Eshift: Q7                                           */
     229             : /*   _ (Word16 *) LPC1:  lpc coefficients. Q12                       */
     230             : /*   _ (Word16 *) LPC2:  lpc coefficients. Q12                       */
     231             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
     232             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
     233             : /*-------------------------------------------------------------------*/
     234             : /* OUTPUT ARGUMENTS :                                                */
     235             : /*   _ (Word16) fshift_fx :           Q7                             */
     236             : /*-------------------------------------------------------------------*/
     237             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     238             : /*                    _ None                                         */
     239             : /*-------------------------------------------------------------------*/
     240             : /* RETURN ARGUMENTS : _ None.                                        */
     241             : /*-------------------------------------------------------------------*/
     242             : /* CALLED FROM : TX/RX                                               */
     243             : /*===================================================================*/
     244             : 
     245           0 : static Word16 DTFS_alignment_weight_fx(
     246             :     DTFS_STRUCTURE *X_fx, /* i  : X1 the reference DTFS to keep fixed          */
     247             :     DTFS_STRUCTURE X2,    /* i  : X2 the test DTFS to shift to find best match */
     248             :     Word16 Eshift,        /* i  : Expected shift - coarse value                */
     249             :     const Word16 *LPC1,   /* i  : LPC to filter to find correlation in spch    */
     250             :     const Word16 *LPC2,   /* i  : LPC to filter to find correlation in spch    */
     251             :     Word16 *S_fx,
     252             :     Word16 *C_fx,
     253             :     Word16 *pf_temp1,
     254             :     Word16 *pf_temp2,
     255             :     Word16 *pf_temp,
     256             :     Word16 *pf_n2 )
     257             : {
     258             :     /* Eshift is w.r.t  X2  */
     259             :     Word16 k, HalfLag, start, end, ab1[MAXLAG_WI], ab2[MAXLAG_WI];
     260             :     Word32 corr_fx;
     261             :     Word32 maxcorr_fx, wcorr_fx, diff_corr;
     262             :     DTFS_STRUCTURE X1;
     263             :     Word16 temp, temp1, Qcorr, Qmaxcorr, inv_lag, n_fx, diff_fx, fshift_fx, Adiff_fx;
     264             :     Word16 tmplpc_fx[M + 1];
     265             :     Word16 exp, tmp;
     266             :     Word32 L_tmp;
     267           0 :     diff_fx = 0; /* to avoid compilation warnings */
     268           0 :     move16();
     269             : 
     270           0 :     DTFS_copy_fx( &X1, *X_fx ); /* X1 = *X_fx ; */
     271           0 :     DTFS_adjustLag_fx( &X1, X2.lag_fx );
     272             : 
     273             :     /*  PORTING: Handling the functions with variable no. of arguments */
     274           0 :     poleFilter_setup_fx( LPC1, add( M, 1 ), X1, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 );
     275           0 :     DTFS_poleFilter_fx_9( &X1, pf_temp1, pf_temp2, pf_temp, pf_n2 );
     276           0 :     FOR( k = 0; k < M + 1; k++ )
     277             :     {
     278           0 :         tmplpc_fx[k] = mult_r( LPC1[k], pwf_fx[k] ); /*  Q12 */
     279           0 :         move16();
     280             :     }
     281           0 :     DTFS_zeroFilter_fx( &X1, tmplpc_fx, M + 1, S_fx, C_fx );
     282             : 
     283             :     /*  PORTING: Handling the functions with variable no. of arguments */
     284           0 :     poleFilter_setup_fx( LPC2, add( M, 1 ), X2, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 );
     285           0 :     DTFS_poleFilter_fx_9( &X2, pf_temp1, pf_temp2, pf_temp, pf_n2 );
     286           0 :     FOR( k = 0; k < M + 1; k++ )
     287             :     {
     288           0 :         tmplpc_fx[k] = mult_r( LPC2[k], pwf_fx[k] ); /*  Q12 */
     289           0 :         move16();
     290             :     }
     291           0 :     DTFS_zeroFilter_fx( &X2, tmplpc_fx, M + 1, S_fx, C_fx );
     292             : 
     293           0 :     maxcorr_fx = L_add( MIN_32, 0 );
     294           0 :     Qmaxcorr = 0;
     295           0 :     move16();
     296           0 :     fshift_fx = Eshift;
     297           0 :     move16();
     298           0 :     Adiff_fx = s_max( 768, mult_r( 4915, shl( X2.lag_fx, 7 ) ) ); /*  Q7, 768=6*128, 4915 = 0.15*32768 */
     299             : 
     300           0 :     if ( LT_16( X2.lag_fx, 60 ) )
     301             :     {
     302           0 :         diff_fx = 32;
     303           0 :         move16(); /*  Q7 of 0.25 */
     304             :     }
     305           0 :     if ( GE_16( X2.lag_fx, 60 ) )
     306             :     {
     307           0 :         diff_fx = 64;
     308           0 :         move16(); /*  Q7 of 0.5 */
     309             :     }
     310             : 
     311           0 :     HalfLag = s_min( shr( X2.lag_fx, 1 ), X2.nH_4kHz_fx );
     312           0 :     exp = norm_s( X2.lag_fx );
     313           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), X2.lag_fx );
     314           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
     315           0 :     inv_lag = round_fx( L_tmp );
     316             : 
     317           0 :     FOR( k = 0; k <= HalfLag; k++ )
     318             :     {
     319           0 :         ab1[k] = round_fx_sat( L_mac0_sat( L_mult0( X1.a_fx[k], X2.a_fx[k] ), X1.b_fx[k], X2.b_fx[k] ) ); /*  Q(-15) */
     320           0 :         ab2[k] = round_fx_sat( L_msu0_sat( L_mult0( X1.a_fx[k], X2.b_fx[k] ), X1.b_fx[k], X2.a_fx[k] ) ); /*  Q(-15) */
     321           0 :         move16();
     322           0 :         move16();
     323             :     }
     324             : 
     325           0 :     start = sub( Eshift, Adiff_fx );
     326           0 :     end = add( Eshift, Adiff_fx );
     327             : 
     328           0 :     FOR( n_fx = start; n_fx <= end; n_fx += diff_fx )
     329             :     {
     330             :         /*  Q7 */
     331           0 :         corr_fx = L_deposit_l( 0 );
     332           0 :         temp = 0;
     333           0 :         move16();
     334           0 :         temp1 = round_fx( L_shr( L_mult( inv_lag, n_fx ), 2 ) ); /*  Q(19+7+1-2-16)=Q9 of n/X2.lag */
     335             : 
     336           0 :         if ( temp1 < 0 )
     337             :         {
     338           0 :             temp1 = add( temp1, 0x200 ); /*  avoid negative, 0x200 is Q9 of 1 ( 2*pi ) */
     339             :         }
     340             : 
     341           0 :         FOR( k = 0; k <= HalfLag; k++ )
     342             :         {
     343           0 :             corr_fx = L_mac0_sat( corr_fx, ab1[k], cos_table[s_and( temp, 511 )] );
     344           0 :             corr_fx = L_mac0_sat( corr_fx, ab2[k], cos_table[s_and( add( temp, 128 ), 511 )] );
     345           0 :             move32();
     346           0 :             move32();
     347           0 :             temp = add( temp, temp1 );
     348             :         }
     349           0 :         temp = sub( 8192, mult_r( 20972, abs_s( sub( n_fx, Eshift ) ) ) ); /*  Q13, 20972 = Q21 of 0.01. */
     350           0 :         Qcorr = norm_l( corr_fx );
     351           0 :         if ( corr_fx == 0 )
     352             :         {
     353           0 :             Qcorr = 31;
     354           0 :             move16();
     355             :         }
     356             : 
     357           0 :         temp1 = round_fx_sat( (Word32) L_shl_sat( corr_fx, Qcorr ) );                          /*  Q(Qcorr-16) */
     358           0 :         wcorr_fx = L_mult_sat( temp1, shl_sat( temp, 2 ) ); /*  Q(Qcorr-16+13+2+1)=Q(Qcorr) */ //!!sat
     359           0 :         IF( GE_16( Qmaxcorr, Qcorr ) )
     360             :         {
     361           0 :             diff_corr = L_sub_sat( wcorr_fx, L_shl_sat( maxcorr_fx, sub( Qcorr, Qmaxcorr ) ) ); /*  Qcorr */
     362             :         }
     363             :         ELSE
     364             :         {
     365           0 :             diff_corr = L_sub_sat( L_shl_sat( wcorr_fx, sub( Qmaxcorr, Qcorr ) ), maxcorr_fx ); /*  Qmaxcorr */
     366             :         }
     367             : 
     368           0 :         IF( diff_corr > 0 )
     369             :         {
     370           0 :             fshift_fx = n_fx;
     371           0 :             move16();
     372           0 :             maxcorr_fx = L_add( wcorr_fx, 0 );
     373           0 :             Qmaxcorr = Qcorr;
     374           0 :             move16();
     375             :         }
     376             :     }
     377             : 
     378           0 :     return fshift_fx;
     379             : }
     380             : 
     381             : 
     382             : /*===========================================================================*/
     383             : /* FUNCTION      :  DTFS_alignment_full_fx ()                                     */
     384             : /*---------------------------------------------------------------------------*/
     385             : /* PURPOSE       :  search for alignment                                     */
     386             : /*---------------------------------------------------------------------------*/
     387             : /* INPUT ARGUMENTS  :                                                        */
     388             : /*   _ (struct DTFS_STRUCTURE) X1_DTFS_fx :  a_fx/b_fx in X1_DTFS_fx.Q    */
     389             : /*   _ (struct DTFS_STRUCTURE) X2_DTFS_fx :  a_fx/b_fx in X2_DTFS_fx.Q    */
     390             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                        */
     391             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                        */
     392             : /*---------------------------------------------------------------------------*/
     393             : /* OUTPUT ARGUMENTS :                                                        */
     394             : /*   _ (Word16) fshift_fx :           Q1                                     */
     395             : /*---------------------------------------------------------------------------*/
     396             : /* INPUT/OUTPUT ARGUMENTS :                                                  */
     397             : /*                    _ None                                                 */
     398             : /*---------------------------------------------------------------------------*/
     399             : /* RETURN ARGUMENTS : _ None.                                                */
     400             : /*---------------------------------------------------------------------------*/
     401             : /* CALLED FROM : TX                                                          */
     402             : /*===========================================================================*/
     403             : 
     404           0 : Word16 DTFS_alignment_full_fx(
     405             :     DTFS_STRUCTURE X1_DTFS_fx,
     406             :     DTFS_STRUCTURE X2_DTFS_fx,
     407             :     Word16 ph_offset_fx,
     408             :     Word16 *S_fx,
     409             :     Word16 *C_fx,
     410             :     Word16 FR_flag )
     411             : {
     412             :     Word16 temp, temp1, k, start, end, HalfLag, ab1[MAXLAG_WI], ab2[MAXLAG_WI];
     413             :     Word16 n, fshift_fx;
     414             :     Word32 corr_fx, maxcorr_fx;
     415             :     Word16 Eshift, Adiff_fx;
     416             : 
     417             :     /* Calculating the expected alignment shift */
     418           0 :     Eshift = mult_r( ph_offset_fx, shl( X2_DTFS_fx.lag_fx, 7 ) ); /* confirmed I<2 by smv12.org, Q7 */
     419           0 :     find_rem( (Word16) L_FRAME, shr( add( X2_DTFS_fx.lag_fx, X1_DTFS_fx.lag_fx ), 1 ), &temp );
     420           0 :     temp = add_sat( shl( temp, 7 ), Eshift ); /*  Q7 */
     421           0 :     IF( temp < 0 )
     422             :     {
     423           0 :         temp = add_sat( temp, shl_sat( X1_DTFS_fx.lag_fx, 7 ) ); /*  Q7 */
     424             :     }
     425           0 :     find_rem( temp, shl( X1_DTFS_fx.lag_fx, 7 ), &Eshift ); /*  Q7 */
     426           0 :     Eshift = shl( shr( Eshift, 7 ), 1 );                    /* Q1 but integer */
     427             : 
     428           0 :     IF( GT_16( X2_DTFS_fx.lag_fx, 60 ) )
     429             :     {
     430           0 :         Adiff_fx = shl( X2_DTFS_fx.lag_fx, 1 - 3 ); /* lag_fx/8 in Q1 */
     431             :     }
     432             :     ELSE
     433             :     {
     434           0 :         Adiff_fx = shl( X2_DTFS_fx.lag_fx, 1 - 2 ); /* lag_fx/4 in Q1 */
     435             :     }
     436             : 
     437             : 
     438           0 :     IF( LT_16( X1_DTFS_fx.lag_fx, X2_DTFS_fx.lag_fx ) )
     439             :     {
     440           0 :         DTFS_zeroPadd_fx( X2_DTFS_fx.lag_fx, &X1_DTFS_fx );
     441             :     }
     442             : 
     443           0 :     maxcorr_fx = L_add( MIN_32, 0 );
     444           0 :     HalfLag = s_min( shr( X2_DTFS_fx.lag_fx, 1 ), X2_DTFS_fx.nH_4kHz_fx );
     445             : 
     446           0 :     FOR( k = 0; k <= HalfLag; k++ )
     447             :     {
     448           0 :         ab1[k] = round_fx_sat( L_mac_sat( L_mult_sat( X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k] ), X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k] ) ); /*  Q(-15); */
     449           0 :         ab2[k] = round_fx_sat( L_msu_sat( L_mult_sat( X1_DTFS_fx.b_fx[k], X2_DTFS_fx.a_fx[k] ), X1_DTFS_fx.a_fx[k], X2_DTFS_fx.b_fx[k] ) ); /*  Q(-15); */
     450             :     }
     451           0 :     IF( FR_flag == 0 )
     452             :     {
     453           0 :         start = sub( Eshift, Adiff_fx ); /*Q1*/
     454           0 :         end = add( Eshift, Adiff_fx );   /*Q1*/
     455             :     }
     456             :     ELSE
     457             :     {
     458             :         /*
     459             :         in FR mode, we cannot save and cary forward ph_offset as in VBR mode encoder "ph_offset_E_fx",
     460             :         so we set ph_offset_fx = 0, as a result we cannot accurately estimate the expected alignment shift Eshift to limit the search,
     461             :         so we search the full range [0 to X2_DTFS_fx.lag_fx] similar to FL
     462             :         */
     463           0 :         start = 0;                         /*Q1*/
     464           0 :         end = shl( X2_DTFS_fx.lag_fx, 1 ); /*Q1*/
     465             :     }
     466             : 
     467           0 :     fshift_fx = start;
     468           0 :     move16(); /*Q1*/
     469             : 
     470           0 :     FOR( n = start; n <= end; n++ ) /*n in Q1*/
     471             :     {
     472             :         /*  Q1 */
     473           0 :         corr_fx = L_deposit_l( 0 );
     474           0 :         temp = 0;
     475           0 :         move16();
     476           0 :         temp1 = add( n, shl( X2_DTFS_fx.lag_fx, 1 ) ); /* add lag_fx in Q1to make positive */
     477           0 :         FOR( k = 0; k <= HalfLag; k++ )
     478             :         {
     479           0 :             corr_fx = L_mac_sat( corr_fx, ab1[k], C_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )] );
     480           0 :             corr_fx = L_mac_sat( corr_fx, ab2[k], S_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )] );
     481           0 :             temp = add_sat( temp, temp1 );
     482             :         }
     483             : 
     484           0 :         IF( GT_32( corr_fx, maxcorr_fx ) )
     485             :         {
     486           0 :             fshift_fx = n; /*  Q1 */
     487           0 :             move16();
     488           0 :             maxcorr_fx = L_add( corr_fx, 0 );
     489             :         }
     490             :     }
     491             : 
     492           0 :     return fshift_fx; /*Q1*/
     493             : }
     494             : /*===================================================================*/
     495             : /* FUNCTION      :  DTFS_phaseShift_fx ()                                 */
     496             : /*-------------------------------------------------------------------*/
     497             : /* PURPOSE       :  Phase is shifted by 2pi*ph/Lag                   */
     498             : /*-------------------------------------------------------------------*/
     499             : /* INPUT ARGUMENTS  :                                                */
     500             : /*   _ (Word16) ph:    shift index, Q7                               */
     501             : /*   _ (Word16) Lag:   Pitch Lag value as for shift                  */
     502             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
     503             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
     504             : /*-------------------------------------------------------------------*/
     505             : /* OUTPUT ARGUMENTS :                                                */
     506             : /*   _ None.                                                         */
     507             : /*-------------------------------------------------------------------*/
     508             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     509             : /*   _ (struct DTFS_fx) X1 :  a/b in X1.Q                                   */
     510             : /*-------------------------------------------------------------------*/
     511             : /* RETURN ARGUMENTS : _ None.                                        */
     512             : /*-------------------------------------------------------------------*/
     513             : /* CALLED FROM : TX/RX                                               */
     514             : /*===================================================================*/
     515             : 
     516           0 : void DTFS_phaseShift_fx( DTFS_STRUCTURE *X_fx, Word16 ph, Word16 Lag, Word16 *S_fx, Word16 *C_fx )
     517             : {
     518             :     Word16 k;
     519             :     Word16 temp, HalfLag;
     520             :     Word32 L_temp, L_temp2;
     521             : 
     522           0 :     L_temp2 = L_deposit_l( 0 );
     523           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
     524             : 
     525           0 :     IF( ph > 0 )
     526             :     {
     527           0 :         FOR( k = 0; k <= HalfLag; k++ )
     528             :         {
     529           0 :             temp = X_fx->a_fx[k];
     530           0 :             L_temp = L_shr( L_temp2, 5 );                                                                                               /*  Q2 */
     531           0 :             X_fx->a_fx[k] = round_fx( L_msu( L_mult( temp, C_fx[L_temp % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[L_temp % ( 4 * Lag )] ) ); /*  X.Q */
     532           0 :             move16();
     533           0 :             X_fx->b_fx[k] = round_fx( L_mac( L_mult( X_fx->b_fx[k], C_fx[L_temp % ( 4 * Lag )] ), temp, S_fx[L_temp % ( 4 * Lag )] ) );
     534           0 :             move16();
     535           0 :             L_temp2 = L_add( L_temp2, ph );
     536             :         }
     537             :     }
     538             : 
     539           0 :     IF( ph < 0 )
     540             :     {
     541           0 :         FOR( k = 0; k <= HalfLag; k++ )
     542             :         {
     543           0 :             temp = X_fx->a_fx[k];
     544           0 :             L_temp = L_shr( L_negate( L_temp2 ), 5 );                                                                                   /*  Q2 */
     545           0 :             X_fx->a_fx[k] = round_fx( L_mac( L_mult( temp, C_fx[L_temp % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[L_temp % ( 4 * Lag )] ) ); /*  X.Q */
     546           0 :             move16();
     547           0 :             X_fx->b_fx[k] = round_fx( L_msu( L_mult( X_fx->b_fx[k], C_fx[L_temp % ( 4 * Lag )] ), temp, S_fx[L_temp % ( 4 * Lag )] ) );
     548           0 :             move16();
     549           0 :             L_temp2 = L_add( L_temp2, ph );
     550             :         }
     551             :     }
     552           0 :     return;
     553             : }
     554             : 
     555             : /*===================================================================*/
     556             : /* FUNCTION      :  Q2phaseShift_fx ()                               */
     557             : /*-------------------------------------------------------------------*/
     558             : /* PURPOSE       :  Phase is shifted by 2pi*ph/Lag                   */
     559             : /*-------------------------------------------------------------------*/
     560             : /* INPUT ARGUMENTS  :                                                */
     561             : /*   _ (Word16) ph:    shift index, Q2                               */
     562             : /*   _ (Word16) Lag:   Pitch Lag value as for shift                  */
     563             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
     564             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
     565             : /*-------------------------------------------------------------------*/
     566             : /* OUTPUT ARGUMENTS :                                                */
     567             : /*   _ None.                                                         */
     568             : /*-------------------------------------------------------------------*/
     569             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     570             : /*   _ (struct DTFS_STRUCTURE) X_fx :  a/b in X_fx->Q             */
     571             : /*-------------------------------------------------------------------*/
     572             : /* RETURN ARGUMENTS : _ None.                                        */
     573             : /*-------------------------------------------------------------------*/
     574             : /* CALLED FROM : TX/RX                                               */
     575             : /*===================================================================*/
     576             : 
     577           0 : void Q2phaseShift_fx(
     578             :     DTFS_STRUCTURE *X_fx,
     579             :     Word16 ph,
     580             :     Word16 Lag,
     581             :     Word16 *S_fx,
     582             :     Word16 *C_fx )
     583             : {
     584             :     Word16 k;
     585             :     Word16 temp, HalfLag;
     586             :     Word32 temp2;
     587           0 :     temp2 = L_deposit_l( 0 );
     588             : 
     589           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
     590             : 
     591             : 
     592           0 :     IF( ph > 0 )
     593             :     {
     594           0 :         FOR( k = 0; k <= HalfLag; k++ )
     595             :         {
     596           0 :             temp = X_fx->a_fx[k];
     597           0 :             X_fx->a_fx[k] = round_fx_sat( L_msu_sat( L_mult_sat( temp, C_fx[temp2 % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )] ) ); /*  X.Q */
     598           0 :             X_fx->b_fx[k] = round_fx_sat( L_mac_sat( L_mult_sat( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )] ), temp, S_fx[temp2 % ( 4 * Lag )] ) );
     599           0 :             temp2 = L_add_sat( temp2, (Word32) ph );
     600           0 :             move16();
     601           0 :             move16();
     602             :         }
     603             :     }
     604             : 
     605             : 
     606           0 :     IF( ph < 0 )
     607             :     {
     608           0 :         FOR( k = 0; k <= HalfLag; k++ )
     609             :         {
     610           0 :             temp = X_fx->a_fx[k];
     611           0 :             X_fx->a_fx[k] = round_fx_sat( L_mac_sat( L_mult_sat( temp, C_fx[temp2 % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )] ) ); /*  X.Q */
     612           0 :             X_fx->b_fx[k] = round_fx_sat( L_msu_sat( L_mult_sat( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )] ), temp, S_fx[temp2 % ( 4 * Lag )] ) );
     613           0 :             temp2 = add_sat( (Word16) temp2, negate( ph ) );
     614           0 :             move16();
     615           0 :             move16();
     616             :         }
     617             :     }
     618           0 : }
     619             : /*===================================================================*/
     620             : /* FUNCTION      :  DTFS_zeroPadd_fx ()                              */
     621             : /*-------------------------------------------------------------------*/
     622             : /* PURPOSE       :  zeroPadding                                      */
     623             : /*-------------------------------------------------------------------*/
     624             : /* INPUT ARGUMENTS  :                                                */
     625             : /*   _ (Word16) N_fx:    length  , Q0                                */
     626             : /*-------------------------------------------------------------------*/
     627             : /* OUTPUT ARGUMENTS :                                                */
     628             : /*   _ None.                                                         */
     629             : /*-------------------------------------------------------------------*/
     630             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     631             : /*   _ (struct DTFS_STRUCTURE) X_fx :  a/b in X_fx.Q i.e Q6       */
     632             : /*   _ (Word16) lag: pitch lag of *X_fx, Q0                          */
     633             : /*-------------------------------------------------------------------*/
     634             : /* RETURN ARGUMENTS : _ None.                                        */
     635             : /*-------------------------------------------------------------------*/
     636             : /* CALLED FROM : TX/RX                                               */
     637             : /*===================================================================*/
     638             : 
     639           0 : void DTFS_zeroPadd_fx(
     640             :     Word16 N_fx,
     641             :     DTFS_STRUCTURE *X_fx )
     642             : {
     643             :     Word16 i, start, end, diff_fx, rem_fx;
     644             : 
     645           0 :     IF( EQ_16( N_fx, X_fx->lag_fx ) )
     646             :     {
     647           0 :         return;
     648             :     }
     649           0 :     start = add( shr( X_fx->lag_fx, 1 ), 1 );
     650           0 :     end = shr( N_fx, 1 );
     651             : 
     652           0 :     move16();
     653           0 :     FOR( i = start; i <= end; i++ )
     654             :     {
     655           0 :         X_fx->a_fx[i] = 0;
     656           0 :         move16();
     657           0 :         X_fx->b_fx[i] = 0;
     658           0 :         move16();
     659             :     }
     660             : 
     661           0 :     X_fx->lag_fx = N_fx;
     662           0 :     move16();
     663             : 
     664             :     /* recompute nH for new lag */
     665           0 :     diff_fx = find_rem( 12800, X_fx->lag_fx, &rem_fx );
     666           0 :     X_fx->nH_fx = find_rem( X_fx->upper_cut_off_freq_fx, diff_fx, &rem_fx );
     667           0 :     move16();
     668             : 
     669           0 :     if ( GE_16( sub( X_fx->upper_cut_off_freq_fx, shr( extract_l( L_mult( diff_fx, X_fx->nH_fx ) ), 1 ) ), diff_fx ) )
     670             :     {
     671           0 :         X_fx->nH_fx = add( X_fx->nH_fx, 1 );
     672           0 :         move16();
     673             :     }
     674             : }
     675             : /*===================================================================*/
     676             : /* FUNCTION      :  to_fs_fx ()                                      */
     677             : /*-------------------------------------------------------------------*/
     678             : /* PURPOSE       :                                                   */
     679             : /*-------------------------------------------------------------------*/
     680             : /* INPUT ARGUMENTS  :                                                */
     681             : /*   _ (Word16 *) x:    input time domain series. Q0                 */
     682             : /*   _ (Word16) N:    Lag                                            */
     683             : /*   _ (struct DTFS_STRUCTURE) PREVCW_FX: a/b in PREVCW_FX.Q      */
     684             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
     685             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
     686             : /*-------------------------------------------------------------------*/
     687             : /* OUTPUT ARGUMENTS :                                                */
     688             : /*   _ (struct DTFS_STRUCTURE) (Word16 a[]) :  in Q               */
     689             : /*   _ (struct DTFS_STRUCTURE) (Word16 b[]) :  in Q               */
     690             : /*   _ (struct DTFS_STRUCTURE) (Word16 lag) :  Q0                 */
     691             : /*   _ (struct DTFS_STRUCTURE) (Word16 Q  ) :  Q value of a/b     */
     692             : /*-------------------------------------------------------------------*/
     693             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     694             : /*   _ None.                                                         */
     695             : /*-------------------------------------------------------------------*/
     696             : /* RETURN ARGUMENTS : _ None.                                        */
     697             : /*-------------------------------------------------------------------*/
     698             : /* CALLED FROM : TX/RX                                               */
     699             : /*===================================================================*/
     700           0 : void DTFS_to_fs_fx(
     701             :     const Word16 *x,      /* i : time domain signal               */
     702             :     Word16 N,             /* i : Length of input vector           */
     703             :     DTFS_STRUCTURE *X_fx, /* o : DTFS structure with a, b, lag    */
     704             :     const Word16 Fs,      /* i : sampling rate                    */
     705             :     const Word16 FR_flag, /* i :  FR flag                         */
     706             :     Word16 *S_fx,
     707             :     Word16 *C_fx )
     708             : 
     709             : {
     710             :     Word16 n, temp, temp_neg, inv_lag, sum, diff_fx;
     711             :     Word16 nH, k, nH_band, nH_4kHz;
     712             :     Word32 L_temp, Lx0;
     713             :     Word32 L_a, L_b, L_tmp;
     714             :     Word32 La[MAXLAG_WI], Lb[MAXLAG_WI], Labmax;
     715             :     Word16 exp, tmp;
     716             :     Word32 L_tmp1;
     717             : 
     718           0 :     IF( !FR_flag )
     719             :     {
     720           0 :         IF( EQ_16( Fs, 16000 ) )
     721             :         {
     722           0 :             X_fx->upper_cut_off_freq_of_interest_fx = 4000;
     723           0 :             move16();
     724           0 :             X_fx->upper_cut_off_freq_fx = 6400;
     725           0 :             move16();
     726           0 :             X_fx->Fs_fx = INT_FS_FX;
     727           0 :             move16();
     728             :         }
     729           0 :         ELSE IF( EQ_16( Fs, 8000 ) )
     730             :         {
     731           0 :             X_fx->upper_cut_off_freq_of_interest_fx = 3300;
     732           0 :             move16();
     733           0 :             X_fx->upper_cut_off_freq_fx = 4000;
     734           0 :             move16();
     735           0 :             X_fx->Fs_fx = INT_FS_FX;
     736           0 :             move16();
     737             :         }
     738             :     }
     739             :     ELSE
     740             :     {
     741           0 :         X_fx->upper_cut_off_freq_of_interest_fx = 8000;
     742           0 :         move16();
     743           0 :         X_fx->upper_cut_off_freq_fx = 8000;
     744           0 :         move16();
     745           0 :         X_fx->Fs_fx = 16000;
     746           0 :         move16();
     747             :     }
     748           0 :     X_fx->lag_fx = N;
     749           0 :     move16();
     750             : 
     751           0 :     exp = norm_s( X_fx->lag_fx );
     752           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx->lag_fx );      /* Q29-exp */
     753           0 :     L_tmp1 = L_mult( 12800, tmp );                              /* Q(30-exp) */
     754           0 :     diff_fx = extract_h( L_shl_sat( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */
     755             : 
     756           0 :     exp = norm_s( diff_fx );
     757           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), diff_fx );           /* Q29-exp */
     758           0 :     L_tmp1 = L_mult_sat( X_fx->upper_cut_off_freq_fx, tmp );    /* Q(30-exp) */
     759           0 :     nH_band = extract_h( L_shl_sat( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */
     760           0 :     nH_4kHz = mult( 10240, ( X_fx->lag_fx ) );                  /* 4000/12800 in Q15 */
     761             : 
     762           0 :     if ( GE_16( sub( X_fx->upper_cut_off_freq_fx, shr( (Word16) L_mult( diff_fx, nH_band ), 1 ) ), diff_fx ) )
     763             :     {
     764           0 :         nH_band = add( nH_band, 1 );
     765             :     }
     766             : 
     767           0 :     if ( GE_16( sub( 4000, shr( (Word16) L_mult( diff_fx, nH_4kHz ), 1 ) ), diff_fx ) )
     768             :     {
     769           0 :         nH_4kHz = add( nH_4kHz, 1 );
     770             :     }
     771             : 
     772             :     /* Number of harmonics excluding the ones at 0 and at pi */
     773           0 :     nH = shr( sub( N, 1 ), 1 );
     774             : 
     775             :     /* The DC component */
     776           0 :     X_fx->a_fx[0] = 0;
     777           0 :     move16();
     778           0 :     X_fx->b_fx[0] = 0;
     779           0 :     move16();
     780             : 
     781           0 :     exp = norm_s( N );
     782           0 :     tmp = div_s( shl( 1, ( sub( 14, exp ) ) ), N );
     783           0 :     L_tmp = L_shl_sat( tmp, add( exp, 6 ) );
     784           0 :     inv_lag = round_fx_sat( L_tmp );
     785           0 :     Lx0 = L_deposit_h( x[0] );
     786           0 :     Labmax = L_deposit_l( 0 );
     787           0 :     FOR( k = 1; k <= nH; k++ )
     788             :     {
     789           0 :         L_a = L_shr( Lx0, 1 ); /*  Q16 */
     790             : 
     791           0 :         L_b = L_deposit_l( 0 );
     792           0 :         sum = k;
     793           0 :         move16();
     794           0 :         temp = k;
     795           0 :         move16();
     796           0 :         FOR( n = 1; n < N; n++ )
     797             :         {
     798           0 :             L_a = L_mac0_sat( L_a, x[n], C_fx[( 4 * sum ) % ( 4 * N )] ); /*  Q16 of x[n]*cos(sum) */
     799           0 :             L_b = L_mac0_sat( L_b, x[n], S_fx[( 4 * sum ) % ( 4 * N )] ); /*  Q16 of x[n]*sin(sum) */
     800           0 :             sum = add( sum, temp );
     801             :         }
     802           0 :         La[k] = L_shr( L_a, 6 ); /*  Q8 of a[k]*2.0 */
     803           0 :         move32();
     804           0 :         Lb[k] = L_shr( L_b, 6 ); /*  Q8 of b[k]*2.0 */
     805           0 :         move32();
     806             : 
     807           0 :         L_temp = L_abs( La[k] );
     808             : 
     809           0 :         if ( GT_32( L_temp, Labmax ) )
     810             :         {
     811           0 :             Labmax = L_temp;
     812           0 :             move32();
     813             :         }
     814           0 :         L_temp = L_abs( Lb[k] );
     815             : 
     816           0 :         if ( GT_32( L_temp, Labmax ) )
     817             :         {
     818           0 :             Labmax = L_temp;
     819           0 :             move32();
     820             :         }
     821             :     }
     822             : 
     823             : 
     824             :     /* The harmonic at 'pi' */
     825             : 
     826             :     /* IF ( N%2 == 0 )  */
     827           0 :     IF( s_and( N, 1 ) == 0 )
     828             :     {
     829             : 
     830           0 :         L_a = L_deposit_l( 0 );
     831           0 :         temp = 1;
     832           0 :         move16();
     833           0 :         temp_neg = negate( temp );
     834           0 :         FOR( n = 0; n < N - 1; n += 2 )
     835             :         {
     836           0 :             L_a = L_mac_sat( L_a, x[n], temp ); /*  Q1 */
     837           0 :             L_a = L_mac_sat( L_a, x[n + 1], temp_neg );
     838             :             /*temp= negate(temp); */
     839             :         }
     840           0 :         if ( s_and( N, 1 ) ) /*if N is odd we need to calculate last  */
     841             :         {
     842           0 :             L_a = L_mac_sat( L_a, x[n], temp ); /*  Q1 */
     843             :         }
     844             : 
     845           0 :         La[k] = L_shl( L_a, 7 );
     846           0 :         move32(); /*  Q8 of a[k]*1.0 */
     847             : 
     848             : 
     849           0 :         L_temp = L_abs( La[k] );
     850             : 
     851           0 :         if ( GT_32( L_temp, Labmax ) )
     852             :         {
     853           0 :             Labmax = L_add( L_temp, 0 );
     854             :         }
     855             : 
     856           0 :         X_fx->b_fx[k] = 0;
     857           0 :         move16();
     858             :     }
     859             : 
     860           0 :     temp = norm_l( Labmax );
     861           0 :     if ( Labmax == 0 )
     862             :     {
     863           0 :         temp = 31;
     864           0 :         move16();
     865             :     }
     866             : 
     867           0 :     FOR( k = 1; k <= nH; k++ )
     868             :     {
     869           0 :         X_fx->a_fx[k] = round_fx_sat( L_shl_sat( La[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */
     870           0 :         move16();
     871           0 :         X_fx->a_fx[k] = mult_r_sat( X_fx->a_fx[k], inv_lag );
     872           0 :         move16();                                                 /* Q(temp-8+19+1-16)=Q(temp-4) of a[k]*2.0/N */
     873           0 :         X_fx->b_fx[k] = round_fx_sat( L_shl_sat( Lb[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */
     874           0 :         move16();
     875           0 :         X_fx->b_fx[k] = mult_r_sat( X_fx->b_fx[k], inv_lag );
     876           0 :         move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of b[k]*2.0/N */
     877             :     }
     878             : 
     879             :     /* IF ( N%2 == 0 ) */
     880           0 :     IF( s_and( N, 1 ) == 0 )
     881             :     {
     882           0 :         X_fx->a_fx[k] = round_fx_sat( L_shl_sat( La[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */
     883           0 :         X_fx->a_fx[k] = mult_r_sat( X_fx->a_fx[k], inv_lag );
     884           0 :         move16();
     885           0 :         move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of a[k]*1.0/N */
     886           0 :         X_fx->b_fx[k] = 0;
     887           0 :         move16();
     888             :     }
     889             : 
     890           0 :     X_fx->Q = sub( temp, 4 );
     891           0 :     move16();
     892             : 
     893           0 :     tmp = s_min( shr( X_fx->lag_fx, 1 ), sub( MAXLAG_WI, 1 ) );
     894           0 :     FOR( k = ( nH_band + 1 ); k <= tmp; k++ )
     895             :     {
     896           0 :         X_fx->a_fx[k] = 0;
     897           0 :         move16();
     898           0 :         X_fx->b_fx[k] = 0;
     899           0 :         move16();
     900             :     }
     901           0 :     X_fx->nH_fx = nH_band;
     902           0 :     move16();
     903           0 :     X_fx->nH_4kHz_fx = nH_4kHz;
     904           0 :     move16();
     905           0 :     return;
     906             : }
     907             : 
     908             : 
     909             : /*===================================================================*/
     910             : /* FUNCTION      :  DTFS_transform_fx ()                             */
     911             : /*-------------------------------------------------------------------*/
     912             : /* PURPOSE       :                                                   */
     913             : /*-------------------------------------------------------------------*/
     914             : /* INPUT ARGUMENTS  :                                                */
     915             : /*   _ (struct DTFS_STRUCTURE) X_fx:     a/b in X1.Q, lag in Q0   */
     916             : /*   _ (struct DTFS_STRUCTURE) X2_fx. a/b in X2.Q, lag in Q0      */
     917             : /*   _ (Word16 *) phase_fx: 2pi normalized, Q12                      */
     918             : /*   _ (Word16) N:      length of series.                            */
     919             : /*-------------------------------------------------------------------*/
     920             : /* OUTPUT ARGUMENTS :                                                */
     921             : /*   _ (Word16 *) out_fx: output transformed series. Q0.             */
     922             : /*-------------------------------------------------------------------*/
     923             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     924             : /*   _ None.                                                         */
     925             : /*-------------------------------------------------------------------*/
     926             : /* RETURN ARGUMENTS : _ None.                                        */
     927             : /*-------------------------------------------------------------------*/
     928             : /* CALLED FROM : TX/RX                                               */
     929             : /*===================================================================*/
     930           0 : static void DTFS_transform_fx(
     931             :     DTFS_STRUCTURE X_fx,    /* i : Starting DTFS to use in WI    */
     932             :     DTFS_STRUCTURE X2_fx,   /* i : Ending DTFS to use in WI      */
     933             :     const Word32 *phase_fx, /* i : Phase contour                 */
     934             :     Word16 *out_fx,         /* o : Output time domain waveform   */
     935             :     Word16 N,               /* i : Number of samples to generate */
     936             :     const Word16 FR_flag    /* i : Flag to indicate called in FR context */
     937             : )
     938             : {
     939             : 
     940             :     Word16 i, j;
     941             :     Word32 L_temp_fx;
     942             :     Word16 w_fx;
     943             :     Word16 inv1_fx, inv2_fx, inv_fx, q1, q2;
     944             :     Word32 Lw_fx, temp32_fx;
     945             :     Word16 x2_256_fx[256], x1_256_fx[256];
     946             :     Word16 k, m, l1;
     947             :     Word32 x_r_fx[256];
     948             :     Word32 tmptmp3_40_fx;
     949             :     Word16 temp_w;
     950             :     Word16 N1;
     951           0 :     Word16 nrg_flag = 0;
     952           0 :     move16();
     953             :     Word32 L_tmp;
     954             :     Word16 tmp, tmp1, tmp2, frac, exp1, exp2;
     955             :     Word16 expa, expb, fraca, fracb, scale;
     956             : 
     957             :     ivas_error error;
     958             : 
     959             :     DTFS_STRUCTURE *tmp1_dtfs_fx;
     960             :     DTFS_STRUCTURE *tmp2_dtfs_fx;
     961             :     DTFS_STRUCTURE *tmp3_dtfs_fx;
     962             : 
     963           0 :     error = IVAS_ERR_OK;
     964           0 :     move16();
     965           0 :     set32_fx( x_r_fx, 0, 256 );
     966             : 
     967           0 :     IF( ( error = DTFS_new_fx( &tmp1_dtfs_fx ) ) != IVAS_ERR_OK )
     968             :     {
     969           0 :         IVAS_ERROR( error, "Error creating DTFS structure 1" );
     970             :     }
     971           0 :     IF( ( error = DTFS_new_fx( &tmp2_dtfs_fx ) ) != IVAS_ERR_OK )
     972             :     {
     973           0 :         IVAS_ERROR( error, "Error creating DTFS structure 2" );
     974             :     }
     975           0 :     IF( ( error = DTFS_new_fx( &tmp3_dtfs_fx ) ) != IVAS_ERR_OK )
     976             :     {
     977           0 :         IVAS_ERROR( error, "Error creating DTFS structure 3" );
     978             :     }
     979             : 
     980           0 :     DTFS_copy_fx( tmp1_dtfs_fx, X_fx );
     981           0 :     DTFS_copy_fx( tmp2_dtfs_fx, X2_fx );
     982             : 
     983           0 :     tmp2 = 0; /* to avoid compilation warnings */
     984           0 :     move16();
     985             : 
     986           0 :     DTFS_fast_fs_inv_fx( tmp1_dtfs_fx, x1_256_fx, 256, 8 );
     987           0 :     DTFS_fast_fs_inv_fx( tmp2_dtfs_fx, x2_256_fx, 256, 8 );
     988             : 
     989             : 
     990             :     /* L_temp_fx=invert_dp((Word40)N,4,&n,1);         = 1/M, Q(61-n) */
     991             :     /*    inv1_fx=round_fx(L_temp_fx);          = 1/M in Q(45-n) */
     992             :     /*    q1=sub(n,15); */
     993           0 :     exp1 = norm_s( N );
     994           0 :     inv1_fx = div_s( shl( 1, sub( 14, exp1 ) ), N ); /* 29-exp1 */
     995           0 :     q1 = add( exp1, 1 );
     996             : 
     997           0 :     tmp1 = sub( X_fx.lag_fx, N );
     998           0 :     exp2 = norm_s( tmp1 );
     999             : 
    1000           0 :     if ( tmp1 < 0 )
    1001             :     {
    1002           0 :         tmp2 = negate( tmp1 );
    1003             :     }
    1004           0 :     tmp = div_s( shl( 1, sub( 14, exp2 ) ), tmp2 ); /* 29-exp2 */
    1005           0 :     L_tmp = L_shl( tmp, 16 );
    1006             : 
    1007           0 :     if ( tmp1 < 0 )
    1008             :     {
    1009           0 :         L_tmp = L_negate( L_tmp );
    1010             :     }
    1011             : 
    1012           0 :     q2 = sub( exp2, 3 );
    1013             : 
    1014             : 
    1015             :     /*L_temp_fx=(Word32) Mpy_32_16(extract_h(L_tmp),extract_l(L_tmp),22904); move32(); */ /*  L_temp=log(0.2)*log10(e)/(lag-M), Q(61-n) */
    1016           0 :     L_temp_fx = Mult_32_16( L_tmp, 22904 );                                               /*  L_temp=log(0.2)*log10(e)/(lag-M), Q(61-n) */
    1017           0 :     inv2_fx = round_fx( L_temp_fx );                                                      /*  log(0.2)*log10(e)/(lag-M), Q(45-n) */
    1018             :     /* q2=sub(n,19);  */                                                                  /* adjust Q factor to Q26 */
    1019             : 
    1020             : 
    1021           0 :     IF( GT_16( sub( N, WI_SAMPLE_THLD ), X_fx.lag_fx ) )
    1022             :     {
    1023           0 :         inv_fx = inv2_fx;
    1024           0 :         move16();
    1025             :     }
    1026             :     ELSE
    1027             :     {
    1028           0 :         inv_fx = inv1_fx;
    1029           0 :         move16();
    1030           0 :         exp2 = exp1;
    1031           0 :         move16();
    1032             :     }
    1033             : 
    1034           0 :     Lw_fx = L_deposit_l( inv_fx );
    1035             : 
    1036           0 :     FOR( i = 0; i < N; i++ )
    1037             :     {
    1038           0 :         IF( FR_flag == 0 )
    1039             :         {
    1040           0 :             IF( GT_16( sub( N, WI_SAMPLE_THLD ), X_fx.lag_fx ) )
    1041             :             {
    1042             : 
    1043           0 :                 L_tmp = L_shl( Lw_fx, q2 );                                          /* Q29-exp2+q2     */
    1044           0 :                 L_tmp = Mult_32_16( L_tmp, 27213 ); /* 3.321928 in Q13 -> 16+13+1 */ /*27-exp2 */
    1045           0 :                 L_tmp = L_shl( L_tmp, sub( exp2, add( q2, 11 ) ) );
    1046           0 :                 frac = L_Extract_lc( L_tmp, &exp1 ); /* Extract exponent  */
    1047           0 :                 L_temp_fx = Pow2( 14, frac );
    1048           0 :                 exp1 = sub( exp1, 14 );
    1049           0 :                 L_temp_fx = L_shl( L_temp_fx, add( exp1, 15 ) ); /* Q15 */
    1050             : 
    1051           0 :                 w_fx = sub( 16384, extract_h( L_shl( L_temp_fx, 15 ) ) ); /*  w_fx in Q14 1- exp(- (i+1) * log(.2)/(lag-M)) */
    1052             :             }
    1053             :             ELSE
    1054             :             {
    1055           0 :                 w_fx = round_fx( L_shl( Lw_fx, q1 ) ); /*  Q14 */
    1056             :             }
    1057             :         }
    1058             :         ELSE
    1059             :         {
    1060           0 :             IF( nrg_flag )
    1061             :             {
    1062           0 :                 w_fx = round_fx( L_shl( Lw_fx, q1 ) ); /*  Q14 */
    1063             :             }
    1064             :             ELSE
    1065             :             {
    1066             : 
    1067           0 :                 N1 = sub( N, tmp2_dtfs_fx->lag_fx );
    1068             : 
    1069           0 :                 IF( LT_16( i, N1 ) )
    1070             :                 /*   w =  (i+1)/N1;  */
    1071             :                 {
    1072             : 
    1073             :                     /* w =  (i+1)/N1; */
    1074           0 :                     IF( N1 )
    1075             :                     {
    1076           0 :                         expa = norm_s( N1 );
    1077           0 :                         fraca = shl( N1, expa );
    1078           0 :                         expa = sub( 14, expa );
    1079             : 
    1080           0 :                         tmp = add( i, 1 );
    1081           0 :                         expb = norm_s( tmp );
    1082           0 :                         fracb = shl( tmp, expb );
    1083           0 :                         expb = sub( 14, expb );
    1084             : 
    1085           0 :                         scale = shr( sub( fraca, fracb ), 15 );
    1086           0 :                         fracb = shl( fracb, scale );
    1087           0 :                         expb = sub( expb, scale );
    1088             : 
    1089           0 :                         w_fx = div_s( fracb, fraca );
    1090           0 :                         exp1 = sub( expb, expa );
    1091           0 :                         w_fx = shl( w_fx, sub( exp1, 1 ) ); /*Q14*/
    1092             :                     }
    1093             :                     ELSE
    1094             :                     {
    1095           0 :                         w_fx = 0;
    1096           0 :                         move16();
    1097             :                     }
    1098             : 
    1099           0 :                     Lw_fx = L_deposit_h( w_fx );
    1100             :                 }
    1101             :                 ELSE
    1102             :                 {
    1103           0 :                     w_fx = 16384; // 1.Q14
    1104           0 :                     move16();
    1105             :                 }
    1106             :             }
    1107             :         }
    1108             : 
    1109           0 :         Lw_fx = L_add( Lw_fx, inv_fx ); /*  (i+1)*inv */
    1110             :         /* mapping phase to 8x256 length signal */
    1111           0 :         temp32_fx = phase_fx[i]; /* Q(27-11)=Q16 due to multiplication by pow(2.0,11) */
    1112           0 :         move32();
    1113           0 :         j = rint_new_fx( temp32_fx );
    1114           0 :         j = s_and( j, 0x07ff );
    1115             : 
    1116             :         /*   k=j%8; */
    1117           0 :         k = s_and( j, 7 );
    1118           0 :         l1 = shr( j, 3 ); /* reminder and quotient */
    1119             : 
    1120           0 :         temp_w = sub( 16384, w_fx );
    1121           0 :         tmptmp3_40_fx = L_deposit_l( 0 );
    1122             : 
    1123           0 :         FOR( j = 0; j < 12; j++ )
    1124             :         {
    1125           0 :             m = L_add( 1000 * LL - OSLENGTH / 2, add( l1, j ) ) % LL; /* use circular addressing */
    1126           0 :             x_r_fx[m] = L_mac( L_mult( x1_256_fx[m], temp_w ), x2_256_fx[m], w_fx );
    1127           0 :             move32();
    1128             :         }
    1129           0 :         tmptmp3_40_fx = L_deposit_l( 0 );
    1130             : 
    1131             : 
    1132           0 :         FOR( j = 0; j < 12; j++ )
    1133             :         {
    1134           0 :             m = L_add( 1000 * LL - OSLENGTH / 2, add( l1, j ) ) % LL; /* use circular addressing */
    1135           0 :             tmptmp3_40_fx = L_add( tmptmp3_40_fx, Mult_32_16( x_r_fx[m], sinc_fx[k][j] ) );
    1136             :         }
    1137           0 :         out_fx[i] = round_fx_sat( L_shl_sat( tmptmp3_40_fx, 2 ) );
    1138           0 :         move16();
    1139             :     }
    1140             : 
    1141             : 
    1142           0 :     free( tmp1_dtfs_fx );
    1143           0 :     free( tmp2_dtfs_fx );
    1144           0 :     free( tmp3_dtfs_fx );
    1145           0 :     return;
    1146             : }
    1147             : /*===================================================================*/
    1148             : /* FUNCTION      :  zeroFilter_fx()                                  */
    1149             : /*-------------------------------------------------------------------*/
    1150             : /* PURPOSE       :  zero filtering                                   */
    1151             : /*-------------------------------------------------------------------*/
    1152             : /* INPUT ARGUMENTS  :                                                */
    1153             : /*   _ (Word16) lpc[] :  lpc coefficients in Q12                     */
    1154             : /*   _ (Word16) N     :  lpc order                                   */
    1155             : /*   _ (Word16) this->lag:  in Q0                                    */
    1156             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
    1157             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
    1158             : /*-------------------------------------------------------------------*/
    1159             : /* OUTPUT ARGUMENTS :                                                */
    1160             : /*   _ None.                                                         */
    1161             : /*-------------------------------------------------------------------*/
    1162             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1163             : /*   _ (Word16) this->a[] :    in Q(this->Q)                         */
    1164             : /*   _ (Word16) this->b[] :    in Q(this->Q)                         */
    1165             : /*   _ (Word16) this->Q:       in Q0                                 */
    1166             : /*-------------------------------------------------------------------*/
    1167             : /* RETURN ARGUMENTS : _ None.                                        */
    1168             : /*-------------------------------------------------------------------*/
    1169             : /* CALLED FROM : TX/RX                                               */
    1170             : /*===================================================================*/
    1171             : 
    1172           0 : void DTFS_zeroFilter_fx(
    1173             :     DTFS_STRUCTURE *X_fx,
    1174             :     Word16 *LPC,
    1175             :     Word16 N,
    1176             :     Word16 *S_fx,
    1177             :     Word16 *C_fx )
    1178             : {
    1179             :     Word32 sum1_fx, sum2_fx;
    1180             :     Word16 k, n, HalfLag;
    1181             :     Word16 temp, temp1, temp2;
    1182             :     Word32 L_temp1, L_temp2;
    1183             :     Word16 Qmin, Qab[MAXLAG_WI], na, nb;
    1184           0 :     Qmin = 32767;
    1185           0 :     move16();
    1186           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
    1187           0 :     FOR( k = 0; k <= HalfLag; k++ )
    1188             :     {
    1189           0 :         temp = k;
    1190           0 :         move16();
    1191           0 :         temp2 = k;
    1192           0 :         move16();
    1193             : 
    1194             :         /* Calculate sum1 and sum2 */
    1195           0 :         sum1_fx = L_deposit_h( 4096 ); /*  1: Q(12+15+1)  */
    1196           0 :         sum2_fx = L_deposit_l( 0 );
    1197             : 
    1198           0 :         FOR( n = 0; n < N; n++ )
    1199             :         {
    1200           0 :             sum1_fx = L_mac_sat( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )] ); /* Q(12+15+1) */
    1201           0 :             sum2_fx = L_mac_sat( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )] );
    1202           0 :             temp2 = add( temp2, temp );
    1203             :         }
    1204             : 
    1205           0 :         temp1 = round_fx_sat( sum1_fx ); /* Q(12+15+1-16)=Q(12) */
    1206           0 :         temp2 = round_fx_sat( sum2_fx ); /*               Q(12) */
    1207             : 
    1208             :         /* Calculate the circular convolution */
    1209           0 :         L_temp1 = L_mult( temp1, X_fx->a_fx[k] );
    1210           0 :         L_temp1 = L_msu_sat( L_temp1, temp2, X_fx->b_fx[k] ); /*  Q(12+Q+1) */
    1211           0 :         L_temp2 = L_mult( temp1, X_fx->b_fx[k] );
    1212             : 
    1213           0 :         L_temp2 = L_mac_sat( L_temp2, temp2, X_fx->a_fx[k] ); /*  Q(12+Q+1) */
    1214             :         /*  normalization */
    1215           0 :         na = norm_l( L_temp1 );
    1216           0 :         if ( L_temp1 == 0 )
    1217             :         {
    1218           0 :             na = 31;
    1219           0 :             move16();
    1220             :         }
    1221           0 :         nb = norm_l( L_temp2 );
    1222           0 :         if ( L_temp2 == 0 )
    1223             :         {
    1224           0 :             nb = 31;
    1225           0 :             move16();
    1226             :         }
    1227             : 
    1228           0 :         if ( LT_16( na, nb ) )
    1229             :         {
    1230           0 :             nb = na;
    1231           0 :             move16();
    1232             :         }
    1233           0 :         X_fx->a_fx[k] = round_fx_sat( (Word32) L_shl_sat( L_temp1, nb ) ); /* Q(13+Q+nb-16)=Q(Q+nb-3) */
    1234           0 :         X_fx->b_fx[k] = round_fx_sat( (Word32) L_shl_sat( L_temp2, nb ) ); /*               Q(Q+nb-3) */
    1235           0 :         move32();
    1236           0 :         move32();
    1237             : 
    1238           0 :         Qab[k] = sub( nb, 3 );
    1239           0 :         move16();
    1240             : 
    1241           0 :         if ( LT_16( Qab[k], Qmin ) )
    1242             :         {
    1243           0 :             Qmin = Qab[k];
    1244           0 :             move16();
    1245             :         }
    1246             :     }
    1247             :     /* bring to the same Q */
    1248           0 :     FOR( k = 0; k <= HalfLag; k++ )
    1249             :     {
    1250           0 :         X_fx->a_fx[k] = shl_sat( X_fx->a_fx[k], sub( Qmin, Qab[k] ) );
    1251           0 :         move16(); /*  Q(Q+Qab[k]+Qmin-Qab[k]=Q(Q+Qmin) */
    1252           0 :         X_fx->b_fx[k] = shl_sat( X_fx->b_fx[k], sub( Qmin, Qab[k] ) );
    1253           0 :         move16(); /*                         Q(Q+Qmin) */
    1254             :     }
    1255             : 
    1256           0 :     X_fx->Q = add( X_fx->Q, Qmin );
    1257           0 :     move16();
    1258           0 :     return;
    1259             : }
    1260             : /*===================================================================*/
    1261             : /* FUNCTION      :  DTFS_poleFilter_fx()                                  */
    1262             : /*-------------------------------------------------------------------*/
    1263             : /* PURPOSE       :  pole filtering                                   */
    1264             : /*-------------------------------------------------------------------*/
    1265             : /* INPUT ARGUMENTS  :                                                */
    1266             : /*   _ (Word16) lpc[] :  lpc coefficients in Q12                     */
    1267             : /*   _ (Word16) N     :  lpc order                                   */
    1268             : /*   _ (Word16) lag:  in Q0                                          */
    1269             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
    1270             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
    1271             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
    1272             : /*-------------------------------------------------------------------*/
    1273             : /* OUTPUT ARGUMENTS :                                                */
    1274             : /*   _ None                                                          */
    1275             : /*-------------------------------------------------------------------*/
    1276             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1277             : /*   _ (Word16) this->a[] :    in Q(this->Q)                         */
    1278             : /*   _ (Word16) this->b[] :    in Q(this->Q)                         */
    1279             : /*   _ (Word16) this->Q:       in Q0                                 */
    1280             : /*-------------------------------------------------------------------*/
    1281             : /* RETURN ARGUMENTS : _ None.                                        */
    1282             : /*-------------------------------------------------------------------*/
    1283             : /* CALLED FROM : TX/RX                                               */
    1284             : /*===================================================================*/
    1285             : 
    1286             : /*  PORTING: Handling the functions with variable no. of arguments */
    1287             : 
    1288           0 : void DTFS_poleFilter_fx_9(
    1289             :     DTFS_STRUCTURE *X_fx,
    1290             :     Word16 *pf_temp1,
    1291             :     Word16 *pf_temp2,
    1292             :     Word16 *pf_temp,
    1293             :     Word16 *pf_n2_temp1 )
    1294             : {
    1295             :     Word16 temp, temp1, temp2, HalfLag;
    1296             :     Word32 sum1_fx, sum2_fx;
    1297             :     Word32 L_temp1, L_temp2;
    1298             :     Word16 k, n2_temp1, na, nb;
    1299             :     Word16 Qmin, Qab[MAXLAG_WI];
    1300             : 
    1301           0 :     Qmin = 32767;
    1302           0 :     move16();
    1303           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
    1304           0 :     FOR( k = 0; k <= HalfLag; k++ )
    1305             :     {
    1306           0 :         temp = temp2 = k;
    1307           0 :         move16();
    1308           0 :         move16();
    1309             :         /* Calculate sum1 and sum2 */
    1310             : 
    1311           0 :         n2_temp1 = pf_n2_temp1[k];
    1312           0 :         move16();
    1313             : 
    1314           0 :         temp1 = pf_temp1[k];
    1315           0 :         move16(); /* Q(12+15+1+n2-16)=Q(12+n2) */
    1316           0 :         temp2 = pf_temp2[k];
    1317           0 :         move16(); /*                  Q(12+n2) */
    1318             : 
    1319             :         /* Calculate the circular convolution */
    1320             : 
    1321           0 :         L_temp1 = L_mac( L_mult( temp1, X_fx->a_fx[k] ), temp2, X_fx->b_fx[k] ); /*  Q(12+n2+Q+1)=Q(13+n2+Q) */
    1322           0 :         L_temp2 = L_msu( L_mult( temp1, X_fx->b_fx[k] ), temp2, X_fx->a_fx[k] ); /*  Q(12+n2+Q+1)=Q(13+n2+Q) */
    1323             : 
    1324           0 :         temp = pf_temp[k];
    1325           0 :         move16(); /*  Q(61-25-2*n2-temp1-16)=Q(20-2*n2-temp1) */
    1326             : 
    1327           0 :         sum1_fx = Mult_32_16( L_temp1, temp ); /*  Q(13+n2+Q+15+exp-15) = Q(13+n2+Q+exp) */
    1328           0 :         sum2_fx = Mult_32_16( L_temp2, temp );
    1329             :         /*  normalization */
    1330           0 :         na = norm_l( sum1_fx );
    1331           0 :         if ( sum1_fx == 0 )
    1332             :         {
    1333           0 :             na = 31;
    1334           0 :             move16();
    1335             :         }
    1336           0 :         nb = norm_l( sum2_fx );
    1337           0 :         if ( sum2_fx == 0 )
    1338             :         {
    1339           0 :             nb = 31;
    1340           0 :             move16();
    1341             :         }
    1342             : 
    1343           0 :         if ( LT_16( na, nb ) )
    1344             :         {
    1345           0 :             nb = na;
    1346           0 :             move16();
    1347             :         }
    1348           0 :         nb = sub( nb, 1 );                                         /*  leave one more sign bit */
    1349           0 :         X_fx->a_fx[k] = round_fx( (Word32) L_shl( sum1_fx, nb ) ); /*  Q(-3+n2+Q+exp+nb ) */
    1350           0 :         move16();
    1351           0 :         X_fx->b_fx[k] = round_fx( (Word32) L_shl( sum2_fx, nb ) );
    1352           0 :         move16();
    1353             : 
    1354           0 :         Qab[k] = add( sub( nb, 3 ), n2_temp1 );
    1355           0 :         move16();
    1356             : 
    1357           0 :         if ( LT_16( Qab[k], Qmin ) )
    1358             :         {
    1359           0 :             Qmin = Qab[k];
    1360           0 :             move16();
    1361             :         }
    1362             :     }
    1363             :     /*  bring to the same Q */
    1364             : 
    1365           0 :     FOR( k = 0; k <= HalfLag; k++ )
    1366             :     {
    1367           0 :         X_fx->a_fx[k] = shl( X_fx->a_fx[k], sub( Qmin, Qab[k] ) );
    1368           0 :         move16(); /*  Q(Q+Qab[k]+Qmin-Qab[k])=Q(Q+Qmin) */
    1369           0 :         X_fx->b_fx[k] = shl( X_fx->b_fx[k], sub( Qmin, Qab[k] ) );
    1370           0 :         move16(); /*  Q(Q+Qab[k]+Qmin-Qab[k])=Q(Q+Qmin) */
    1371             :     }
    1372             : 
    1373           0 :     X_fx->Q = add( X_fx->Q, Qmin );
    1374           0 :     move16();
    1375           0 :     return;
    1376             : }
    1377             : /*===================================================================*/
    1378             : /* FUNCTION      :  DTFS_adjustLag_fx ()                             */
    1379             : /*-------------------------------------------------------------------*/
    1380             : /* PURPOSE       :                                                   */
    1381             : /*-------------------------------------------------------------------*/
    1382             : /* INPUT ARGUMENTS  :                                                */
    1383             : /*   _ (Word16) N_fx:  lag value, Q0                                 */
    1384             : /*-------------------------------------------------------------------*/
    1385             : /* OUTPUT ARGUMENTS :                                                */
    1386             : /*   _ (struct DTFS_fx) :    a/b in X1.Q                             */
    1387             : /*-------------------------------------------------------------------*/
    1388             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1389             : /*   _ (struct DTFS_fx) X1 :  lag in Q0                              */
    1390             : /*-------------------------------------------------------------------*/
    1391             : /* RETURN ARGUMENTS : _ None.                                        */
    1392             : /*-------------------------------------------------------------------*/
    1393             : /* CALLED FROM : TX/RX                                               */
    1394             : /*===================================================================*/
    1395             : 
    1396           0 : void DTFS_adjustLag_fx(
    1397             :     DTFS_STRUCTURE *X_DTFS_FX, /* i/o    : DTFS to adjust lag for    */
    1398             :     Word16 N_fx                /* i    : Target lag                  */
    1399             : )
    1400             : {
    1401             :     Word32 en_fx;
    1402             :     Word32 temp32_fx, tempnH_fx, mul1_fx, mul2_fx;
    1403             :     Word16 k, diff_fx;
    1404             :     Word16 exp, tmp;
    1405             :     Word32 L_tmp;
    1406             : 
    1407           0 :     IF( EQ_16( N_fx, X_DTFS_FX->lag_fx ) )
    1408             :     {
    1409           0 :         return;
    1410             :     }
    1411             : 
    1412           0 :     IF( GT_16( N_fx, X_DTFS_FX->lag_fx ) )
    1413             :     {
    1414           0 :         DTFS_zeroPadd_fx( N_fx, X_DTFS_FX );
    1415             :     }
    1416             :     ELSE
    1417             :     {
    1418           0 :         en_fx = DTFS_getEngy_fx( X_DTFS_FX ); /* Q = 2*(X_DTFS_FX->Q) */
    1419             : 
    1420           0 :         tmp = s_min( shr( X_DTFS_FX->lag_fx, 1 ), X_DTFS_FX->nH_fx );
    1421           0 :         FOR( k = ( ( N_fx >> 1 ) + 1 ); k <= tmp; k++ )
    1422             :         {
    1423           0 :             X_DTFS_FX->a_fx[k] = 0;
    1424           0 :             move16();
    1425           0 :             X_DTFS_FX->b_fx[k] = 0;
    1426           0 :             move16();
    1427             :         }
    1428           0 :         DTFS_setEngy_fx( X_DTFS_FX, en_fx );
    1429           0 :         X_DTFS_FX->lag_fx = N_fx;
    1430           0 :         move16();
    1431             : 
    1432             : 
    1433             :         /* recompute nH for new lag */
    1434           0 :         exp = norm_s( X_DTFS_FX->lag_fx );
    1435           0 :         tmp = div_s( shl( 1, sub( 14, exp ) ), X_DTFS_FX->lag_fx ); /* 29 - exp */
    1436           0 :         L_tmp = L_mult0( 12800, tmp );
    1437           0 :         temp32_fx = L_shl( L_tmp, sub( exp, 23 ) );
    1438           0 :         diff_fx = extract_l( L_shl( L_tmp, sub( exp, 29 ) ) );
    1439             : 
    1440             : 
    1441           0 :         exp = norm_s( diff_fx );
    1442           0 :         tmp = div_s( shl( 1, sub( 14, exp ) ), diff_fx ); /* 29 - exp */
    1443           0 :         L_tmp = L_mult0( X_DTFS_FX->upper_cut_off_freq_fx, tmp );
    1444           0 :         X_DTFS_FX->nH_fx = extract_l( L_shl( L_tmp, sub( exp, 29 ) ) );
    1445           0 :         move16();
    1446             : 
    1447           0 :         L_tmp = L_mult0( 4000, tmp );
    1448           0 :         tempnH_fx = L_shl( L_tmp, sub( exp, 23 ) );
    1449           0 :         X_DTFS_FX->nH_4kHz_fx = extract_l( L_shl( L_tmp, sub( exp, 29 ) ) );
    1450           0 :         move16();
    1451             : 
    1452           0 :         IF( GE_16( sub( X_DTFS_FX->upper_cut_off_freq_fx, shr( extract_l( L_mult( diff_fx, X_DTFS_FX->nH_fx ) ), 1 ) ), diff_fx ) )
    1453             :         {
    1454           0 :             X_DTFS_FX->nH_fx = add( X_DTFS_FX->nH_fx, 1 );
    1455           0 :             move16();
    1456             :         }
    1457             : 
    1458           0 :         mul1_fx = L_shl( temp32_fx, 13 );                      /* Q19 */
    1459           0 :         mul2_fx = L_shl( (Word32) X_DTFS_FX->nH_4kHz_fx, 18 ); /* Q18 */
    1460           0 :         tempnH_fx = Mult_32_32( mul1_fx, mul2_fx );            /* Q6 */
    1461           0 :         tempnH_fx = L_sub( (Word32) 256000, tempnH_fx );       /* Q6 */
    1462             : 
    1463           0 :         IF( GE_32( tempnH_fx, temp32_fx ) )
    1464             :         {
    1465           0 :             X_DTFS_FX->nH_4kHz_fx = add( X_DTFS_FX->nH_4kHz_fx, 1 );
    1466           0 :             move16();
    1467             :         }
    1468             :     }
    1469           0 :     return;
    1470             : }
    1471             : /*===================================================================*/
    1472             : /* FUNCTION      :  DTFS_getEngy_fx ()                               */
    1473             : /*-------------------------------------------------------------------*/
    1474             : /* PURPOSE       :                                                   */
    1475             : /*-------------------------------------------------------------------*/
    1476             : /* INPUT ARGUMENTS  :                                                */
    1477             : /*   _ (struct DTFS_STRUCTURE) :    a/b in X_fx.Q i.e Q6, lag in Q0*/
    1478             : /*-------------------------------------------------------------------*/
    1479             : /* OUTPUT ARGUMENTS : _ None                                         */
    1480             : /*-------------------------------------------------------------------*/
    1481             : /* INPUT/OUTPUT ARGUMENTS : _ None                                   */
    1482             : /*-------------------------------------------------------------------*/
    1483             : /* RETURN ARGUMENTS :                                                */
    1484             : /*   _ (Word40) en_fx: output energy, 2*X1.Q                         */
    1485             : /*-------------------------------------------------------------------*/
    1486             : /* CALLED FROM : TX/RX                                               */
    1487             : /*===================================================================*/
    1488             : 
    1489             : 
    1490           0 : Word32 DTFS_getEngy_fx(
    1491             :     DTFS_STRUCTURE *X_fx )
    1492             : {
    1493             :     Word16 k, HalfLag_fx;
    1494           0 :     Word32 en_fx = 0;
    1495           0 :     move32();
    1496             :     Word16 temp_a_fx, temp_b_fx;
    1497           0 :     HalfLag_fx = shr( sub( X_fx->lag_fx, 1 ), 1 );
    1498           0 :     HalfLag_fx = s_min( HalfLag_fx, X_fx->nH_fx );
    1499           0 :     FOR( k = 1; k <= HalfLag_fx; k++ )
    1500             :     {
    1501           0 :         temp_a_fx = X_fx->a_fx[k];
    1502           0 :         move16();
    1503           0 :         temp_b_fx = X_fx->b_fx[k];
    1504           0 :         move16();
    1505           0 :         en_fx = L_mac0_sat( en_fx, temp_a_fx, temp_a_fx );
    1506           0 :         en_fx = L_mac0_sat( en_fx, temp_b_fx, temp_b_fx );
    1507             :     }
    1508             : 
    1509           0 :     en_fx = L_shr( en_fx, 1 );
    1510           0 :     temp_a_fx = X_fx->a_fx[0];
    1511           0 :     move16();
    1512           0 :     en_fx = L_mac0_sat( en_fx, temp_a_fx, temp_a_fx );
    1513             :     /*  IF (X_fx->lag_fx%2 == 0)  */
    1514           0 :     IF( s_and( X_fx->lag_fx, 1 ) == 0 )
    1515             :     {
    1516           0 :         temp_a_fx = X_fx->a_fx[k];
    1517           0 :         move16();
    1518           0 :         temp_b_fx = X_fx->b_fx[k];
    1519           0 :         move16();
    1520           0 :         en_fx = L_mac0_sat( en_fx, temp_a_fx, temp_a_fx );
    1521           0 :         en_fx = L_mac0_sat( en_fx, temp_b_fx, temp_b_fx );
    1522             :     }
    1523             : 
    1524           0 :     return en_fx; /*  2*X1.Q+1=Q13 */
    1525             : }
    1526             : 
    1527             : 
    1528             : /*===================================================================*/
    1529             : /* FUNCTION      :  DTFS_getEngy_P2A_fx ()                           */
    1530             : /*-------------------------------------------------------------------*/
    1531             : /* PURPOSE       :                                                   */
    1532             : /*-------------------------------------------------------------------*/
    1533             : /* INPUT ARGUMENTS  :                                                */
    1534             : /*   _ (struct DTFS_STRUCTURE) :    a/b in X_fx.Q, lag in Q0      */
    1535             : /*-------------------------------------------------------------------*/
    1536             : /* OUTPUT ARGUMENTS : _ None                                         */
    1537             : /*-------------------------------------------------------------------*/
    1538             : /* INPUT/OUTPUT ARGUMENTS : _ None                                   */
    1539             : /*-------------------------------------------------------------------*/
    1540             : /* RETURN ARGUMENTS :                                                */
    1541             : /*   _ (Word40) en_fx: output energy, 2*X1.Q                         */
    1542             : /*-------------------------------------------------------------------*/
    1543             : /* CALLED FROM : TX/RX                                               */
    1544             : /*===================================================================*/
    1545             : 
    1546           0 : Word32 DTFS_getEngy_P2A_fx(
    1547             :     DTFS_STRUCTURE *X_fx )
    1548             : {
    1549             :     Word16 k, HalfLag_fx;
    1550           0 :     Word32 en_fx = 0;
    1551           0 :     move32();
    1552           0 :     HalfLag_fx = shr( sub( X_fx->lag_fx, 1 ), 1 );
    1553           0 :     HalfLag_fx = s_min( HalfLag_fx, X_fx->nH_fx );
    1554           0 :     FOR( k = 1; k <= HalfLag_fx; k++ )
    1555             :     {
    1556           0 :         en_fx = L_mac0_sat( en_fx, X_fx->a_fx[k], X_fx->a_fx[k] );
    1557           0 :         en_fx = L_mac0_sat( en_fx, X_fx->b_fx[k], X_fx->b_fx[k] );
    1558             :     }
    1559           0 :     en_fx = L_shr( en_fx, 1 );
    1560           0 :     en_fx = L_mac0_sat( en_fx, X_fx->a_fx[0], X_fx->a_fx[0] );
    1561             :     /* IF (X_fx->lag_fx%2 == 0) */
    1562           0 :     IF( s_and( X_fx->lag_fx, 1 ) == 0 )
    1563             :     {
    1564           0 :         en_fx = L_mac0_sat( en_fx, X_fx->a_fx[k], X_fx->a_fx[k] );
    1565           0 :         en_fx = L_mac0_sat( en_fx, X_fx->b_fx[k], X_fx->b_fx[k] );
    1566             :     }
    1567           0 :     return en_fx; /*  2*X1.Q */
    1568             : }
    1569             : 
    1570             : 
    1571             : /*===================================================================*/
    1572             : /* FUNCTION      :  DTFS_setEngy_fx ( )                              */
    1573             : /*-------------------------------------------------------------------*/
    1574             : /* PURPOSE       :                                                   */
    1575             : /*-------------------------------------------------------------------*/
    1576             : /* INPUT ARGUMENTS  :                                                */
    1577             : /*   _ (Word40) en2_fx:        2*X1.Q+1 i.e. Q13                     */
    1578             : /*-------------------------------------------------------------------*/
    1579             : /* OUTPUT ARGUMENTS :                                                */
    1580             : /*   _ (Word40) en1_fx :       2*X1.Q+1 i.e. Q13                     */
    1581             : /*-------------------------------------------------------------------*/
    1582             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1583             : /*   _ (struct DTFS_STRUCTURE) X_DTFS_FX :  a/b in X1.Q i.e. Q6,  */
    1584             : /*                    lag in Q0                                      */
    1585             : /*-------------------------------------------------------------------*/
    1586             : /* RETURN ARGUMENTS : _ None.                                        */
    1587             : /*-------------------------------------------------------------------*/
    1588             : /* CALLED FROM : TX/RX                                               */
    1589             : /*===================================================================*/
    1590             : 
    1591           0 : static Word32 DTFS_setEngy_fx(
    1592             :     DTFS_STRUCTURE *X_DTFS_FX,
    1593             :     Word32 en2_fx )
    1594             : {
    1595             :     Word16 k, HalfLag_fx;
    1596             :     Word32 en1_fx;
    1597             :     Word32 L_temp_fx;
    1598             :     Word16 expa, expb, fraca, fracb, scale, tmp, exp;
    1599             :     Word32 L_tmp, factor_fx;
    1600             : 
    1601           0 :     HalfLag_fx = s_min( shr( X_DTFS_FX->lag_fx, 1 ), X_DTFS_FX->nH_fx );
    1602           0 :     move16();
    1603           0 :     en1_fx = DTFS_getEngy_fx( X_DTFS_FX );
    1604           0 :     move16();
    1605             : 
    1606           0 :     IF( en1_fx == 0 )
    1607             :     {
    1608           0 :         return 0;
    1609             :     }
    1610             : 
    1611           0 :     IF( en2_fx == 0 )
    1612             :     {
    1613           0 :         factor_fx = 0;
    1614           0 :         move32();
    1615             :     }
    1616             :     ELSE
    1617             :     {
    1618           0 :         expa = norm_l( en2_fx );
    1619           0 :         fraca = extract_h( L_shl( en2_fx, expa ) );
    1620           0 :         expa = sub( 30, add( expa, shl( X_DTFS_FX->Q, 1 ) ) );
    1621             : 
    1622             : 
    1623           0 :         expb = norm_l( en1_fx );
    1624           0 :         fracb = round_fx_sat( L_shl_sat( en1_fx, expb ) );
    1625           0 :         expb = sub( 30, add( expb, shl( X_DTFS_FX->Q, 1 ) ) );
    1626             : 
    1627             : 
    1628           0 :         scale = shr( sub( fraca, fracb ), 15 );
    1629           0 :         fracb = shl( fracb, scale );
    1630           0 :         expb = sub( expb, scale );
    1631             : 
    1632           0 :         tmp = div_s( fracb, fraca );
    1633           0 :         exp = sub( expb, expa );
    1634             : 
    1635           0 :         L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    1636           0 :         factor_fx = L_shr( L_tmp, 1 );
    1637             :     }
    1638             : 
    1639           0 :     FOR( k = 0; k <= HalfLag_fx; k++ )
    1640             :     {
    1641           0 :         L_temp_fx = Mult_32_16( factor_fx, X_DTFS_FX->a_fx[k] ); /*  Q(temp+X1.Q-15) */
    1642           0 :         X_DTFS_FX->a_fx[k] = round_fx( L_temp_fx );              /*  Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */
    1643           0 :         move16();
    1644             : 
    1645           0 :         L_temp_fx = Mult_32_16( factor_fx, X_DTFS_FX->b_fx[k] ); /*  Q(temp+X1.Q-15) */
    1646           0 :         X_DTFS_FX->b_fx[k] = round_fx( L_temp_fx );              /*  Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */
    1647           0 :         move16();
    1648             :     }
    1649             : 
    1650             : 
    1651           0 :     return en1_fx; /*  2*X1.Q+1 = Q13 */
    1652             : }
    1653             : 
    1654             : /*===================================================================*/
    1655             : /* FUNCTION      :  struct DTFS_car2pol_fx ()                        */
    1656             : /*-------------------------------------------------------------------*/
    1657             : /* PURPOSE       :  Cartesian to polar representation                */
    1658             : /*                  returning amplitudes and 0 phases                */
    1659             : /*-------------------------------------------------------------------*/
    1660             : /* INPUT ARGUMENTS  :                                                */
    1661             : /*   _ (struct DTFS_STRUCTURE) X_fx :  prototype in Cartesian domain*/
    1662             : /*         (Word16) lag: length of prototype in time domain          */
    1663             : /*         (Word16 []) a,b: re/im of harmonics, normalized            */
    1664             : /*         (Word16) Q: norm factor of a/b                             */
    1665             : /*-------------------------------------------------------------------*/
    1666             : /* OUTPUT ARGUMENTS :                                                */
    1667             : /*   _ (struct DTFS_STRUCTURE) X_fx :  prototype in polar domain  */
    1668             : /*          (Word16) lag: length of prototype in time domain         */
    1669             : /*          (Word16 []) a: amplitude of harmonics, normalized        */
    1670             : /*          (Word16 []) b: phase of harmonics,cleared to 0           */
    1671             : /*          (Word16) Q: norm factor of a                             */
    1672             : /*-------------------------------------------------------------------*/
    1673             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1674             : /*                    _ None                                         */
    1675             : /*-------------------------------------------------------------------*/
    1676             : /* RETURN ARGUMENTS : _ None.                                        */
    1677             : /*-------------------------------------------------------------------*/
    1678             : /* CALLED FROM : TX/RX                                               */
    1679             : /*===================================================================*/
    1680             : /* NOTE: output X.b (angle) is not computed and should be ignored    */
    1681             : /*       When phases are needed, such as in QPPP, instead uses the   */
    1682             : /*       Cartesian representation to avoid computing phases by arctan*/
    1683             : /*===================================================================*/
    1684           0 : void DTFS_car2pol_fx(
    1685             :     DTFS_STRUCTURE *X_fx /* i/o : DTFS structure a, b, lag  */
    1686             : )
    1687             : 
    1688             : {
    1689             :     Word16 k, HalfLag_fx;
    1690             :     Word32 Ltemp_fx;
    1691             :     Word32 Lacc_fx;
    1692             :     Word16 exp, tmp, frac;
    1693           0 :     HalfLag_fx = s_min( shr( sub( X_fx->lag_fx, 1 ), 1 ), X_fx->nH_fx );
    1694           0 :     FOR( k = 1; k <= HalfLag_fx; k++ )
    1695             :     {
    1696             : 
    1697           0 :         Lacc_fx = L_mult( X_fx->a_fx[k], X_fx->a_fx[k] );             /*  a[k]^2, 2Q+1 */
    1698           0 :         Lacc_fx = L_mac_sat( Lacc_fx, X_fx->b_fx[k], X_fx->b_fx[k] ); /*  a[k]^2+b[k]^2, 2Q+1 */
    1699           0 :         Lacc_fx = L_shr( Lacc_fx, 3 );                                /*  Lacc=(a[k]^2+b[k]^2)/4, 2Q */
    1700             : 
    1701           0 :         IF( Lacc_fx )
    1702             :         {
    1703           0 :             exp = norm_l( Lacc_fx );
    1704           0 :             frac = extract_h( L_shl( Lacc_fx, exp ) ); /* Q14 */
    1705           0 :             exp = sub( exp, sub( 30, ( 2 * X_fx->Q ) ) );
    1706             : 
    1707           0 :             tmp = div_s( 16384, frac );                      /* Q15 */
    1708           0 :             Ltemp_fx = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    1709             : 
    1710           0 :             X_fx->a_fx[k] = extract_h( L_shl( Ltemp_fx, sub( add( X_fx->Q, exp ), 15 ) ) ); /*  Q */
    1711           0 :             move16();
    1712             :         }
    1713             :         ELSE
    1714             :         {
    1715           0 :             X_fx->a_fx[k] = 0;
    1716           0 :             move16();
    1717             :         }
    1718             : 
    1719           0 :         X_fx->b_fx[k] = 0;
    1720           0 :         move16(); /*  clear b[k] */
    1721             :     }
    1722             : 
    1723             : 
    1724           0 :     IF( s_and( X_fx->lag_fx, 1 ) == 0 )
    1725             :     {
    1726           0 :         IF( X_fx->a_fx[k] )
    1727             :         {
    1728           0 :             Lacc_fx = L_mult0( X_fx->a_fx[k], X_fx->a_fx[k] );         /*  a[k]^2, 2Q+1 */
    1729           0 :             Lacc_fx = L_mac0( Lacc_fx, X_fx->b_fx[k], X_fx->b_fx[k] ); /*  a[k]^2+b[k]^2, 2Q+1 */
    1730             : 
    1731           0 :             exp = norm_l( Lacc_fx );
    1732           0 :             frac = extract_h( L_shl( Lacc_fx, exp ) ); /* Q14 */
    1733           0 :             exp = sub( exp, sub( 30, shl( X_fx->Q, 1 ) ) );
    1734             : 
    1735           0 :             tmp = div_s( 16384, frac );                      /* Q15 */
    1736           0 :             Ltemp_fx = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    1737             : 
    1738           0 :             X_fx->a_fx[k] = extract_h( L_shl( Ltemp_fx, sub( add( X_fx->Q, exp ), 15 ) ) ); /*  Q */
    1739           0 :             move16();
    1740             :         }
    1741             :         ELSE
    1742             :         {
    1743           0 :             X_fx->a_fx[k] = 0;
    1744           0 :             move16();
    1745             :         }
    1746             : 
    1747           0 :         X_fx->b_fx[k] = 0;
    1748           0 :         move16(); /*  clear b[k];   */
    1749             :     }
    1750           0 :     return;
    1751             : }
    1752             : 
    1753             : 
    1754             : /*==============================================================================*/
    1755             : /* FUNCTION      :  DTFS_setEngyHarm_fx ( )                                     */
    1756             : /*------------------------------------------------------------------------------*/
    1757             : /* PURPOSE       :  Set a band of harmonics to specified energy                 */
    1758             : /*----------------------------------------------------------------------- ------*/
    1759             : /* INPUT ARGUMENTS  :                                                            */
    1760             : /*   _ (struct DTFS_fx) : lag in Q0                                              */
    1761             : /*   _ (Word16) f1_fx:   lower bound of input, normalized by 12800, Q15          */
    1762             : /*   _ (Word16) f2_fx:   upper bound of input, normalized by 12800, Q15          */
    1763             : /*   _ (Word16) g1_fx:   lower bound of output, normalized by 12800, Q15         */
    1764             : /*   _ (Word16) g2_fx:   upper bound of output, normalized by 12800, Q15         */
    1765             : /*   _ (Word32) en2_fx:  in Q(Qen2)                                              */
    1766             : /*   _ (Word16) Qen2_fx: Q value of en2                                          */
    1767             : /*---------------------------------------------------------------------------- --*/
    1768             : /* OUTPUT ARGUMENTS :                                                            */
    1769             : /*   _ (Word16) Qa_fx: Q value of output a[].                                    */
    1770             : /*----------------------------------------------------------------------------- -*/
    1771             : /* INPUT/OUTPUT ARGUMENTS :                                                      */
    1772             : /* _(struct DTFS_STRUCTURE) : a_fx[] in X1_fx.Q at start, then changed to     */
    1773             : /*                    *Qa later.                                                 */
    1774             : /*---------------------------------------------------------------------------- --*/
    1775             : /* RETURN ARGUMENTS : _ None.                                                    */
    1776             : /*   _ (Word32) en1_fx:  Q(2*X1.Q)                                               */
    1777             : /*----------------------------------------------------------------------------- -*/
    1778             : /* CALLED FROM : TX/RX                                                           */
    1779             : /*============================================================================== */
    1780             : /* NOTE: This function cannot change Q because it works on a band                */
    1781             : /*       of harmonics, instead of the whole DTFS                                 */
    1782             : /*============================================================================== */
    1783           0 : Word32 DTFS_setEngyHarm_fx(
    1784             :     Word16 f1_fx,        /* i  : lower band freq of input to control energy   */
    1785             :     Word16 f2_fx,        /* i  : upper band freq of input to control energy   */
    1786             :     Word16 g1_fx,        /* i  : lower band freq of output to control energy  */
    1787             :     Word16 g2_fx,        /* i  : upper band freq of output to control energy  */
    1788             :     Word32 en2_fx,       /* i  : Target Energy to set the DTFS to             */
    1789             :     Word16 Qen2_fx,      /* i  : Input Q format for en2                         */
    1790             :     Word16 *Qa_fx,       /* i  : Output Q format for x->a                     */
    1791             :     DTFS_STRUCTURE *X_fx /* i/o: DTFS to adjust the energy of                 */
    1792             : )
    1793             : {
    1794             : 
    1795           0 :     Word16 k, count = 0, HalfLag_fx;
    1796             :     Word16 f_low_fx, f_high_fx, g_low_fx, g_high_fx;
    1797             :     Word32 L_temp_fx, factor_fx;
    1798             :     Word32 en1_fx;
    1799             :     Word32 Lacc;
    1800             :     Word16 exp, tmp, expa, expb, fraca, fracb, scale;
    1801             :     Word32 L_tmp;
    1802           0 :     Word32 Lacc_max = 0;
    1803           0 :     move32();
    1804           0 :     Word16 expp = 0;
    1805           0 :     move16();
    1806             : 
    1807             : 
    1808           0 :     f_low_fx = mult( f1_fx, X_fx->lag_fx );  /*  Q0 */
    1809           0 :     f_high_fx = mult( f2_fx, X_fx->lag_fx ); /*  Q0 */
    1810           0 :     g_low_fx = mult( g1_fx, X_fx->lag_fx );  /*  Q0 */
    1811           0 :     g_high_fx = mult( g2_fx, X_fx->lag_fx ); /*  Q0 */
    1812           0 :     HalfLag_fx = s_min( f_high_fx, shl( X_fx->nH_fx, 1 ) );
    1813             : 
    1814           0 :     Lacc = L_deposit_l( 0 );
    1815           0 :     FOR( k = f_low_fx + 1; k <= HalfLag_fx; k++ )
    1816             :     {
    1817           0 :         Lacc = L_mac0_sat( Lacc, X_fx->a_fx[k], X_fx->a_fx[k] ); /*  2*X1.Q */
    1818           0 :         Lacc_max = L_max( Lacc_max, Lacc );
    1819             : 
    1820           0 :         count = add( count, 1 );
    1821             :     }
    1822             : 
    1823           0 :     IF( GE_32( Lacc_max, 2147483647 /*1.Q31*/ ) )
    1824             :     {
    1825           0 :         tmp = sub( HalfLag_fx, f_low_fx );
    1826           0 :         exp = norm_s( tmp );
    1827           0 :         expp = sub( 15, exp );
    1828             : 
    1829           0 :         Lacc = L_deposit_l( 0 );
    1830           0 :         FOR( k = f_low_fx + 1; k <= HalfLag_fx; k++ )
    1831             :         {
    1832           0 :             L_tmp = L_mult_sat( X_fx->a_fx[k], X_fx->a_fx[k] );
    1833           0 :             Lacc = L_add_sat( Lacc, L_shr( L_tmp, expp ) ); /*  2*X1.Q-expp */
    1834           0 :             count = add( count, 1 );
    1835             :         }
    1836             :     }
    1837             : 
    1838           0 :     if ( count <= 0 )
    1839             :     {
    1840           0 :         count = 1;
    1841           0 :         move16();
    1842             :     }
    1843             : 
    1844           0 :     exp = norm_s( count );
    1845           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), count ); /* 29 - exp */
    1846           0 :     en1_fx = L_shl_sat( Mult_32_16( Lacc, tmp ), sub( exp, 14 ) );
    1847           0 :     test();
    1848           0 :     IF( en1_fx > 0 && en2_fx > 0 )
    1849             :     {
    1850             :         /* factor_fx = sqrt_divide_dp((Word40)en2_fx, en1_fx, sub(Qen2_fx, shl(X_fx->Q, 1)), &temp_fx,1);      : Q(temp) */
    1851           0 :         expa = norm_l( en2_fx );
    1852           0 :         fraca = extract_h( L_shl( en2_fx, expa ) );
    1853           0 :         expa = sub( 30, add( expa, Qen2_fx ) );
    1854             : 
    1855             : 
    1856           0 :         expb = norm_l( en1_fx );
    1857           0 :         fracb = round_fx_sat( L_shl( en1_fx, expb ) );
    1858           0 :         IF( GE_32( Lacc_max, 2147483647 /*1.Q31*/ ) )
    1859             :         {
    1860           0 :             expb = sub( 30, add( expb, sub( shl( X_fx->Q, 1 ), expp ) ) );
    1861             :         }
    1862             :         ELSE
    1863             :         {
    1864           0 :             expb = sub( 30, add( expb, shl( X_fx->Q, 1 ) ) );
    1865             :         }
    1866             : 
    1867           0 :         scale = shr( sub( fraca, fracb ), 15 );
    1868           0 :         fracb = shl( fracb, scale );
    1869           0 :         expb = sub( expb, scale );
    1870             : 
    1871           0 :         tmp = div_s( fracb, fraca );
    1872           0 :         exp = sub( expb, expa );
    1873             : 
    1874           0 :         L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    1875             : 
    1876           0 :         IF( GE_32( Lacc_max, 2147483647 ) )
    1877             :         {
    1878           0 :             factor_fx = L_shr( L_tmp, add( 1, s_min( 2, expp ) ) );
    1879             :         }
    1880             :         ELSE
    1881             :         {
    1882           0 :             factor_fx = L_shr( L_tmp, 1 );
    1883             :         }
    1884             :     }
    1885             :     ELSE
    1886             :     {
    1887           0 :         factor_fx = L_deposit_l( 0 );
    1888             :     }
    1889             : 
    1890           0 :     HalfLag_fx = s_min( g_high_fx, shl( X_fx->nH_fx, 1 ) );
    1891           0 :     FOR( k = g_low_fx + 1; k <= HalfLag_fx; k++ )
    1892             :     {
    1893             :         /*L_temp_fx =(Word32)Mpy_32_16(extract_h(factor_fx),extract_l(factor_fx), X_fx->a_fx[k]);  move32();           */ /*  Q(temp+X1.Q-15) */
    1894           0 :         L_temp_fx = Mult_32_16( factor_fx, X_fx->a_fx[k] );                                                               /*  Q(temp+X1.Q-15) */
    1895           0 :         X_fx->a_fx[k] = round_fx_sat( L_temp_fx );                                                                        /*  Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */
    1896           0 :         move16();
    1897             :     }
    1898             : 
    1899           0 :     IF( GE_32( Lacc_max, 2147483647 /*1.Q31*/ ) )
    1900             :     {
    1901           0 :         *Qa_fx = sub( sub( X_fx->Q, add( 1, s_min( 2, expp ) ) ), exp );
    1902           0 :         move16();
    1903             :     }
    1904             :     ELSE
    1905             :     {
    1906           0 :         *Qa_fx = sub( sub( X_fx->Q, 1 ), exp );
    1907           0 :         move16();
    1908             :     }
    1909             : 
    1910           0 :     return en1_fx; /*  Q(2*X1.Q) */
    1911             : }
    1912             : /*===================================================================*/
    1913             : /* FUNCTION      :  cubicPhase_fx ()                                 */
    1914             : /*-------------------------------------------------------------------*/
    1915             : /* PURPOSE       :  Compute cubic phase track for WI synthesis       */
    1916             : /*-------------------------------------------------------------------*/
    1917             : /* INPUT ARGUMENTS  :                                                */
    1918             : /*   _ (Word16) ph1_fx :  initial phase, Q15 (normalized by 2pi)     */
    1919             : /*   _ (Word16) ph2_fx :  final phase, Q15 (normalized by 2pi)       */
    1920             : /*   _ (Word16) L1 :  previous pitch lag, Q0                         */
    1921             : /*   _ (Word16) L2 :  current pitch lag, Q0                          */
    1922             : /*   _ (Word16) N :  length of phase track, Q0                       */
    1923             : /*-------------------------------------------------------------------*/
    1924             : /* OUTPUT ARGUMENTS :                                                */
    1925             : /*   _ (Word32 []) phOut_fx :  phase track, Q27 (normalized by 2pi)  */
    1926             : /*-------------------------------------------------------------------*/
    1927             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    1928             : /*                    _ None                                         */
    1929             : /*-------------------------------------------------------------------*/
    1930             : /* RETURN ARGUMENTS : _ None.                                        */
    1931             : /*-------------------------------------------------------------------*/
    1932             : /* CALLED FROM : TX/RX                                               */
    1933             : /*===================================================================*/
    1934             : /* NOTE: This function outputs phase in (-1,1)                       */
    1935             : /*===================================================================*/
    1936           0 : static void cubicPhase_fx(
    1937             :     Word16 ph1_fx,   /* i  : phase offset       */
    1938             :     Word16 ph2_fx,   /* i  : phase 2            */
    1939             :     const Word16 L1, /* i  : previous lag       */
    1940             :     const Word16 L2, /* i  : current lag        */
    1941             :     Word16 N,        /* i  : input length       */
    1942             :     Word32 *phOut_fx /* o  : cubic phase output */
    1943             : )
    1944             : {
    1945             :     Word16 n;
    1946             :     Word16 n2;
    1947             :     Word16 f1, f2; /*  invert of L1, L2, Q19 */
    1948             :     Word16 factor, temp;
    1949             :     Word16 c0, c1, c2, c3; /*  cubic polynomial coefficients */
    1950             :     /*  Q33, Q27, Q19, Q15 respectively */
    1951             :     Word32 Ltemp1, Ltemp2, Ltemp3, Ltemp4, Ltemp;
    1952             :     Word16 tmp, exp;
    1953             :     Word32 Lacc;
    1954             :     Word16 expa, expb, fraca, fracb, scale;
    1955             :     Word32 L_tmp, L_tmp1;
    1956             :     Word16 num_flag, den_flag;
    1957             :     Word32 N2;
    1958             :     Word16 dbgshft;
    1959           0 :     num_flag = 0;
    1960           0 :     move16();
    1961           0 :     den_flag = 0;
    1962           0 :     move16();
    1963             : 
    1964           0 :     N = sub( N, L2 );
    1965             : 
    1966           0 :     exp = norm_s( L1 );
    1967           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), L1 );
    1968           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
    1969           0 :     f1 = round_fx( L_tmp );
    1970             : 
    1971           0 :     exp = norm_s( L2 );
    1972           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), L2 );
    1973           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
    1974           0 :     Ltemp4 = inverse_table[L2];
    1975           0 :     f2 = round_fx( L_tmp );
    1976             : 
    1977           0 :     c3 = ph1_fx;
    1978           0 :     move16(); /*  c3 in Q15 */
    1979           0 :     c2 = f1;
    1980           0 :     move16(); /*  c2 in Q19 */
    1981             : 
    1982           0 :     Ltemp1 = L_sub( ph1_fx, ph2_fx ); /*  Ltemp1=ph1_fx-ph2_fx, Q15 */
    1983           0 :     Ltemp2 = L_add( f1, f2 );         /*  Ltemp2=0.5*(f1+f2), Q20 */
    1984           0 :     temp = extract_l( Ltemp2 );       /* Q20 */
    1985             : 
    1986           0 :     IF( temp < 0 )
    1987             :     {
    1988           0 :         L_tmp1 = L_shl( L_add( 65536, temp ), 14 ); /* Q30 */
    1989           0 :         L_tmp = Mult_32_16( L_tmp1, N );            /* 30-15=15 */
    1990           0 :         Ltemp2 = L_shl( L_tmp, 1 );
    1991             :     }
    1992             :     ELSE
    1993             :     {
    1994           0 :         Ltemp2 = (Word32) L_mult0( N, temp ); /*  Ltemp2=0.5*N*(f1+f2), Q20 */
    1995             :     }
    1996             : 
    1997           0 :     Ltemp1 = L_add( L_shl( Ltemp1, 5 ), Ltemp2 ); /*  Ltemp1=ph1_fx - ph2_fx + 0.5*N*(f2+f1), Q16, Q20 */
    1998             : 
    1999           0 :     factor = round_fx( L_shr( Ltemp1, 4 ) ); /*  factor in Q0 */
    2000             : 
    2001           0 :     c1 = sub( f2, f1 );                                          /*  c1=f2-f1, Q19 */
    2002           0 :     Ltemp1 = L_sub( ph2_fx, ph1_fx );                            /*  Q15 */
    2003           0 :     Ltemp2 = L_mult( N, f1 );                                    /*  Ltemp2=N*f1, Q20 */
    2004           0 :     Ltemp2 = L_sub( L_shl( L_deposit_h( factor ), 4 ), Ltemp2 ); /*  Ltemp2=factor-N*f1, Q20 */
    2005           0 :     Ltemp1 = L_add( Ltemp2, L_shl( Ltemp1, 5 ) );                /*  Ltemp1 in Q20 */
    2006             : 
    2007           0 :     IF( GT_16( N, 180 ) )
    2008             :     {
    2009           0 :         Ltemp2 = L_shl( L_mult0( N, N ), 14 );
    2010           0 :         Ltemp2 = L_shl( Mult_32_16( Ltemp2, N ), 1 );
    2011             : 
    2012             :         /* IF(N%2) */
    2013           0 :         if ( EQ_16( s_and( N, 1 ), 1 ) )
    2014             :         {
    2015           0 :             Ltemp2 = L_add( Ltemp2, 1 );
    2016             :         }
    2017             :     }
    2018             :     ELSE
    2019             :     {
    2020           0 :         Ltemp2 = L_shr( L_mult( N, N ), 1 );
    2021           0 :         Ltemp2 = L_mult0( N, extract_l( Ltemp2 ) ); /*  Ltemp2=N^3 */
    2022             :     }
    2023           0 :     Ltemp3 = L_mult( N, c1 );                     /*  Q20 */
    2024           0 :     Ltemp3 = L_sub( Ltemp3, L_shl( Ltemp1, 1 ) ); /*  Ltemp3=N*c1-2*Ltemp1, Q20 */
    2025             : 
    2026           0 :     IF( GE_32( L_abs( Ltemp3 ), L_shl_sat( Ltemp2, 8 ) ) )
    2027             :     {
    2028           0 :         Lacc = L_add( MIN_32, 0 );
    2029           0 :         if ( Ltemp3 > 0 )
    2030             :         {
    2031           0 :             Lacc = L_add( MAX_32, 0 );
    2032             :         }
    2033             : 
    2034           0 :         c0 = extract_h( Lacc ); /*  c0 in Q33 */
    2035             :     }
    2036             :     ELSE
    2037             :     {
    2038           0 :         expa = norm_l( Ltemp3 );
    2039           0 :         fraca = extract_h( L_shl( Ltemp3, expa ) );
    2040           0 :         expa = sub( 30, add( expa, 20 ) );
    2041           0 :         if ( fraca < 0 )
    2042             :         {
    2043           0 :             num_flag = 1;
    2044           0 :             move16();
    2045             :         }
    2046             : 
    2047           0 :         expb = norm_l( Ltemp2 );
    2048           0 :         fracb = extract_h( L_shl( Ltemp2, expb ) );
    2049           0 :         expb = sub( 30, expb );
    2050           0 :         if ( fracb < 0 )
    2051             :         {
    2052           0 :             den_flag = 1;
    2053           0 :             move16();
    2054             :         }
    2055             : 
    2056           0 :         if ( num_flag )
    2057             :         {
    2058           0 :             fraca = negate( fraca );
    2059             :         }
    2060           0 :         if ( den_flag )
    2061             :         {
    2062           0 :             fracb = negate( fracb );
    2063             :         }
    2064           0 :         scale = shr( sub( fracb, fraca ), 15 );
    2065           0 :         fraca = shl_sat( fraca, scale );
    2066           0 :         expa = sub( expa, scale );
    2067             : 
    2068           0 :         tmp = div_s( fraca, fracb ); /* 15-exp */
    2069           0 :         exp = sub( expa, expb );
    2070           0 :         test();
    2071           0 :         if ( num_flag && !den_flag )
    2072             :         {
    2073           0 :             tmp = negate( tmp );
    2074             :         }
    2075           0 :         test();
    2076           0 :         if ( den_flag && !num_flag )
    2077             :         {
    2078           0 :             tmp = negate( tmp );
    2079             :         }
    2080             : 
    2081           0 :         Lacc = L_shl_sat( tmp, add( exp, 34 ) );
    2082           0 :         Lacc = L_add_sat( Lacc, 0x08000 );
    2083           0 :         c0 = extract_h( Lacc ); /*  c0 in Q33 */
    2084             :     }
    2085             : 
    2086           0 :     Ltemp1 = L_mult( N, N );                      /*  Ltemp1=2*N*N */
    2087           0 :     Ltemp1 = L_add( Ltemp1, L_shr( Ltemp1, 1 ) ); /*  Ltemp1=3*N*N, max is 3*140*140 */
    2088             : 
    2089             :     /* patch added for time warping support, where N can be more than 140 */
    2090           0 :     dbgshft = norm_l( Ltemp1 );
    2091           0 :     Ltemp1 = L_shl( Ltemp1, dbgshft );
    2092           0 :     temp = extract_h( Ltemp1 );
    2093           0 :     Ltemp1 = (Word32) L_shl( (Word32) L_mult0( c0, temp ), sub( 16, dbgshft ) ); /*  Ltemp1=3*N*N*c0, Q33 */
    2094             :     /* Patch end */
    2095             : 
    2096           0 :     num_flag = den_flag = 0;
    2097           0 :     move16();
    2098           0 :     move16();
    2099           0 :     Ltemp1 = L_sub( L_shr( L_deposit_h( c1 ), 2 ), Ltemp1 ); /*  Ltemp1=c1-3*N*N*c0, Q33 */
    2100             : 
    2101           0 :     expa = norm_l( Ltemp1 );
    2102           0 :     fraca = extract_h( L_shl( Ltemp1, expa ) );
    2103           0 :     expa = sub( 30, add( expa, 33 ) );
    2104           0 :     if ( fraca < 0 )
    2105             :     {
    2106           0 :         num_flag = 1;
    2107           0 :         move16();
    2108             :     }
    2109             : 
    2110           0 :     expb = norm_l( N );
    2111           0 :     fracb = extract_h( L_shl( N, expb ) );
    2112           0 :     expb = sub( 30, expb );
    2113           0 :     if ( fracb < 0 )
    2114             :     {
    2115           0 :         den_flag = 1;
    2116           0 :         move16();
    2117             :     }
    2118             : 
    2119           0 :     if ( num_flag )
    2120             :     {
    2121           0 :         fraca = negate( fraca );
    2122             :     }
    2123           0 :     if ( den_flag )
    2124             :     {
    2125           0 :         fracb = negate( fracb );
    2126             :     }
    2127           0 :     scale = shr( sub( fracb, fraca ), 15 );
    2128           0 :     fraca = shl( fraca, scale );
    2129           0 :     expa = sub( expa, scale );
    2130             : 
    2131           0 :     tmp = div_s( fraca, fracb ); /* 15-exp */
    2132           0 :     exp = sub( expa, expb );
    2133           0 :     test();
    2134           0 :     if ( num_flag && !den_flag )
    2135             :     {
    2136           0 :         tmp = negate( tmp );
    2137             :     }
    2138           0 :     test();
    2139           0 :     if ( den_flag && !num_flag )
    2140             :     {
    2141           0 :         tmp = negate( tmp );
    2142             :     }
    2143             : 
    2144           0 :     Lacc = L_shl( tmp, add( exp, 27 ) );
    2145           0 :     Lacc = L_add( Lacc, 0x08000 );
    2146           0 :     c1 = extract_h( Lacc ); /*  c1 in Q27 */
    2147             : 
    2148             : 
    2149             :     /*  Computation of the phase value at each sample point */
    2150             :     /*  ph[n]=  c0*n^3+c1*n^2+c2*n+c3, Q15 */
    2151           0 :     phOut_fx[0] = L_shl( ph1_fx, 11 ); /* Q27 */
    2152           0 :     move32();
    2153             : 
    2154           0 :     IF( LT_16( N, 181 ) )
    2155             :     {
    2156           0 :         FOR( n = 1; n < N; n++ )
    2157             :         {
    2158             :             /*     phOut_fx[n] = _POLY3(n,coef) ; */
    2159           0 :             n2 = i_mult2( n, n );                            /*  n2=n^2 */
    2160           0 :             Ltemp3 = (Word32) L_mult0( n, (UNS_Word16) n2 ); /*  Ltemp3=n^3 */
    2161             : 
    2162           0 :             Ltemp3 = L_shl( Mult_32_16( L_shl( Ltemp3, 7 ), c0 ), 2 ); /*  Ltemp3=c0*n^3, Q27 */
    2163           0 :             Ltemp2 = (Word32) L_mult0( c1, (UNS_Word16) n2 );          /*  Ltemp2=c1*n^2, Q27 */
    2164           0 :             Ltemp1 = L_shl( L_mult( c2, n ), 7 );                      /*  Ltemp1=c2*n, Q27 */
    2165             : 
    2166           0 :             Ltemp = L_shl( (Word32) c3, 12 ); /* Q27 */
    2167           0 :             Ltemp = L_add( Ltemp1, Ltemp );   /* Q27 */
    2168           0 :             Ltemp = L_add( Ltemp2, Ltemp );   /* Q27 */
    2169           0 :             Ltemp = L_add( Ltemp3, Ltemp );   /*  Q27 */
    2170             : 
    2171           0 :             phOut_fx[n] = Ltemp;
    2172           0 :             move32(); /* Q27 */
    2173             :         }
    2174             :     }
    2175             :     ELSE
    2176             :     {
    2177             : 
    2178           0 :         FOR( n = 1; n < 181; n++ )
    2179             :         {
    2180             :             /*     phOut_fx[n] = _POLY3(n,coef) ; */
    2181           0 :             n2 = i_mult2( n, n );                            /*  n2=n^2 */
    2182           0 :             Ltemp3 = (Word32) L_mult0( n, (UNS_Word16) n2 ); /*  Ltemp3=n^3 */
    2183             : 
    2184           0 :             Ltemp3 = L_shl( Mult_32_16( L_shl( Ltemp3, 7 ), c0 ), 2 ); /*  Ltemp3=c0*n^3, Q27 */
    2185           0 :             Ltemp2 = (Word32) L_mult0( c1, (UNS_Word16) n2 );          /*  Ltemp2=c1*n^2, Q27 */
    2186           0 :             Ltemp1 = L_shl( L_mult( c2, n ), 7 );                      /*  Ltemp1=c2*n, Q27 */
    2187             : 
    2188           0 :             Ltemp = L_shl( (Word32) c3, 12 ); /* Q27 */
    2189           0 :             Ltemp = L_add( Ltemp1, Ltemp );   /* Q27 */
    2190           0 :             Ltemp = L_add( Ltemp2, Ltemp );   /* Q27 */
    2191           0 :             Ltemp = L_add( Ltemp3, Ltemp );   /*  Q27 */
    2192             : 
    2193           0 :             phOut_fx[n] = Ltemp;
    2194           0 :             move32(); /* Q27 */
    2195             :         }
    2196             : 
    2197           0 :         FOR( n = 181; n < N; n++ )
    2198             :         {
    2199             :             /*     phOut_fx[n] = _POLY3(n,coef) ; */
    2200           0 :             N2 = L_shl( L_mult0( n, n ), 14 );
    2201           0 :             Ltemp3 = L_shl( Mult_32_16( N2, n ), 1 );
    2202             : 
    2203           0 :             if ( EQ_16( s_and( N, 1 ), 1 ) )
    2204             :             {
    2205           0 :                 Ltemp3 = L_add( Ltemp3, 1 );
    2206             :             }
    2207             : 
    2208           0 :             Ltemp3 = L_shl_sat( Mult_32_16( L_shl_sat( Ltemp3, 7 ), c0 ), 2 ); /*  Ltemp3=c0*n^3, Q27 */ //?sat
    2209           0 :             Ltemp2 = L_shl( Mult_32_16( N2, c1 ), 1 );
    2210             :             /*  Ltemp2 = (Word32)L_mult_su(c1,(UNS_Word16)n2); : Ltemp2=c1*n^2, Q27 */
    2211           0 :             Ltemp1 = L_shl( L_mult( c2, n ), 7 ); /*  Ltemp1=c2*n, Q27 */
    2212             : 
    2213           0 :             Ltemp = L_shl( (Word32) c3, 12 ); /* Q27 */
    2214           0 :             Ltemp = L_add( Ltemp1, Ltemp );   /* Q27 */
    2215           0 :             Ltemp = L_add( Ltemp2, Ltemp );   /* Q27 */
    2216           0 :             Ltemp = L_add( Ltemp3, Ltemp );   /*  Q27 */
    2217             : 
    2218           0 :             phOut_fx[n] = Ltemp;
    2219           0 :             move32(); /* Q27 */
    2220             :         }
    2221             :     }
    2222             : 
    2223           0 :     tmp = add( N, L2 );
    2224           0 :     FOR( ; n < tmp; n++ )
    2225             :     {
    2226           0 :         Ltemp = L_add( phOut_fx[n - 1], Ltemp4 ); /* Q27 */
    2227           0 :         phOut_fx[n] = Ltemp;
    2228           0 :         move32(); /* Q27 */
    2229             :     }
    2230           0 :     return;
    2231             : }
    2232             : 
    2233             : /*===================================================================*/
    2234             : /* FUNCTION      :   DTFS_to_erb_fx ()                               */
    2235             : /*-------------------------------------------------------------------*/
    2236             : /* PURPOSE       :  Convert harmonics to erb bands                   */
    2237             : /*-------------------------------------------------------------------*/
    2238             : /* INPUT ARGUMENTS  :                                                */
    2239             : /*   _ (struct DTFS_STRUCTURE) X_fx :  prototype in polar domain  */
    2240             : /*                (Word16) lag_fx: length of prototype in time domain*/
    2241             : /*                (Word16 []) a_fx: amplitude, normalized            */
    2242             : /*                (Word16) Q_fx: norm factor of a                    */
    2243             : /*-------------------------------------------------------------------*/
    2244             : /* OUTPUT ARGUMENTS :                                                */
    2245             : /*   _ (Word16 []) out_fx : erb output, Q13                          */
    2246             : /*-------------------------------------------------------------------*/
    2247             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2248             : /*                    _ None                                         */
    2249             : /*-------------------------------------------------------------------*/
    2250             : /* RETURN ARGUMENTS : _ None.                                        */
    2251             : /*-------------------------------------------------------------------*/
    2252             : /* CALLED FROM : TX/RX                                               */
    2253             : /*===================================================================*/
    2254           0 : void DTFS_to_erb_fx(
    2255             :     const DTFS_STRUCTURE X_fx, /* i : DTFS input       */
    2256             :     Word16 *out_fx             /* o : ERB output       */
    2257             : )
    2258             : 
    2259             : {
    2260             :     Word16 num_erb_fx;
    2261             :     Word16 i, j, n, count[NUM_ERB_WB];
    2262             :     Word16 diff_fx;
    2263             :     Word32 sum_a_fx[NUM_ERB_WB], Ltemp_fx, L_tmp, L_temp;
    2264             :     Word16 exp, tmp;
    2265             :     Word16 expa, expb, fraca, fracb, scale;
    2266           0 :     const Word16 *erb_fx = NULL;
    2267           0 :     num_erb_fx = NUM_ERB_NB;
    2268           0 :     move16();
    2269             : 
    2270           0 :     test();
    2271           0 :     test();
    2272           0 :     IF( EQ_16( X_fx.upper_cut_off_freq_fx, 0x02800 ) || EQ_16( X_fx.upper_cut_off_freq_fx, 4000 ) ) /*  0x2800=0.3125 in Q15 (4000Hz) */
    2273             :     {
    2274           0 :         num_erb_fx = NUM_ERB_NB;
    2275           0 :         move16();
    2276           0 :         erb_fx = &( erb_NB_fx[0] );
    2277           0 :         move16();
    2278             :     }
    2279           0 :     ELSE IF( EQ_16( X_fx.upper_cut_off_freq_fx, 0x04000 ) || EQ_16( X_fx.upper_cut_off_freq_fx, 6400 ) ) /*  0x4000=0.5 in Q15 (6400Hz) */
    2280             :     {
    2281           0 :         num_erb_fx = NUM_ERB_WB;
    2282           0 :         move16();
    2283           0 :         erb_fx = &( erb_WB_fx[0] );
    2284           0 :         move16();
    2285             :     }
    2286             : 
    2287             : 
    2288           0 :     FOR( i = 0; i < num_erb_fx; i++ )
    2289             :     {
    2290             : 
    2291             : 
    2292           0 :         count[i] = 0;
    2293           0 :         move16();
    2294           0 :         sum_a_fx[i] = L_deposit_l( 0 );
    2295           0 :         move32();
    2296             :     }
    2297             : 
    2298           0 :     exp = norm_s( X_fx.lag_fx );
    2299           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx.lag_fx ); /* 29-exp */
    2300             : 
    2301           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
    2302           0 :     diff_fx = round_fx( L_tmp );
    2303             : 
    2304           0 :     n = s_min( shr( X_fx.lag_fx, 1 ), X_fx.nH_fx );
    2305             : 
    2306           0 :     j = 0;
    2307           0 :     move16();
    2308           0 :     FOR( i = 0; i <= n; i++ )
    2309             :     {
    2310           0 :         Ltemp_fx = L_mult( diff_fx, i ); /*  Ltemp=i*diff, Q20 */
    2311           0 :         FOR( ; j < num_erb_fx; j++ )
    2312             :         {
    2313           0 :             IF( LT_32( Ltemp_fx, L_shl( erb_fx[j + 1], 5 ) ) )
    2314             :             {
    2315           0 :                 sum_a_fx[j] = L_add( sum_a_fx[j], L_deposit_l( X_fx.a_fx[i] ) );
    2316           0 :                 move32(); /*  X_fx.Q */
    2317           0 :                 count[j] = add( count[j], 1 );
    2318           0 :                 move16();
    2319           0 :                 BREAK;
    2320             :             }
    2321             :         }
    2322             :     }
    2323             :     /* Make output in Q13  */
    2324           0 :     n = sub( 29, X_fx.Q );
    2325           0 :     j = negate( X_fx.Q );
    2326             : 
    2327             : 
    2328           0 :     FOR( i = 0; i < num_erb_fx; i++ )
    2329             :     {
    2330           0 :         out_fx[i] = round_fx_sat( L_shl_sat( sum_a_fx[i], n ) ); /*  Q13 */ //?�sat
    2331           0 :         move16();
    2332           0 :         IF( GT_16( count[i], 1 ) )
    2333             :         {
    2334           0 :             IF( sum_a_fx[i] < 0 )
    2335             :             {
    2336           0 :                 L_temp = L_negate( sum_a_fx[i] );
    2337             :             }
    2338             :             ELSE
    2339             :             {
    2340           0 :                 L_temp = L_add( sum_a_fx[i], 0 );
    2341             :             }
    2342             : 
    2343           0 :             expb = norm_l( L_temp );
    2344           0 :             fracb = round_fx( L_shl( L_temp, expb ) );
    2345           0 :             expb = sub( 30, add( expb, X_fx.Q ) );
    2346             : 
    2347             : 
    2348           0 :             expa = norm_l( count[i] );
    2349           0 :             fraca = extract_h( L_shl( count[i], expa ) );
    2350           0 :             expa = sub( 30, expa );
    2351             : 
    2352           0 :             scale = shr( sub( fraca, fracb ), 15 );
    2353           0 :             fracb = shl( fracb, scale );
    2354           0 :             expb = sub( expb, scale );
    2355             : 
    2356           0 :             tmp = div_s( fracb, fraca );
    2357           0 :             exp = sub( expb, expa );
    2358           0 :             L_tmp = L_shl_sat( tmp, add( exp, 14 ) );
    2359           0 :             out_fx[i] = round_fx_sat( L_tmp );
    2360           0 :             move16();
    2361             :         }
    2362             :     }
    2363           0 :     return;
    2364             : }
    2365             : /*===================================================================*/
    2366             : /* FUNCTION      :  erb_slot_fx ()                                   */
    2367             : /*-------------------------------------------------------------------*/
    2368             : /* PURPOSE       :  Allocate harmonics in ERB bins                   */
    2369             : /*-------------------------------------------------------------------*/
    2370             : /* INPUT ARGUMENTS  :                                                */
    2371             : /*   _ (Word16) lag_fx :  pitch lag, Q0                              */
    2372             : /*-------------------------------------------------------------------*/
    2373             : /* OUTPUT ARGUMENTS :                                                */
    2374             : /*   _ (Word16 []) out_fx : number of harmonics in the ERB bins, Q0  */
    2375             : /*   _ (Word16 []) mfreq_fx : frequency bounds of the ERB bins, Q15  */
    2376             : /*-------------------------------------------------------------------*/
    2377             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2378             : /*                    _ None                                         */
    2379             : /*-------------------------------------------------------------------*/
    2380             : /* RETURN ARGUMENTS : _ None.                                        */
    2381             : /*-------------------------------------------------------------------*/
    2382             : /* CALLED FROM : TX/RX                                               */
    2383             : /*===================================================================*/
    2384             : /* NOTE: Frequency is normalized by 12800, i.e. 1=12800Hz            */
    2385             : /*===================================================================*/
    2386           0 : void erb_slot_fx(
    2387             :     Word16 lag_fx,    /* i : input lag          */
    2388             :     Word16 *out_fx,   /* o : ERB slots          */
    2389             :     Word16 *mfreq_fx, /* o : ERB frequencies    */
    2390             :     Word16 num_erb_fx /* i : number of ERBs     */
    2391             : )
    2392             : {
    2393             :     Word16 i, j, n;
    2394             :     Word16 diff_fx;
    2395             :     Word16 upper_cut_off_freq_fx;
    2396             :     Word32 Ltemp_fx;
    2397             :     Word32 mf_fx[NUM_ERB_WB];
    2398             :     Word16 nH_band_fx;
    2399             :     Word16 exp, tmp;
    2400             :     Word32 L_tmp1, L_tmp;
    2401             :     Word16 fraca, fracb, expa, expb, scale;
    2402           0 :     const Word16 *erb_fx = NULL; /*move16(); */
    2403             : 
    2404           0 :     upper_cut_off_freq_fx = 4000;
    2405           0 :     move16();
    2406             : 
    2407           0 :     IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
    2408             :     {
    2409           0 :         upper_cut_off_freq_fx = 4000;
    2410           0 :         move16();
    2411           0 :         erb_fx = &( erb_NB_fx[0] );
    2412             :     }
    2413           0 :     ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
    2414             :     {
    2415           0 :         upper_cut_off_freq_fx = 6400;
    2416           0 :         move16();
    2417           0 :         erb_fx = &( erb_WB_fx[0] );
    2418             :     }
    2419             : 
    2420           0 :     exp = norm_s( lag_fx );
    2421           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), lag_fx );        /* Q29-exp */
    2422           0 :     L_tmp1 = L_mult( 12800, tmp );                          /* Q(30-exp) */
    2423           0 :     diff_fx = extract_h( L_shl( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */
    2424             : 
    2425           0 :     exp = norm_s( diff_fx );
    2426           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), diff_fx );         /* Q29-exp */
    2427           0 :     L_tmp1 = L_mult( upper_cut_off_freq_fx, tmp );            /* Q(30-exp) */
    2428           0 :     nH_band_fx = round_fx( L_shl( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */
    2429             : 
    2430           0 :     FOR( i = 0; i < num_erb_fx; i++ )
    2431             :     {
    2432           0 :         out_fx[i] = 0;
    2433           0 :         move16();
    2434           0 :         mf_fx[i] = 0;
    2435           0 :         move16();
    2436             :     }
    2437             : 
    2438             : 
    2439           0 :     L_tmp = L_mult0( diff_fx, nH_band_fx ); /* Q0 */
    2440             : 
    2441             : 
    2442           0 :     IF( GE_32( L_sub( upper_cut_off_freq_fx, L_tmp ), L_deposit_l( diff_fx ) ) ) /* Q0 compare */
    2443             :     {
    2444           0 :         nH_band_fx = add( nH_band_fx, 1 ); /* Q0 */
    2445             :     }
    2446             : 
    2447           0 :     n = s_min( shr( lag_fx, 1 ), nH_band_fx );
    2448           0 :     exp = norm_s( lag_fx );
    2449           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), lag_fx ); /* Q29-exp */
    2450           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
    2451           0 :     diff_fx = round_fx( L_tmp );
    2452             : 
    2453           0 :     j = 0;
    2454           0 :     move16();
    2455           0 :     FOR( i = 0; i <= n; i++ )
    2456             :     {
    2457           0 :         Ltemp_fx = L_mult( diff_fx, i ); /*  Ltemp=i*diff, Q20 */
    2458             :         /* freq=round32_16(L_shl(Ltemp,11)); : freq=i*diff, Q15 */
    2459             : 
    2460           0 :         IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
    2461             :         {
    2462           0 :             Ltemp_fx = L_min( Ltemp_fx, 0x050000 ); /*  0x50000=0.3125 in Q20 (4000Hz) */
    2463             :         }
    2464           0 :         ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
    2465             :         {
    2466           0 :             Ltemp_fx = L_min( Ltemp_fx, 0x080000 ); /*  0x80000=0.5 in Q20 (6400Hz)     */
    2467             :         }
    2468             : 
    2469           0 :         FOR( ; j < num_erb_fx; j++ )
    2470             :         {
    2471           0 :             IF( LT_32( Ltemp_fx, L_shl( erb_fx[j + 1], 5 ) ) )
    2472             :             {
    2473           0 :                 mf_fx[j] = L_add( mf_fx[j], Ltemp_fx );
    2474           0 :                 move32();
    2475           0 :                 out_fx[j] = add( out_fx[j], 1 );
    2476           0 :                 move16();
    2477           0 :                 BREAK;
    2478             :             }
    2479             :         }
    2480             :     }
    2481           0 :     FOR( j = 0; j < num_erb_fx; j++ )
    2482             :     {
    2483           0 :         mfreq_fx[j] = round_fx_sat( L_shl_sat( mf_fx[j], 11 ) ); /*  Q15 */
    2484           0 :         move16();
    2485           0 :         IF( GT_16( out_fx[j], 1 ) )
    2486             :         {
    2487           0 :             expb = norm_l( mf_fx[j] );
    2488           0 :             fracb = round_fx_sat( L_shl_sat( mf_fx[j], expb ) );
    2489           0 :             expb = sub( 30, add( expb, 20 ) );
    2490             : 
    2491             : 
    2492           0 :             expa = norm_l( out_fx[j] );
    2493           0 :             fraca = extract_h( L_shl( out_fx[j], expa ) );
    2494           0 :             expa = sub( 30, expa );
    2495             : 
    2496           0 :             scale = shr( sub( fraca, fracb ), 15 );
    2497           0 :             fracb = shl( fracb, scale );
    2498           0 :             expb = sub( expb, scale );
    2499             : 
    2500           0 :             tmp = div_s( fracb, fraca );
    2501           0 :             exp = sub( expb, expa );
    2502           0 :             L_tmp = L_shl_sat( tmp, add( exp, 16 ) );
    2503             : 
    2504           0 :             mfreq_fx[j] = round_fx_sat( L_tmp );
    2505           0 :             move16();
    2506             :         }
    2507             :     }
    2508           0 :     return;
    2509             : }
    2510             : /*===================================================================*/
    2511             : /* FUNCTION      :   DTFS_erb_inv_fx ()                              */
    2512             : /*-------------------------------------------------------------------*/
    2513             : /* PURPOSE       :  Convert erb into harmonics                       */
    2514             : /*-------------------------------------------------------------------*/
    2515             : /* INPUT ARGUMENTS  :                                                */
    2516             : /*   _ (Word16 []) in_fx : erb output, Q13                           */
    2517             : /*   _ (Word16 []) slot_fx : number of harmonics in the ERB bins, Q0 */
    2518             : /*   _ (Word16 []) mfreq_fx : frequency bounds of the ERB bins, Q15  */
    2519             : /*   _ (struct DTFS_STRUCTURE) (Word16) lag_fx: length of         */
    2520             : /*                                       prototype in time domain    */
    2521             : /*-------------------------------------------------------------------*/
    2522             : /* OUTPUT ARGUMENTS :                                                */
    2523             : /*   _ (struct DTFS_STRUCTURE) : prototype in polar domain        */
    2524             : /*                (Word16 []) a_fx: amplitude, normalized            */
    2525             : /*                (Word16) Q: norm factor of a                       */
    2526             : /*-------------------------------------------------------------------*/
    2527             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2528             : /*                    _ None                                         */
    2529             : /*-------------------------------------------------------------------*/
    2530             : /* RETURN ARGUMENTS : _ None.                                        */
    2531             : /*-------------------------------------------------------------------*/
    2532             : /* CALLED FROM : TX/RX                                               */
    2533             : /*===================================================================*/
    2534             : 
    2535           0 : void DTFS_erb_inv_fx(
    2536             :     Word16 *in_fx,        /* i : ERB inpt                      */
    2537             :     Word16 *slot_fx,      /* i : ERB slots filled based on lag */
    2538             :     Word16 *mfreq_fx,     /* i : erb frequence edges           */
    2539             :     DTFS_STRUCTURE *X_fx, /* o : DTFS after erb-inv             */
    2540             :     Word16 num_erb_fx     /* i : Number of ERB bands             */
    2541             : )
    2542             : {
    2543             : 
    2544           0 :     Word16 i, j, m_fx = 0, n, HalfLag_fx;
    2545             :     Word16 diff_fx; /* 1/lag, Q19 */
    2546           0 :     Word16 d1, d2, q[MAXLAG_WI], min_q = 0;
    2547             :     Word16 d1h, d1l, d2h, d2l;
    2548             :     Word16 freq_fx, f_fx[NUM_ERB_WB + 2], amp_fx[NUM_ERB_WB + 2];
    2549           0 :     Word16 upper_cut_off_freq_fx = 0;
    2550             :     Word32 Ltemp_fx, Ltemp2_fx;
    2551             :     Word32 Lacc_fx;
    2552             :     Word16 exp, tmp;
    2553           0 :     move16();
    2554           0 :     move16();
    2555           0 :     move16();
    2556             : 
    2557           0 :     IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
    2558             :     {
    2559           0 :         upper_cut_off_freq_fx = 0x02800;
    2560           0 :         move16(); /*  0x2800=0.3125 in Q15 (4000Hz) */
    2561             :     }
    2562           0 :     ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
    2563             :     {
    2564           0 :         upper_cut_off_freq_fx = 0x04000;
    2565           0 :         move16(); /*  0x4000=0.5 in Q15 (6400Hz) */
    2566             :     }
    2567             : 
    2568           0 :     f_fx[m_fx] = 0;
    2569           0 :     move16();
    2570           0 :     amp_fx[m_fx] = 0;
    2571           0 :     move16();
    2572           0 :     m_fx = add( m_fx, 1 );
    2573             : 
    2574           0 :     FOR( i = 0; i < num_erb_fx; i++ )
    2575             :     {
    2576           0 :         IF( slot_fx[i] != 0 )
    2577             :         {
    2578           0 :             f_fx[m_fx] = mfreq_fx[i];
    2579           0 :             move16();
    2580           0 :             amp_fx[m_fx] = in_fx[i];
    2581           0 :             move16();
    2582           0 :             m_fx = add( m_fx, 1 );
    2583             :         }
    2584             :     }
    2585           0 :     f_fx[m_fx] = upper_cut_off_freq_fx;
    2586           0 :     move16();
    2587           0 :     amp_fx[m_fx] = 0;
    2588           0 :     move16();
    2589           0 :     m_fx = add( m_fx, 1 );
    2590             : 
    2591           0 :     exp = norm_s( X_fx->lag_fx );
    2592           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx->lag_fx ); /* 29-exp */
    2593           0 :     diff_fx = shl( tmp, sub( exp, 10 ) );                  /* Q19 */
    2594             : 
    2595           0 :     min_q = EVS_SW_MAX;
    2596           0 :     move16();
    2597           0 :     X_fx->a_fx[0] = 0;
    2598           0 :     move16();
    2599             : 
    2600           0 :     HalfLag_fx = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
    2601             : 
    2602           0 :     j = 1;
    2603           0 :     move16();
    2604           0 :     FOR( i = 1; i <= HalfLag_fx; i++ )
    2605             :     {
    2606           0 :         Ltemp_fx = L_mult( diff_fx, i );             /*  Ltemp=i*diff, Q20 */
    2607           0 :         freq_fx = round_fx( L_shl( Ltemp_fx, 11 ) ); /*  Q15                             */
    2608             : 
    2609           0 :         freq_fx = s_min( freq_fx, upper_cut_off_freq_fx ); /*  0x4000 is 0.5 in Q15 */
    2610             : 
    2611           0 :         FOR( ; j < m_fx; j++ )
    2612             :         {
    2613           0 :             d1 = sub( f_fx[j], freq_fx );
    2614             : 
    2615           0 :             IF( d1 >= 0 )
    2616             :             {
    2617           0 :                 d2 = sub( freq_fx, f_fx[j - 1] );
    2618           0 :                 Ltemp_fx = L_mac( L_mult( amp_fx[j], d2 ), amp_fx[j - 1], d1 ); /*  Q29 */
    2619           0 :                 d2 = sub( f_fx[j], f_fx[j - 1] );                               /*  Q15 */
    2620             :                 /* Ltemp2_fx=invert_dp((Word40)d2, 4, &n,1); : Ltemp2=1/d2, Q(61-15-n) */
    2621           0 :                 exp = norm_s( d2 );
    2622           0 :                 tmp = div_s( shl( 1, sub( 14, exp ) ), d2 ); /* 29-exp */
    2623             :                 /* L_tmp = L_shr(tmp,8); */
    2624           0 :                 Ltemp2_fx = L_shl( tmp, 16 );
    2625           0 :                 n = add( exp, 16 );
    2626             : 
    2627           0 :                 d1h = extract_h( Ltemp_fx );
    2628           0 :                 d1l = extract_l( Ltemp_fx );
    2629           0 :                 d2h = extract_h( Ltemp2_fx );
    2630           0 :                 d2l = extract_l( Ltemp2_fx );
    2631           0 :                 Ltemp_fx = (Word32) L_mult0( d1h, d2l );
    2632           0 :                 Lacc_fx = L_mac0( (Word32) Ltemp_fx, d2h, d1l );
    2633           0 :                 Ltemp_fx = L_add( (Word32) L_shr( Lacc_fx, 15 ), L_mult( d1h, d2h ) ); /*  46-n+29-31 */
    2634           0 :                 d2h = norm_l( Ltemp_fx );                                              /*  d2h is 0 IF Ltemp=0 */
    2635           0 :                 if ( Ltemp_fx == 0 )
    2636             :                 {
    2637           0 :                     d2h = 31;
    2638           0 :                     move16();
    2639             :                 }
    2640           0 :                 X_fx->a_fx[i] = round_fx_sat( L_shl_sat( Ltemp_fx, d2h ) ); /*  Q(28-n+d2h) */
    2641           0 :                 move16();
    2642           0 :                 q[i] = add( sub( 28, n ), d2h );
    2643           0 :                 move16();
    2644           0 :                 min_q = s_min( min_q, q[i] );
    2645             : 
    2646           0 :                 BREAK;
    2647             :             }
    2648             :         }
    2649             :     }
    2650             :     /*  block normalize a[i] */
    2651           0 :     FOR( i = 1; i <= HalfLag_fx; i++ )
    2652             :     {
    2653           0 :         X_fx->a_fx[i] = shl( X_fx->a_fx[i], sub( min_q, q[i] ) );
    2654           0 :         move16();
    2655             :     }
    2656             : 
    2657           0 :     X_fx->Q = min_q;
    2658           0 :     move16();
    2659           0 :     return;
    2660             : }
    2661             : 
    2662             : 
    2663             : /*===================================================================*/
    2664             : /* FUNCTION      :  erb_add_fx ()                                    */
    2665             : /*-------------------------------------------------------------------*/
    2666             : /* PURPOSE       :  Reconstruct current erb amplitude for QPPP       */
    2667             : /*-------------------------------------------------------------------*/
    2668             : /* INPUT ARGUMENTS  :                                                */
    2669             : /*   _ (Word16) pl_fx :  previous pitch lag, Q0                      */
    2670             : /*   _ (Word16) l_fx :   current pitch lag, Q0                       */
    2671             : /*   _ (Word16 []) prev_erb_fx : Previous erb amplitude, Q13         */
    2672             : /*   _ (Word16 []) index_fx: quantized differential erb index        */
    2673             : /*-------------------------------------------------------------------*/
    2674             : /* OUTPUT ARGUMENTS :                                                */
    2675             : /*   _ (Word16 []) curr_erb_fx : Current erb amplitude, Q13          */
    2676             : /*-------------------------------------------------------------------*/
    2677             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2678             : /*                    _ None                                         */
    2679             : /*-------------------------------------------------------------------*/
    2680             : /* RETURN ARGUMENTS : _ None.                                        */
    2681             : /*-------------------------------------------------------------------*/
    2682             : /* CALLED FROM : TX/RX                                               */
    2683             : /*===================================================================*/
    2684           0 : void erb_add_fx(
    2685             :     Word16 *curr_erb_fx,       /* i/o:  current ERB    */
    2686             :     Word16 l_fx,               /* i  :  current lag    */
    2687             :     const Word16 *prev_erb_fx, /* i  :  previous ERB   */
    2688             :     Word16 pl_fx,              /* i  :  previous lag   */
    2689             :     const Word16 *index_fx,    /* i  :  ERB index      */
    2690             :     Word16 num_erb_fx          /* i  :  number of ERBs */
    2691             : )
    2692             : {
    2693             :     Word16 i;
    2694             :     Word16 pslot_fx[NUM_ERB_WB], cslot_fx[NUM_ERB_WB], t_prev_erb_fx[NUM_ERB_WB];
    2695             :     Word16 tmp_fx, tmp2_fx, tmp_loop;
    2696           0 :     const Word16 *AmpCB1_fx = NULL; /*move16(); */
    2697             : 
    2698           0 :     IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
    2699             :     {
    2700           0 :         AmpCB1_fx = AmpCB1_NB_fx;
    2701           0 :         move16();
    2702             :     }
    2703           0 :     ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
    2704             :     {
    2705           0 :         AmpCB1_fx = AmpCB1_WB_fx;
    2706           0 :         move16();
    2707             :     }
    2708             : 
    2709           0 :     erb_slot_fx( l_fx, cslot_fx, t_prev_erb_fx, num_erb_fx );
    2710           0 :     erb_slot_fx( pl_fx, pslot_fx, t_prev_erb_fx, num_erb_fx );
    2711             : 
    2712           0 :     FOR( i = 0; i < num_erb_fx; i++ )
    2713             :     {
    2714           0 :         t_prev_erb_fx[i] = prev_erb_fx[i];
    2715           0 :         move16(); /* Q13 */
    2716             :     }
    2717             : 
    2718             : 
    2719           0 :     IF( GT_16( pl_fx, l_fx ) )
    2720             :     {
    2721           0 :         tmp_fx = t_prev_erb_fx[0];
    2722           0 :         move16(); /* Q13  */
    2723           0 :         FOR( i = 0; i < num_erb_fx; i++ )
    2724             :         {
    2725             : 
    2726           0 :             IF( pslot_fx[i] != 0 )
    2727             :             {
    2728           0 :                 tmp_fx = t_prev_erb_fx[i];
    2729           0 :                 move16(); /* Q13 */
    2730             :             }
    2731             :             ELSE
    2732             :             {
    2733           0 :                 t_prev_erb_fx[i] = tmp_fx;
    2734           0 :                 move16(); /* Q13 */
    2735             :             }
    2736             :         }
    2737             :     }
    2738           0 :     ELSE IF( GT_16( l_fx, pl_fx ) )
    2739             :     {
    2740           0 :         tmp_fx = t_prev_erb_fx[( num_erb_fx - 1 )]; /* Q13 */
    2741           0 :         FOR( i = ( num_erb_fx - 1 ); i >= 0; i-- )
    2742             :         {
    2743             : 
    2744           0 :             IF( pslot_fx[i] != 0 )
    2745             :             {
    2746           0 :                 tmp_fx = t_prev_erb_fx[i];
    2747           0 :                 move16(); /* Q13 */
    2748             :             }
    2749             :             ELSE
    2750             :             {
    2751           0 :                 t_prev_erb_fx[i] = tmp_fx;
    2752           0 :                 move16(); /* Q13 */
    2753             :             }
    2754             :         }
    2755             :     }
    2756             : 
    2757           0 :     tmp_fx = add( shl( index_fx[0], 3 ), shl( index_fx[0], 1 ) ); /*  tmp_fx=10*index_fx[0] */
    2758           0 :     FOR( i = 1; i < 11; i++ )
    2759             :     {
    2760             : 
    2761           0 :         IF( cslot_fx[i] != 0 )
    2762             :         {
    2763           0 :             curr_erb_fx[i] = add( AmpCB1_fx[( ( tmp_fx + i ) - 1 )], t_prev_erb_fx[i] );
    2764           0 :             move16(); /*  Q13+Q13=Q13 */
    2765           0 :             curr_erb_fx[i] = s_max( 0, curr_erb_fx[i] );
    2766           0 :             move16();
    2767             :         }
    2768             :         ELSE
    2769             :         {
    2770           0 :             curr_erb_fx[i] = 0;
    2771           0 :             move16();
    2772             :         }
    2773             :     }
    2774             : 
    2775           0 :     tmp_fx = add( shl( index_fx[1], 3 ), index_fx[1] ); /*  tmp=9*index[1] */
    2776           0 :     tmp2_fx = mult( shl( index_fx[1], 6 ), 5632 );      /* temp=11*index_fx[1] */
    2777           0 :     tmp_loop = sub( num_erb_fx, 2 );
    2778           0 :     FOR( i = 11; i < tmp_loop; i++ )
    2779             :     {
    2780             : 
    2781           0 :         IF( cslot_fx[i] != 0 )
    2782             :         {
    2783           0 :             IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
    2784             :             {
    2785           0 :                 curr_erb_fx[i] = add( AmpCB2_NB_fx[( ( tmp_fx + i ) - 11 )], t_prev_erb_fx[i] ); /* Q13+Q13=Q13 */
    2786           0 :                 move16();
    2787           0 :                 curr_erb_fx[i] = s_max( 0, curr_erb_fx[i] );
    2788           0 :                 move16();
    2789             :             }
    2790           0 :             ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
    2791             :             {
    2792           0 :                 curr_erb_fx[i] = add( AmpCB2_WB_fx[( ( tmp2_fx + i ) - 11 )], t_prev_erb_fx[i] ); /* Q13 */
    2793           0 :                 move16();
    2794           0 :                 curr_erb_fx[i] = s_max( 0, curr_erb_fx[i] );
    2795           0 :                 move16();
    2796             :             }
    2797             :         }
    2798             :         ELSE
    2799             :         {
    2800           0 :             curr_erb_fx[i] = 0;
    2801           0 :             move16();
    2802             :         }
    2803             :     }
    2804           0 :     return;
    2805             : }
    2806             : 
    2807             : 
    2808             : /*===================================================================*/
    2809             : /* FUNCTION      :  struct quant_target_fx()                          */
    2810             : /*-------------------------------------------------------------------*/
    2811             : /* PURPOSE       :  Get weighting and target for power quantization  */
    2812             : /*-------------------------------------------------------------------*/
    2813             : /* INPUT ARGUMENTS  :                                                */
    2814             : /*   _ (Word16 []) curr_lpc: LPC coefficients, Q12                   */
    2815             : /*   _ (Word16 []) sin_tab: sine table based on lag, Q15             */
    2816             : /*   _ (Word16 []) cos_tab: cosine table based on lag, Q15           */
    2817             : /*-------------------------------------------------------------------*/
    2818             : /* OUTPUT ARGUMENTS :                                                */
    2819             : /*   _ (Word16[]) w: Weighting for power quantization, Q15           */
    2820             : /*   _ (Word16[]) target: Power of 2 bands for quantization, Q11     */
    2821             : /*-------------------------------------------------------------------*/
    2822             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    2823             : /*   _ (struct DTFS_fx) X :  prototype in polar domain                      */
    2824             : /*                (Word16) lag: length of prototype in time domain   */
    2825             : /*                (Word16 []) a: amplitude of harmonics, normalized  */
    2826             : /*                (Word16) Q: norm factor of a                       */
    2827             : /*-------------------------------------------------------------------*/
    2828             : /* RETURN ARGUMENTS :                                                */
    2829             : /*                    _ None                                         */
    2830             : /*-------------------------------------------------------------------*/
    2831             : /* CALLED FROM : TX                                                  */
    2832             : /*===================================================================*/
    2833             : /* NOTE: This function is used by quant_cw_fx and quant_cw_memless_fx*/
    2834             : /*===================================================================*/
    2835           0 : void quant_target_fx( DTFS_STRUCTURE *X_fx, const Word16 *curr_lpc, Word16 *w, Word16 *target, Word16 *sin_tab, Word16 *cos_tab )
    2836             : {
    2837             :     Word16 tmp, n, exp;
    2838             :     Word16 Ql, Qh;
    2839             :     Word32 Ltemp1, Ltemp, Ltemp2, logLag, Ltemp3, Lacc;
    2840             : 
    2841           0 :     tmp = sub( shl( X_fx->Q, 1 ), 13 );        /*  tmp=2Q-13, Q factor of getSpEngy... output */
    2842           0 :     Ltemp3 = L_shl( L_mult( tmp, 24660 ), 9 ); /*  Ltemp3=(2Q-13)*10log10(2), Q23, 24660=10log10(2) in Q13 */
    2843             : 
    2844           0 :     Ltemp1 = getSpEngyFromResAmp_fx( X_fx, 0, 2828, curr_lpc, sin_tab, cos_tab );
    2845           0 :     Ltemp1 = log10_fx( Ltemp1 );
    2846             : 
    2847             :     /*  subtract 10log10(2)*(2Q-13), Q23 */
    2848           0 :     Ltemp1 = L_sub_sat( Ltemp1, Ltemp3 );
    2849           0 :     Ltemp1 = L_max( 0, Ltemp1 );
    2850           0 :     Ltemp2 = getSpEngyFromResAmp_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, curr_lpc, sin_tab, cos_tab );
    2851           0 :     Ltemp2 = log10_fx( Ltemp2 );          /*  Ltemp1=10log10(eng_hb), Q23, need to adjust for Q factor of energy (2Q-13) */
    2852           0 :     Ltemp2 = L_sub_sat( Ltemp2, Ltemp3 ); /*  Ltemp2 in Q23 */
    2853             : 
    2854           0 :     Ltemp2 = L_max( 0, Ltemp2 );
    2855             : 
    2856             :     /* Getting the Speech Domain Energy LOG Ratio    */
    2857             : 
    2858           0 :     Lacc = L_add( Ltemp1, Ltemp2 );
    2859           0 :     exp = norm_l( Lacc );
    2860           0 :     tmp = round_fx( L_shl( Lacc, exp ) );
    2861           0 :     exp = sub( sub( 30, exp ), 23 );
    2862           0 :     IF( tmp )
    2863             :     {
    2864           0 :         tmp = div_s( 16384, tmp ); /* 15+exp1 */
    2865             :     }
    2866             :     ELSE
    2867             :     {
    2868           0 :         tmp = 0;
    2869           0 :         move16();
    2870             :     }
    2871           0 :     Ltemp = L_deposit_h( tmp );
    2872             : 
    2873           0 :     tmp = round_fx( Ltemp );            /*  tmp in Q(22-n) */
    2874           0 :     Ltemp1 = Mult_32_16( Ltemp1, tmp ); /*  Q(30-n) */
    2875           0 :     n = sub( 8, exp );
    2876           0 :     w[0] = round_fx_sat( L_shl_sat( Ltemp1, n ) ); /*  w[0] in Q15 */
    2877           0 :     move16();
    2878           0 :     Ltemp2 = Mult_32_16( Ltemp2, tmp );
    2879           0 :     w[1] = round_fx_sat( L_shl_sat( Ltemp2, n ) ); /*  w[1] in Q15 */
    2880           0 :     move16();
    2881             : 
    2882           0 :     logLag = log10_fx( X_fx->lag_fx );                       /*  logLag=10*log10(lag), Q23 */
    2883           0 :     Ltemp3 = L_shl( L_mult( shl( X_fx->Q, 1 ), 24660 ), 9 ); /*  Ltemp3=2Q*10log10(2), Q23 */
    2884             :     /* Process low band */
    2885           0 :     Ltemp = DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, X_fx ); /*  Ql is norm factor of low band a[], Ltemp is energy in 2Q */
    2886             :     /* Compensate for Q factor of energy to get log10(lag*eng)  */
    2887           0 :     Ltemp = log10_fx( Ltemp );                       /*  Ltemp=10log10(eng), Q23 */
    2888           0 :     Ltemp = L_add( L_sub( Ltemp, Ltemp3 ), logLag ); /*  Ltemp=10*log10(lag*eng), Q23 */
    2889             : 
    2890           0 :     target[0] = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /*  Q11 */
    2891           0 :     move16();
    2892             : 
    2893             :     /* Process high band */
    2894           0 :     Ltemp = DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, 1, 0, &Qh, X_fx );
    2895           0 :     Ltemp = log10_fx( Ltemp );
    2896           0 :     Ltemp = L_add( L_sub( Ltemp, Ltemp3 ), logLag );                 /*  Ltemp=10*log10(lag*eng), Q23 */
    2897           0 :     target[1] = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /*  Q11 */
    2898           0 :     move16();
    2899             : 
    2900             :     /* Need to unify the Q factors of both bands */
    2901           0 :     X_fx->Q = s_min( Ql, Qh ); /*  set Q factor to be the smaller one */
    2902           0 :     move16();
    2903           0 :     n = sub( Ql, Qh ); /*  compare band Q factors */
    2904             : 
    2905           0 :     IF( n < 0 )
    2906             :     {
    2907           0 :         rshiftHarmBand_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, n );
    2908             :     }
    2909           0 :     ELSE IF( n > 0 )
    2910             :     {
    2911           0 :         rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) );
    2912             :     }
    2913           0 : }
    2914             : 
    2915             : /*==========================================================================*/
    2916             : /* FUNCTION      :  WIsyn_fx ()                                             */
    2917             : /*--------------------------------------------------------------------------*/
    2918             : /* PURPOSE       :                                                          */
    2919             : /*--------------------------------------------------------------------------*/
    2920             : /* INPUT ARGUMENTS  :                                                       */
    2921             : /*   _ (struct DTFS_STRUCTURE) PREVCW_FX: a/b in PREVCW_FX.Q             */
    2922             : /*   _ (struct DTFS_fx *) CURRCW_DTFS_out: a/b in CURRCW_DTFS_out->Q        */
    2923             : /*   _ (Word16 *) curr_lpc_fx: lpc coefficients in Q12                      */
    2924             : /*   _ (Word16 *) ph_offset_fx: in Q15, normalized by 2pi                   */
    2925             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                       */
    2926             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                       */
    2927             : /*   _ (Word16 *) N:     length, Q0                                         */
    2928             : /*--------------------------------------------------------------------------*/
    2929             : /* OUTPUT ARGUMENTS :                                                       */
    2930             : /*   _ (Word16 *) out_fx: Q0                                                */
    2931             : /*--------------------------------------------------------------------------*/
    2932             : /* INPUT/OUTPUT ARGUMENTS :                                                 */
    2933             : /* _ (struct DTFS_STRUCTURE *) CURRCW_DTFS_out: a/b in CURRCW_DTFS_out->Q*/
    2934             : /* _ (Word16 *) ph_offset_fx: in Q15, normalized by 2pi                     */
    2935             : /*--------------------------------------------------------------------------*/
    2936             : /* RETURN ARGUMENTS : _ None.                                               */
    2937             : /*==========================================================================*/
    2938           0 : ivas_error WIsyn_fx(
    2939             :     DTFS_STRUCTURE PREVCW_FX,        /* i  : Prev frame DTFS                                */
    2940             :     DTFS_STRUCTURE *CURRCW_DTFS_out, /* i/o: Curr frame DTFS                                */
    2941             :     const Word16 *curr_lpc_fx,       /* i  : LPC                                            */
    2942             :     Word16 *ph_offset_fx,            /* i/o: Phase offset to line up at end of frame        */
    2943             :     Word16 *out_fx,                  /* o  : Waveform Interpolated time domain signal       */
    2944             :     const Word16 N,                  /* i  : Number of output samples to generate           */
    2945             :     const Word16 FR_flag,            /* i  : called for post-smoothing in FR                */
    2946             :     Word16 *S_fx,
    2947             :     Word16 *C_fx,
    2948             :     Word16 *pf_temp1,
    2949             :     Word16 *pf_temp2,
    2950             :     Word16 *pf_temp,
    2951             :     Word16 *pf_n2 )
    2952             : {
    2953             :     Word16 i;
    2954           0 :     UWord16 I = 1, flag = 0;
    2955           0 :     move16();
    2956           0 :     move16();
    2957             :     /* Word16 *phase_fx = (Word16*)malloc(sizeof(Word16) * (2*N));         new operator used size 2*N */
    2958             :     Word32 phase_fx[WI_FX_phase_fx];
    2959             :     Word16 alignment_fx;
    2960             :     Word16 tmp_fx, temp;
    2961             :     Word32 L_temp;
    2962             :     Word16 exp, tmp;
    2963             :     Word32 L_tmp;
    2964             :     /* prev_lsp_fx; */
    2965             : 
    2966             : 
    2967             :     DTFS_STRUCTURE *CURRCW_DTFS_FX;
    2968             :     ivas_error error;
    2969             : 
    2970           0 :     error = IVAS_ERR_OK;
    2971           0 :     move16();
    2972             : 
    2973           0 :     IF( ( error = DTFS_new_fx( &CURRCW_DTFS_FX ) ) != IVAS_ERR_OK )
    2974             :     {
    2975           0 :         return IVAS_ERROR( error, "Error creating new DTFS structure\n" );
    2976             :     }
    2977           0 :     IF( LT_16( PREVCW_FX.Q, CURRCW_DTFS_out->Q ) )
    2978             :     {
    2979           0 :         temp = sub( CURRCW_DTFS_out->Q, PREVCW_FX.Q );
    2980           0 :         tmp = s_min( shr( CURRCW_DTFS_out->lag_fx, 1 ), CURRCW_DTFS_out->nH_fx );
    2981           0 :         FOR( i = 0; i <= tmp; i++ )
    2982             :         {
    2983           0 :             CURRCW_DTFS_out->a_fx[i] = shr( CURRCW_DTFS_out->a_fx[i], temp );
    2984           0 :             move16();
    2985           0 :             CURRCW_DTFS_out->b_fx[i] = shr( CURRCW_DTFS_out->b_fx[i], temp );
    2986           0 :             move16();
    2987             :         }
    2988           0 :         CURRCW_DTFS_out->Q = PREVCW_FX.Q;
    2989           0 :         move16();
    2990             :     }
    2991             : 
    2992             : 
    2993           0 :     IF( LT_16( CURRCW_DTFS_out->Q, PREVCW_FX.Q ) )
    2994             :     {
    2995           0 :         temp = sub( PREVCW_FX.Q, CURRCW_DTFS_out->Q );
    2996           0 :         tmp = s_min( shr( PREVCW_FX.lag_fx, 1 ), PREVCW_FX.nH_fx );
    2997           0 :         FOR( i = 0; i <= tmp; i++ )
    2998             :         {
    2999           0 :             PREVCW_FX.a_fx[i] = shr( PREVCW_FX.a_fx[i], temp );
    3000           0 :             move16();
    3001           0 :             PREVCW_FX.b_fx[i] = shr( PREVCW_FX.b_fx[i], temp );
    3002           0 :             move16();
    3003             :         }
    3004           0 :         PREVCW_FX.Q = CURRCW_DTFS_out->Q;
    3005           0 :         move16();
    3006             :     }
    3007             : 
    3008           0 :     DTFS_copy_fx( CURRCW_DTFS_FX, *CURRCW_DTFS_out );
    3009             : 
    3010             :     /* Calculating the expected alignment shift */
    3011           0 :     alignment_fx = mult_r( *ph_offset_fx, shl( PREVCW_FX.lag_fx, 7 ) ); /* confirmed I<2 by smv12.org, Q7 */
    3012             : 
    3013             : 
    3014           0 :     IF( EQ_16( flag, 1 ) )
    3015           0 :     alignment_fx = extract_l( L_shr( L_mult( alignment_fx, I ), 1 ) ); /* Q7 */
    3016             : 
    3017             :     /* Calculating the expected alignment shift */
    3018           0 :     find_rem( (Word16) N, shr( add( PREVCW_FX.lag_fx, CURRCW_DTFS_FX->lag_fx ), 1 ), &temp );
    3019           0 :     temp = add( shl( temp, 7 ), alignment_fx ); /*  Q7 */
    3020             : 
    3021             : 
    3022           0 :     IF( temp < 0 )
    3023             :     {
    3024           0 :         temp = add( temp, shl( CURRCW_DTFS_FX->lag_fx, 7 ) ); /*  Q7 */
    3025             :     }
    3026             : 
    3027           0 :     find_rem( temp, shl( CURRCW_DTFS_FX->lag_fx, 7 ), &tmp_fx ); /*  Q7 */
    3028           0 :     IF( FR_flag == 0 )
    3029             :     {
    3030           0 :         alignment_fx = DTFS_alignment_weight_fx( &PREVCW_FX, *CURRCW_DTFS_FX, tmp_fx, curr_lpc_fx, curr_lpc_fx, S_fx,
    3031             :                                                  C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 ); /* Q7 */
    3032             :     }
    3033             :     ELSE
    3034             :     {
    3035           0 :         alignment_fx = DTFS_alignment_full_fx( PREVCW_FX, *CURRCW_DTFS_FX, *ph_offset_fx, S_fx, C_fx, FR_flag );
    3036             : 
    3037             :         /*alignment_fx is in Q1, we make it Q7*/
    3038           0 :         alignment_fx = shl( alignment_fx, 6 );
    3039             :     }
    3040             : 
    3041             : 
    3042           0 :     IF( GE_16( alignment_fx, shl( CURRCW_DTFS_FX->lag_fx, 7 ) ) )
    3043             :     {
    3044           0 :         temp = sub( alignment_fx, shl( CURRCW_DTFS_FX->lag_fx, 7 ) );
    3045           0 :         tmp = shl( CURRCW_DTFS_FX->lag_fx, 7 );
    3046           0 :         exp = norm_s( tmp );
    3047           0 :         tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* 22-exp */
    3048           0 :         L_tmp = L_shl( L_mult( temp, tmp ), add( exp, 1 ) );
    3049           0 :         tmp_fx = round_fx( L_tmp );
    3050             :     }
    3051           0 :     ELSE IF( alignment_fx < 0 )
    3052             :     {
    3053           0 :         temp = negate( alignment_fx );
    3054           0 :         tmp = shl( CURRCW_DTFS_FX->lag_fx, 7 );
    3055           0 :         exp = norm_s( tmp );
    3056           0 :         tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* 22-exp */
    3057           0 :         L_tmp = L_shl( L_mult( temp, tmp ), add( exp, 1 ) );
    3058           0 :         tmp_fx = negate( round_fx( L_tmp ) );
    3059             :     }
    3060             :     ELSE
    3061             :     {
    3062           0 :         temp = alignment_fx;
    3063           0 :         move16();
    3064           0 :         tmp = shl( CURRCW_DTFS_FX->lag_fx, 7 );
    3065           0 :         exp = norm_s( tmp );
    3066           0 :         tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* 22-exp */
    3067           0 :         L_tmp = L_shl( L_mult( temp, tmp ), add( exp, 1 ) );
    3068           0 :         tmp_fx = round_fx( L_tmp );
    3069             :     }
    3070             : 
    3071           0 :     DTFS_phaseShift_fx( CURRCW_DTFS_FX, alignment_fx, CURRCW_DTFS_FX->lag_fx, S_fx, C_fx );   /*  Qmin */
    3072           0 :     DTFS_phaseShift_fx( CURRCW_DTFS_out, alignment_fx, CURRCW_DTFS_out->lag_fx, S_fx, C_fx ); /*  Qmin */
    3073             : 
    3074             :     /*  Compute the cubic phase track and transform to 1-D signal */
    3075           0 :     cubicPhase_fx( *ph_offset_fx, tmp_fx, PREVCW_FX.lag_fx, CURRCW_DTFS_FX->lag_fx, N, phase_fx );
    3076             : 
    3077           0 :     temp = shr( add( PREVCW_FX.lag_fx, CURRCW_DTFS_FX->lag_fx ), 1 ); /*  Q0 */
    3078             : 
    3079           0 :     IF( FR_flag == 0 )
    3080             :     {
    3081           0 :         DTFS_transform_fx( PREVCW_FX, *CURRCW_DTFS_FX, phase_fx, out_fx, N, 0 );
    3082             :     }
    3083             :     ELSE
    3084             :     {
    3085           0 :         DTFS_transform_fx( PREVCW_FX, *CURRCW_DTFS_FX, phase_fx, out_fx, N, 1 );
    3086             :     }
    3087             : 
    3088             : 
    3089             :     /*  Adjust the phase offset and wrap it between 0 and 2pi */
    3090             : 
    3091             :     // PMT("NEED a complete verification of mem flow and assignment")
    3092             : 
    3093             : 
    3094           0 :     IF( EQ_16( flag, 2 ) )
    3095             :     {
    3096           0 :         L_temp = L_shr( L_mult( tmp_fx, I ), 1 ); /*  Q15 */
    3097             :     }
    3098             :     ELSE
    3099             :     {
    3100           0 :         L_temp = L_deposit_l( tmp_fx ); /*  Q15 */
    3101             :     }
    3102             : 
    3103             : 
    3104           0 :     FOR( ; L_temp < 0; L_temp += 0x8000L )
    3105             :     {
    3106             :         /* empty loop */
    3107             :     }
    3108           0 :     L_temp = L_and( L_temp, 0x7fff );
    3109           0 :     move16(); /*  fraction part */
    3110           0 :     *ph_offset_fx = extract_l( L_temp );
    3111           0 :     move16();
    3112             : 
    3113             :     /* free(phase_fx) ; */
    3114           0 :     free( CURRCW_DTFS_FX );
    3115           0 :     return error;
    3116             : }
    3117             : 
    3118             : 
    3119             : /*===================================================================*/
    3120             : /* FUNCTION      :  ppp_extract_pitch_period_fx ()                   */
    3121             : /*-------------------------------------------------------------------*/
    3122             : /* PURPOSE       :  Update background noise estimate, signal energy  */
    3123             : /*                  estimate, and band snrs                          */
    3124             : /*-------------------------------------------------------------------*/
    3125             : /* INPUT ARGUMENTS  :                                                */
    3126             : /*   _ (Word16 []) in :  residual input, Q0                          */
    3127             : /*   _ (Word16) l :  pitch lag, Q0                                   */
    3128             : /*-------------------------------------------------------------------*/
    3129             : /* OUTPUT ARGUMENTS :                                                */
    3130             : /*   _ (Word16 []) out :  pitch period prototype, Q0                 */
    3131             : /*   _ (Word16*) out_of_bound :  pitch lag, Q0                       */
    3132             : /*-------------------------------------------------------------------*/
    3133             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3134             : /*                    _ None                                         */
    3135             : /*-------------------------------------------------------------------*/
    3136             : /* RETURN ARGUMENTS :                                                 */
    3137             : /*   _ (Word16) spike_near_edge :   Q0                                */
    3138             : /*===================================================================*/
    3139           0 : Word16 ppp_extract_pitch_period_fx(
    3140             :     const Word16 *in,     /* i : input residual     */
    3141             :     Word16 *out,          /* o : output residual    */
    3142             :     Word16 l,             /* i : lag                */
    3143             :     Word16 *out_of_bound, /* o : out of bound flag  */
    3144             :     Word16 Qres
    3145             : 
    3146             : )
    3147             : {
    3148             :     Word16 i, j, k;
    3149           0 :     Word16 spike = 0, range;
    3150           0 :     move16();
    3151           0 :     Word16 max = 0;
    3152           0 :     move16();
    3153           0 :     const Word16 *ptr = in + L_FRAME - l;
    3154           0 :     Word32 en1 = 0, Lacc, L_tmp;
    3155           0 :     move32();
    3156           0 :     Word16 spike_near_edge = 0, scale;
    3157           0 :     move16();
    3158             :     Word16 pos_max, neg_max;
    3159           0 :     Word16 spike_pos = 0, spike_neg = 0;
    3160           0 :     move16();
    3161           0 :     move16();
    3162             :     Word16 x, tmp, expa, fraca, expb, fracb, scale1, exp;
    3163             : 
    3164           0 :     pos_max = -0x8000L;
    3165           0 :     move16();
    3166           0 :     neg_max = 0;
    3167           0 :     move16();
    3168           0 :     *out_of_bound = 0;
    3169           0 :     move16();
    3170             : 
    3171           0 :     en1 = L_deposit_l( 0 );
    3172           0 :     FOR( i = 0; i < l; i++ )
    3173             :     {
    3174           0 :         x = abs_s( ptr[i] );
    3175             : 
    3176           0 :         IF( GT_16( x, max ) )
    3177             :         {
    3178           0 :             max = x;
    3179           0 :             move16();
    3180           0 :             spike = i;
    3181           0 :             move16();
    3182             :         }
    3183           0 :         en1 = L_mac0_sat( en1, ptr[i], ptr[i] ); /*  Q0 */
    3184             :     }
    3185             : 
    3186           0 :     IF( ptr[spike] > 0 )
    3187             :     {
    3188           0 :         spike_pos = spike;
    3189           0 :         move16();
    3190             :         /* search for neg spike around the pos spike */
    3191           0 :         FOR( j = spike - 10; j < spike + 10; j++ )
    3192             :         {
    3193           0 :             k = add( j, l ) % l;
    3194           0 :             move16();
    3195             : 
    3196           0 :             IF( LT_16( ptr[k], neg_max ) )
    3197             :             {
    3198           0 :                 neg_max = ptr[k];
    3199           0 :                 move16();
    3200           0 :                 spike_neg = k;
    3201           0 :                 move16();
    3202             :             }
    3203             :         }
    3204             :     }
    3205           0 :     ELSE IF( ptr[spike] < 0 )
    3206             :     {
    3207           0 :         spike_neg = spike;
    3208           0 :         move16();
    3209             :         /* search for pos spike around the neg spike */
    3210           0 :         FOR( j = spike - 10; j < spike + 10; j++ )
    3211             :         {
    3212           0 :             k = add( j, l ) % l;
    3213           0 :             move16();
    3214             : 
    3215           0 :             IF( GT_16( ptr[k], pos_max ) )
    3216             :             {
    3217           0 :                 pos_max = ptr[k];
    3218           0 :                 move16();
    3219           0 :                 spike_pos = k;
    3220           0 :                 move16();
    3221             :             }
    3222             :         }
    3223             :     }
    3224             : 
    3225           0 :     test();
    3226           0 :     IF( ( LE_16( sub( sub( l, 1 ), s_max( spike_pos, spike_neg ) ), 2 ) ) || ( LE_16( s_min( spike_pos, spike_neg ), 2 ) ) )
    3227             :     {
    3228           0 :         *out_of_bound = 1;
    3229           0 :         move16();
    3230           0 :         return spike_near_edge;
    3231             :     }
    3232             : 
    3233             : 
    3234           0 :     tmp = extract_l( ( L_max( L_mult( CUTFREE_REL_RANGE_Q2, l ), CUTFREE_ABS_RANGE_Q3 ) ) ); /* Q3 */
    3235             : 
    3236           0 :     IF( tmp > 0 )
    3237             :     {
    3238           0 :         tmp = add( tmp, 4 ); /* Q3 */
    3239             :     }
    3240             :     ELSE
    3241             :     {
    3242           0 :         tmp = sub( tmp, 4 ); /* Q3 */
    3243             :     }
    3244           0 :     range = shr( tmp, 3 ); /* Q0 */
    3245             : 
    3246           0 :     test();
    3247           0 :     IF( ( LT_16( spike, range ) ) || ( GE_16( add( spike, range ), l ) ) )
    3248             :     {
    3249             :         /* need to grab from one lag before
    3250             :         ensure that there is no array bound read */
    3251             : 
    3252           0 :         IF( LT_16( sub( L_FRAME, l ), l ) )
    3253             :         {
    3254           0 :             *out_of_bound = 1;
    3255           0 :             move16();
    3256           0 :             return spike_near_edge;
    3257             :         }
    3258           0 :         spike_near_edge = 1;
    3259           0 :         move16();
    3260             :     }
    3261             : 
    3262           0 :     IF( LT_16( spike, range ) )
    3263             :     {
    3264           0 :         tmp = add( l, sub( spike, range ) );
    3265           0 :         FOR( i = 0; i < tmp; i++ )
    3266             :         {
    3267           0 :             out[i] = ptr[i];
    3268           0 :             move16();
    3269             :         }
    3270             :         /* Grab Remaining From One Lag Before */
    3271           0 :         ptr -= l;
    3272           0 :         FOR( ; i < l; i++ )
    3273             :         {
    3274           0 :             out[i] = ptr[i];
    3275           0 :             move16();
    3276             :         }
    3277             :     }
    3278           0 :     ELSE IF( GE_16( add( spike, range ), l ) )
    3279             :     {
    3280           0 :         tmp = sub( spike, range );
    3281           0 :         FOR( i = 0; i < tmp; i++ )
    3282             :         {
    3283           0 :             out[i] = ptr[i];
    3284           0 :             move16();
    3285             :         }
    3286             :         /* Grab Remaining From One Lag Before */
    3287           0 :         IF( ptr - l + i >= in )
    3288             :         {
    3289           0 :             FOR( ptr -= l; i < l; i++ )
    3290             :             {
    3291           0 :                 out[i] = ptr[i];
    3292           0 :                 move16();
    3293             :             }
    3294             :         }
    3295             :         ELSE
    3296             :         {
    3297           0 :             FOR( ; i < l; i++ )
    3298             :             {
    3299           0 :                 out[i] = ptr[i];
    3300           0 :                 move16();
    3301             :             }
    3302             :         }
    3303             :     }
    3304             :     ELSE
    3305             :     {
    3306           0 :         FOR( i = 0; i < l; i++ )
    3307             :         {
    3308           0 :             out[i] = ptr[i];
    3309           0 :             move16();
    3310             :         }
    3311             :     }
    3312             :     /* Energy adjustment added to eliminate artifacts at the end of voicing */
    3313           0 :     Lacc = L_deposit_l( 0 );
    3314           0 :     FOR( i = 0; i < l; i++ )
    3315             :     {
    3316           0 :         Lacc = L_mac0_sat( Lacc, out[i], out[i] ); /*  Q0 */
    3317             :     }
    3318             : 
    3319             : 
    3320           0 :     IF( LT_32( en1, Lacc ) )
    3321             :     {
    3322             :         /*  Ltmp=sqrt_divide_dp(en1, Lacc, 0, &n,1); */
    3323             :         /*  scale=round_fx(L_shl(Ltmp,sub(31,n))); in Q15 */
    3324           0 :         expa = norm_l( en1 );
    3325           0 :         fraca = extract_h( L_shl( en1, expa ) );
    3326           0 :         expa = sub( 30, add( expa, Qres ) );
    3327             : 
    3328             : 
    3329           0 :         expb = norm_l( Lacc );
    3330           0 :         fracb = round_fx_sat( L_shl_sat( Lacc, expb ) );
    3331           0 :         expb = sub( 30, add( expb, Qres ) );
    3332             : 
    3333           0 :         scale1 = shr( sub( fraca, fracb ), 15 );
    3334           0 :         fracb = shl( fracb, scale1 );
    3335           0 :         expb = sub( expb, scale1 );
    3336             : 
    3337           0 :         tmp = div_s( fracb, fraca );
    3338           0 :         exp = sub( expb, expa );
    3339             : 
    3340           0 :         L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    3341           0 :         scale = round_fx( L_tmp );                    /* Q15 */
    3342             : 
    3343           0 :         FOR( i = 0; i < l; i++ )
    3344             :         {
    3345           0 :             out[i] = mult_r( out[i], scale );
    3346           0 :             move16();
    3347             :         }
    3348             :     }
    3349           0 :     return spike_near_edge;
    3350             : }
    3351             : /*===========================================================================*/
    3352             : /* FUNCTION      :  DTFS_peaktoaverage_fx ()                                 */
    3353             : /*---------------------------------------------------------------------------*/
    3354             : /* PURPOSE       :                                                           */
    3355             : /*---------------------------------------------------------------------------*/
    3356             : /* INPUT ARGUMENTS  :                                                        */
    3357             : /*   _ (struct DTFS_STRUCTURE) X_fx: a_fx/b_fx in Q(X_fx.Q), lag in Q0    */
    3358             : /*---------------------------------------------------------------------------*/
    3359             : /* OUTPUT ARGUMENTS :                                                        */
    3360             : /*   _ (Word32 *) pos_fx :  in *Qpos                                         */
    3361             : /*   _ (Word32 *) neg_fx :  in *Qneg                                         */
    3362             : /*   _ (Word16 *) Qpos: Q valule of output *pos_fx                           */
    3363             : /*   _ (Word16 *) Qneg: Q valule of output *neg_fx                           */
    3364             : /*---------------------------------------------------------------------------*/
    3365             : /* INPUT/OUTPUT ARGUMENTS :                                                  */
    3366             : /*                    _ None                                                 */
    3367             : /*---------------------------------------------------------------------------*/
    3368             : /* RETURN ARGUMENTS : _ None.                                                */
    3369             : /*===========================================================================*/
    3370           0 : void DTFS_peaktoaverage_fx( DTFS_STRUCTURE X_fx, Word32 *pos_fx, Word16 *Qpos, Word32 *neg_fx, Word16 *Qneg )
    3371             : {
    3372             :     Word32 L_sum;
    3373           0 :     Word32 maxPosEn_fx = 0, maxNegEn_fx = 0, L_temp;
    3374           0 :     move32();
    3375           0 :     move32();
    3376             :     Word16 i;
    3377             :     Word16 time_fx[256];
    3378             :     Word16 expa, expb, fraca, fracb, scale;
    3379             :     Word16 exp, tmp;
    3380             :     Word32 L_tmp;
    3381           0 :     L_sum = DTFS_getEngy_P2A_fx( &X_fx ); /*  2Q */
    3382           0 :     DTFS_fast_fs_inv_fx( &X_fx, time_fx, 256, 8 );
    3383             : 
    3384           0 :     FOR( i = 0; i < 256; i++ )
    3385             :     {
    3386           0 :         L_temp = L_mult_sat( time_fx[i], time_fx[i] ); /*  Q(1) */
    3387           0 :         IF( time_fx[i] >= 0 )
    3388             :         {
    3389           0 :             if ( GT_32( L_temp, maxPosEn_fx ) )
    3390             :             {
    3391           0 :                 maxPosEn_fx = L_temp; /*  Q(1) */
    3392           0 :                 move32();
    3393             :             }
    3394             :         }
    3395             :         ELSE
    3396             :         {
    3397           0 :             if ( GT_32( L_temp, maxNegEn_fx ) )
    3398             :             {
    3399           0 :                 maxNegEn_fx = L_temp; /*  Q(1) */
    3400           0 :                 move32();
    3401             :             }
    3402             :         }
    3403             :     }
    3404             : 
    3405             : 
    3406           0 :     IF( L_sum == 0 )
    3407             :     {
    3408           0 :         *pos_fx = *neg_fx = 0;
    3409           0 :         move32();
    3410           0 :         move32();
    3411             :     }
    3412             :     ELSE
    3413             :     {
    3414           0 :         IF( maxPosEn_fx == 0 )
    3415             :         {
    3416           0 :             *pos_fx = 0;
    3417           0 :             move32();
    3418           0 :             *Qpos = 31;
    3419           0 :             move16();
    3420             :         }
    3421             :         ELSE
    3422             :         {
    3423           0 :             expa = norm_l( maxPosEn_fx );
    3424           0 :             fraca = extract_h( L_shl( maxPosEn_fx, expa ) );
    3425           0 :             expa = sub( 30, add( expa, 1 ) );
    3426             : 
    3427             : 
    3428           0 :             expb = norm_l( L_sum );
    3429           0 :             fracb = round_fx_sat( L_shl( L_sum, expb ) );
    3430             : 
    3431           0 :             expb = sub( 30, add( expb, shl( X_fx.Q, 1 ) ) );
    3432             : 
    3433             : 
    3434           0 :             scale = shr( sub( fraca, fracb ), 15 );
    3435           0 :             fracb = shl_sat( fracb, scale );
    3436           0 :             expb = sub( expb, scale );
    3437             : 
    3438           0 :             tmp = div_s( fracb, fraca );
    3439           0 :             exp = sub( expb, expa );
    3440             : 
    3441           0 :             L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    3442           0 :             *pos_fx = L_tmp;
    3443           0 :             move32();
    3444           0 :             *Qpos = sub( 31, exp );
    3445           0 :             move16();
    3446             :         }
    3447             : 
    3448           0 :         IF( maxNegEn_fx == 0 )
    3449             :         {
    3450           0 :             *neg_fx = 0;
    3451           0 :             move32();
    3452           0 :             *Qneg = 31;
    3453           0 :             move16();
    3454             :         }
    3455             :         ELSE
    3456             :         {
    3457             : 
    3458           0 :             expa = norm_l( maxNegEn_fx );
    3459           0 :             fraca = extract_h( L_shl( maxNegEn_fx, expa ) );
    3460           0 :             expa = sub( Q29, expa ); // 30 - expa - 1;
    3461             : 
    3462             : 
    3463           0 :             expb = norm_l( L_sum );
    3464           0 :             fracb = round_fx_sat( L_shl( L_sum, expb ) );
    3465           0 :             expb = sub( 30, add( expb, shl( X_fx.Q, 1 ) ) );
    3466             : 
    3467             : 
    3468           0 :             scale = shr( sub( fraca, fracb ), 15 );
    3469           0 :             fracb = shl_sat( fracb, scale );
    3470           0 :             expb = sub( expb, scale );
    3471             : 
    3472           0 :             tmp = div_s( fracb, fraca );
    3473           0 :             exp = sub( expb, expa );
    3474             : 
    3475           0 :             L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
    3476           0 :             *neg_fx = L_tmp;
    3477           0 :             move32();
    3478           0 :             *Qneg = sub( Q31, exp );
    3479           0 :             move16();
    3480             :         }
    3481             :     }
    3482           0 : }
    3483             : 
    3484             : /*===================================================================*/
    3485             : /* FUNCTION      :  struct DTFS_fx:: rshiftHarmBand_fx()             */
    3486             : /*-------------------------------------------------------------------*/
    3487             : /* PURPOSE       :  Right-shift harmonics in band to align Q factor  */
    3488             : /*-------------------------------------------------------------------*/
    3489             : /* INPUT ARGUMENTS  :                                                */
    3490             : /*   _ (Word16) lband: lower band boundary, Q15                      */
    3491             : /*   _ (Word16) hband: upper band boundary, Q15                      */
    3492             : /*   _ (Word16) shift: right shift value, Q0 (must be <0)            */
    3493             : /*-------------------------------------------------------------------*/
    3494             : /* OUTPUT ARGUMENTS :                                                */
    3495             : /*                    _ None                                         */
    3496             : /*-------------------------------------------------------------------*/
    3497             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3498             : /*   _ (struct DTFS_fx) X :  prototype in polar domain               */
    3499             : /*                (Word16) lag: length of prototype in time domain   */
    3500             : /*                (Word16 []) a: amplitude of harmonics, normalized  */
    3501             : /*-------------------------------------------------------------------*/
    3502             : /* RETURN ARGUMENTS : _ None.                                        */
    3503             : /*-------------------------------------------------------------------*/
    3504             : /* CALLED FROM : TX/RX                                               */
    3505             : /*===================================================================*/
    3506             : /* NOTE: This function should be called after two consecutive calls  */
    3507             : /*       to setEngyHarm_fx, because the norm factor outputs from     */
    3508             : /*       the two previous calls might be different                   */
    3509             : /*===================================================================*/
    3510           0 : void rshiftHarmBand_fx( DTFS_STRUCTURE *X_fx, Word16 lband_fx, Word16 hband_fx, Word16 shift_fx )
    3511             : {
    3512             :     Word16 k_fx, HalfLag_fx;
    3513             :     Word16 low_fx, high_fx;
    3514             : 
    3515           0 :     low_fx = mult( lband_fx, X_fx->lag_fx );  /*  low=lband*lag, Q0 */
    3516           0 :     high_fx = mult( hband_fx, X_fx->lag_fx ); /*  high=hband*lag, Q0 */
    3517           0 :     HalfLag_fx = s_min( high_fx, shl( X_fx->nH_fx, 1 ) );
    3518             : 
    3519           0 :     FOR( k_fx = low_fx + 1; k_fx <= HalfLag_fx; k_fx++ )
    3520             :     {
    3521           0 :         X_fx->a_fx[k_fx] = shl_r( X_fx->a_fx[k_fx], shift_fx );
    3522           0 :         move16(); /*  right shift and round */
    3523             :     }
    3524           0 : }
    3525             : 
    3526             : /*===================================================================*/
    3527             : /* FUNCTION      :  GetSinCosTab_fx ()                               */
    3528             : /*-------------------------------------------------------------------*/
    3529             : /* PURPOSE       :  Compute sine & cosine table given pitch lag,     */
    3530             : /*                  by interpolating the 512-entry cosine table.     */
    3531             : /*                  sin(2pi/4L*n) & cos(2pi/4L*n) for n=0,1,... 4L-1 */
    3532             : /*-------------------------------------------------------------------*/
    3533             : /* INPUT ARGUMENTS  :                                                */
    3534             : /*   _ (Word16) L :  Pitch lag, Q0                                   */
    3535             : /*-------------------------------------------------------------------*/
    3536             : /* OUTPUT ARGUMENTS :                                                */
    3537             : /*   _ (Word16 []) sinTab, Q15 : sin(2pi/4L*n), n=0,1,...,4L-1       */
    3538             : /*   _ (Word16 []) cosTab, Q15 : cos(2pi/4L*n), n=0,1,...,4L-1       */
    3539             : /*-------------------------------------------------------------------*/
    3540             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3541             : /*                    _ None                                         */
    3542             : /*-------------------------------------------------------------------*/
    3543             : /* RETURN ARGUMENTS : _ None.                                        */
    3544             : /*-------------------------------------------------------------------*/
    3545             : /* CALLED FROM : TX/RX                                               */
    3546             : /*===================================================================*/
    3547             : /* NOTE: This function interpolates cos_table for better accuracy    */
    3548             : /*===================================================================*/
    3549           0 : void GetSinCosTab_fx( Word16 L, Word16 *sinTab, Word16 *cosTab )
    3550             : {
    3551             :     Word16 i, L4;
    3552             :     Word16 dl, t1, w, dt;
    3553             :     /* Word16 t2; */
    3554             :     Word32 invL; /*  1/4L in Q25 */
    3555             :     Word32 Ltemp, Lw;
    3556             :     Word32 L_tmp;
    3557             : 
    3558           0 :     invL = L_shr( inverse_table[L], 4 );
    3559             : 
    3560           0 :     L4 = shl( L, 2 );
    3561           0 :     Lw = L_deposit_l( 0 );
    3562           0 :     FOR( i = 0; i < L4; i++ )
    3563             :     {
    3564           0 :         w = extract_h( Lw );  /*  w in Q9 */
    3565           0 :         dl = extract_l( Lw ); /*  dl has 16 bits left-over */
    3566           0 :         w = s_and( w, 511 );
    3567             :         /*  t1=cos_table[w%512]; */
    3568           0 :         t1 = cos_table[w];
    3569           0 :         move16();
    3570             :         /*   t2=cos_table[add(w,1)%512]; */
    3571           0 :         dt = cos_diff_table[w];
    3572           0 :         move16();
    3573             :         /*t2=cos_table[s_and(add(w,1),511)]; */
    3574             :         /*dt = sub(t2,t1); */ /*  Q15 */
    3575             : 
    3576           0 :         IF( dl < 0 )
    3577             :         {
    3578           0 :             L_tmp = L_add( 65536, dl );
    3579           0 :             Ltemp = imult3216( L_tmp, dt );
    3580             :         }
    3581             :         ELSE
    3582             :         {
    3583           0 :             Ltemp = (Word32) L_mult0( dt, dl ); /*  Ltemp in Q31 */
    3584             :         }
    3585           0 :         cosTab[i] = add( t1, (Word16) L_shr( Ltemp, 16 ) );
    3586           0 :         move16(); /*  interpolated cos(i*2pi/4L) */
    3587             : 
    3588           0 :         Ltemp = L_add( Lw, 0x1800000 ); /*  add 0.75 in Q25, which is 3pi/2 to convert sin to cos */
    3589           0 :         w = extract_h( Ltemp );         /*  w is equivalent cos index */
    3590             :         /*dl = extract_l(Ltemp); */     /*  dl is 16 bit left-over for interpolation */
    3591           0 :         w = s_and( w, 511 );
    3592             : 
    3593             : 
    3594             :         /*  t1=cos_table[w%512]; */
    3595           0 :         t1 = cos_table[w];
    3596           0 :         move16();
    3597             :         /*   t2=cos_table[add(w,1)%512]; */
    3598           0 :         dt = cos_diff_table[w];
    3599           0 :         move16();
    3600             :         /*t2=cos_table[s_and(add(w,1),511)];move16(); */
    3601             :         /*dt = sub(t2,t1); */ /*  dt=t2-t1, Q15 */
    3602             : 
    3603           0 :         IF( dl < 0 )
    3604             :         {
    3605           0 :             L_tmp = L_add( 65536, dl );
    3606           0 :             Ltemp = imult3216( L_tmp, dt );
    3607             :         }
    3608             :         ELSE
    3609             :         {
    3610           0 :             Ltemp = L_mult0( dt, dl ); /*  Ltemp in Q31 */
    3611             :         }
    3612           0 :         sinTab[i] = add( t1, (Word16) L_shr( Ltemp, 16 ) );
    3613           0 :         move16(); /*  t1 is interpolated cos(w) */
    3614             : 
    3615           0 :         Lw = L_add( Lw, invL ); /*  Lw=(i+1)/4L, Q25 */
    3616             :     }
    3617           0 : }
    3618             : 
    3619             : 
    3620             : /*
    3621             :  * The decimation-in-time complex FFT/IFFT is implemented below.
    3622             :  * The input complex numbers are presented as real part followed by
    3623             :  * imaginary part for each sample.  The counters are therefore
    3624             :  * incremented by two to access the complex valued samples.
    3625             :  */
    3626           0 : static void c_fft_wi_fx( Word16 *farray_ptr_fx, Word16 size, Word16 stage, Word16 isign )
    3627             : {
    3628             : 
    3629             :     Word16 i, j, k, ii, jj, kk, ji, kj;
    3630             :     Word32 ftmp_fx, ftmp_real_fx, ftmp_imag_fx;
    3631             :     Word16 tmp, tmp1, tmp2, temp_sand;
    3632             :     Word16 n_2, K;
    3633             :     Word16 ii_table[8];
    3634             : 
    3635           0 :     K = 0;
    3636           0 :     move16();
    3637             : 
    3638           0 :     FOR( k = 256; k > 0; k -= size )
    3639             :     {
    3640           0 :         K = add( K, 1 ); /*  K=512/size */
    3641             :     }
    3642           0 :     n_2 = shr( size, 1 );
    3643           0 :     FOR( i = 1; i <= stage; i++ )
    3644             :     {
    3645           0 :         ii_table[i - 1] = shr( size, i );
    3646             :     }
    3647             : 
    3648             :     /* Rearrange the input array in bit reversed order */
    3649           0 :     j = 0;
    3650           0 :     move16();
    3651           0 :     FOR( i = 0; i < size - 2; i = i + 2 )
    3652             :     {
    3653             : 
    3654           0 :         IF( GT_16( j, i ) )
    3655             :         {
    3656           0 :             ftmp_fx = *( farray_ptr_fx + i );
    3657           0 :             *( farray_ptr_fx + i ) = *( farray_ptr_fx + j );
    3658           0 :             *( farray_ptr_fx + j ) = (Word16) ftmp_fx;
    3659           0 :             move32();
    3660           0 :             move16();
    3661           0 :             move16();
    3662             : 
    3663           0 :             ftmp_fx = *( farray_ptr_fx + add( i, 1 ) );
    3664           0 :             *( farray_ptr_fx + add( i, 1 ) ) = *( farray_ptr_fx + add( j, 1 ) );
    3665           0 :             *( farray_ptr_fx + add( j, 1 ) ) = (Word16) ftmp_fx;
    3666           0 :             move32();
    3667           0 :             move16();
    3668           0 :             move16();
    3669             :         }
    3670             : 
    3671           0 :         k = n_2;
    3672           0 :         move16();
    3673           0 :         WHILE( ( j >= k ) )
    3674             :         {
    3675           0 :             j = sub( j, k );
    3676           0 :             k = shr( k, 1 );
    3677             :         }
    3678           0 :         j = add( j, k );
    3679             :     }
    3680             : 
    3681             :     /* The FFT part */
    3682             : 
    3683             : 
    3684           0 :     IF( EQ_16( isign, 1 ) )
    3685             :     {
    3686           0 :         FOR( i = 0; i < stage; i++ ) /* i is stage counter */
    3687             :         {
    3688           0 :             jj = shl( 2, i );  /* FFT size */
    3689           0 :             kk = shl( jj, 1 ); /* 2 * FFT size */
    3690             : 
    3691           0 :             move16();
    3692             : 
    3693           0 :             ii = ii_table[i]; /* 2 * number of FFT's */
    3694             : 
    3695           0 :             FOR( j = 0; j < jj; j = j + 2 ) /* j is sample counter */
    3696             :             {
    3697           0 :                 ji = i_mult( j, ii ); /* ji is phase table index */
    3698             : 
    3699           0 :                 FOR( k = j; k < size; k = k + kk ) /* k is butterfly top */
    3700             :                 {
    3701           0 :                     kj = add( k, jj ); /* kj is butterfly bottom */
    3702           0 :                     temp_sand = s_and( ( add( i_mult( ji, K ), 384 ) ), 511 );
    3703             :                     /* Butterfly computations */
    3704             :                     /*  ftmp_real_fx = L_sub(L_mult(*(farray_ptr_fx + kj), cos_table[ji*K]), */
    3705             :                     /*                   L_mult(*(farray_ptr_fx + kj + 1), cos_table[(ji*K+384)%512])); */
    3706           0 :                     ftmp_real_fx = L_msu( L_mult( *( farray_ptr_fx + kj ), cos_table[( ji * K )] ),
    3707           0 :                                           *( farray_ptr_fx + add( kj, 1 ) ), cos_table[temp_sand] );
    3708             : 
    3709             :                     /*   ftmp_imag_fx = L_add(L_mult(*(farray_ptr_fx + kj + 1), cos_table[ji*K]), */
    3710             :                     /*                    L_mult(*(farray_ptr_fx + kj), cos_table[(ji*K+384)%512])); */
    3711           0 :                     ftmp_imag_fx = L_mac( L_mult( *( farray_ptr_fx + add( kj, 1 ) ), cos_table[( ji * K )] ),
    3712           0 :                                           *( farray_ptr_fx + kj ), cos_table[temp_sand] );
    3713             : 
    3714           0 :                     tmp1 = round_fx( ftmp_real_fx );
    3715           0 :                     tmp2 = round_fx( ftmp_imag_fx );
    3716             : 
    3717           0 :                     tmp = sub( *( farray_ptr_fx + k ), tmp1 );
    3718           0 :                     *( farray_ptr_fx + kj ) = shr( tmp, 1 );
    3719           0 :                     move16();
    3720             : 
    3721           0 :                     tmp = sub( *( farray_ptr_fx + add( k, 1 ) ), tmp2 );
    3722           0 :                     *( farray_ptr_fx + add( kj, 1 ) ) = shr( tmp, 1 );
    3723           0 :                     move16();
    3724             : 
    3725           0 :                     tmp = add( *( farray_ptr_fx + k ), tmp1 );
    3726           0 :                     *( farray_ptr_fx + k ) = shr( tmp, 1 );
    3727           0 :                     move16();
    3728             : 
    3729           0 :                     tmp = add( *( farray_ptr_fx + add( k, 1 ) ), tmp2 );
    3730           0 :                     *( farray_ptr_fx + add( k, 1 ) ) = shr( tmp, 1 );
    3731           0 :                     move16();
    3732             :                 }
    3733             :             }
    3734             :         }
    3735             : 
    3736             :         /* The IFFT part */
    3737             :     }
    3738             :     ELSE
    3739             :     {
    3740           0 :         FOR( i = 0; i < stage; i++ ) /* i is stage counter */
    3741             :         {
    3742           0 :             jj = shl( 2, i );  /* FFT size */
    3743           0 :             kk = shl( jj, 1 ); /* 2 * FFT size */
    3744           0 :             ii = ii_table[i];  /* 2 * number of FFT's */
    3745             : 
    3746           0 :             FOR( j = 0; j < jj; j = j + 2 ) /* j is sample counter */
    3747             :             {
    3748           0 :                 ji = i_mult( j, ii ); /* ji is phase table index */
    3749             : 
    3750           0 :                 FOR( k = j; k < size; k = k + kk ) /* k is butterfly top */
    3751             :                 {
    3752           0 :                     kj = add( k, jj ); /* kj is butterfly bottom */
    3753           0 :                     temp_sand = s_and( ( add( i_mult( ji, K ), 384 ) ), 511 );
    3754             :                     /* Butterfly computations */
    3755             :                     /*  ftmp_real_fx = L_add(L_mult(*(farray_ptr_fx + kj), cos_table[ji*K]), */
    3756             :                     /*                   L_mult(*(farray_ptr_fx + kj + 1), cos_table[(ji*K+384)%512])); */
    3757           0 :                     ftmp_real_fx = L_mac( L_mult( *( farray_ptr_fx + kj ), cos_table[( ji * K )] ),
    3758           0 :                                           *( farray_ptr_fx + kj + 1 ), cos_table[temp_sand] );
    3759             : 
    3760             :                     /*    ftmp_imag_fx = L_sub(L_mult(*(farray_ptr_fx + kj + 1), cos_table[ji*K]), */
    3761             :                     /*                   L_mult(*(farray_ptr_fx + kj), cos_table[(ji*K+384)%512])); */
    3762           0 :                     ftmp_imag_fx = L_msu( L_mult( *( farray_ptr_fx + add( kj, 1 ) ), cos_table[( ji * K )] ),
    3763           0 :                                           *( farray_ptr_fx + kj ), cos_table[temp_sand] );
    3764             : 
    3765           0 :                     tmp1 = round_fx( ftmp_real_fx );
    3766           0 :                     tmp2 = round_fx( ftmp_imag_fx );
    3767             : 
    3768           0 :                     *( farray_ptr_fx + kj ) = sub_sat( *( farray_ptr_fx + k ), tmp1 );
    3769           0 :                     move16();
    3770           0 :                     *( farray_ptr_fx + kj + 1 ) = sub_sat( *( farray_ptr_fx + k + 1 ), tmp2 );
    3771           0 :                     move16();
    3772           0 :                     *( farray_ptr_fx + k ) = add_sat( *( farray_ptr_fx + k ), tmp1 );
    3773           0 :                     move16();
    3774           0 :                     *( farray_ptr_fx + k + 1 ) = add_sat( *( farray_ptr_fx + k + 1 ), tmp2 );
    3775           0 :                     move16();
    3776             :                 }
    3777             :             }
    3778             :         }
    3779             :     }
    3780             : 
    3781           0 : } /* end of c_fft () */
    3782             : 
    3783             : 
    3784           0 : void r_fft_4_fx( Word16 *farray_ptr_fx /*Q0*/, Word16 size, Word16 stage, Word16 isign )
    3785             : {
    3786             : 
    3787             :     Word16 ftmp1_real_fx, ftmp1_imag_fx, ftmp2_real_fx, ftmp2_imag_fx;
    3788             :     Word32 Lftmp1_real_fx, Lftmp1_imag_fx;
    3789             :     Word16 i, j, temp_sand;
    3790             :     Word32 Ltmp1_fx, Ltmp2_fx;
    3791             :     Word16 n_2, k, K;
    3792             : 
    3793           0 :     n_2 = shr( size, 1 );
    3794           0 :     K = 0;
    3795           0 :     move16();
    3796             : 
    3797           0 :     FOR( k = 256; k > 0; k -= size )
    3798             :     {
    3799           0 :         K = add( K, 1 ); /*  K=512/size */
    3800             :     }
    3801             : 
    3802             :     /* The FFT part */
    3803           0 :     IF( EQ_16( isign, 1 ) )
    3804             :     {
    3805             :         /* Perform the complex FFT */
    3806           0 :         c_fft_wi_fx( farray_ptr_fx, size, stage, isign );
    3807             : 
    3808             :         /* First, handle the DC and foldover frequencies */
    3809           0 :         ftmp1_real_fx = *farray_ptr_fx;
    3810           0 :         ftmp2_real_fx = *( farray_ptr_fx + 1 );
    3811           0 :         *farray_ptr_fx = add( ftmp1_real_fx, ftmp2_real_fx );
    3812           0 :         move16();
    3813           0 :         *( farray_ptr_fx + 1 ) = sub( ftmp1_real_fx, ftmp2_real_fx );
    3814           0 :         move16();
    3815             : 
    3816             :         /* Now, handle the remaining positive frequencies */
    3817           0 :         j = sub( size, 2 );
    3818           0 :         FOR( i = 2; i <= n_2; i = i + 2 )
    3819             :         {
    3820           0 :             ftmp1_real_fx = add( *( farray_ptr_fx + i ), *( farray_ptr_fx + j ) );
    3821           0 :             ftmp1_imag_fx = sub( *( farray_ptr_fx + i + 1 ), *( farray_ptr_fx + j + 1 ) );
    3822           0 :             ftmp2_real_fx = add( *( farray_ptr_fx + i + 1 ), *( farray_ptr_fx + j + 1 ) );
    3823           0 :             ftmp2_imag_fx = sub( *( farray_ptr_fx + j ), *( farray_ptr_fx + i ) );
    3824             : 
    3825           0 :             Lftmp1_real_fx = L_deposit_h( ftmp1_real_fx );
    3826           0 :             Lftmp1_imag_fx = L_deposit_h( ftmp1_imag_fx );
    3827           0 :             temp_sand = s_and( add( i_mult( i, K ), 384 ), 511 );
    3828             :             /*  Ltmp1_fx = L_sub(L_mult(ftmp2_real_fx, cos_table[i*K]), L_mult(ftmp2_imag_fx, cos_table[(i*K+384)%512])); */
    3829           0 :             Ltmp1_fx = L_msu( L_mult( ftmp2_real_fx, cos_table[( i * K )] ), ftmp2_imag_fx, cos_table[temp_sand] );
    3830           0 :             *( farray_ptr_fx + i ) = round_fx( L_shr( L_add( Lftmp1_real_fx, Ltmp1_fx ), 1 ) );
    3831           0 :             move16();
    3832             : 
    3833             :             /*   Ltmp1_fx = L_add(L_mult(ftmp2_imag_fx, cos_table[i*K]), L_mult(ftmp2_real_fx, cos_table[(i*K+384)%512])); */
    3834           0 :             Ltmp1_fx = L_mac( L_mult( ftmp2_imag_fx, cos_table[( i * K )] ), ftmp2_real_fx, cos_table[temp_sand] );
    3835           0 :             *( farray_ptr_fx + i + 1 ) = round_fx( L_shr( L_add( Lftmp1_imag_fx, Ltmp1_fx ), 1 ) );
    3836           0 :             move16();
    3837             : 
    3838             :             /*    Ltmp1_fx = L_add(L_mult(ftmp2_real_fx, cos_table[j*K]), L_mult(ftmp2_imag_fx, cos_table[(j*K+384)%512])); */
    3839           0 :             Ltmp1_fx = L_mac( L_mult( ftmp2_real_fx, cos_table[( j * K )] ), ftmp2_imag_fx, cos_table[temp_sand] );
    3840           0 :             *( farray_ptr_fx + j ) = round_fx( L_shr( L_add( Lftmp1_real_fx, Ltmp1_fx ), 1 ) );
    3841           0 :             move16();
    3842             : 
    3843             :             /*    Ltmp1_fx = L_add(L_negate(L_mult(ftmp2_imag_fx, cos_table[j*K])), L_mult(ftmp2_real_fx, cos_table[(j*K+384)%512])); */
    3844           0 :             Ltmp1_fx = L_msu( L_mult( ftmp2_real_fx, cos_table[temp_sand] ), ftmp2_imag_fx, cos_table[( j * K )] );
    3845           0 :             Ltmp2_fx = L_sub( Ltmp1_fx, Lftmp1_imag_fx );
    3846           0 :             *( farray_ptr_fx + j + 1 ) = round_fx( L_shr( Ltmp2_fx, 1 ) );
    3847           0 :             move16();
    3848           0 :             j = sub( size, i );
    3849             :         }
    3850             :     }
    3851             :     ELSE
    3852             :     {
    3853             : 
    3854             :         /* First, handle the DC and foldover frequencies */
    3855             : 
    3856           0 :         move16();
    3857           0 :         move16();
    3858             : 
    3859           0 :         ftmp1_real_fx = *farray_ptr_fx;
    3860           0 :         ftmp2_real_fx = *( farray_ptr_fx + 1 );
    3861           0 :         *farray_ptr_fx = shr( add( ftmp1_real_fx, ftmp2_real_fx ), 1 );
    3862           0 :         move16();
    3863           0 :         *( farray_ptr_fx + 1 ) = shr( sub( ftmp1_real_fx, ftmp2_real_fx ), 1 );
    3864           0 :         move16();
    3865             : 
    3866             :         /* Now, handle the remaining positive frequencies */
    3867           0 :         FOR( i = 2; i <= n_2; i += 2 )
    3868             :         {
    3869           0 :             j = sub( size, i );
    3870             : 
    3871           0 :             ftmp1_real_fx = add( *( farray_ptr_fx + i ), *( farray_ptr_fx + j ) );
    3872           0 :             ftmp1_imag_fx = sub( *( farray_ptr_fx + i + 1 ), *( farray_ptr_fx + j + 1 ) );
    3873           0 :             ftmp2_real_fx = negate( add( *( farray_ptr_fx + j + 1 ), *( farray_ptr_fx + i + 1 ) ) );
    3874           0 :             ftmp2_imag_fx = negate( sub( *( farray_ptr_fx + j ), *( farray_ptr_fx + i ) ) );
    3875             : 
    3876           0 :             Lftmp1_real_fx = L_deposit_h( ftmp1_real_fx );
    3877           0 :             Lftmp1_imag_fx = L_deposit_h( ftmp1_imag_fx );
    3878           0 :             temp_sand = s_and( ( add( i_mult( i, K ), 384 ) ), 511 );
    3879             :             /*  Ltmp1_fx = L_add(L_mult(ftmp2_real_fx, cos_table[i*K]), L_mult(ftmp2_imag_fx, cos_table[(i*K+384)%512])); */
    3880           0 :             Ltmp1_fx = L_mac( L_mult( ftmp2_real_fx, cos_table[( i * K )] ), ftmp2_imag_fx, cos_table[temp_sand] );
    3881           0 :             *( farray_ptr_fx + i ) = round_fx( L_shr( L_add( Lftmp1_real_fx, Ltmp1_fx ), 1 ) );
    3882           0 :             move16();
    3883             : 
    3884             :             /*  Ltmp1_fx = L_sub(L_mult(ftmp2_imag_fx, cos_table[i*K]), L_mult(ftmp2_real_fx, cos_table[(i*K+384)%512])); */
    3885           0 :             Ltmp1_fx = L_msu( L_mult( ftmp2_imag_fx, cos_table[( i * K )] ), ftmp2_real_fx, cos_table[temp_sand] );
    3886           0 :             *( farray_ptr_fx + i + 1 ) = round_fx( L_shr( L_add( Lftmp1_imag_fx, Ltmp1_fx ), 1 ) );
    3887           0 :             move16();
    3888             : 
    3889             :             /*  Ltmp1_fx = L_sub(L_mult(ftmp2_real_fx, cos_table[j*K]), L_mult(ftmp2_imag_fx, cos_table[(j*K+384)%512])); */
    3890           0 :             Ltmp1_fx = L_msu( L_mult( ftmp2_real_fx, cos_table[( j * K )] ), ftmp2_imag_fx, cos_table[temp_sand] );
    3891           0 :             *( farray_ptr_fx + j ) = round_fx( L_shr( L_add( Lftmp1_real_fx, Ltmp1_fx ), 1 ) );
    3892           0 :             move16();
    3893             : 
    3894             :             /*  Ltmp1_fx = L_negate(L_add(L_mult(ftmp2_imag_fx, cos_table[j*K]), L_mult(ftmp2_real_fx, cos_table[(j*K+384)%512]))); */
    3895           0 :             Ltmp1_fx = L_negate( L_mac( L_mult( ftmp2_imag_fx, cos_table[( j * K )] ), ftmp2_real_fx, cos_table[temp_sand] ) );
    3896           0 :             Ltmp2_fx = L_sub( Ltmp1_fx, Lftmp1_imag_fx );
    3897           0 :             *( farray_ptr_fx + j + 1 ) = round_fx( L_shr( Ltmp2_fx, 1 ) );
    3898           0 :             move16();
    3899             :         }
    3900             : 
    3901             :         /* Perform the complex IFFT */
    3902           0 :         c_fft_wi_fx( farray_ptr_fx, size, stage, isign );
    3903             :     }
    3904           0 : }
    3905             : 
    3906             : 
    3907             : /*===================================================================*/
    3908             : /* FUNCTION      :  struct DTFS_fx::copy_phase_fx ()                 */
    3909             : /*-------------------------------------------------------------------*/
    3910             : /* PURPOSE       :  Retain the amplitudes of a prototype X2, but copy*/
    3911             : /*                  the phases of another prototype X1 of same length*/
    3912             : /*                  over to make a new prototype                     */
    3913             : /*-------------------------------------------------------------------*/
    3914             : /* INPUT ARGUMENTS  :                                                */
    3915             : /*   _ (struct DTFS_fx) X1 :  prototype in Cartesian domain          */
    3916             : /*                (Word16) X1.lag: length of prototype in time domain*/
    3917             : /*                (Word16 []) X1.a,b: re/im of harmonics, normalized */
    3918             : /*                (Word16) X1.Q: norm factor of X2.a/b               */
    3919             : /*   _ (struct DTFS_fx) X2 :  prototype in polar domain              */
    3920             : /*                (Word16) X2.lag: should be same as X1.lag          */
    3921             : /*                (Word16 []) X2.a:amplitude of harmonics, normalized*/
    3922             : /*                (Word16 []) X2.b: phase of harmonics, don't care   */
    3923             : /*                (Word16) X2.Q: norm factor of X2.a                 */
    3924             : /*-------------------------------------------------------------------*/
    3925             : /* OUTPUT ARGUMENTS :                                                */
    3926             : /*                    _ None                                         */
    3927             : /*-------------------------------------------------------------------*/
    3928             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    3929             : /*                    _ None                                         */
    3930             : /*-------------------------------------------------------------------*/
    3931             : /* RETURN ARGUMENTS :                                                */
    3932             : /*   _ (struct DTFS_fx) X :  prototype in Cartesian domain           */
    3933             : /*                    The amplitudes of this prototype are from X2   */
    3934             : /*                    and the phases are from X1                     */
    3935             : /*-------------------------------------------------------------------*/
    3936             : /* CALLED FROM : TX/RX                                               */
    3937             : /*===================================================================*/
    3938             : /* X.a[k]=2*X2.a[k]/sqrt(X1.a[k]^2+X1.b[k]^2)*X1.a[k]                */
    3939             : /* X.b[k]=2*X2.a[k]/sqrt(X1.a[k]^2+X1.b[k]^2)*X1.b[k]                */
    3940             : /*===================================================================*/
    3941           0 : void copy_phase_fx( DTFS_STRUCTURE *X1_fx, DTFS_STRUCTURE X2_fx, DTFS_STRUCTURE *retX_fx )
    3942             : {
    3943             :     /* DTFS_fx X; */
    3944             :     Word16 k, q, sn, cn, HalfLag;
    3945             :     Word16 d1h, d1l;
    3946             :     Word32 Ltemp_fx, L_tmp;
    3947             :     Word32 Lacc_fx;
    3948             :     Word16 exp, tmp, exp1;
    3949             : 
    3950           0 :     retX_fx->lag_fx = X1_fx->lag_fx;
    3951           0 :     move16();
    3952           0 :     retX_fx->Q = sub( X2_fx.Q, 1 ); /*  equivalent to 2x MIN_FX(shr(sub(X_fx->lag_fx,1),1),X_fx->nH_fx) */
    3953           0 :     move16();
    3954           0 :     HalfLag = s_min( shr( X1_fx->lag_fx, 1 ), X1_fx->nH_fx );
    3955             : 
    3956           0 :     FOR( k = 1; k <= HalfLag; k++ )
    3957             :     {
    3958           0 :         Lacc_fx = L_mult_sat( X1_fx->a_fx[k], X1_fx->a_fx[k] );
    3959           0 :         Lacc_fx = L_mac_sat( Lacc_fx, X1_fx->b_fx[k], X1_fx->b_fx[k] ); /*  2*Q+1 */
    3960             : 
    3961           0 :         exp = norm_l( Lacc_fx );
    3962           0 :         tmp = extract_h( L_shl( Lacc_fx, exp ) );
    3963           0 :         exp1 = sub( sub( 30, exp ), 2 * X1_fx->Q + 1 );
    3964             : 
    3965           0 :         IF( tmp )
    3966             :         {
    3967           0 :             tmp = div_s( 16384, tmp ); /* 15+exp1 */
    3968             :         }
    3969             :         ELSE
    3970             :         {
    3971           0 :             tmp = 0;
    3972           0 :             move16();
    3973             :         }
    3974           0 :         tmp = shr( tmp, 1 );
    3975           0 :         q = sub( add( add( 15, exp1 ), 16 ), 1 );
    3976             : 
    3977           0 :         IF( tmp )
    3978             :         {
    3979           0 :             exp = norm_s( tmp );
    3980           0 :             tmp = shl( tmp, exp );
    3981           0 :             tmp = div_s( 16384, tmp );
    3982           0 :             L_tmp = L_deposit_h( tmp );
    3983           0 :             Ltemp_fx = Isqrt_lc( L_tmp, &exp ); /* Q(31-exp) */
    3984             :         }
    3985             :         ELSE
    3986             :         {
    3987           0 :             Ltemp_fx = 0;
    3988           0 :             move32();
    3989             :         }
    3990             : 
    3991           0 :         IF( s_and( q, 1 ) )
    3992             :         {
    3993           0 :             Ltemp_fx = Mult_32_16( Ltemp_fx, 23170 ); /*  23170 is 1/sqrt(2) in Q15 */
    3994             :         }
    3995             : 
    3996           0 :         q = shr( q, 1 ); /*  Ltemp_fx in Q(q+16) */
    3997             : 
    3998           0 :         d1h = extract_h( Ltemp_fx );
    3999           0 :         d1l = extract_l( Ltemp_fx );
    4000           0 :         Ltemp_fx = L_mult0( X1_fx->b_fx[k], d1l );
    4001           0 :         Ltemp_fx = L_add_sat( L_shr( Ltemp_fx, 15 ), L_mult_sat( X1_fx->b_fx[k], d1h ) ); /*  sin(w) in Q(q+16+Q-15) */
    4002           0 :         sn = round_fx_sat( L_shl_sat( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ) ) );        /*  Q15 */
    4003           0 :         retX_fx->b_fx[k] = mult_r_sat( X2_fx.a_fx[k], sn );                               /*  X2_fx.Q */
    4004           0 :         move16();
    4005             : 
    4006           0 :         Ltemp_fx = L_mult0( X1_fx->a_fx[k], d1l );
    4007           0 :         Ltemp_fx = L_add_sat( L_shr( Ltemp_fx, 15 ), L_mult_sat( X1_fx->a_fx[k], d1h ) ); /*  cos(w) in Q(q+Q+1) */
    4008           0 :         cn = round_fx_sat( L_shl_sat( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ) ) );        /*  Q15 */
    4009           0 :         retX_fx->a_fx[k] = mult_r_sat( X2_fx.a_fx[k], cn );                               /*  X2_fx.Q         */
    4010           0 :         move16();
    4011             :     }
    4012           0 :     k = sub( k, 1 );
    4013             : 
    4014             : 
    4015           0 :     IF( s_and( X1_fx->lag_fx, 1 ) == 0 )
    4016             :     {
    4017           0 :         retX_fx->a_fx[k] = shr( retX_fx->a_fx[k], 1 );
    4018           0 :         move16();
    4019           0 :         retX_fx->b_fx[k] = shr( retX_fx->b_fx[k], 1 );
    4020           0 :         move16();
    4021             :     }
    4022           0 : }
    4023             : 
    4024             : 
    4025             : /*===================================================================*/
    4026             : /* FUNCTION      :  getSpEngyFromResAmp_fx ()                        */
    4027             : /*-------------------------------------------------------------------*/
    4028             : /* PURPOSE       :  Get band energy                                  */
    4029             : /*-------------------------------------------------------------------*/
    4030             : /* INPUT ARGUMENTS  :                                                */
    4031             : /*   _ (struct DTFS_STRUCTURE) X_fx :  prototype in polar domain  */
    4032             : /*                (Word16) lag: length of prototype in time domain   */
    4033             : /*                (Word16 []) a: amplitude of harmonics, normalized  */
    4034             : /*                (Word16) Q: norm factor of a                       */
    4035             : /*   _ (Word16 []) curr_lpc: LPC coefficients, Q12                   */
    4036             : /*   _ (Word16) lband: lower frequency bound, Q15                    */
    4037             : /*   _ (Word16) hband: upper frequency bound, Q15                    */
    4038             : /*   _ (Word16 []) sin_tab: sine table based on lag, Q15             */
    4039             : /*   _ (Word16 []) cos_tab: cosine table based on lag, Q15           */
    4040             : /*-------------------------------------------------------------------*/
    4041             : /* OUTPUT ARGUMENTS :                                                */
    4042             : /*                    _ None                                         */
    4043             : /*-------------------------------------------------------------------*/
    4044             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    4045             : /*                    _ None                                         */
    4046             : /*-------------------------------------------------------------------*/
    4047             : /* RETURN ARGUMENTS :                                                */
    4048             : /*   _ (Word32) en: energy of the specified frequency band,          */
    4049             : /*                  Q factor is 2Q-13                                */
    4050             : /*-------------------------------------------------------------------*/
    4051             : /* CALLED FROM : TX                                                  */
    4052             : /*===================================================================*/
    4053           0 : Word32 getSpEngyFromResAmp_fx( DTFS_STRUCTURE *X_fx, Word16 lband, Word16 hband, const Word16 *curr_lpc, Word16 *sin_tab, Word16 *cos_tab )
    4054             : {
    4055             :     Word16 i, k, k4, n, M_fx, HalfLag;
    4056             :     Word16 fdiff, freq;
    4057             :     Word32 Ltemp;
    4058             :     Word32 Lacc;
    4059             :     Word32 Re, Im; /*  Q27 */
    4060             :     Word32 en;
    4061             :     Word16 exp, tmp, expa, fraca, expb, fracb, scale;
    4062             :     Word32 L_tmp;
    4063           0 :     en = L_deposit_l( 0 );
    4064             : 
    4065           0 :     if ( EQ_16( hband, X_fx->upper_cut_off_freq_fx ) )
    4066             :     {
    4067           0 :         hband = 0x2803;
    4068           0 :         move16(); /*  4001.0/12800 in Q15 */
    4069             :     }
    4070           0 :     M_fx = shl( X_fx->lag_fx, 2 ); /*  M_fx=4*lag */
    4071             : 
    4072             :     /*  Ltemp=invert_dp(X_fx->lag_fx, 4, &n,1); : Ltemp=1/lag, Q(61-n) */
    4073             :     /* fdiff=round_fx(L_shl(Ltemp,sub(n,26))); : fdiff=1/lag, Q19 */
    4074             : 
    4075           0 :     exp = norm_s( X_fx->lag_fx );
    4076           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx->lag_fx );
    4077           0 :     L_tmp = L_shl( tmp, add( exp, 6 ) );
    4078           0 :     fdiff = round_fx( L_tmp );
    4079             : 
    4080           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_4kHz_fx );
    4081           0 :     FOR( k = 0; k <= HalfLag; k++ )
    4082             :     {
    4083           0 :         Ltemp = L_mult( fdiff, k );             /*  Ltemp=k*fdiff, Q20 */
    4084           0 :         freq = extract_h( L_shl( Ltemp, 11 ) ); /*  k*fdiff in Q15 */
    4085             : 
    4086           0 :         test();
    4087           0 :         IF( LT_16( freq, hband ) && GE_16( freq, lband ) )
    4088             :         {
    4089           0 :             Lacc = L_add( 0x10000000, 0 ); /*  Re=1.0, Q28 */
    4090           0 :             k4 = shl( k, 2 );              /*  k4=4*k */
    4091             : 
    4092           0 :             n = k4;
    4093           0 :             move16();
    4094           0 :             FOR( i = 0; i < M + 1; i++ )
    4095             :             {
    4096             :                 /*  Compute Re */
    4097           0 :                 Lacc = L_mac_sat( Lacc, curr_lpc[i], cos_tab[n % M_fx] ); /*  Q28 */
    4098           0 :                 n = add( n, k4 );                                         /*  n=4*i*k */
    4099             :             }
    4100           0 :             Re = L_shr( Lacc, 1 ); /*  Q27 */
    4101             : 
    4102           0 :             n = k4;
    4103           0 :             move16();
    4104           0 :             Lacc = L_deposit_l( 0 );
    4105           0 :             FOR( i = 0; i < M + 1; i++ )
    4106             :             {
    4107             :                 /*  Compute Im */
    4108           0 :                 Lacc = L_msu_sat( Lacc, curr_lpc[i], sin_tab[n % M_fx] ); /*  Q28 */
    4109           0 :                 n = add( n, k4 );                                         /*  n=4*i*k */
    4110             :             }
    4111           0 :             Im = L_shr( Lacc, 1 );                                          /*  Q27 */
    4112             :                                                                             /* Lacc=L_add(L_mult_ll(Re,Re),(Word32)L_mult_ll(Im,Im)); : Lacc=Re^2+Im^2 in Q23 */
    4113           0 :             Lacc = L_add_sat( Mult_32_32( Re, Re ), Mult_32_32( Im, Im ) ); /*  Lacc=Re^2+Im^2 in Q23 */
    4114           0 :             Ltemp = L_mult0( X_fx->a_fx[k], X_fx->a_fx[k] );                /*  2*a[k]^2 in 2Q */
    4115             :             /* Ltemp=(Word32)L_sat32_40(divide_dp(Ltemp,Lacc,-19,1)); : Ltemp in Q(2Q-13) */
    4116             : 
    4117           0 :             if ( Lacc < 0 )
    4118             :             {
    4119           0 :                 Lacc = L_negate( Lacc );
    4120             :             }
    4121             : 
    4122           0 :             IF( Lacc )
    4123             :             {
    4124             : 
    4125           0 :                 expa = norm_l( Lacc );
    4126           0 :                 fraca = extract_h( L_shl( Lacc, expa ) );
    4127           0 :                 expa = sub( 30, add( expa, 23 ) );
    4128             : 
    4129             : 
    4130           0 :                 expb = norm_l( Ltemp );
    4131           0 :                 fracb = round_fx( L_shl( Ltemp, expb ) );
    4132           0 :                 expb = sub( 30, add( expb, shl( X_fx->Q, 1 ) ) );
    4133             : 
    4134           0 :                 scale = shr( sub( fraca, fracb ), 15 );
    4135           0 :                 fracb = shl( fracb, scale );
    4136           0 :                 expb = sub( expb, scale );
    4137             : 
    4138           0 :                 tmp = div_s( fracb, fraca ); /* 15-exp */
    4139           0 :                 exp = sub( expb, expa );
    4140           0 :                 Ltemp = L_shl_sat( tmp, sub( add( shl( X_fx->Q, 1 ), exp ), 27 ) );
    4141             :             }
    4142             :             ELSE
    4143             :             {
    4144           0 :                 Ltemp = L_deposit_l( 0 );
    4145             :             }
    4146             : 
    4147           0 :             test();
    4148           0 :             IF( X_fx->lag_fx % 2 == 0 && EQ_16( k, shr( X_fx->lag_fx, 1 ) ) )
    4149           0 :             en = L_add( en, L_shr( Ltemp, 1 ) );
    4150             :             ELSE
    4151           0 :                 en = L_add( en, Ltemp ); /*  en in 2Q-13 */
    4152             :         }
    4153             :     }
    4154           0 :     return ( en ); /*  en in 2Q-13 */
    4155             : }
    4156             : /*===================================================================*/
    4157             : /* FUNCTION      :  DTFS_poleFilter_fx()                             */
    4158             : /*-------------------------------------------------------------------*/
    4159             : /* PURPOSE       :  pole filtering                                   */
    4160             : /*-------------------------------------------------------------------*/
    4161             : /* INPUT ARGUMENTS  :                                                */
    4162             : /*   _ (Word16) lpc[] :  lpc coefficients in Q12                     */
    4163             : /*   _ (Word16) N     :  lpc order                                   */
    4164             : /*   _ (Word16) X_fx->lag_fx:  in Q0                                 */
    4165             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
    4166             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
    4167             : /*-------------------------------------------------------------------*/
    4168             : /* OUTPUT ARGUMENTS :                                                */
    4169             : /*   _ None                                                          */
    4170             : /*-------------------------------------------------------------------*/
    4171             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    4172             : /*   _ (Word16) X_fx->a_fx[] :    in Q(X_fx->Q)                      */
    4173             : /*   _ (Word16) X_fx->b_fx[] :    in Q(X_fx->Q)                      */
    4174             : /*   _ (Word16) X_fx->Q:       in Q0                                 */
    4175             : /*-------------------------------------------------------------------*/
    4176             : /* RETURN ARGUMENTS : _ None.                                        */
    4177             : /*-------------------------------------------------------------------*/
    4178             : /* CALLED FROM : TX/RX                                               */
    4179             : /*===================================================================*/
    4180           0 : void DTFS_poleFilter_fx( DTFS_STRUCTURE *X_fx, Word16 *LPC, Word16 N, Word16 *S_fx, Word16 *C_fx )
    4181             : {
    4182             :     Word16 temp, temp1, temp2, HalfLag;
    4183             :     Word32 sum1_fx, sum2_fx;
    4184             :     Word32 sum, L_temp1, L_temp2;
    4185             :     Word16 k, n, na, nb;
    4186             :     Word16 Qmin, Qab[MAXLAG_WI];
    4187             :     Word16 exp, tmp;
    4188           0 :     Qmin = 32767;
    4189           0 :     move16();
    4190           0 :     HalfLag = s_min( shr( X_fx->lag_fx, 1 ), X_fx->nH_fx );
    4191           0 :     FOR( k = 0; k <= HalfLag; k++ )
    4192             :     {
    4193           0 :         temp2 = k;
    4194           0 :         move16();
    4195             :         /* Calculate sum1 and sum2 */
    4196           0 :         sum1_fx = L_deposit_h( 4096 ); /*  1: Q(12+15+1)  */
    4197             : 
    4198           0 :         sum2_fx = L_deposit_l( 0 );
    4199           0 :         FOR( n = 0; n < N; n++ )
    4200             :         {
    4201           0 :             sum1_fx = L_mac_sat( sum1_fx, LPC[n], C_fx[shl( temp2, 2 ) % shl( X_fx->lag_fx, 2 )] ); /* Q(12+15+1) */
    4202           0 :             sum2_fx = L_mac_sat( sum2_fx, LPC[n], S_fx[shl( temp2, 2 ) % shl( X_fx->lag_fx, 2 )] ); /* Q(12+15+1) */
    4203           0 :             temp2 = add( temp2, k );
    4204             :         }
    4205             : 
    4206           0 :         temp1 = round_fx_sat( sum1_fx ); /* Q(12+15+1-16)=Q(12) */
    4207           0 :         temp2 = round_fx_sat( sum2_fx ); /*               Q(12) */
    4208             :         /* Calculate the circular convolution */
    4209           0 :         sum = L_mac_sat( L_mult_sat( temp1, temp1 ), temp2, temp2 ); /*  Q(12+12+1)=Q(25) */
    4210             : 
    4211           0 :         L_temp1 = L_mult( temp1, X_fx->a_fx[k] );
    4212           0 :         L_temp1 = L_mac_sat( L_temp1, temp2, X_fx->b_fx[k] ); /*  Q(12+Q+1)=Q(13+Q) */
    4213           0 :         L_temp2 = L_mult( temp1, X_fx->b_fx[k] );
    4214           0 :         L_temp2 = L_msu_sat( L_temp2, temp2, X_fx->a_fx[k] ); /*  Q(12+Q+1)=Q(13+Q) */
    4215           0 :         IF( sum )
    4216             :         {
    4217           0 :             exp = norm_l( sum );
    4218           0 :             temp1 = exp;
    4219           0 :             tmp = extract_h( L_shl( sum, exp ) );
    4220           0 :             exp = sub( sub( 30, exp ), 25 );
    4221           0 :             tmp = div_s( 16384, tmp ); /* Q(15+exp) */
    4222           0 :             sum = L_shl( tmp, 16 );
    4223           0 :             temp = round_fx( sum );
    4224             :         }
    4225             :         ELSE
    4226             :         {
    4227           0 :             sum = 0;
    4228           0 :             move16();
    4229           0 :             temp = 0;
    4230           0 :             move16();
    4231           0 :             temp1 = 0;
    4232           0 :             move16();
    4233             :         }
    4234           0 :         sum1_fx = Mult_32_16( L_temp1, temp ); /*  Q(13+Q+20-temp1-15)=Q(Q-temp1+18) */
    4235           0 :         sum2_fx = Mult_32_16( L_temp2, temp ); /*                      Q(Q-temp1+18) */
    4236             : 
    4237             :         /*  normalization */
    4238           0 :         na = norm_l( sum1_fx );
    4239           0 :         if ( sum1_fx == 0 )
    4240             :         {
    4241           0 :             na = 31;
    4242           0 :             move16();
    4243             :         }
    4244           0 :         nb = norm_l( sum2_fx );
    4245           0 :         if ( sum2_fx == 0 )
    4246             :         {
    4247           0 :             nb = 31;
    4248           0 :             move16();
    4249             :         }
    4250             : 
    4251           0 :         if ( LT_16( na, nb ) )
    4252             :         {
    4253           0 :             nb = na;
    4254           0 :             move16();
    4255             :         }
    4256           0 :         nb = sub( nb, 1 );                                /*  leave one more sign bit */
    4257           0 :         X_fx->a_fx[k] = round_fx( L_shl( sum1_fx, nb ) ); /* Q(Q-temp1+22+nb-16)=Q(Q-temp1+nb+2) */
    4258           0 :         move16();
    4259           0 :         X_fx->b_fx[k] = round_fx( L_shl( sum2_fx, nb ) ); /*                    Q(Q-temp1+nb+2) */
    4260           0 :         move16();
    4261             : 
    4262           0 :         Qab[k] = add( sub( add( nb, 2 ), temp1 ), X_fx->Q );
    4263             : 
    4264           0 :         if ( LT_16( Qab[k], Qmin ) )
    4265             :         {
    4266           0 :             Qmin = Qab[k];
    4267           0 :             move16();
    4268             :         }
    4269             :     }
    4270             :     /*  bring to the same Q */
    4271           0 :     FOR( k = 0; k <= HalfLag; k++ )
    4272             :     {
    4273           0 :         X_fx->a_fx[k] = shl( X_fx->a_fx[k], sub( Qmin, Qab[k] ) );
    4274           0 :         move16(); /*  Q(Q+Qab[k]+Qmin-Qab[k])=Q(Q+Qmin) */
    4275           0 :         X_fx->b_fx[k] = shl( X_fx->b_fx[k], sub( Qmin, Qab[k] ) );
    4276           0 :         move16(); /*  Q(Q+Qab[k]+Qmin-Qab[k])=Q(Q+Qmin) */
    4277             :     }
    4278             : 
    4279           0 :     X_fx->Q = Qmin;
    4280           0 :     move16();
    4281           0 : }
    4282             : /*===================================================================*/
    4283             : /* FUNCTION      :  poleFilter_setup_fx()                            */
    4284             : /*-------------------------------------------------------------------*/
    4285             : /* PURPOSE       :  Sets up pole filtering LPC dependent intermediate*/
    4286             : /*            values to be used by poleFilter                        */
    4287             : /*-------------------------------------------------------------------*/
    4288             : /* INPUT ARGUMENTS  :                                                */
    4289             : /*   _ (Word16) lpc[] :  lpc coefficients in Q12                     */
    4290             : /*   _ (Word16) N     :  lpc order                                   */
    4291             : /*   _ (Word16) lag      :  in Q0                                    */
    4292             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
    4293             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
    4294             : /*-------------------------------------------------------------------*/
    4295             : /* OUTPUT ARGUMENTS :                                                */
    4296             : /*   _ None                                                          */
    4297             : /*-------------------------------------------------------------------*/
    4298             : /* INPUT/OUTPUT ARGUMENTS :                                          */
    4299             : /*   _ None                                                          */
    4300             : /*-------------------------------------------------------------------*/
    4301             : /* RETURN ARGUMENTS : _ None.                                        */
    4302             : /*-------------------------------------------------------------------*/
    4303             : /* CALLED FROM : TX/RX                                               */
    4304             : /*===================================================================*/
    4305           0 : void poleFilter_setup_fx( const Word16 *LPC, Word16 N, DTFS_STRUCTURE X_fx, Word16 *S_fx, Word16 *C_fx, Word16 *pf_temp1, Word16 *pf_temp2, Word16 *pf_temp, Word16 *pf_n2_temp1 )
    4306             : {
    4307             :     Word16 temp1, temp2, HalfLag;
    4308             :     Word32 sum1_fx, sum2_fx;
    4309             :     Word32 sum;
    4310             :     Word16 k, n, n1, n2;
    4311             :     Word16 exp, tmp;
    4312           0 :     HalfLag = s_min( shr( X_fx.lag_fx, 1 ), X_fx.nH_fx );
    4313             : 
    4314           0 :     FOR( k = 0; k <= HalfLag; k++ )
    4315             :     {
    4316           0 :         temp2 = k;
    4317           0 :         move16();
    4318             :         /* Calculate sum1 and sum2 */
    4319           0 :         sum1_fx = L_deposit_h( 4096 ); /*  1: Q(12+15+1)  */
    4320             : 
    4321           0 :         sum2_fx = L_deposit_l( 0 );
    4322           0 :         FOR( n = 0; n < N; n++ )
    4323             :         {
    4324           0 :             sum1_fx = L_mac_sat( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )] ); /* Q(12+15+1) */
    4325           0 :             sum2_fx = L_mac_sat( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )] ); /* Q(12+15+1) */
    4326           0 :             temp2 = add( temp2, k );
    4327             :         }
    4328             : 
    4329           0 :         n1 = norm_l( sum1_fx );
    4330           0 :         if ( sum1_fx == 0 )
    4331             :         {
    4332           0 :             n1 = 31;
    4333           0 :             move16();
    4334             :         }
    4335             : 
    4336           0 :         n2 = norm_l( sum2_fx );
    4337           0 :         if ( sum2_fx == 0 )
    4338             :         {
    4339           0 :             n2 = 31;
    4340           0 :             move16();
    4341             :         }
    4342             : 
    4343           0 :         if ( LT_16( n1, n2 ) )
    4344             :         {
    4345           0 :             n2 = n1;
    4346           0 :             move16();
    4347             :         }
    4348           0 :         n2 = sub( n2, 1 );
    4349           0 :         temp1 = pf_temp1[k] = round_fx( (Word32) L_shl( sum1_fx, n2 ) ); /* Q(12+15+1+n2-16)=Q(12+n2) */
    4350           0 :         move16();
    4351           0 :         move16();
    4352           0 :         temp2 = pf_temp2[k] = round_fx( (Word32) L_shl( sum2_fx, n2 ) ); /*                  Q(12+n2) */
    4353           0 :         move16();
    4354           0 :         move16();
    4355             : 
    4356             :         /* Calculate the circular convolution */
    4357           0 :         sum = L_mac( L_mult( temp1, temp1 ), temp2, temp2 ); /*  Q(12+n2+12+n2+1)=Q(25+2*n2) */
    4358             : 
    4359           0 :         exp = norm_l( sum );
    4360           0 :         tmp = extract_h( L_shl( sum, exp ) );
    4361           0 :         exp = sub( sub( 30, exp ), add( 25, shl( n2, 1 ) ) );
    4362           0 :         tmp = div_s( 16384, tmp ); /* Q(15+exp) */
    4363           0 :         sum = tmp;
    4364             : 
    4365           0 :         pf_n2_temp1[k] = add( n2, exp );
    4366           0 :         move16();
    4367           0 :         pf_temp[k] = (Word16) sum;
    4368           0 :         move16(); /*  Q15+exp */
    4369             :     }
    4370           0 : }
    4371             : 
    4372             : 
    4373             : /*=================================================================================*/
    4374             : /* FUNCTION      :  DTFS_getEngy_band_wb_fx (Word16 lband, Word16 hband)     */
    4375             : /*---------------------------------------------------------------------------------*/
    4376             : /* PURPOSE       :  compute the energy of X1.a[k] and X2.b[k]                      */
    4377             : /*             Get DTFS energy in the specified range from lband to hband.             */
    4378             : /*             This function is different to "DTFS_getEngy_band" as this can calculate */
    4379             : /*             lband, hband \in [1,6400] where "DTFS_getEngy_band" only upperlimited to*/
    4380             : /*             4Khz. Possibility: modify ""DTFS_getEngy_band"" and get rid of this     */
    4381             : /*             function.                                                               */
    4382             : /*---------------------------------------------------------------------------------*/
    4383             : /* INPUT ARGUMENTS  :                                                              */
    4384             : /*   _ (struct DTFS_STRUCTURE) X_fx :  a_fx/b_fx in X_fx.Q, lag in Q0           */
    4385             : /*   _ (Word16) lband:  Q0                                                         */
    4386             : /*   _ (Word16) hband:  Q0                                                         */
    4387             : /*---------------------------------------------------------------------------------*/
    4388             : /* OUTPUT ARGUMENTS :                                                              */
    4389             : /*   _ (Word32) en_fx :       2*X1.Q+1                                             */
    4390             : /*---------------------------------------------------------------------------------*/
    4391             : /* INPUT/OUTPUT ARGUMENTS :                                                        */
    4392             : /*                    _ None                                                       */
    4393             : /*---------------------------------------------------------------------------------*/
    4394             : /* RETURN ARGUMENTS : _ None.                                                      */
    4395             : /*---------------------------------------------------------------------------------*/
    4396             : /* CALLED FROM : TX                                                                */
    4397             : /*=================================================================================*/
    4398           0 : Word32 DTFS_getEngy_band_wb_fx( DTFS_STRUCTURE X_fx, Word16 lband, Word16 hband )
    4399             : {
    4400             :     Word16 k, lk, hk, HalfLag;
    4401             :     Word32 freq_fx, L_lband, L_hband;
    4402           0 :     Word32 en_fx = 0;
    4403             : 
    4404           0 :     L_lband = L_mult( lband, X_fx.lag_fx );
    4405           0 :     L_hband = L_mult( hband, X_fx.lag_fx );
    4406           0 :     HalfLag = shr( sub( X_fx.lag_fx, 1 ), 1 );
    4407             : 
    4408             :     /* get lband and hband */
    4409           0 :     FOR( k = 1; k <= HalfLag; k++ )
    4410             :     {
    4411           0 :         freq_fx = L_mult( k, 12800 );
    4412             : 
    4413           0 :         IF( GE_32( freq_fx, L_lband ) )
    4414             :         {
    4415           0 :             BREAK;
    4416             :         }
    4417             :     }
    4418           0 :     lk = k;
    4419           0 :     move16();
    4420           0 :     FOR( k = 1; k <= HalfLag; k++ )
    4421             :     {
    4422           0 :         freq_fx = L_mult( k, 12800 );
    4423           0 :         IF( GE_32( freq_fx, L_hband ) )
    4424             :         {
    4425           0 :             BREAK;
    4426             :         }
    4427             :     }
    4428           0 :     hk = k;
    4429           0 :     move16();
    4430             : 
    4431           0 :     FOR( k = lk; k < hk; k++ )
    4432             :     {
    4433           0 :         en_fx = L_mac0( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] ); /*  2*X1.Q+1 */
    4434           0 :         en_fx = L_mac0( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] );
    4435             :     }
    4436           0 :     en_fx = L_shr( en_fx, 1 ); /*  2*X1.Q+1 */
    4437             : 
    4438           0 :     IF( lband == 0 )
    4439             :     {
    4440           0 :         en_fx = L_mac0( en_fx, X_fx.a_fx[0], X_fx.a_fx[0] ); /*  2*X1.Q+1 */
    4441             :     }
    4442             : 
    4443             :     /* IF ((X_fx.lag_fx%2 == 0) && (hband == X_fx.upper_cut_off_freq_fx))  */
    4444           0 :     test();
    4445           0 :     IF( ( s_and( X_fx.lag_fx, 1 ) == 0 ) && EQ_16( hband, X_fx.upper_cut_off_freq_fx ) )
    4446             :     {
    4447           0 :         en_fx = L_mac0( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] );
    4448           0 :         en_fx = L_mac0( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] );
    4449             :     }
    4450             : 
    4451           0 :     return en_fx; /*  2*X1.Q+1 */
    4452             : }

Generated by: LCOV version 1.14