#ifndef _GSM2DEC_H
#define _GSM2DEC_H

/*_____________________
 |                     |
 | Basic types.        |
 |_____________________|
*/

#define USE_32BIT	1

typedef short True16;

#if (USE_32BIT)
typedef long Word16;
#else
typedef short Word16;
#endif
typedef long Word32;
typedef long long Word64;
typedef int Flag;

void vGSMDecoderInit( );
void vGSMDecodePacket( unsigned char *pubInputBuffer, True16 *pwOutputBuffer );

/*___________________________________________________________________________
 |                                                                           |
 |   Constants and Globals                                                   |
 |___________________________________________________________________________|
*/
extern Flag Overflow;
extern Flag Carry;

#define MAX_32 (Word32)0x7fffffffL
#define MIN_32 (Word32)0x80000000L

#if (USE_32BIT)
#define MAX_16 (Word16)0x7fffffffL
#define MIN_16 (Word16)0x80000000L
#define TRUE_MAX_16 (Word16)0x00007fffL
#define TRUE_MIN_16 (Word16)0xffff8000L
#else
#define MAX_16 (Word16)0x7fffL
#define MIN_16 (Word16)0x8000L
#endif

/*___________________________________________________________________________
 |                                                                           |
 |   Prototypes for basic arithmetic operators                               |
 |___________________________________________________________________________|
*/

#define saturate(var1)	(var1)
//Word16 add (Word16 var1, Word16 var2);    /* Short add,           1   */
//#define	add(var1, var2)	((var1) + (var2))
//Word16 sub (Word16 var1, Word16 var2);    /* Short sub,           1   */
//#define	sub(var1, var2)	((var1) - (var2))
//Word16 abs_s (Word16 var1);               /* Short abs,           1   */
//Word16 shl (Word16 var1, Word16 var2);    /* Short shift left,    1   */
//Word16 shr (Word16 var1, Word16 var2);    /* Short shift right,   1   */
//Word16 mult (Word16 var1, Word16 var2);   /* Short mult,          1   */
#define mult(var1, var2) (((var1) * (var2)) >> 15)
//Word16 negate (Word16 var1);              /* Short negate,        1   */
//#define negate(var1)	(((var1) == MIN_16) ? MAX_16 : -(var1))
#define	negate(v)	(-(v))
//Word16 extract_h (Word32 L_var1);         /* Extract high,        1   */
//Word16 extract_l (Word32 L_var1);         /* Extract low,         1   */
//Word32 L_add (Word32 L_var1, Word32 L_var2);    /* Long add,        2 */
//Word32 L_negate (Word32 L_var1);                /* Long negate,     2 */
//#define L_negate(var1)	(((var1) == MIN_32) ? MAX_32 : -(var1))
#define L_negate(v)	(-(v))
//Word32 L_deposit_h (Word16 var1);        /* 16 bit var1 -> MSB,     2 */
//Word32 L_deposit_l (Word16 var1);        /* 16 bit var1 -> LSB,     2 */
#define L_deposit_h(var1)	((var1) << 16)
#define L_deposit_l(var1)	((var1))
//Word32 L_abs (Word32 L_var1);            /* Long abs,              3  */

/*--------------------------------------------------------------*
* Function prototypes for general SIGnal PROCessing functions. *
*--------------------------------------------------------------*/

/* Mathematic functions  */

Word32 Inv_sqrt (      /* (o) : output value   (range: 0<=val<1)            */
    Word32 L_x         /* (i) : input value    (range: 0<=val<=7fffffff)    */
);
void Log2 (
    Word32 L_x,        /* (i) : input value                                 */
    Word16 *exponent,  /* (o) : Integer part of Log2.   (range: 0<=val<=30) */
    Word16 *fraction   /* (o) : Fractional part of Log2. (range: 0<=val<1)*/
);
Word32 Pow2 (          /* (o) : result       (range: 0<=val<=0x7fffffff)    */
    Word16 exponent,   /* (i) : Integer part.      (range: 0<=val<=30)      */
    Word16 fraction    /* (i) : Fractional part.  (range: 0.0<=val<1.0)     */
);

/* General signal processing */

void Init_Pre_Process (void);
void Pre_Process (
    Word16 signal[],   /* Input/output signal                               */
    Word16 lg          /* Lenght of signal                                  */
);

Word16 Autocorr (
    Word16 x[],        /* (i)    : Input signal                             */
    Word16 m,          /* (i)    : LPC order                                */
    Word16 r_h[],      /* (o)    : Autocorrelations  (msb)                  */
    Word16 r_l[],      /* (o)    : Autocorrelations  (lsb)                  */
    const Word16 wind[]/* (i)    : window for LPC analysis.                 */
);
void Lag_window (
    Word16 m,          /* (i)    : LPC order                                */
    Word16 r_h[],      /* (i/o)  : Autocorrelations  (msb)                  */
    Word16 r_l[]       /* (i/o)  : Autocorrelations  (lsb)                  */
);
void Levinson (
    Word16 Rh[],       /* (i)    : Rh[m+1] Vector of autocorrelations (msb) */
    Word16 Rl[],       /* (i)    : Rl[m+1] Vector of autocorrelations (lsb) */
    Word16 A[],        /* (o)    : A[m]    LPC coefficients  (m = 10)       */
    Word16 rc[]        /* (o)    : rc[4]   First 4 reflection coefficients  */
);
void Az_lsp (
    Word16 a[],        /* (i)    : predictor coefficients                   */
    Word16 lsp[],      /* (o)    : line spectral pairs                      */
    Word16 old_lsp[]   /* (i)    : old lsp[] (in case not found 10 roots)   */
);
void Lsp_Az (
    Word16 lsp[],      /* (i)    : line spectral frequencies                */
    Word16 a[]         /* (o)    : predictor coefficients (order = 10)      */
);
void Lsf_lsp (
    Word16 lsf[],      /* (i)    : lsf[m] normalized (range: 0.0<=val<=0.5) */
    Word16 lsp[],      /* (o)    : lsp[m] (range: -1<=val<1)                */
    Word16 m           /* (i)    : LPC order                                */
);
void Lsp_lsf (
    Word16 lsp[],      /* (i)    : lsp[m] (range: -1<=val<1)                */
    Word16 lsf[],      /* (o)    : lsf[m] normalized (range: 0.0<=val<=0.5) */
    Word16 m           /* (i)    : LPC order                                */
);
void Reorder_lsf (
    Word16 *lsf,       /* (i/o)  : vector of LSFs   (range: 0<=val<=0.5)    */
    Word16 min_dist,   /* (i)    : minimum required distance                */
    Word16 n           /* (i)    : LPC order                                */
);
void Weight_Fac (
    Word16 gamma,      /* (i)    : Spectral expansion.                      */
    Word16 fac[]       /* (i/o)  : Computed factors.                        */
);
void Weight_Ai (
    Word16 a[],        /* (i)  : a[m+1]  LPC coefficients   (m=10)          */
    const Word16 fac[],/* (i)  : Spectral expansion factors.                */
    Word16 a_exp[]     /* (o)  : Spectral expanded LPC coefficients         */
);
void Residu (
    Word16 a[],        /* (i)  : prediction coefficients                    */
    Word16 x[],        /* (i)  : speech signal                              */
    Word16 y[],        /* (o)  : residual signal                            */
    Word16 lg          /* (i)  : size of filtering                          */
);
void Syn_filt (
    Word16 a[],        /* (i)  : a[m+1] prediction coefficients   (m=10)    */
    Word16 x[],        /* (i)  : input signal                               */
    Word16 y[],        /* (o)  : output signal                              */
    Word16 lg          /* (i)  : size of filtering                          */
//	Word16 mem[],      /* (i/o): memory associated with this filtering.     */
//	Word16 update      /* (i)  : 0=no update, 1=update of memory.           */
);
void Convolve (
    Word16 x[],        /* (i)  : input vector                               */
    Word16 h[],        /* (i)  : impulse response                           */
    Word16 y[],        /* (o)  : output vector                              */
    Word16 L           /* (i)  : vector size                                */
);
void agc (
    Word16 *sig_in,    /* (i)  : postfilter input signal                    */
    Word16 *sig_out,   /* (i/o): postfilter output signal                   */
    Word16 agc_fac,    /* (i)  : AGC factor                                 */
    Word16 l_trm       /* (i)  : subframe size                              */
);
void agc2 (
    Word16 *sig_in,    /* (i)  : postfilter input signal                    */
    Word16 *sig_out,   /* (i/o): postfilter output signal                   */
    Word16 l_trm       /* (i)  : subframe size                              */
);
void preemphasis (
    Word16 *signal,    /* (i/o): input signal overwritten by the output     */
    Word16 g,          /* (i)  : preemphasis coefficient                    */
    Word16 L           /* (i)  : size of filtering                          */
);

/* General */

void Init_Coder_12k2 (void);

void Coder_12k2 (
    Word16 ana[],      /* output  : Analysis parameters */
    Word16 synth[]     /* output  : Local synthesis     */
);

void Init_Post_Filter (void);

void Post_Filter (
    Word16 *syn,       /* in/out: synthesis speech (postfiltered is output) */
    Word16 *Az_4       /* input : interpolated LPC parameters in all subfr. */
);

void code_10i40_35bits (
    Word16 x[],        /* (i)   : target vector                             */
    Word16 cn[],       /* (i)   : residual after long term prediction       */
    Word16 h[],        /* (i)   : impulse response of weighted synthesis
                                  filter                                    */
    Word16 cod[],      /* (o)   : algebraic (fixed) codebook excitation     */
    Word16 y[],        /* (o)   : filtered fixed codebook excitation        */
    Word16 indx[]      /* (o)   : index of 10 pulses (sign + position)      */
);
void dec_10i40_35bits (
    Word32 index[],    /* (i)   : index of 10 pulses (sign+position)        */
    Word16 cod[]       /* (o)   : algebraic (fixed) codebook excitation     */
);
Word16 Dec_lag6 (      /* output: return integer pitch lag                  */
    Word16 index,      /* input : received pitch index                      */
    Word16 i_subfr,    /* input : subframe flag                             */
    Word16 *T0_frac    /* output: fractional part of pitch lag              */
);

Word16 d_gain_pitch (  /* out      : quantized pitch gain                   */
    Word16 index,      /* in       : index of quantization                  */
    Word16 state       /* in       : state of the state machine             */
);

void d_gain_code (
    Word16 index,      /* input : received quantization index               */
    Word16 code[],     /* input : innovation codevector                     */
    Word16 *gain_code, /* output: decoded innovation gain                   */
    Word16 i_subfr
);
void D_plsf_5 (
    Word32 *indice,    /* input : quantization indices of 5 submatrices     */
    Word16 *lsp1_q,    /* output: quantized 1st LSP vector                  */
    Word16 *lsp2_q     /* output: quantized 2nd LSP vector                  */
);

Word16 q_gain_pitch (  /* Return index of quantization                      */
    Word16 *gain       /* (i)    :  Pitch gain to quantize                  */
);

Word16 q_gain_code (   /* Return quantization index                         */
    Word16 code[],     /* (i)      : fixed codebook excitation              */
    Word16 lcode,      /* (i)      : codevector size                        */
    Word16 *gain,      /* (i/o)    : quantized fixed codebook gain          */
    Word16 i_subfr
);

Word16 G_pitch (       /* (o)     : Gain of pitch lag saturated to 1.2      */
    Word16 xn[],       /* (i)     : Pitch target.                           */
    Word16 y1[],       /* (i)     : Filtered adaptive codebook.             */
    Word16 L_subfr     /*         : Length of subframe.                     */
);
Word16 G_code (        /* out      : Gain of innovation code.               */
    Word16 xn[],       /* in       : target vector                          */
    Word16 y2[]        /* in       : filtered inovation vector              */
);

Word16 Interpol_6 (    /* (o)  : interpolated value                         */
    Word16 *x,         /* (i)  : input vector                               */
    Word16 frac        /* (i)  : fraction                                   */
);
void Int_lpc (
    Word16 lsp_old[],  /* input: LSP vector at the 4th subfr. of past frame */
    Word16 lsp_mid[],  /* input: LSP vector at the 2nd subfr. of
                          present frame                                     */
    Word16 lsp_new[],  /* input: LSP vector at the 4th subfr. of
                          present frame                                     */
    Word16 Az[]        /* output: interpolated LP parameters in all subfr.  */
);
void Int_lpc2 (
    Word16 lsp_old[],  /* input: LSP vector at the 4th subfr. of past frame */
    Word16 lsp_mid[],  /* input: LSP vector at the 2nd subframe of
                          present frame                                     */
    Word16 lsp_new[],  /* input: LSP vector at the 4th subframe of
                          present frame                                     */
    Word16 Az[]        /* output:interpolated LP parameters
                          in subframes 1 and 3                              */
);
Word16 Pitch_ol (      /* output: open loop pitch lag                       */
    Word16 signal[],   /* input: signal used to compute the open loop pitch */
                       /* signal[-pit_max] to signal[-1] should be known    */
    Word16 pit_min,    /* input : minimum pitch lag                         */
    Word16 pit_max,    /* input : maximum pitch lag                         */
    Word16 L_frame     /* input : length of frame to compute pitch          */
);
void Pred_lt_6 (
    Word16 exc[],      /* in/out: excitation buffer                         */
    Word16 T0,         /* input : integer pitch lag                         */
    Word16 frac,       /* input : fraction of lag                           */
    Word16 L_subfr     /* input : subframe size                             */
);
void Bits2prm_12k2 (
    UB		*bits,     /* input : serial bits                               */
    Word32	prm[]       /* output: analysis parameters                       */
);
void Prm2bits_12k2 (
    Word16 prm[],      /* input : analysis parameters                       */
    True16 bits[]      /* output: serial bits                               */
);

/*--------------------------------------------------------------------------*
*       Codec constant parameters (coder, decoder, and postfilter)          *
*---------------------------------------------------------------------------*/

#define  L_TOTAL      320       /* Total size of speech buffer.             */
#define  L_WINDOW     240       /* Window size in LP analysis               */
#define  L_FRAME      160       /* Frame size                               */
#define  L_FRAME_BY2  80        /* Frame size divided by 2                  */
#define  L_SUBFR      40        /* Subframe size                            */
#define  M            10        /* Order of LP filter                       */
#define  MP1          (M+1)     /* Order of LP filter + 1                   */
#define  AZ_SIZE      (4*M+4)   /* Size of array of LP filters in 4 subfr.s */
#define  PIT_MIN      18        /* Minimum pitch lag                        */
#define  PIT_MAX      143       /* Maximum pitch lag                        */
#define  L_INTERPOL   (10+1)    /* Length of filter for interpolation       */

#define  PRM_SIZE     57        /* Size of vector of analysis parameters    */
#define  SERIAL_SIZE  (31)		/* bits per frame + bfi              */

#define  MU       26214         /* Factor for tilt compensation filter 0.8  */
#define  AGC_FAC  29491         /* Factor for automatic gain control 0.9    */

/* Double precision operations */

void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo);
Word32 L_Comp (Word16 hi, Word16 lo);
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);
Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo);

/**************************************************************************
 *
 *   File Name:  d_homing.h
 *
 *   Purpose:   Contains the prototypes for all the functions of
 *              decoder homing.
 *
 **************************************************************************/

#define EHF_MASK 0x0008 /* Encoder Homing Frame pattern */

//#define D_HOMING

/* Function Prototypes */

Word16 decoder_homing_frame_test (Word32 parm[], Word16 nbr_of_params);

void decoder_reset (void);

#endif
