shithub: sox

Download patch

ref: 0925455043d9bafe48052fc0734a54753bd5fb87
parent: f54982203e17a06ba080a28723382bd04c09d303
author: robs <robs>
date: Thu Feb 15 18:22:20 EST 2007

Add AMR-WB format

diff: cannot open b/amr-wb//null: file does not exist: 'b/amr-wb//null'
--- a/AUTHORS
+++ b/AUTHORS
@@ -88,9 +88,9 @@
 		Build system makeover, Lua scripting, Secret Rabbit
                 Code resampling, much cleanup.
 	Rob Sykes		robs@users.sourceforge.net
-		Bass & treble effects, FLAC support, initial 24bit
+		Bass & treble effects, FLAC & AMR-WB formats, initial 24bit
 		support, filters makeover inc. octave plots, new flanger,
-                file merging, speed via resampling, pad effect,
-                various small fixes, enhancements and clean-ups,
+                file merging, speed via resampling, soft-knee companding,
+                pad effect, various fixes, enhancements and clean-ups,
 		much manual improvement and expansion, play multiple
                 files with mixed format types.
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
   o Added support for ADPCM-encoded PRC files, based on Danny Smith's
     rec2wav and sndcmp.
 
+  o Added AMR-WB format.  (robs)
+
   Effects:
 
   o Add soft-knee companding.  (robs)
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,8 +2,8 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = @LIBGSM_SUBDIR@ src
-DIST_SUBDIRS = src/libgsm src
+SUBDIRS = amr-wb @LIBGSM_SUBDIR@ src
+DIST_SUBDIRS = amr-wb src/libgsm src
 
 # man pages are not considered to be sources, so need to add "dist_"
 # prefix to ensure they are added to the distribution.
--- /dev/null
+++ b/amr-wb/acelp.h
@@ -1,0 +1,493 @@
+/*--------------------------------------------------------------------------*
+ *                         ACELP.H                                          *
+ *--------------------------------------------------------------------------*
+ *       Function                                                           *
+ *--------------------------------------------------------------------------*/
+
+#include "typedef.h"
+
+/*-----------------------------------------------------------------*
+ *                        LPC prototypes                           *
+ *-----------------------------------------------------------------*/
+
+void Isf_Extrapolation(Word16 HfIsf[]);
+
+void Init_Lagconc(Word16 lag_hist[]);
+void lagconc(
+     Word16 gain_hist[],                   /* (i) : Gain history     */
+     Word16 lag_hist[],                    /* (i) : Subframe size         */
+     Word16 * T0,
+     Word16 * old_T0,
+     Word16 * seed,
+     Word16 unusable_frame
+);
+
+void agc2(
+     Word16 * sig_in,                      /* input : postfilter input signal  */
+     Word16 * sig_out,                     /* in/out: postfilter output signal */
+     Word16 l_trm                          /* input : subframe size            */
+);
+
+void Init_Filt_7k(Word16 mem[]);
+void Filt_7k(
+     Word16 signal[],                      /* input:  signal                  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 mem[]                          /* in/out: memory (size=30)        */
+);
+
+Word16 median5(Word16 x[]);
+
+void Autocorr(
+     Word16 x[],                           /* (i)    : Input signal                      */
+     Word16 m,                             /* (i)    : LPC order                         */
+     Word16 r_h[],                         /* (o)    : Autocorrelations  (msb)           */
+     Word16 r_l[]                          /* (o)    : Autocorrelations  (lsb)           */
+);
+void Lag_window(
+     Word16 r_h[],                         /* (i/o)   : Autocorrelations  (msb)          */
+     Word16 r_l[]                          /* (i/o)   : Autocorrelations  (lsb)          */
+);
+void Init_Levinson(
+     Word16 * mem                          /* output  :static memory (18 words) */
+);
+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) Q12 : A[M]    LPC coefficients  (m = 16)       */
+     Word16 rc[],                          /* (o) Q15 : rc[M]   Reflection coefficients.         */
+     Word16 * mem                          /* (i/o)   :static memory (18 words)                  */
+);
+
+void Az_isp(
+     Word16 a[],                           /* (i) Q12 : predictor coefficients                 */
+     Word16 isp[],                         /* (o) Q15 : Immittance spectral pairs              */
+     Word16 old_isp[]                      /* (i)     : old isp[] (in case not found M roots)  */
+);
+void Isp_Az(
+     Word16 isp[],                         /* (i) Q15 : Immittance spectral pairs            */
+     Word16 a[],                           /* (o) Q12 : predictor coefficients (order = M)   */
+     Word16 m,
+     Word16 adaptive_scaling               /* (i) 0   : adaptive scaling disabled */
+                                           /*     1   : adaptive scaling enabled  */
+);
+void Isp_isf(
+     Word16 isp[],                         /* (i) Q15 : isp[m] (range: -1<=val<1)                */
+     Word16 isf[],                         /* (o) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+     Word16 m                              /* (i)     : LPC order                                */
+);
+void Isf_isp(
+     Word16 isf[],                         /* (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+     Word16 isp[],                         /* (o) Q15 : isp[m] (range: -1<=val<1)                */
+     Word16 m                              /* (i)     : LPC order                                */
+);
+void Int_isp(
+     Word16 isp_old[],                     /* input : isps from past frame              */
+     Word16 isp_new[],                     /* input : isps from present frame           */
+     Word16 frac[],                        /* input : fraction for 3 first subfr (Q15)  */
+     Word16 Az[]                           /* output: LP coefficients in 4 subframes    */
+);
+void Weight_a(
+     Word16 a[],                           /* (i) Q12 : a[m+1]  LPC coefficients             */
+     Word16 ap[],                          /* (o) Q12 : Spectral expanded LPC coefficients   */
+     Word16 gamma,                         /* (i) Q15 : Spectral expansion factor.           */
+     Word16 m                              /* (i)     : LPC order.                           */
+);
+
+
+/*-----------------------------------------------------------------*
+ *                        isf quantizers                           *
+ *-----------------------------------------------------------------*/
+
+void Qpisf_2s_46b(
+     Word16 * isf1,                        /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* (o) Q15 : quantized ISF               (0..0.5) */
+     Word16 * past_isfq,                   /* (io)Q15 : past ISF quantizer                   */
+     Word16 * indice,                      /* (o)     : quantization indices                 */
+     Word16 nb_surv                        /* (i)     : number of survivor (1, 2, 3 or 4)    */
+);
+void Qpisf_2s_36b(
+     Word16 * isf1,                        /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* (o) Q15 : quantized ISF               (0..0.5) */
+     Word16 * past_isfq,                   /* (io)Q15 : past ISF quantizer                   */
+     Word16 * indice,                      /* (o)     : quantization indices                 */
+     Word16 nb_surv                        /* (i)     : number of survivor (1, 2, 3 or 4)    */
+);
+void Dpisf_2s_46b(
+     Word16 * indice,                      /* input:  quantization indices                       */
+     Word16 * isf_q,                       /* output: quantized ISF in frequency domain (0..0.5) */
+     Word16 * past_isfq,                   /* i/0   : past ISF quantizer                    */
+     Word16 * isfold,                      /* input : past quantized ISF                    */
+     Word16 * isf_buf,                     /* input : isf buffer                                                        */
+     Word16 bfi,                           /* input : Bad frame indicator                   */
+     Word16 enc_dec
+);
+void Dpisf_2s_36b(
+     Word16 * indice,                      /* input:  quantization indices                       */
+     Word16 * isf_q,                       /* output: quantized ISF in frequency domain (0..0.5) */
+     Word16 * past_isfq,                   /* i/0   : past ISF quantizer                    */
+     Word16 * isfold,                      /* input : past quantized ISF                    */
+     Word16 * isf_buf,                     /* input : isf buffer                                                        */
+     Word16 bfi,                           /* input : Bad frame indicator                   */
+     Word16 enc_dec
+);
+void Qisf_ns(
+     Word16 * isf1,                        /* input : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* output: quantized ISF                        */
+     Word16 * indice                       /* output: quantization indices                 */
+);
+void Disf_ns(
+     Word16 * indice,                      /* input:  quantization indices                  */
+     Word16 * isf_q                        /* input : ISF in the frequency domain (0..0.5)  */
+);
+Word16 Sub_VQ(                             /* output: return quantization index     */
+     Word16 * x,                           /* input : ISF residual vector           */
+     Word16 * dico,                        /* input : quantization codebook         */
+     Word16 dim,                           /* input : dimention of vector           */
+     Word16 dico_size,                     /* input : size of quantization codebook */
+     Word32 * distance                     /* output: error of quantization         */
+);
+void Reorder_isf(
+     Word16 * isf,                         /* (i/o) Q15: ISF in the frequency domain (0..0.5) */
+     Word16 min_dist,                      /* (i) Q15  : minimum distance to keep             */
+     Word16 n                              /* (i)      : number of ISF                        */
+);
+
+/*-----------------------------------------------------------------*
+ *                       filter prototypes                         *
+ *-----------------------------------------------------------------*/
+
+void Init_Decim_12k8(
+     Word16 mem[]                          /* output: memory (2*NB_COEF_DOWN) set to zeros */
+);
+void Decim_12k8(
+     Word16 sig16k[],                      /* input:  signal to downsampling  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 sig12k8[],                     /* output: decimated signal        */
+     Word16 mem[]                          /* in/out: memory (2*NB_COEF_DOWN) */
+);
+
+void Init_Oversamp_16k(
+     Word16 mem[]                          /* output: memory (2*NB_COEF_UP) set to zeros  */
+);
+void Oversamp_16k(
+     Word16 sig12k8[],                     /* input:  signal to oversampling  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 sig16k[],                      /* output: oversampled signal      */
+     Word16 mem[]                          /* in/out: memory (2*NB_COEF_UP)   */
+);
+
+void Init_HP50_12k8(Word16 mem[]);
+void HP50_12k8(
+     Word16 signal[],                      /* input/output signal */
+     Word16 lg,                            /* lenght of signal    */
+     Word16 mem[]                          /* filter memory [6]   */
+);
+void Init_HP400_12k8(Word16 mem[]);
+void HP400_12k8(
+     Word16 signal[],                      /* input/output signal */
+     Word16 lg,                            /* lenght of signal    */
+     Word16 mem[]                          /* filter memory [6]   */
+);
+
+void Init_Filt_6k_7k(Word16 mem[]);
+void Filt_6k_7k(
+     Word16 signal[],                      /* input:  signal                  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 mem[]                          /* in/out: memory (size=30)        */
+);
+
+void LP_Decim2(
+     Word16 x[],                           /* in/out: signal to process         */
+     Word16 l,                             /* input : size of filtering         */
+     Word16 mem[]                          /* in/out: memory (size=3)           */
+);
+
+void Preemph(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : preemphasis coefficient                */
+     Word16 lg,                            /* (i)     : lenght of filtering                    */
+     Word16 * mem                          /* (i/o)   : memory (x[-1])                         */
+);
+void Preemph2(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : preemphasis coefficient                */
+     Word16 lg,                            /* (i)     : lenght of filtering                    */
+     Word16 * mem                          /* (i/o)   : memory (x[-1])                         */
+);
+void Deemph(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor                      */
+     Word16 L,                             /* (i)     : vector size                            */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])                         */
+);
+void Deemph2(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor                      */
+     Word16 L,                             /* (i)     : vector size                            */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])                         */
+);
+void Deemph_32(
+     Word16 x_hi[],                        /* (i)     : input signal (bit31..16) */
+     Word16 x_lo[],                        /* (i)     : input signal (bit15..4)  */
+     Word16 y[],                           /* (o)     : output signal (x16)      */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor        */
+     Word16 L,                             /* (i)     : vector size              */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])           */
+);
+
+void Convolve(
+     Word16 x[],                           /* (i)     : input vector                              */
+     Word16 h[],                           /* (i) Q15    : impulse response                       */
+     Word16 y[],                           /* (o) 12 bits: output vector                          */
+     Word16 L                              /* (i)     : vector size                               */
+);
+
+void Residu(
+     Word16 a[],                           /* (i) Q12 : prediction coefficients                     */
+     Word16 m,                             /* (i)     : order of LP filter                          */
+     Word16 x[],                           /* (i)     : speech (values x[-m..-1] are needed         */
+     Word16 y[],                           /* (o)     : residual signal                             */
+     Word16 lg                             /* (i)     : size of filtering                           */
+);
+void Syn_filt(
+     Word16 a[],                           /* (i) Q12 : a[m+1] prediction coefficients           */
+     Word16 m,                             /* (i)     : order of LP filter                       */
+     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 Syn_filt_32(
+     Word16 a[],                           /* (i) Q12 : a[m+1] prediction coefficients */
+     Word16 m,                             /* (i)     : order of LP filter             */
+     Word16 exc[],                         /* (i) Qnew: excitation (exc[i] >> Qnew)    */
+     Word16 Qnew,                          /* (i)     : exc scaling = 0(min) to 8(max) */
+     Word16 sig_hi[],                      /* (o) /16 : synthesis high                 */
+     Word16 sig_lo[],                      /* (o) /16 : synthesis low                  */
+     Word16 lg                             /* (i)     : size of filtering              */
+);
+
+/*-----------------------------------------------------------------*
+ *                       pitch prototypes                          *
+ *-----------------------------------------------------------------*/
+
+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           */
+);
+
+Word16 Pitch_med_ol(                       /* output: open loop pitch lag                        */
+     Word16 wsp[],                         /* input : signal used to compute the open loop pitch */
+/* wsp[-pit_max] to wsp[-1] should be known   */
+     Word16 L_min,                         /* input : minimum pitch lag                          */
+     Word16 L_max,                         /* input : maximum pitch lag                          */
+     Word16 L_frame,                       /* input : length of frame to compute pitch           */
+     Word16 L_0,                           /* input : old_ open-loop pitch                       */
+     Word16 * gain,                        /* output: normalize correlation of hp_wsp for the Lag */
+     Word16 * hp_wsp_mem,                  /* i:o   : memory of the hypass filter for hp_wsp[] (lg=9)   */
+     Word16 * old_hp_wsp,                  /* i:o   : hypass wsp[]                               */
+     Word16 wght_flg                       /* input : is weighting function used                 */
+);
+Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
+     Word16 prev_ol_lag,                   /* input  : previous open-loop lag                     */
+     Word16 old_ol_lag[5]
+);
+void Init_Hp_wsp(Word16 mem[]);
+void scale_mem_Hp_wsp(Word16 mem[], Word16 exp);
+void Hp_wsp(
+     Word16 wsp[],                         /* i   : wsp[]  signal       */
+     Word16 hp_wsp[],                      /* o   : hypass wsp[]        */
+     Word16 lg,                            /* i   : lenght of signal    */
+     Word16 mem[]                          /* i/o : filter memory [9]   */
+);
+
+Word16 Pitch_fr4(                          /* (o)     : pitch period.                         */
+     Word16 exc[],                         /* (i)     : excitation buffer                     */
+     Word16 xn[],                          /* (i)     : target vector                         */
+     Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
+     Word16 t0_min,                        /* (i)     : minimum value in the searched range.  */
+     Word16 t0_max,                        /* (i)     : maximum value in the searched range.  */
+     Word16 * pit_frac,                    /* (o)     : chosen fraction (0, 1, 2 or 3).       */
+     Word16 i_subfr,                       /* (i)     : indicator for first subframe.         */
+     Word16 t0_fr2,                        /* (i)     : minimum value for resolution 1/2      */
+     Word16 t0_fr1,                        /* (i)     : minimum value for resolution 1        */
+     Word16 L_subfr                        /* (i)     : Length of subframe                    */
+);
+void Pred_lt4(
+     Word16 exc[],                         /* in/out: excitation buffer */
+     Word16 T0,                            /* input : integer pitch lag */
+     Word16 frac,                          /* input : fraction of lag   */
+     Word16 L_subfr                        /* input : subframe size     */
+);
+
+
+/*-----------------------------------------------------------------*
+ *                       gain prototypes                           *
+ *-----------------------------------------------------------------*/
+
+Word16 G_pitch(                            /* (o) Q14 : Gain of pitch lag saturated to 1.2   */
+     Word16 xn[],                          /* (i)     : Pitch target.                        */
+     Word16 y1[],                          /* (i)     : filtered adaptive codebook.          */
+     Word16 g_coeff[],                     /* : Correlations need for gain quantization. */
+     Word16 L_subfr                        /* : Length of subframe.                  */
+);
+void Init_Q_gain2(
+     Word16 * mem                          /* output  :static memory (2 words)      */
+);
+Word16 Q_gain2(                            /* Return index of quantization.        */
+     Word16 xn[],                          /* (i) Q_xn:Target vector.               */
+     Word16 y1[],                          /* (i) Q_xn:Adaptive codebook.           */
+     Word16 Q_xn,                          /* (i)     :xn and y1 format             */
+     Word16 y2[],                          /* (i) Q9  :Filtered innovative vector.  */
+     Word16 code[],                        /* (i) Q9  :Innovative vector.           */
+     Word16 g_coeff[],                     /* (i)     :Correlations <xn y1> <y1 y1> */
+/* Compute in G_pitch().        */
+     Word16 L_subfr,                       /* (i)     :Subframe lenght.             */
+     Word16 nbits,                         /* (i)     : number of bits (6 or 7)     */
+     Word16 * gain_pit,                    /* (i/o)Q14:Pitch gain.                  */
+     Word32 * gain_cod,                    /* (o) Q16 :Code gain.                   */
+     Word16 gp_clip,                       /* (i)     : Gp Clipping flag            */
+     Word16 * mem                          /* (i/o)   :static memory (2 words)      */
+);
+
+void Init_D_gain2(
+     Word16 * mem                          /* output  :static memory (4 words)      */
+);
+void D_gain2(
+     Word16 index,                         /* (i)     :index of quantization.       */
+     Word16 nbits,                         /* (i)     : number of bits (6 or 7)     */
+     Word16 code[],                        /* (i) Q9  :Innovative vector.           */
+     Word16 L_subfr,                       /* (i)     :Subframe lenght.             */
+     Word16 * gain_pit,                    /* (o) Q14 :Pitch gain.                  */
+     Word32 * gain_cod,                    /* (o) Q16 :Code gain.                   */
+     Word16 bfi,                           /* (i)     :bad frame indicator          */
+     Word16 prev_bfi,                      /* (i) : Previous BF indicator      */
+     Word16 state,                         /* (i) : State of BFH               */
+     Word16 unusable_frame,                /* (i) : UF indicator            */
+     Word16 vad_hist,                      /* (i)         :number of non-speech frames  */
+     Word16 * mem                          /* (i/o)   :static memory (4 words)      */
+);
+
+/*-----------------------------------------------------------------*
+ *                       acelp prototypes                          *
+ *-----------------------------------------------------------------*/
+
+void cor_h_x(
+     Word16 h[],                           /* (i) Q12 : impulse response of weighted synthesis filter */
+     Word16 x[],                           /* (i) Q0  : target vector                                 */
+     Word16 dn[]                           /* (o) <12bit : correlation between target and h[]         */
+);
+void ACELP_2t64_fx(
+     Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
+     Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
+     Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
+     Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
+     Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
+     Word16 * index                        /* (o) : index (12): 5+1+5+1 = 11 bits.                     */
+);
+void DEC_ACELP_2t64_fx(
+     Word16 index,                         /* (i) :    12 bits index                                  */
+     Word16 code[]                         /* (o) :Q9  algebraic (fixed) codebook excitation          */
+);
+void ACELP_4t64_fx(
+     Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
+     Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
+     Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
+     Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
+     Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
+     Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
+     Word16 ser_size,                      /* (i) : bit rate                                         */
+     Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
+                                           /* (o) : index (36): 9+9+9+9 = 36 bits.                   */
+                                           /* (o) : index (44): 13+9+13+9 = 44 bits.                 */
+                                           /* (o) : index (52): 13+13+13+13 = 52 bits.               */
+                                           /* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
+                                           /* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
+                                           /* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
+);
+void DEC_ACELP_4t64_fx(
+     Word16 index[],                       /* (i) : index (20): 5+5+5+5 = 20 bits.                 */
+                                           /* (i) : index (36): 9+9+9+9 = 36 bits.                 */
+                                           /* (i) : index (44): 13+9+13+9 = 44 bits.               */
+                                           /* (i) : index (52): 13+13+13+13 = 52 bits.             */
+                                           /* (i) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.     */
+                                           /* (i) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.   */
+                                           /* (i) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. */
+     Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits              */
+     Word16 code[]                         /* (o) Q9: algebraic (fixed) codebook excitation        */
+);
+void Pit_shrp(
+     Word16 * x,                           /* in/out: impulse response (or algebraic code) */
+     Word16 pit_lag,                       /* input : pitch lag                            */
+     Word16 sharp,                         /* input : pitch sharpening factor (Q15)        */
+     Word16 L_subfr                        /* input : subframe size                        */
+);
+
+
+/*-----------------------------------------------------------------*
+ *                        others prototypes                        *
+ *-----------------------------------------------------------------*/
+
+void Copy(
+     Word16 x[],                           /* (i)   : input vector   */
+     Word16 y[],                           /* (o)   : output vector  */
+     Word16 L                              /* (i)   : vector length  */
+);
+void Set_zero(
+     Word16 x[],                           /* (o)    : vector to clear     */
+     Word16 L                              /* (i)    : length of vector    */
+);
+void Updt_tar(
+     Word16 * x,                           /* (i) Q0  : old target (for pitch search)     */
+     Word16 * x2,                          /* (o) Q0  : new target (for codebook search)  */
+     Word16 * y,                           /* (i) Q0  : filtered adaptive codebook vector */
+     Word16 gain,                          /* (i) Q14 : adaptive codebook gain            */
+     Word16 L                              /* (i)     : subframe size                     */
+);
+Word16 voice_factor(                       /* (o) Q15 : factor (-1=unvoiced to 1=voiced) */
+     Word16 exc[],                         /* (i) Q_exc: pitch excitation                */
+     Word16 Q_exc,                         /* (i)     : exc format                       */
+     Word16 gain_pit,                      /* (i) Q14 : gain of pitch                    */
+     Word16 code[],                        /* (i) Q9  : Fixed codebook excitation        */
+     Word16 gain_code,                     /* (i) Q0  : gain of code                     */
+     Word16 L_subfr                        /* (i)     : subframe length                  */
+);
+void Scale_sig(
+     Word16 x[],                           /* (i/o) : signal to scale               */
+     Word16 lg,                            /* (i)   : size of x[]                   */
+     Word16 exp                            /* (i)   : exponent: x = round(x << exp) */
+);
+
+void snr(Word16 x[], Word16 y[], Word16 l, Word16 Q_x);
+
+Word16 Random(Word16 * seed);
+
+void Init_gp_clip(
+     Word16 mem[]                          /* (o) : memory of gain of pitch clipping algorithm */
+);
+Word16 Gp_clip(
+     Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
+);
+void Gp_clip_test_isf(
+     Word16 isf[],                         /* (i)   : isf values (in frequency domain)           */
+     Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
+);
+void Gp_clip_test_gain_pit(
+     Word16 gain_pit,                      /* (i)   : gain of quantized pitch                    */
+     Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
+);
+
+void Init_Phase_dispersion(
+     Word16 disp_mem[]                     /* (i/o): static memory (size = 8) */
+);
+void Phase_dispersion(
+     Word16 gain_code,                     /* (i) Q0  : gain of code             */
+     Word16 gain_pit,                      /* (i) Q14 : gain of pitch            */
+     Word16 code[],                        /* (i/o)   : code vector              */
+     Word16 mode,                          /* (i)     : level, 0=hi, 1=lo, 2=off */
+     Word16 disp_mem[]                     /* (i/o)   : static memory (size = 8) */
+);
--- /dev/null
+++ b/amr-wb/agc2.c
@@ -1,0 +1,89 @@
+/*------------------------------------------------------------------------*
+ *                         AGC2.C                                         *
+ *------------------------------------------------------------------------*
+ * Performs adaptive gain control                                         *
+ *------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cnst.h"
+#include "acelp.h"
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "math_op.h"
+
+void agc2(
+     Word16 * sig_in,                      /* (i)     : postfilter input signal  */
+     Word16 * sig_out,                     /* (i/o)   : postfilter output signal */
+     Word16 l_trm                          /* (i)     : subframe size            */
+)
+{
+
+    Word16 i, exp;
+    Word16 gain_in, gain_out, g0;
+    Word32 s;
+
+    Word16 temp;
+
+    /* calculate gain_out with exponent */
+
+    temp = shr(sig_out[0], 2);
+    s = L_mult(temp, temp);
+    for (i = 1; i < l_trm; i++)
+    {
+        temp = shr(sig_out[i], 2);
+        s = L_mac(s, temp, temp);
+    }
+
+    test();
+    if (s == 0)
+    {
+        return;
+    }
+    exp = sub(norm_l(s), 1);
+    gain_out = round(L_shl(s, exp));
+
+    /* calculate gain_in with exponent */
+
+    temp = shr(sig_in[0], 2);
+    s = L_mult(temp, temp);
+    for (i = 1; i < l_trm; i++)
+    {
+        temp = shr(sig_in[i], 2);
+        s = L_mac(s, temp, temp);
+    }
+
+    test();
+    if (s == 0)
+    {
+        g0 = 0;
+        move16();
+    } else
+    {
+        i = norm_l(s);
+        gain_in = round(L_shl(s, i));
+        exp = sub(exp, i);
+
+        /*---------------------------------------------------*
+         *  g0 = sqrt(gain_in/gain_out);                     *
+         *---------------------------------------------------*/
+
+        s = L_deposit_l(div_s(gain_out, gain_in));
+        s = L_shl(s, 7);                   /* s = gain_out / gain_in */
+        s = L_shr(s, exp);                 /* add exponent */
+
+        s = Isqrt(s);
+        g0 = round(L_shl(s, 9));
+    }
+    /* sig_out(n) = gain(n) sig_out(n) */
+
+    for (i = 0; i < l_trm; i++)
+    {
+        sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], g0), 2));
+        move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/amr-wb.h
@@ -1,0 +1,9 @@
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "cnst.h"
+#include "main.h"
+#include "bits.h"
+#include "dtx.h"
+#include "count.h"
+#include "cod_main.h"
--- /dev/null
+++ b/amr-wb/autocorr.c
@@ -1,0 +1,81 @@
+/*------------------------------------------------------------------------*
+ *                         AUTOCORR.C                                     *
+ *------------------------------------------------------------------------*
+ *   Compute autocorrelations of signal with windowing                    *
+ *                                                                        *
+ *------------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+#include "count.h"
+
+#include "ham_wind.tab"
+
+
+void Autocorr(
+     Word16 x[],                           /* (i)    : Input signal                      */
+     Word16 m,                             /* (i)    : LPC order                         */
+     Word16 r_h[],                         /* (o) Q15: Autocorrelations  (msb)           */
+     Word16 r_l[]                          /* (o)    : Autocorrelations  (lsb)           */
+)
+{
+    Word16 i, j, norm, shift, y[L_WINDOW];
+    Word32 L_sum, L_tmp;
+
+    /* Windowing of signal */
+
+    for (i = 0; i < L_WINDOW; i++)
+    {
+        y[i] = mult_r(x[i], window[i]);    move16();
+    }
+
+    /* calculate energy of signal */
+
+    L_sum = L_deposit_h(16);               /* sqrt(256), avoid overflow after rounding */
+    for (i = 0; i < L_WINDOW; i++)
+    {
+        L_tmp = L_mult(y[i], y[i]);
+        L_tmp = L_shr(L_tmp, 8);
+        L_sum = L_add(L_sum, L_tmp);
+    }
+
+    /* scale signal to avoid overflow in autocorrelation */
+
+    norm = norm_l(L_sum);
+    shift = sub(4, shr(norm, 1));
+    test();
+    if (shift < 0)
+    {
+        shift = 0;                         move16();
+    }
+    for (i = 0; i < L_WINDOW; i++)
+    {
+        y[i] = shr_r(y[i], shift);         move16();
+    }
+
+    /* Compute and normalize r[0] */
+
+    L_sum = 1;                             move32();
+    for (i = 0; i < L_WINDOW; i++)
+        L_sum = L_mac(L_sum, y[i], y[i]);
+
+    norm = norm_l(L_sum);
+    L_sum = L_shl(L_sum, norm);
+    L_Extract(L_sum, &r_h[0], &r_l[0]);    /* Put in DPF format (see oper_32b) */
+
+    /* Compute r[1] to r[m] */
+
+    for (i = 1; i <= m; i++)
+    {
+        L_sum = 0;                         move32();
+        for (j = 0; j < L_WINDOW - i; j++)
+            L_sum = L_mac(L_sum, y[j], y[j + i]);
+
+        L_sum = L_shl(L_sum, norm);
+        L_Extract(L_sum, &r_h[i], &r_l[i]);
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/az_isp.c
@@ -1,0 +1,275 @@
+/*-----------------------------------------------------------------------*
+ *                         Az_isp.C                                      *
+ *-----------------------------------------------------------------------*
+ * Compute the ISPs from  the LPC coefficients  (order=M)                *
+ *-----------------------------------------------------------------------*
+ *                                                                       *
+ * The ISPs are the roots of the two polynomials F1(z) and F2(z)         *
+ * defined as                                                            *
+ *               F1(z) = A(z) + z^-m A(z^-1)                             *
+ *  and          F2(z) = A(z) - z^-m A(z^-1)                             *
+ *                                                                       *
+ * For a even order m=2n, F1(z) has M/2 conjugate roots on the unit      *
+ * circle and F2(z) has M/2-1 conjugate roots on the unit circle in      *
+ * addition to two roots at 0 and pi.                                    *
+ *                                                                       *
+ * For a 16th order LP analysis, F1(z) and F2(z) can be written as       *
+ *                                                                       *
+ *   F1(z) = (1 + a[M])   PRODUCT  (1 - 2 cos(w_i) z^-1 + z^-2 )         *
+ *                        i=0,2,4,6,8,10,12,14                           *
+ *                                                                       *
+ *   F2(z) = (1 - a[M]) (1 - z^-2) PRODUCT (1 - 2 cos(w_i) z^-1 + z^-2 ) *
+ *                                 i=1,3,5,7,9,11,13                     *
+ *                                                                       *
+ * The ISPs are the M-1 frequencies w_i, i=0...M-2 plus the last         *
+ * predictor coefficient a[M].                                           *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "stdio.h"
+#include "count.h"
+
+#include "grid100.tab"
+
+#define M   16
+#define NC  (M/2)
+
+/* local function */
+static Word16 Chebps2(Word16 x, Word16 f[], Word16 n);
+
+void Az_isp(
+     Word16 a[],                           /* (i) Q12 : predictor coefficients                 */
+     Word16 isp[],                         /* (o) Q15 : Immittance spectral pairs              */
+     Word16 old_isp[]                      /* (i)     : old isp[] (in case not found M roots)  */
+)
+{
+    Word16 i, j, nf, ip, order;
+    Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
+    Word16 x, y, sign, exp;
+    Word16 *coef;
+    Word16 f1[NC + 1], f2[NC];
+    Word32 t0;
+
+    /*-------------------------------------------------------------*
+     * find the sum and diff polynomials F1(z) and F2(z)           *
+     *      F1(z) = [A(z) + z^M A(z^-1)]                           *
+     *      F2(z) = [A(z) - z^M A(z^-1)]/(1-z^-2)                  *
+     *                                                             *
+     * for (i=0; i<NC; i++)                                        *
+     * {                                                           *
+     *   f1[i] = a[i] + a[M-i];                                    *
+     *   f2[i] = a[i] - a[M-i];                                    *
+     * }                                                           *
+     * f1[NC] = 2.0*a[NC];                                         *
+     *                                                             *
+     * for (i=2; i<NC; i++)            Divide by (1-z^-2)          *
+     *   f2[i] += f2[i-2];                                         *
+     *-------------------------------------------------------------*/
+
+    for (i = 0; i < NC; i++)
+    {
+        t0 = L_mult(a[i], 16384);
+        f1[i] = round(L_mac(t0, a[M - i], 16384));      move16();  /* =(a[i]+a[M-i])/2 */
+        f2[i] = round(L_msu(t0, a[M - i], 16384));      move16();  /* =(a[i]-a[M-i])/2 */
+    }
+    f1[NC] = a[NC];                        move16();
+
+    for (i = 2; i < NC; i++)               /* Divide by (1-z^-2) */
+        f2[i] = add(f2[i], f2[i - 2]);     move16();
+
+    /*---------------------------------------------------------------------*
+     * Find the ISPs (roots of F1(z) and F2(z) ) using the                 *
+     * Chebyshev polynomial evaluation.                                    *
+     * The roots of F1(z) and F2(z) are alternatively searched.            *
+     * We start by finding the first root of F1(z) then we switch          *
+     * to F2(z) then back to F1(z) and so on until all roots are found.    *
+     *                                                                     *
+     *  - Evaluate Chebyshev pol. at grid points and check for sign change.*
+     *  - If sign change track the root by subdividing the interval        *
+     *    2 times and ckecking sign change.                                *
+     *---------------------------------------------------------------------*/
+
+    nf = 0;                                move16();  /* number of found frequencies */
+    ip = 0;                                move16();  /* indicator for f1 or f2      */
+
+    coef = f1;                             move16();
+    order = NC;                            move16();
+
+    xlow = grid[0];                        move16();
+    ylow = Chebps2(xlow, coef, order);
+
+    j = 0;
+    test();test();
+    while ((nf < M - 1) && (j < GRID_POINTS))
+    {
+        j = add(j, 1);
+        xhigh = xlow;                      move16();
+        yhigh = ylow;                      move16();
+        xlow = grid[j];                    move16();
+        ylow = Chebps2(xlow, coef, order);
+
+        test();
+        if (L_mult(ylow, yhigh) <= (Word32) 0)
+        {
+            /* divide 2 times the interval */
+
+            for (i = 0; i < 2; i++)
+            {
+                xmid = add(shr(xlow, 1), shr(xhigh, 1));        /* xmid = (xlow + xhigh)/2 */
+
+                ymid = Chebps2(xmid, coef, order);
+
+                test();
+                if (L_mult(ylow, ymid) <= (Word32) 0)
+                {
+                    yhigh = ymid;          move16();
+                    xhigh = xmid;          move16();
+                } else
+                {
+                    ylow = ymid;           move16();
+                    xlow = xmid;           move16();
+                }
+            }
+
+            /*-------------------------------------------------------------*
+             * Linear interpolation                                        *
+             *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
+             *-------------------------------------------------------------*/
+
+            x = sub(xhigh, xlow);
+            y = sub(yhigh, ylow);
+
+            test();
+            if (y == 0)
+            {
+                xint = xlow;               move16();
+            } else
+            {
+                sign = y;                  move16();
+                y = abs_s(y);
+                exp = norm_s(y);
+                y = shl(y, exp);
+                y = div_s((Word16) 16383, y);
+                t0 = L_mult(x, y);
+                t0 = L_shr(t0, sub(20, exp));
+                y = extract_l(t0);         /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */
+
+                test();
+                if (sign < 0)
+                    y = negate(y);
+
+                t0 = L_mult(ylow, y);      /* result in Q26 */
+                t0 = L_shr(t0, 11);        /* result in Q15 */
+                xint = sub(xlow, extract_l(t0));        /* xint = xlow - ylow*y */
+            }
+
+            isp[nf] = xint;                move16();
+            xlow = xint;                   move16();
+            nf++;                          move16();
+
+            test();
+            if (ip == 0)
+            {
+                ip = 1;                    move16();
+                coef = f2;                 move16();
+                order = NC - 1;            move16();
+            } else
+            {
+                ip = 0;                    move16();
+                coef = f1;                 move16();
+                order = NC;                move16();
+            }
+            ylow = Chebps2(xlow, coef, order);
+        }
+        test();test();
+    }
+
+    /* Check if M-1 roots found */
+
+    test();
+    if (sub(nf, M - 1) < 0)
+    {
+        for (i = 0; i < M; i++)
+        {
+            isp[i] = old_isp[i];           move16();
+        }
+    } else
+    {
+        isp[M - 1] = shl(a[M], 3);         move16();  /* From Q12 to Q15 with saturation */
+    }
+
+    return;
+}
+
+
+/*--------------------------------------------------------------*
+ * function  Chebps2:                                           *
+ *           ~~~~~~~                                            *
+ *    Evaluates the Chebishev polynomial series                 *
+ *--------------------------------------------------------------*
+ *                                                              *
+ *  The polynomial order is                                     *
+ *     n = M/2   (M is the prediction order)                    *
+ *  The polynomial is given by                                  *
+ *    C(x) = f(0)T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
+ * Arguments:                                                   *
+ *  x:     input value of evaluation; x = cos(frequency) in Q15 *
+ *  f[]:   coefficients of the pol.                      in Q11 *
+ *  n:     order of the pol.                                    *
+ *                                                              *
+ * The value of C(x) is returned. (Satured to +-1.99 in Q14)    *
+ *                                                              *
+ *--------------------------------------------------------------*/
+
+static Word16 Chebps2(Word16 x, Word16 f[], Word16 n)
+{
+    Word16 i, cheb;
+    Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l;
+    Word32 t0;
+
+    /* Note: All computation are done in Q24. */
+
+    t0 = L_mult(f[0], 4096);
+    L_Extract(t0, &b2_h, &b2_l);           /* b2 = f[0] in Q24 DPF */
+
+    t0 = Mpy_32_16(b2_h, b2_l, x);         /* t0 = 2.0*x*b2        */
+    t0 = L_shl(t0, 1);
+    t0 = L_mac(t0, f[1], 4096);            /* + f[1] in Q24        */
+    L_Extract(t0, &b1_h, &b1_l);           /* b1 = 2*x*b2 + f[1]   */
+
+    for (i = 2; i < n; i++)
+    {
+        t0 = Mpy_32_16(b1_h, b1_l, x);     /* t0 = 2.0*x*b1              */
+
+        t0 = L_mac(t0, b2_h, -16384);
+        t0 = L_mac(t0, f[i], 2048);
+        t0 = L_shl(t0, 1);
+        t0 = L_msu(t0, b2_l, 1);           /* t0 = 2.0*x*b1 - b2 + f[i]; */
+
+        L_Extract(t0, &b0_h, &b0_l);       /* b0 = 2.0*x*b1 - b2 + f[i]; */
+
+        b2_l = b1_l;                       move16();  /* b2 = b1; */
+        b2_h = b1_h;                       move16();
+        b1_l = b0_l;                       move16();  /* b1 = b0; */
+        b1_h = b0_h;                       move16();
+    }
+
+    t0 = Mpy_32_16(b1_h, b1_l, x);         /* t0 = x*b1;              */
+    t0 = L_mac(t0, b2_h, (Word16) - 32768);/* t0 = x*b1 - b2          */
+    t0 = L_msu(t0, b2_l, 1);
+    t0 = L_mac(t0, f[n], 2048);            /* t0 = x*b1 - b2 + f[i]/2 */
+
+    t0 = L_shl(t0, 6);                     /* Q24 to Q30 with saturation */
+
+    cheb = extract_h(t0);                  /* Result in Q14              */
+
+    test();
+    if (sub(cheb, -32768) == 0)
+    {
+        cheb = -32767;                     /* to avoid saturation in Az_isp */
+        move16();
+    }
+    return (cheb);
+}
--- /dev/null
+++ b/amr-wb/basic_op.h
@@ -1,0 +1,67 @@
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Constants and Globals                                                   |
+ |                                                                           |
+ | $Id $
+ |___________________________________________________________________________|
+*/
+extern Flag Overflow;
+extern Flag Carry;
+
+#define MAX_32 (Word32)0x7fffffffL
+#define MIN_32 (Word32)0x80000000L
+
+#define MAX_16 (Word16)+32767   /* 0x7fff */
+#define MIN_16 (Word16)-32768   /* 0x8000 */
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Prototypes for basic arithmetic operators                               |
+ |___________________________________________________________________________|
+*/
+
+Word16 add (Word16 var1, Word16 var2);    /* Short add,           1   */
+Word16 sub (Word16 var1, Word16 var2);    /* Short sub,           1   */
+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   */
+//Word32 L_mult (Word16 var1, Word16 var2); /* Long mult,           1   */
+#define L_mult(a,b) ((a)*(b)<<1)
+Word16 negate (Word16 var1);              /* Short negate,        1   */
+Word16 extract_h (Word32 L_var1);         /* Extract high,        1   */
+Word16 extract_l (Word32 L_var1);         /* Extract low,         1   */
+Word16 round (Word32 L_var1);             /* Round,               1   */
+Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);   /* Mac,  1  */
+Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);   /* Msu,  1  */
+Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2); /* Mac without
+                                                             sat, 1   */
+Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2); /* Msu without
+                                                             sat, 1   */
+Word32 L_add (Word32 L_var1, Word32 L_var2);    /* Long add,        2 */
+Word32 L_add (Word32 L_var1, Word32 L_var2);    /* Long add,        2 */
+Word32 L_sub (Word32 L_var1, Word32 L_var2);    /* Long sub,        2 */
+Word32 L_add_c (Word32 L_var1, Word32 L_var2);  /* Long add with c, 2 */
+Word32 L_sub_c (Word32 L_var1, Word32 L_var2);  /* Long sub with c, 2 */
+Word32 L_negate (Word32 L_var1);                /* Long negate,     2 */
+Word16 mult_r (Word16 var1, Word16 var2);       /* Mult with round, 2 */
+Word32 L_shl (Word32 L_var1, Word16 var2);      /* Long shift left, 2 */
+Word32 L_shr (Word32 L_var1, Word16 var2);      /* Long shift right, 2*/
+Word16 shr_r (Word16 var1, Word16 var2);        /* Shift right with
+                                                   round, 2           */
+Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with
+                                                           rounding,2 */
+Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with
+                                                           rounding,2 */
+Word32 L_deposit_h (Word16 var1);        /* 16 bit var1 -> MSB,     2 */
+Word32 L_deposit_l (Word16 var1);        /* 16 bit var1 -> LSB,     2 */
+
+Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with
+                                                round,  3             */
+Word32 L_abs (Word32 L_var1);            /* Long abs,              3  */
+Word32 L_sat (Word32 L_var1);            /* Long saturation,       4  */
+Word16 norm_s (Word16 var1);             /* Short norm,           15  */
+Word16 div_s (Word16 var1, Word16 var2); /* Short division,       18  */
+Word16 norm_l (Word32 L_var1);           /* Long norm,            30  */   
+
+
--- /dev/null
+++ b/amr-wb/basicop2.c
@@ -1,0 +1,2136 @@
+/*___________________________________________________________________________
+ |                                                                           |
+ | Basic arithmetic operators.                                               |
+ |                                                                           |
+ | $Id $
+ |___________________________________________________________________________|
+*/
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Include-Files                                                           |
+ |___________________________________________________________________________|
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "typedef.h"
+#include "basic_op.h"
+
+#if (WMOPS)
+#include "count.h"
+extern BASIC_OP multiCounter[MAXCOUNTERS];
+extern int currCounter;
+
+#endif
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Local Functions                                                         |
+ |___________________________________________________________________________|
+*/
+Word16 saturate (Word32 L_var1);
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Constants and Globals                                                   |
+ |___________________________________________________________________________|
+*/
+Flag Overflow = 0;
+Flag Carry = 0;
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Functions                                                               |
+ |___________________________________________________________________________|
+*/
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : saturate                                                |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Limit the 32 bit input to the range of a 16 bit word.                  |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 
+saturate (Word32 L_var1)
+{
+    Word16 var_out;
+
+    if (L_var1 > 0X00007fffL)
+    {
+        Overflow = 1;
+        var_out = MAX_16;
+    }
+    else if (L_var1 < (Word32) 0xffff8000L)
+    {
+        Overflow = 1;
+        var_out = MIN_16;
+    }
+    else
+    {
+        var_out = extract_l (L_var1);
+#if (WMOPS)
+        multiCounter[currCounter].extract_l--;
+#endif
+    }
+
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : add                                                     |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Performs the addition (var1+var2) with overflow control and saturation;|
+ |    the 16 bit result is set at +32767 when overflow occurs or at -32768   |
+ |    when underflow occurs.                                                 |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 add (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+    Word32 L_sum;
+
+    L_sum = (Word32) var1 + var2;
+    var_out = saturate (L_sum);
+#if (WMOPS)
+    multiCounter[currCounter].add++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : sub                                                     |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Performs the subtraction (var1+var2) with overflow control and satu-   |
+ |    ration; the 16 bit result is set at +32767 when overflow occurs or at  |
+ |    -32768 when underflow occurs.                                          |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 sub (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+    Word32 L_diff;
+
+    L_diff = (Word32) var1 - var2;
+    var_out = saturate (L_diff);
+#if (WMOPS)
+    multiCounter[currCounter].sub++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : abs_s                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Absolute value of var1; abs_s(-32768) = 32767.                         |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 abs_s (Word16 var1)
+{
+    Word16 var_out;
+
+    if (var1 == MIN_16)
+    {
+        var_out = MAX_16;
+    }
+    else
+    {
+        if (var1 < 0)
+        {
+            var_out = (Word16)-var1;
+        }
+        else
+        {
+            var_out = var1;
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].abs_s++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : shl                                                     |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
+ |   the var2 LSB of the result. If var2 is negative, arithmetically shift   |
+ |   var1 right by -var2 with sign extension. Saturate the result in case of |
+ |   underflows or overflows.                                                |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 shl (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+    Word32 result;
+
+    if (var2 < 0)
+    {
+        if (var2 < -16)
+            var2 = -16;
+        var_out = shr (var1, (Word16)-var2);
+#if (WMOPS)
+        multiCounter[currCounter].shr--;
+#endif
+    }
+    else
+    {
+        result = (Word32) var1 *((Word32) 1 << var2);
+
+        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
+        {
+            Overflow = 1;
+            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
+        }
+        else
+        {
+            var_out = extract_l (result);
+#if (WMOPS)
+            multiCounter[currCounter].extract_l--;
+#endif
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].shl++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : shr                                                     |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Arithmetically shift the 16 bit input var1 right var2 positions with    |
+ |   sign extension. If var2 is negative, arithmetically shift var1 left by  |
+ |   -var2 with sign extension. Saturate the result in case of underflows or |
+ |   overflows.                                                              |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 shr (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+
+    if (var2 < 0)
+    {
+        if (var2 < -16)
+            var2 = -16;
+        var_out = shl (var1, (Word16)-var2);
+#if (WMOPS)
+        multiCounter[currCounter].shl--;
+#endif
+    }
+    else
+    {
+        if (var2 >= 15)
+        {
+            var_out = (Word16)((var1 < 0) ? -1 : 0);
+        }
+        else
+        {
+            if (var1 < 0)
+            {
+                var_out = (Word16)(~((~var1) >> var2));
+            }
+            else
+            {
+                var_out = (Word16)(var1 >> var2);
+            }
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].shr++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : mult                                                    |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Performs the multiplication of var1 by var2 and gives a 16 bit result  |
+ |    which is scaled i.e.:                                                  |
+ |             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |
+ |             mult(-32768,-32768) = 32767.                                  |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 mult (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+    Word32 L_product;
+
+    L_product = (Word32) var1 *(Word32) var2;
+
+    L_product = (L_product & (Word32) 0xffff8000L) >> 15;
+
+    if (L_product & (Word32) 0x00010000L)
+        L_product = L_product | (Word32) 0xffff0000L;
+
+    var_out = saturate (L_product);
+#if (WMOPS)
+    multiCounter[currCounter].mult++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_mult                                                  |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   L_mult is the 32 bit result of the multiplication of var1 times var2    |
+ |   with one shift left i.e.:                                               |
+ |        L_mult(var1,var2) = L_shl((var1 times var2),1) and                   |
+ |        L_mult(-32768,-32768) = 2147483647.                                |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 _L_mult (Word16 var1, Word16 var2)
+{
+    Word32 L_var_out;
+
+    L_var_out = (Word32) var1 *(Word32) var2;
+
+    if (L_var_out != (Word32) 0x40000000L)
+    {
+        L_var_out *= 2;
+    }
+    else
+    {
+        Overflow = 1;
+        L_var_out = MAX_32;
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].L_mult++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : negate                                                  |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Negate var1 with saturation, saturate in the case where input is -32768:|
+ |                negate(var1) = sub(0,var1).                                |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 negate (Word16 var1)
+{
+    Word16 var_out;
+
+    var_out = (Word16)((var1 == MIN_16) ? MAX_16 : -var1);
+#if (WMOPS)
+    multiCounter[currCounter].negate++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : extract_h                                               |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Return the 16 MSB of L_var1.                                            |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32 ) whose value falls in the |
+ |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 extract_h (Word32 L_var1)
+{
+    Word16 var_out;
+
+    var_out = (Word16) (L_var1 >> 16);
+#if (WMOPS)
+    multiCounter[currCounter].extract_h++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : extract_l                                               |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Return the 16 LSB of L_var1.                                            |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32 ) whose value falls in the |
+ |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 extract_l (Word32 L_var1)
+{
+    Word16 var_out;
+
+    var_out = (Word16) L_var1;
+#if (WMOPS)
+    multiCounter[currCounter].extract_l++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : round                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |
+ |   with saturation. Shift the resulting bits right by 16 and return the 16 |
+ |   bit number:                                                             |
+ |               round(L_var1) = extract_h(L_add(L_var1,32768))              |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32 ) whose value falls in the |
+ |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 round (Word32 L_var1)
+{
+    Word16 var_out;
+    Word32 L_rounded;
+
+    L_rounded = L_add (L_var1, (Word32) 0x00008000L);
+#if (WMOPS)
+    multiCounter[currCounter].L_add--;
+#endif
+    var_out = extract_h (L_rounded);
+#if (WMOPS)
+    multiCounter[currCounter].extract_h--;
+    multiCounter[currCounter].round++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_mac                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
+ |   result to L_var3 with saturation, return a 32 bit result:               |
+ |        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word32 L_var_out;
+    Word32 L_product;
+
+    L_product = L_mult (var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_mult--;
+#endif
+    L_var_out = L_add (L_var3, L_product);
+#if (WMOPS)
+    multiCounter[currCounter].L_add--;
+    multiCounter[currCounter].L_mac++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_msu                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
+ |   bit result to L_var3 with saturation, return a 32 bit result:           |
+ |        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word32 L_var_out;
+    Word32 L_product;
+
+    L_product = L_mult (var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_mult--;
+#endif
+    L_var_out = L_sub (L_var3, L_product);
+#if (WMOPS)
+    multiCounter[currCounter].L_sub--;
+    multiCounter[currCounter].L_msu++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_macNs                                                 |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
+ |   result to L_var3 without saturation, return a 32 bit result. Generate   |
+ |   carry and overflow values :                                             |
+ |        L_macNs(L_var3,var1,var2) = L_add_c(L_var3,L_mult(var1,var2)).     |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |                                                                           |
+ |   Caution :                                                               |
+ |                                                                           |
+ |    In some cases the Carry flag has to be cleared or set before using     |
+ |    operators which take into account its value.                           |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word32 L_var_out;
+
+    L_var_out = L_mult (var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_mult--;
+#endif
+    L_var_out = L_add_c (L_var3, L_var_out);
+#if (WMOPS)
+    multiCounter[currCounter].L_add_c--;
+    multiCounter[currCounter].L_macNs++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_msuNs                                                 |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
+ |   bit result from L_var3 without saturation, return a 32 bit result. Ge-  |
+ |   nerate carry and overflow values :                                      |
+ |        L_msuNs(L_var3,var1,var2) = L_sub_c(L_var3,L_mult(var1,var2)).     |
+ |                                                                           |
+ |   Complexity weight : 1                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |                                                                           |
+ |   Caution :                                                               |
+ |                                                                           |
+ |    In some cases the Carry flag has to be cleared or set before using     |
+ |    operators which take into account its value.                           |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word32 L_var_out;
+
+    L_var_out = L_mult (var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_mult--;
+#endif
+    L_var_out = L_sub_c (L_var3, L_var_out);
+#if (WMOPS)
+    multiCounter[currCounter].L_sub_c--;
+    multiCounter[currCounter].L_msuNs++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_add                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |
+ |   overflow control and saturation; the result is set at +2147483647 when  |
+ |   overflow occurs or at -2147483648 when underflow occurs.                |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_add (Word32 L_var1, Word32 L_var2)
+{
+    Word32 L_var_out;
+
+    L_var_out = L_var1 + L_var2;
+
+    if (((L_var1 ^ L_var2) & MIN_32) == 0)
+    {
+        if ((L_var_out ^ L_var1) & MIN_32)
+        {
+            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
+            Overflow = 1;
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_add++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_sub                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
+ |   overflow control and saturation; the result is set at +2147483647 when  |
+ |   overflow occurs or at -2147483648 when underflow occurs.                |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_sub (Word32 L_var1, Word32 L_var2)
+{
+    Word32 L_var_out;
+
+    L_var_out = L_var1 - L_var2;
+
+    if (((L_var1 ^ L_var2) & MIN_32) != 0)
+    {
+        if ((L_var_out ^ L_var1) & MIN_32)
+        {
+            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
+            Overflow = 1;
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_sub++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_add_c                                                 |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)|
+ |   with carry. No saturation. Generate carry and Overflow values. The car- |
+ |   ry and overflow values are binary variables which can be tested and as- |
+ |   signed values.                                                          |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |                                                                           |
+ |   Caution :                                                               |
+ |                                                                           |
+ |    In some cases the Carry flag has to be cleared or set before using     |
+ |    operators which take into account its value.                           |
+ |___________________________________________________________________________|
+*/
+Word32 L_add_c (Word32 L_var1, Word32 L_var2)
+{
+    Word32 L_var_out;
+    Word32 L_test;
+    Flag carry_int = 0;
+
+    L_var_out = L_var1 + L_var2 + Carry;
+
+    L_test = L_var1 + L_var2;
+
+    if ((L_var1 > 0) && (L_var2 > 0) && (L_test < 0))
+    {
+        Overflow = 1;
+        carry_int = 0;
+    }
+    else
+    {
+        if ((L_var1 < 0) && (L_var2 < 0))
+        {
+            if (L_test >= 0)
+        {
+                Overflow = 1;
+                carry_int = 1;
+        }
+            else
+        {
+                Overflow = 0;
+                carry_int = 1;
+        }
+        }
+        else
+        {
+            if (((L_var1 ^ L_var2) < 0) && (L_test >= 0))
+            {
+                Overflow = 0;
+                carry_int = 1;
+            }
+            else
+            {
+                Overflow = 0;
+                carry_int = 0;
+            }
+        }
+    }
+
+    if (Carry)
+    {
+        if (L_test == MAX_32)
+        {
+            Overflow = 1;
+            Carry = carry_int;
+        }
+        else
+        {
+            if (L_test == (Word32) 0xFFFFFFFFL)
+            {
+                Carry = 1;
+            }
+            else
+            {
+                Carry = carry_int;
+            }
+        }
+    }
+    else
+    {
+        Carry = carry_int;
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].L_add_c++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_sub_c                                                 |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Performs 32 bits subtraction of the two 32 bits variables with carry    |
+ |   (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow  |
+ |   values. The carry and overflow values are binary variables which can    |
+ |   be tested and assigned values.                                          |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |                                                                           |
+ |   Caution :                                                               |
+ |                                                                           |
+ |    In some cases the Carry flag has to be cleared or set before using     |
+ |    operators which take into account its value.                           |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
+{
+    Word32 L_var_out;
+    Word32 L_test;
+    Flag carry_int = 0;
+
+    if (Carry)
+    {
+        Carry = 0;
+        if (L_var2 != MIN_32)
+        {
+            L_var_out = L_add_c (L_var1, -L_var2);
+#if (WMOPS)
+            multiCounter[currCounter].L_add_c--;
+#endif
+        }
+        else
+        {
+            L_var_out = L_var1 - L_var2;
+            if (L_var1 > 0L)
+            {
+                Overflow = 1;
+                Carry = 0;
+            }
+        }
+    }
+    else
+    {
+        L_var_out = L_var1 - L_var2 - (Word32) 0X00000001L;
+        L_test = L_var1 - L_var2;
+
+        if ((L_test < 0) && (L_var1 > 0) && (L_var2 < 0))
+        {
+            Overflow = 1;
+            carry_int = 0;
+        }
+        else if ((L_test > 0) && (L_var1 < 0) && (L_var2 > 0))
+        {
+            Overflow = 1;
+            carry_int = 1;
+        }
+        else if ((L_test > 0) && ((L_var1 ^ L_var2) > 0))
+        {
+            Overflow = 0;
+            carry_int = 1;
+        }
+        if (L_test == MIN_32)
+        {
+            Overflow = 1;
+            Carry = carry_int;
+        }
+        else
+        {
+            Carry = carry_int;
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].L_sub_c++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_negate                                                |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Negate the 32 bit variable L_var1 with saturation; saturate in the case |
+ |   where input is -2147483648 (0x8000 0000).                               |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_negate (Word32 L_var1)
+{
+    Word32 L_var_out;
+
+    L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
+#if (WMOPS)
+    multiCounter[currCounter].L_negate++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : mult_r                                                  |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Same as mult with rounding, i.e.:                                       |
+ |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
+ |     mult_r(-32768,-32768) = 32767.                                        |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 mult_r (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+    Word32 L_product_arr;
+
+    L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
+    L_product_arr += (Word32) 0x00004000L;      /* round */
+    L_product_arr &= (Word32) 0xffff8000L;
+    L_product_arr >>= 15;       /* shift */
+
+    if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
+    {
+        L_product_arr |= (Word32) 0xffff0000L;
+    }
+    var_out = saturate (L_product_arr);
+#if (WMOPS)
+    multiCounter[currCounter].mult_r++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_shl                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
+ |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
+ |   shift L_var1 right by -var2 with sign extension. Saturate the result in |
+ |   case of underflows or overflows.                                        |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_shl (Word32 L_var1, Word16 var2)
+{
+    Word32 L_var_out = 0L;
+
+    if (var2 <= 0)
+    {
+        if (var2 < -32)
+            var2 = -32;
+        L_var_out = L_shr (L_var1, (Word16)-var2);
+#if (WMOPS)
+        multiCounter[currCounter].L_shr--;
+#endif
+    }
+    else
+    {
+        for (; var2 > 0; var2--)
+        {
+            if (L_var1 > (Word32) 0X3fffffffL)
+            {
+                Overflow = 1;
+                L_var_out = MAX_32;
+                break;
+            }
+            else
+            {
+                if (L_var1 < (Word32) 0xc0000000L)
+                {
+                    Overflow = 1;
+                    L_var_out = MIN_32;
+                    break;
+                }
+            }
+            L_var1 *= 2;
+            L_var_out = L_var1;
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_shl++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_shr                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
+ |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
+ |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
+ |   in case of underflows or overflows.                                     |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_shr (Word32 L_var1, Word16 var2)
+{
+    Word32 L_var_out;
+
+    if (var2 < 0)
+    {
+        if (var2 < -32)
+            var2 = -32;
+        L_var_out = L_shl (L_var1, (Word16)-var2);
+#if (WMOPS)
+        multiCounter[currCounter].L_shl--;
+#endif
+    }
+    else
+    {
+        if (var2 >= 31)
+        {
+            L_var_out = (L_var1 < 0L) ? -1 : 0;
+        }
+        else
+        {
+            if (L_var1 < 0)
+            {
+                L_var_out = ~((~L_var1) >> var2);
+            }
+            else
+            {
+                L_var_out = L_var1 >> var2;
+            }
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_shr++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : shr_r                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Same as shr(var1,var2) but with rounding. Saturate the result in case of|
+ |   underflows or overflows :                                               |
+ |    - If var2 is greater than zero :                                       |
+ |          if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1))))            |
+ |          is equal to zero                                                 |
+ |                     then                                                  |
+ |                     shr_r(var1,var2) = shr(var1,var2)                     |
+ |                     else                                                  |
+ |                     shr_r(var1,var2) = add(shr(var1,var2),1)              |
+ |    - If var2 is less than or equal to zero :                              |
+ |                     shr_r(var1,var2) = shr(var1,var2).                    |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 shr_r (Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+
+    if (var2 > 15)
+    {
+        var_out = 0;
+    }
+    else
+    {
+        var_out = shr (var1, var2);
+#if (WMOPS)
+        multiCounter[currCounter].shr--;
+#endif
+
+        if (var2 > 0)
+        {
+            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
+            {
+                var_out++;
+            }
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].shr_r++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : mac_r                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
+ |   result to L_var3 with saturation. Round the LS 16 bits of the result    |
+ |   into the MS 16 bits with saturation and shift the result right by 16.   |
+ |   Return a 16 bit result.                                                 |
+ |            mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2))       |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |
+ |___________________________________________________________________________|
+*/
+
+Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+
+    L_var3 = L_mac (L_var3, var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_mac--;
+#endif
+    L_var3 = L_add (L_var3, (Word32) 0x00008000L);
+#if (WMOPS)
+    multiCounter[currCounter].L_add--;
+#endif
+    var_out = extract_h (L_var3);
+#if (WMOPS)
+    multiCounter[currCounter].extract_h--;
+    multiCounter[currCounter].mac_r++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : msu_r                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
+ |   bit result to L_var3 with saturation. Round the LS 16 bits of the res-  |
+ |   ult into the MS 16 bits with saturation and shift the result right by   |
+ |   16. Return a 16 bit result.                                             |
+ |            msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2))       |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |
+ |___________________________________________________________________________|
+*/
+
+Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
+{
+    Word16 var_out;
+
+    L_var3 = L_msu (L_var3, var1, var2);
+#if (WMOPS)
+    multiCounter[currCounter].L_msu--;
+#endif
+    L_var3 = L_add (L_var3, (Word32) 0x00008000L);
+#if (WMOPS)
+    multiCounter[currCounter].L_add--;
+#endif
+    var_out = extract_h (L_var3);
+#if (WMOPS)
+    multiCounter[currCounter].extract_h--;
+    multiCounter[currCounter].msu_r++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_deposit_h                                             |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The   |
+ |   16 LS bits of the output are zeroed.                                    |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var_out <= 0x7fff 0000.                |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_deposit_h (Word16 var1)
+{
+    Word32 L_var_out;
+
+    L_var_out = (Word32) var1 << 16;
+#if (WMOPS)
+    multiCounter[currCounter].L_deposit_h++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_deposit_l                                             |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The   |
+ |   16 MS bits of the output are sign extended.                             |
+ |                                                                           |
+ |   Complexity weight : 2                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0xFFFF 8000 <= var_out <= 0x0000 7fff.                |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_deposit_l (Word16 var1)
+{
+    Word32 L_var_out;
+
+    L_var_out = (Word32) var1;
+#if (WMOPS)
+    multiCounter[currCounter].L_deposit_l++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_shr_r                                                 |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
+ |   case of underflows or overflows :                                       |
+ |    - If var2 is greater than zero :                                       |
+ |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
+ |          is equal to zero                                                 |
+ |                     then                                                  |
+ |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
+ |                     else                                                  |
+ |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
+ |    - If var2 is less than or equal to zero :                              |
+ |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
+ |                                                                           |
+ |   Complexity weight : 3                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_shr_r (Word32 L_var1, Word16 var2)
+{
+    Word32 L_var_out;
+
+    if (var2 > 31)
+    {
+        L_var_out = 0;
+    }
+    else
+    {
+        L_var_out = L_shr (L_var1, var2);
+#if (WMOPS)
+        multiCounter[currCounter].L_shr--;
+#endif
+        if (var2 > 0)
+        {
+            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
+            {
+                L_var_out++;
+            }
+        }
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_shr_r++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_abs                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    Absolute value of L_var1; Saturate in case where the input is          |
+ |                                                               -214783648  |
+ |                                                                           |
+ |   Complexity weight : 3                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x0000 0000 <= var_out <= 0x7fff ffff.                |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_abs (Word32 L_var1)
+{
+    Word32 L_var_out;
+
+    if (L_var1 == MIN_32)
+    {
+        L_var_out = MAX_32;
+    }
+    else
+    {
+        if (L_var1 < 0)
+        {
+            L_var_out = -L_var1;
+        }
+        else
+        {
+            L_var_out = L_var1;
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].L_abs++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : L_sat                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |    32 bit L_var1 is set to 2147483647 if an overflow occured or to        |
+ |    -2147483648 if an underflow occured on the most recent L_add_c,        |
+ |    L_sub_c, L_macNs or L_msuNs operations. The carry and overflow values  |
+ |    are binary values which can be tested and assigned values.             |
+ |                                                                           |
+ |   Complexity weight : 4                                                   |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    L_var_out                                                              |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
+ |___________________________________________________________________________|
+*/
+
+Word32 L_sat (Word32 L_var1)
+{
+    Word32 L_var_out;
+
+    L_var_out = L_var1;
+
+    if (Overflow)
+    {
+
+        if (Carry)
+        {
+            L_var_out = MIN_32;
+        }
+        else
+        {
+            L_var_out = MAX_32;
+        }
+
+        Carry = 0;
+        Overflow = 0;
+    }
+#if (WMOPS)
+    multiCounter[currCounter].L_sat++;
+#endif
+    return (L_var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : norm_s                                                  |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Produces the number of left shift needed to normalize the 16 bit varia- |
+ |   ble var1 for positive values on the interval with minimum of 16384 and  |
+ |   maximum of 32767, and for negative values on the interval with minimum  |
+ |   of -32768 and maximum of -16384; in order to normalize the result, the  |
+ |   following operation must be done :                                      |
+ |                    norm_var1 = shl(var1,norm_s(var1)).                    |
+ |                                                                           |
+ |   Complexity weight : 15                                                  |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 norm_s (Word16 var1)
+{
+    Word16 var_out;
+
+    if (var1 == 0)
+    {
+        var_out = 0;
+    }
+    else
+    {
+        if (var1 == -1)
+        {
+            var_out = 15;
+        }
+        else
+        {
+            if (var1 < 0)
+            {
+                var1 = (Word16)~var1;
+            }
+            for (var_out = 0; var1 < 0x4000; var_out++)
+            {
+                var1 <<= 1;
+            }
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].norm_s++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : div_s                                                   |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Produces a result which is the fractional integer division of var1  by  |
+ |   var2; var1 and var2 must be positive and var2 must be greater or equal  |
+ |   to var1; the result is positive (leading bit equal to 0) and truncated  |
+ |   to 16 bits.                                                             |
+ |   If var1 = var2 then div(var1,var2) = 32767.                             |
+ |                                                                           |
+ |   Complexity weight : 18                                                  |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    var1                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
+ |                                                                           |
+ |    var2                                                                   |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
+ |             It's a Q15 value (point between b15 and b14).                 |
+ |___________________________________________________________________________|
+*/
+
+Word16 div_s (Word16 var1, Word16 var2)
+{
+    Word16 var_out = 0;
+    Word16 iteration;
+    Word32 L_num;
+    Word32 L_denom;
+
+    if ((var1 > var2) || (var1 < 0) || (var2 < 0))
+    {
+        printf ("Division Error var1=%d  var2=%d\n", var1, var2);
+        abort(); /* exit (0); */
+    }
+    if (var2 == 0)
+    {
+        printf ("Division by 0, Fatal error \n");
+        abort(); /* exit (0); */
+    }
+    if (var1 == 0)
+    {
+        var_out = 0;
+    }
+    else
+    {
+        if (var1 == var2)
+        {
+            var_out = MAX_16;
+        }
+        else
+        {
+            L_num = L_deposit_l (var1);
+#if (WMOPS)
+            multiCounter[currCounter].L_deposit_l--;
+#endif
+            L_denom = L_deposit_l (var2);
+#if (WMOPS)
+            multiCounter[currCounter].L_deposit_l--;
+#endif
+
+            for (iteration = 0; iteration < 15; iteration++)
+            {
+                var_out <<= 1;
+                L_num <<= 1;
+
+                if (L_num >= L_denom)
+                {
+                    L_num = L_sub (L_num, L_denom);
+#if (WMOPS)
+                    multiCounter[currCounter].L_sub--;
+#endif
+                    var_out = add (var_out, 1);
+#if (WMOPS)
+                    multiCounter[currCounter].add--;
+#endif
+                }
+            }
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].div_s++;
+#endif
+    return (var_out);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : norm_l                                                  |
+ |                                                                           |
+ |   Purpose :                                                               |
+ |                                                                           |
+ |   Produces the number of left shifts needed to normalize the 32 bit varia-|
+ |   ble L_var1 for positive values on the interval with minimum of          |
+ |   1073741824 and maximum of 2147483647, and for negative values on the in-|
+ |   terval with minimum of -2147483648 and maximum of -1073741824; in order |
+ |   to normalize the result, the following operation must be done :         |
+ |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
+ |                                                                           |
+ |   Complexity weight : 30                                                  |
+ |                                                                           |
+ |   Inputs :                                                                |
+ |                                                                           |
+ |    L_var1                                                                 |
+ |             32 bit long signed integer (Word32) whose value falls in the  |
+ |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
+ |                                                                           |
+ |   Outputs :                                                               |
+ |                                                                           |
+ |    none                                                                   |
+ |                                                                           |
+ |   Return Value :                                                          |
+ |                                                                           |
+ |    var_out                                                                |
+ |             16 bit short signed integer (Word16) whose value falls in the |
+ |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
+ |___________________________________________________________________________|
+*/
+
+Word16 norm_l (Word32 L_var1)
+{
+    Word16 var_out;
+
+    if (L_var1 == 0)
+    {
+        var_out = 0;
+    }
+    else
+    {
+        if (L_var1 == (Word32) 0xffffffffL)
+        {
+            var_out = 31;
+        }
+        else
+        {
+            if (L_var1 < 0)
+            {
+                L_var1 = ~L_var1;
+            }
+            for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
+            {
+                L_var1 <<= 1;
+            }
+        }
+    }
+
+#if (WMOPS)
+    multiCounter[currCounter].norm_l++;
+#endif
+    return (var_out);
+}
--- /dev/null
+++ b/amr-wb/bits.c
@@ -1,0 +1,532 @@
+/*------------------------------------------------------------------------*
+ *                         BITS.C                                         *
+ *------------------------------------------------------------------------*
+ * Performs bit stream manipulation                                       *
+ *------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "bits.h"
+#include "acelp.h"
+#include "count.h"
+#include "dtx.h"
+
+#include "mime_io.tab"
+
+/*-----------------------------------------------------*
+ * Write_serial -> write serial stream into a file     *
+ *-----------------------------------------------------*/
+
+Word16 Init_write_serial(TX_State ** st)
+{
+   TX_State *s;
+
+   /* allocate memory */
+    test();
+    if ((s = (TX_State *) malloc(sizeof(TX_State))) == NULL)
+    {
+        fprintf(stderr, "write_serial_init: can not malloc state structure\n");
+        return -1;
+    }
+    Reset_write_serial(s);
+    *st = s;
+
+    return 0;
+}
+
+Word16 Close_write_serial(TX_State *st)
+{
+   /* allocate memory */
+    test();
+    if (st != NULL)
+    {
+        free(st);
+        st = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+void Reset_write_serial(TX_State * st)
+{
+    st->sid_update_counter = 3;
+    st->sid_handover_debt = 0;
+    st->prev_ft = TX_SPEECH;
+}
+
+void Write_serial(FILE * fp, Word16 prms[], Word16 coding_mode, Word16 mode, TX_State *st, Word16 bitstreamformat)
+{
+   Word16 i, frame_type;
+   Word16 stream[SIZE_MAX];
+   UWord8 temp;
+   UWord8 *stream_ptr;
+
+   if (coding_mode == MRDTX)
+   {       
+       st->sid_update_counter--;
+       
+       if (st->prev_ft == TX_SPEECH)
+       {
+           frame_type = TX_SID_FIRST;
+           st->sid_update_counter = 3;
+       } else
+       {
+           if ((st->sid_handover_debt > 0) &&
+               (st->sid_update_counter > 2))
+           {
+               /* ensure extra updates are  properly delayed after a possible SID_FIRST */
+               frame_type = TX_SID_UPDATE;
+               st->sid_handover_debt--;
+           } else
+           {
+               if (st->sid_update_counter == 0)
+               {
+                   frame_type = TX_SID_UPDATE;
+                   st->sid_update_counter = 8;
+               } else
+               {
+                   frame_type = TX_NO_DATA;
+               }
+           }
+       }
+   } else
+   {
+       st->sid_update_counter = 8;
+       frame_type = TX_SPEECH;
+   }
+   st->prev_ft = frame_type;
+   
+      
+   if(bitstreamformat == 0)             /* default file format */
+   {
+       stream[0] = TX_FRAME_TYPE;
+       stream[1] = frame_type;
+       stream[2] = mode;
+       for (i = 0; i < nb_of_bits[coding_mode]; i++)
+       {
+           stream[3 + i] = prms[i];
+       }
+       
+       fwrite(stream, sizeof(Word16), 3 + nb_of_bits[coding_mode], fp);
+
+   } else
+   {
+       if (bitstreamformat == 1)        /* ITU file format */
+       {
+           stream[0] = 0x6b21;                          
+          
+           if(frame_type != TX_NO_DATA && frame_type != TX_SID_FIRST)
+           {
+               stream[1]=nb_of_bits[coding_mode];               
+               for (i = 0; i < nb_of_bits[coding_mode]; i++)
+               {
+                   if(prms[i] == BIT_0){
+                       stream[2 + i] = BIT_0_ITU;           
+                   }
+                   else{
+                       stream[2 + i] = BIT_1_ITU;
+                   }
+               }
+               fwrite(stream, sizeof(Word16), 2 + nb_of_bits[coding_mode], fp);    
+           } else
+           {
+               stream[1] = 0;
+               fwrite(stream, sizeof(Word16), 2, fp);      
+           }
+       } else                           /* MIME/storage file format */
+       {
+#define MRSID 9
+           /* change mode index in case of SID frame */
+           if (coding_mode == MRDTX)
+           {
+               coding_mode = MRSID;
+
+               if (frame_type == TX_SID_FIRST)
+               {
+                   for (i = 0; i < NBBITS_SID; i++) prms[i] = BIT_0;
+               }
+           }
+
+           /* we cannot handle unspecified frame types (modes 10 - 13) */
+           /* -> force NO_DATA frame */
+           if (coding_mode < 0 || coding_mode > 15 || (coding_mode > MRSID && coding_mode < 14))
+           {
+               coding_mode = 15;
+           }
+
+           /* mark empty frames between SID updates as NO_DATA frames */
+           if (coding_mode == MRSID && frame_type == TX_NO_DATA)
+           {
+               coding_mode = 15;
+           }
+
+           /* set pointer for packed frame, note that we handle data as bytes */
+           stream_ptr = (UWord8*)stream;
+
+           /* insert table of contents (ToC) byte at the beginning of the packet */
+           *stream_ptr = toc_byte[coding_mode];
+           stream_ptr++;
+
+           temp = 0;
+
+           /* sort and pack AMR-WB speech or SID bits */
+           for (i = 1; i < unpacked_size[coding_mode] + 1; i++)
+           {
+               if (prms[sort_ptr[coding_mode][i-1]] == BIT_1)
+               {
+                   temp++;
+               }
+
+               if (i % 8)
+               {
+                   temp <<= 1;
+               }
+               else
+               {
+                   *stream_ptr = temp;
+                   stream_ptr++;
+                   temp = 0;
+               }
+           }
+           
+           /* insert SID type indication and speech mode in case of SID frame */
+           if (coding_mode == MRSID)
+           {
+               if (frame_type == TX_SID_UPDATE)
+               {
+                   temp++;
+               }
+               temp <<= 4;
+               
+               temp += mode & 0x000F;
+           }
+
+           /* insert unused bits (zeros) at the tail of the last byte */
+           if (unused_size[coding_mode])
+           {
+               temp <<= (unused_size[coding_mode] - 1);
+           }
+           *stream_ptr = temp;
+
+           /* write packed frame into file (1 byte added to cover ToC entry) */
+           fwrite(stream, sizeof(UWord8), 1 + packed_size[coding_mode], fp);
+       }
+   }
+   return;
+}
+
+
+/*-----------------------------------------------------*
+ * Read_serial -> read serial stream into a file       *
+ *-----------------------------------------------------*/
+
+Word16 Init_read_serial(RX_State ** st)
+{
+   RX_State *s;
+
+   /* allocate memory */
+    test();
+    if ((s = (RX_State *) malloc(sizeof(RX_State))) == NULL)
+    {
+        fprintf(stderr, "read_serial_init: can not malloc state structure\n");
+        return -1;
+    }
+    Reset_read_serial(s);
+    *st = s;
+
+    return 0;
+}
+
+Word16 Close_read_serial(RX_State *st)
+{
+   /* allocate memory */
+    test();
+    if (st != NULL)
+    {
+        free(st);
+        st = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+void Reset_read_serial(RX_State * st)
+{
+    st->prev_ft = RX_SPEECH_GOOD;
+    st->prev_mode = 0;
+}
+
+
+Word16 Read_serial(FILE * fp, Word16 prms[], Word16 * frame_type, Word16 * mode, RX_State *st, Word16 bitstreamformat)
+{
+   Word16 n, n1, type_of_frame_type, coding_mode, datalen, i;
+   UWord8 toc, q, temp, *packet_ptr, packet[64];
+
+   if(bitstreamformat == 0)             /* default file format */
+   {
+       n = (Word16) fread(&type_of_frame_type, sizeof(Word16), 1, fp);
+       n = (Word16) (n + fread(frame_type, sizeof(Word16), 1, fp));
+       n = (Word16) (n + fread(mode, sizeof(Word16), 1, fp));
+       coding_mode = *mode;
+       if(*mode < 0 || *mode > NUM_OF_MODES-1)
+       {
+           fprintf(stderr, "Invalid mode received: %d (check file format).\n", *mode);
+           exit(-1);
+       }
+       if (n == 3)
+       {
+           if (type_of_frame_type == TX_FRAME_TYPE)
+           {
+               switch (*frame_type)
+               {
+               case TX_SPEECH:
+                   *frame_type = RX_SPEECH_GOOD;
+                   break;
+               case TX_SID_FIRST:
+                   *frame_type = RX_SID_FIRST;
+                   break;
+               case TX_SID_UPDATE:
+                   *frame_type = RX_SID_UPDATE;
+                   break;
+               case TX_NO_DATA:
+                   *frame_type = RX_NO_DATA;
+                   break;
+               }
+           } else if (type_of_frame_type != RX_FRAME_TYPE)
+           {
+               fprintf(stderr, "Wrong type of frame type:%d.\n", type_of_frame_type);
+           }
+           
+           if ((*frame_type == RX_SID_FIRST) | (*frame_type == RX_SID_UPDATE) | (*frame_type == RX_NO_DATA) | (*frame_type == RX_SID_BAD))
+           {
+               coding_mode = MRDTX;
+           }
+           n = (Word16) fread(prms, sizeof(Word16), nb_of_bits[coding_mode], fp);
+           if (n != nb_of_bits[coding_mode])
+               n = 0;
+       }
+       return (n);
+   } else
+   {
+       if (bitstreamformat == 1)        /* ITU file format */
+       {
+            n = (Word16) fread(&type_of_frame_type, sizeof(Word16), 1, fp);
+            n = (Word16)(n+fread(&datalen, sizeof(Word16), 1, fp));
+
+            if(n == 2)
+            {
+              if(type_of_frame_type == 0x6b20)        /* bad frame */
+              {
+                  *frame_type = RX_SPEECH_LOST;
+                  *mode = st->prev_mode;
+              }
+              else if(type_of_frame_type == 0x6b21)   /* good frame */
+              {
+                  if(datalen == 0)                      /* RX_NO_DATA frame type */
+                  {
+                      if(st->prev_ft == RX_SPEECH_GOOD)
+                      {
+                          *frame_type = RX_SID_FIRST;
+                      }
+                      else 
+                      {
+                          *frame_type = RX_NO_DATA;
+                      }
+                      *mode = st->prev_mode;
+                  }
+                  else
+                  {
+                      coding_mode = -1;
+                      for(i=NUM_OF_MODES-1; i>=0; i--)
+                      {
+                          if(datalen == nb_of_bits[i])
+                          {
+                              coding_mode = i;
+                          }
+                      }
+
+                      if(coding_mode == -1)
+                      {
+                          fprintf(stderr, "\n\n ERROR: Invalid number of data bits received [%d]\n\n", datalen);
+                          exit(-1);
+                      }
+
+                      if(coding_mode == NUM_OF_MODES-1)     /* DTX frame type */
+                      {
+                          *frame_type = RX_SID_UPDATE;
+                          *mode = st->prev_mode;
+                      }
+                      else
+                      {
+                          *frame_type = RX_SPEECH_GOOD;
+                          *mode = coding_mode;
+                      }
+                  }
+                  st->prev_mode = *mode;
+                  st->prev_ft = *frame_type;
+              }
+              else {
+                  fprintf(stderr, "\n\n ERROR: Invalid ITU file format \n\n");
+                  exit(-1);
+              }
+      }
+            n1 = fread(prms, sizeof(Word16), datalen, fp);
+            n += n1;
+            for(i=0; i<n1; i++)
+            {
+                if(prms[i] <= BIT_0_ITU) prms[i] = BIT_0;
+                else                        prms[i] = BIT_1;
+            }          
+            return(n);
+
+       } else                           /* MIME/storage file format */
+       {
+           /* read ToC byte, return immediately if no more data available */
+           if (fread(&toc, sizeof(UWord8), 1, fp) == 0)
+           {
+               return 0;
+           }
+
+           /* extract q and mode from ToC */
+           q  = (toc >> 2) & 0x01;
+           *mode = (toc >> 3) & 0x0F;
+
+           /* read speech bits, return with empty frame if mismatch between mode info and available data */
+           if ((Word16)fread(packet, sizeof(UWord8), packed_size[*mode], fp) != packed_size[*mode])
+           {
+               return 0;
+           }
+
+           packet_ptr = (UWord8*)packet;
+           temp = *packet_ptr;
+           packet_ptr++;
+           
+           /* unpack and unsort speech or SID bits */
+           for (i = 1; i < unpacked_size[*mode] + 1; i++)
+           {
+               if (temp & 0x80) prms[sort_ptr[*mode][i-1]] = BIT_1;
+               else             prms[sort_ptr[*mode][i-1]] = BIT_0;
+               
+               if (i % 8)
+               {
+                   temp <<= 1;
+               }
+               else
+               {
+                   temp = *packet_ptr;
+                   packet_ptr++;
+               }
+           }
+
+           /* set frame type */
+           switch (*mode)
+           {
+           case MODE_7k:
+           case MODE_9k:
+           case MODE_12k:
+           case MODE_14k:
+           case MODE_16k:
+           case MODE_18k:
+           case MODE_20k:
+           case MODE_23k:
+           case MODE_24k:
+               if (q)   *frame_type = RX_SPEECH_GOOD;
+               else     *frame_type = RX_SPEECH_BAD;
+               break;
+           case MRSID:
+               if (q)
+               {
+                   if (temp & 0x80) *frame_type = RX_SID_UPDATE;
+                   else             *frame_type = RX_SID_FIRST;
+               }
+               else
+               {
+                   *frame_type = RX_SID_BAD;
+               }
+
+               /* read speech mode indication */
+               coding_mode = (temp >> 3) & 0x0F;
+
+               /* set mode index */
+               *mode = st->prev_mode;
+               break;
+           case 14:     /* SPEECH_LOST */
+               *frame_type = RX_SPEECH_LOST;
+               *mode = st->prev_mode;
+               break;
+           case 15:     /* NO_DATA */
+               *frame_type = RX_NO_DATA;
+               *mode = st->prev_mode;
+               break;
+           default:     /* replace frame with unused mode index by NO_DATA frame */
+               *frame_type = RX_NO_DATA;
+               *mode = st->prev_mode;
+               break;
+           }
+
+           st->prev_mode = *mode;
+
+           /* return 1 to indicate succesfully parsed frame */
+           return 1;
+       }
+#undef MRSID
+   }
+
+}
+
+
+/*-----------------------------------------------------*
+ * Parm_serial -> convert parameters to serial stream  *
+ *-----------------------------------------------------*/
+
+void Parm_serial(
+     Word16 value,                         /* input : parameter value */
+     Word16 no_of_bits,                    /* input : number of bits  */
+     Word16 ** prms
+)
+{
+    Word16 i, bit;
+
+    *prms += no_of_bits;                   move16();
+
+    for (i = 0; i < no_of_bits; i++)
+    {
+        bit = (Word16) (value & 0x0001);   logic16();  /* get lsb */
+        test();move16();
+        if (bit == 0)
+            *--(*prms) = BIT_0;
+        else
+            *--(*prms) = BIT_1;
+        value = shr(value, 1);             move16();
+    }
+    *prms += no_of_bits;                   move16();
+    return;
+}
+
+
+/*----------------------------------------------------*
+ * Serial_parm -> convert serial stream to parameters *
+ *----------------------------------------------------*/
+
+Word16 Serial_parm(                        /* Return the parameter    */
+     Word16 no_of_bits,                    /* input : number of bits  */
+     Word16 ** prms
+)
+{
+    Word16 value, i;
+    Word16 bit;
+
+    value = 0;                             move16();
+    for (i = 0; i < no_of_bits; i++)
+    {
+        value = shl(value, 1);
+        bit = *((*prms)++);                move16();
+        test();move16();
+        if (bit == BIT_1)
+            value = add(value, 1);
+    }
+    return (value);
+}
--- /dev/null
+++ b/amr-wb/bits.h
@@ -1,0 +1,77 @@
+/*--------------------------------------------------------------------------*
+ *                         BITS.H                                           *
+ *--------------------------------------------------------------------------*
+ *       Number of bits for different modes                                 *
+ *--------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include "typedef.h"
+#include "cnst.h"
+
+#define NBBITS_7k     132                  /* 6.60k  */
+#define NBBITS_9k     177                  /* 8.85k  */
+#define NBBITS_12k    253                  /* 12.65k */
+#define NBBITS_14k    285                  /* 14.25k */
+#define NBBITS_16k    317                  /* 15.85k */
+#define NBBITS_18k    365                  /* 18.25k */
+#define NBBITS_20k    397                  /* 19.85k */
+#define NBBITS_23k    461                  /* 23.05k */
+#define NBBITS_24k    477                  /* 23.85k */
+
+#define NBBITS_SID    35
+#define NB_BITS_MAX   NBBITS_24k
+
+#define BIT_0     (Word16)-127
+#define BIT_1     (Word16)127
+#define BIT_0_ITU (Word16)0x007F
+#define BIT_1_ITU (Word16)0x0081
+
+#define SIZE_MAX  (3+NB_BITS_MAX)          /* serial size max */
+#define TX_FRAME_TYPE (Word16)0x6b21
+#define RX_FRAME_TYPE (Word16)0x6b20
+
+static const Word16 nb_of_bits[NUM_OF_MODES] = {
+    NBBITS_7k,
+    NBBITS_9k,
+    NBBITS_12k,
+    NBBITS_14k,
+    NBBITS_16k,
+    NBBITS_18k,
+    NBBITS_20k,
+    NBBITS_23k,
+    NBBITS_24k,
+NBBITS_SID};
+
+typedef struct
+{
+    Word16 sid_update_counter;
+    Word16 sid_handover_debt;
+    Word16 prev_ft;
+} TX_State;
+
+
+typedef struct
+{
+    Word16 prev_ft;
+    Word16 prev_mode;
+} RX_State;
+
+
+Word16 Init_write_serial(TX_State ** st);
+Word16 Close_write_serial(TX_State *st);
+void Reset_write_serial(TX_State * st);
+Word16 Init_read_serial(RX_State ** st);
+Word16 Close_read_serial(RX_State *st);
+void Reset_read_serial(RX_State * st);
+void Write_serial(FILE * fp, Word16 prms[], Word16 coding_mode, Word16 mode, TX_State *st, Word16 bitstreamformat);
+Word16 Read_serial(FILE * fp, Word16 prms[], Word16 * frame_type, Word16 * mode, RX_State *st, Word16 bitstreamformat);
+
+void Parm_serial(
+     Word16 value,                         /* input : parameter value */
+     Word16 no_of_bits,                    /* input : number of bits  */
+     Word16 ** prms
+);
+Word16 Serial_parm(                        /* Return the parameter    */
+     Word16 no_of_bits,                    /* input : number of bits  */
+     Word16 ** prms
+);
--- /dev/null
+++ b/amr-wb/c2t64fx.c
@@ -1,0 +1,310 @@
+/*------------------------------------------------------------------------*
+ *                         C2T64FX.C                                      *
+ *------------------------------------------------------------------------*
+ * Performs algebraic codebook search for 6.60 kbit/s mode                *
+ *------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*
+ * Function  ACELP_2t64_fx()                                             *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~                                             *
+ * 12 bits algebraic codebook.                                           *
+ * 2 tracks x 32 positions per track = 64 samples.                       *
+ *                                                                       *
+ * 12 bits --> 2 pulses in a frame of 64 samples.                        *
+ *                                                                       *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.            *
+ * Each pulse can have 32 possible positions.                            *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "count.h"
+#include "cnst.h"
+
+#define NB_TRACK  2
+#define STEP      2
+#define NB_POS    32
+#define MSIZE     1024
+
+
+void ACELP_2t64_fx(
+     Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
+     Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
+     Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
+     Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
+     Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
+     Word16 * index                        /* (o) : index (12): 5+1+5+1 = 11 bits.                   */
+)
+{
+    Word16 i, j, k, i0, i1, ix, iy, pos, pos2;
+    Word16 ps, psk, ps1, ps2, alpk, alp1, alp2, sq;
+    Word16 alp, val, exp, k_cn, k_dn;
+    Word16 *p0, *p1, *p2, *psign;
+    Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf;
+
+    Word16 sign[L_SUBFR], vec[L_SUBFR], dn2[L_SUBFR];
+    Word16 h_buf[4 * L_SUBFR];
+    Word16 rrixix[NB_TRACK][NB_POS];
+    Word16 rrixiy[MSIZE];
+
+    Word32 s, cor;
+
+    /*----------------------------------------------------------------*
+     * Find sign for each pulse position.                             *
+     *----------------------------------------------------------------*/
+
+    alp = 8192;                            move16();  /* alp = 2.0 (Q12) */
+
+    /* calculate energy for normalization of cn[] and dn[] */
+
+    /* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
+    s = Dot_product12(cn, cn, L_SUBFR, &exp);
+    Isqrt_n(&s, &exp);
+    s = L_shl(s, add(exp, 5));             /* saturation can occur here */
+    k_cn = round(s);
+
+    /* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
+    s = Dot_product12(dn, dn, L_SUBFR, &exp);
+    Isqrt_n(&s, &exp);
+    k_dn = round(L_shl(s, add(exp, 5 + 3)));    /* k_dn = 256..4096 */
+    k_dn = mult_r(alp, k_dn);              /* alp in Q12 */
+
+    /* mix normalized cn[] and dn[] */
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        s = L_mac(L_mult(k_cn, cn[i]), k_dn, dn[i]);
+        dn2[i] = extract_h(L_shl(s, 8));   move16();
+    }
+
+    /* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[]    */
+
+    for (k = 0; k < NB_TRACK; k++)
+    {
+        for (i = k; i < L_SUBFR; i += STEP)
+        {
+            val = dn[i];                   move16();
+            ps = dn2[i];                   move16();
+
+            test();
+            if (ps >= 0)
+            {
+                sign[i] = 32767;           move16();  /* sign = +1 (Q12) */
+                vec[i] = -32768;           move16();
+            } else
+            {
+                sign[i] = -32768;          move16();  /* sign = -1 (Q12) */
+                vec[i] = 32767;            move16();
+                val = negate(val);
+            }
+            dn[i] = val;                   move16();  /* modify dn[] according to the fixed sign */
+        }
+    }
+
+    /*------------------------------------------------------------*
+     * Compute h_inv[i].                                          *
+     *------------------------------------------------------------*/
+
+    /* impulse response buffer for fast computation */
+
+    h = h_buf;                             move16();
+    h_inv = h_buf + (2 * L_SUBFR);         move16();
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        *h++ = 0;                          move16();
+        *h_inv++ = 0;                      move16();
+    }
+
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        h[i] = H[i];                       move16();
+        h_inv[i] = negate(h[i]);           move16();
+    }
+
+    /*------------------------------------------------------------*
+     * Compute rrixix[][] needed for the codebook search.         *
+     * Result is multiplied by 0.5                                *
+     *------------------------------------------------------------*/
+
+    /* Init pointers to last position of rrixix[] */
+    p0 = &rrixix[0][NB_POS - 1];           move16();
+    p1 = &rrixix[1][NB_POS - 1];           move16();
+
+    ptr_h1 = h;                            move16();
+    cor = 0x00010000L;                     move32();  /* for rounding */
+    for (i = 0; i < NB_POS; i++)
+    {
+        move16();move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p1-- = extract_h(cor);            move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p0-- = extract_h(cor);            move16();
+    }
+
+    p0 = rrixix[0];                        move16();
+    p1 = rrixix[1];                        move16();
+    for (i = 0; i < NB_POS; i++)
+    {
+        *p0 = shr(*p0, 1);                 move16();
+        p0++;
+        *p1 = shr(*p1, 1);                 move16();
+        p1++;
+    }
+
+    /*------------------------------------------------------------*
+     * Compute rrixiy[][] needed for the codebook search.         *
+     *------------------------------------------------------------*/
+
+    pos = MSIZE - 1;                       move16();
+    pos2 = MSIZE - 2;                      move16();
+    ptr_hf = h + 1;                        move16();
+
+    for (k = 0; k < NB_POS; k++)
+    {
+        p1 = &rrixiy[pos];                 move16();
+        p0 = &rrixiy[pos2];                move16();
+
+        cor = 0x00008000L;                 move32();  /* for rounding */
+        ptr_h1 = h;                        move16();
+        ptr_h2 = ptr_hf;                   move16();
+
+        for (i = (Word16) (k + 1); i < NB_POS; i++)
+        {
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p1 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p0 = extract_h(cor);          move16();
+
+            p1 -= (NB_POS + 1);
+            p0 -= (NB_POS + 1);
+        }
+        cor = L_mac(cor, *ptr_h1, *ptr_h2);
+        ptr_h1++;
+        ptr_h2++;
+        *p1 = extract_h(cor);              move16();
+
+        pos -= NB_POS;
+        pos2--;
+        ptr_hf += STEP;
+    }
+
+    /*------------------------------------------------------------*
+     * Modification of rrixiy[][] to take signs into account.     *
+     *------------------------------------------------------------*/
+
+    p0 = rrixiy;                           move16();
+
+    for (i = 0; i < L_SUBFR; i += STEP)
+    {
+        psign = sign;                      move16();
+        test();
+        if (psign[i] < 0)
+        {
+            psign = vec;                   move16();
+        }
+        for (j = 1; j < L_SUBFR; j += STEP)
+        {
+            *p0 = mult(*p0, psign[j]);     move16();
+            p0++;
+        }
+    }
+
+    /*-------------------------------------------------------------------*
+     * search 2 pulses:                                                  *
+     * ~@~~~~~~~~~~~~~~                                                  *
+     * 32 pos x 32 pos = 1024 tests (all combinaisons is tested)         *
+     *-------------------------------------------------------------------*/
+
+    p0 = rrixix[0];                        move16();
+    p1 = rrixix[1];                        move16();
+    p2 = rrixiy;                           move16();
+
+    psk = -1;                              move16();
+    alpk = 1;                              move16();
+    ix = 0;                                move16();
+    iy = 1;                                move16();
+
+    for (i0 = 0; i0 < L_SUBFR; i0 += STEP)
+    {
+        ps1 = dn[i0];                      move16();
+        alp1 = (*p0++);                    move16();
+
+        pos = -1;                          move16();
+        for (i1 = 1; i1 < L_SUBFR; i1 += STEP)
+        {
+            ps2 = add(ps1, dn[i1]);
+            alp2 = add(alp1, add(*p1++, *p2++));
+
+            sq = mult(ps2, ps2);
+
+            s = L_msu(L_mult(alpk, sq), psk, alp2);
+
+            test();
+            if (s > 0)
+            {
+                psk = sq;                  move16();
+                alpk = alp2;               move16();
+                pos = i1;                  move16();
+            }
+        }
+        p1 -= NB_POS;
+
+        test();
+        if (pos >= 0)
+        {
+            ix = i0;                       move16();
+            iy = pos;                      move16();
+        }
+    }
+
+    /*-------------------------------------------------------------------*
+     * Build the codeword, the filtered codeword and index of codevector.*
+     *-------------------------------------------------------------------*/
+
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        code[i] = 0;                       move16();
+    }
+
+    i0 = shr(ix, 1);                       /* pos of pulse 1 (0..31) */
+    i1 = shr(iy, 1);                       /* pos of pulse 2 (0..31) */
+    test();
+    if (sign[ix] > 0)
+    {
+        code[ix] = 512;                    move16();  /* codeword in Q9 format */
+        p0 = h - ix;                       move16();
+    } else
+    {
+        code[ix] = -512;                   move16();
+        i0 += NB_POS;                      move16();
+        p0 = h_inv - ix;                   move16();
+    }
+    test();
+    if (sign[iy] > 0)
+    {
+        code[iy] = 512;                    move16();
+        p1 = h - iy;                       move16();
+    } else
+    {
+        code[iy] = -512;                   move16();
+        i1 += NB_POS;                      move16();
+        p1 = h_inv - iy;                   move16();
+    }
+
+    *index = add(shl(i0, 6), i1);          move16();
+
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        y[i] = shr_r(add(*p0++, *p1++), 3);move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/c4t64fx.c
@@ -1,0 +1,911 @@
+/*------------------------------------------------------------------------*
+ *                         C4T64FX.C                                      *
+ *------------------------------------------------------------------------*
+ * Performs algebraic codebook search for higher modes                    *
+ *------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*
+ * Function  ACELP_4t64_fx()                                             *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~                                             *
+ * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.                   *
+ * 4 tracks x 16 positions per track = 64 samples.                       *
+ *                                                                       *
+ * 20 bits --> 4 pulses in a frame of 64 samples.                        *
+ * 36 bits --> 8 pulses in a frame of 64 samples.                        *
+ * 44 bits --> 10 pulses in a frame of 64 samples.                       *
+ * 52 bits --> 12 pulses in a frame of 64 samples.                       *
+ * 64 bits --> 16 pulses in a frame of 64 samples.                       *
+ * 72 bits --> 18 pulses in a frame of 64 samples.                       *
+ * 88 bits --> 24 pulses in a frame of 64 samples.                       *
+ *                                                                       *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.            *
+ * Each pulse can have sixteen (16) possible positions.                  *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "count.h"
+#include "cnst.h"
+
+#include "q_pulse.h"
+
+static Word16 tipos[36] = {
+    0, 1, 2, 3,                            /* starting point &ipos[0], 1st iter */
+    1, 2, 3, 0,                            /* starting point &ipos[4], 2nd iter */
+    2, 3, 0, 1,                            /* starting point &ipos[8], 3rd iter */
+    3, 0, 1, 2,                            /* starting point &ipos[12], 4th iter */
+    0, 1, 2, 3,
+    1, 2, 3, 0,
+    2, 3, 0, 1,
+    3, 0, 1, 2,
+    0, 1, 2, 3};                           /* end point for 24 pulses &ipos[35], 4th iter */
+
+#define NB_PULSE_MAX  24
+
+#define L_SUBFR   64
+#define NB_TRACK  4
+#define STEP      4
+#define NB_POS    16
+#define MSIZE     256
+#define NB_MAX    8
+#define NPMAXPT   ((NB_PULSE_MAX+NB_TRACK-1)/NB_TRACK)
+
+
+/* locals functions */
+
+static void cor_h_vec(
+     Word16 h[],                           /* (i) scaled impulse response                 */
+     Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
+     Word16 track,                         /* (i) track to use                            */
+     Word16 sign[],                        /* (i) sign vector                             */
+     Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
+     Word16 cor[]                          /* (o) result of correlation (NB_POS elements) */
+);
+static void search_ixiy(
+     Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
+     Word16 track_x,                       /* (i) track of pulse 1                   */
+     Word16 track_y,                       /* (i) track of pulse 2                   */
+     Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
+     Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
+     Word16 * ix,                          /* (o) position of pulse 1                */
+     Word16 * iy,                          /* (o) position of pulse 2                */
+     Word16 dn[],                          /* (i) corr. between target and h[]       */
+     Word16 dn2[],                         /* (i) vector of selected positions       */
+     Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
+     Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
+     Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
+);
+
+
+void ACELP_4t64_fx(
+     Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
+     Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
+     Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
+     Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
+     Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
+     Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
+     Word16 ser_size,                      /* (i) : bit rate                                         */
+     Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
+                                           /* (o) : index (36): 9+9+9+9 = 36 bits.                   */
+                                           /* (o) : index (44): 13+9+13+9 = 44 bits.                 */
+                                           /* (o) : index (52): 13+13+13+13 = 52 bits.               */
+                                           /* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
+                                           /* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
+                                           /* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
+)
+{
+    Word16 i, j, k, st, ix, iy, pos, index, track, nb_pulse, nbiter;
+    Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
+    Word16 *p0, *p1, *p2, *p3, *psign;
+    Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
+    Word32 s, cor, L_tmp, L_index;
+
+    Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
+    Word16 ind[NPMAXPT * NB_TRACK];
+    Word16 codvec[NB_PULSE_MAX], nbpos[10];
+    Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
+    Word16 h_buf[4 * L_SUBFR];
+    Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
+    Word16 ipos[NB_PULSE_MAX];
+
+    switch (nbbits)
+    {
+    case 20:                               /* 20 bits, 4 pulses, 4 tracks */
+        nbiter = 4;                        move16();  /* 4x16x16=1024 loop */
+        alp = 8192;                        move16();  /* alp = 2.0 (Q12) */
+        nb_pulse = 4;                      move16();
+        nbpos[0] = 4;                      move16();
+        nbpos[1] = 8;                      move16();
+        break;
+    case 36:                               /* 36 bits, 8 pulses, 4 tracks */
+        nbiter = 4;                        move16();  /* 4x20x16=1280 loop */
+        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
+        nb_pulse = 8;                      move16();
+        nbpos[0] = 4;                      move16();
+        nbpos[1] = 8;                      move16();
+        nbpos[2] = 8;                      move16();
+        break;
+    case 44:                               /* 44 bits, 10 pulses, 4 tracks */
+        nbiter = 4;                        move16();  /* 4x26x16=1664 loop */
+        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
+        nb_pulse = 10;                     move16();
+        nbpos[0] = 4;                      move16();
+        nbpos[1] = 6;                      move16();
+        nbpos[2] = 8;                      move16();
+        nbpos[3] = 8;                      move16();
+        break;
+    case 52:                               /* 52 bits, 12 pulses, 4 tracks */
+        nbiter = 4;                        move16();  /* 4x26x16=1664 loop */
+        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
+        nb_pulse = 12;                     move16();
+        nbpos[0] = 4;                      move16();
+        nbpos[1] = 6;                      move16();
+        nbpos[2] = 8;                      move16();
+        nbpos[3] = 8;                      move16();
+        break;
+    case 64:                               /* 64 bits, 16 pulses, 4 tracks */
+        nbiter = 3;                        move16();  /* 3x36x16=1728 loop */
+        alp = 3277;                        move16();  /* alp = 0.8 (Q12) */
+        nb_pulse = 16;                     move16();
+        nbpos[0] = 4;                      move16();
+        nbpos[1] = 4;                      move16();
+        nbpos[2] = 6;                      move16();
+        nbpos[3] = 6;                      move16();
+        nbpos[4] = 8;                      move16();
+        nbpos[5] = 8;                      move16();
+        break;
+    case 72:                               /* 72 bits, 18 pulses, 4 tracks */
+        nbiter = 3;                        move16();  /* 3x35x16=1680 loop */
+        alp = 3072;                        move16();  /* alp = 0.75 (Q12) */
+        nb_pulse = 18;                     move16();
+        nbpos[0] = 2;                      move16();
+        nbpos[1] = 3;                      move16();
+        nbpos[2] = 4;                      move16();
+        nbpos[3] = 5;                      move16();
+        nbpos[4] = 6;                      move16();
+        nbpos[5] = 7;                      move16();
+        nbpos[6] = 8;                      move16();
+        break;
+    case 88:                               /* 88 bits, 24 pulses, 4 tracks */
+        test();move16();
+        if (sub(ser_size, 462) > 0)
+            nbiter = 1;
+        else
+            nbiter = 2;                    /* 2x53x16=1696 loop */
+
+        alp = 2048;                        move16();  /* alp = 0.5 (Q12) */
+        nb_pulse = 24;                     move16();
+        nbpos[0] = 2;                      move16();
+        nbpos[1] = 2;                      move16();
+        nbpos[2] = 3;                      move16();
+        nbpos[3] = 4;                      move16();
+        nbpos[4] = 5;                      move16();
+        nbpos[5] = 6;                      move16();
+        nbpos[6] = 7;                      move16();
+        nbpos[7] = 8;                      move16();
+        nbpos[8] = 8;                      move16();
+        nbpos[9] = 8;                      move16();
+        break;
+    default:
+        nbiter = 0;
+        alp = 0;
+        nb_pulse = 0;
+    }
+
+    for (i = 0; i < nb_pulse; i++)
+    {
+        codvec[i] = i;                     move16();
+    }
+
+    /*----------------------------------------------------------------*
+     * Find sign for each pulse position.                             *
+     *----------------------------------------------------------------*/
+
+    /* calculate energy for normalization of cn[] and dn[] */
+
+    /* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
+    s = Dot_product12(cn, cn, L_SUBFR, &exp);
+    Isqrt_n(&s, &exp);
+    s = L_shl(s, add(exp, 5));             /* saturation can occur here */
+    k_cn = round(s);
+
+    /* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
+    s = Dot_product12(dn, dn, L_SUBFR, &exp);
+    Isqrt_n(&s, &exp);
+    k_dn = round(L_shl(s, add(exp, 5 + 3)));    /* k_dn = 256..4096 */
+    k_dn = mult_r(alp, k_dn);              /* alp in Q12 */
+
+    /* mix normalized cn[] and dn[] */
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        s = L_mac(L_mult(k_cn, cn[i]), k_dn, dn[i]);
+        dn2[i] = extract_h(L_shl(s, 8));   move16();
+    }
+
+    /* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[]    */
+
+    for (k = 0; k < NB_TRACK; k++)
+    {
+        for (i = k; i < L_SUBFR; i += STEP)
+        {
+            val = dn[i];                   move16();
+            ps = dn2[i];                   move16();
+
+            test();
+            if (ps >= 0)
+            {
+                sign[i] = 32767;           move16();  /* sign = +1 (Q12) */
+                vec[i] = -32768;           move16();
+            } else
+            {
+                sign[i] = -32768;          move16();  /* sign = -1 (Q12) */
+                vec[i] = 32767;            move16();
+                val = negate(val);
+                ps = negate(ps);
+            }
+            dn[i] = val;                   move16();  /* modify dn[] according to the fixed sign */
+            dn2[i] = ps;                   move16();  /* dn2[] = mix of dn[] and cn[]            */
+        }
+    }
+
+    /*----------------------------------------------------------------*
+     * Select NB_MAX position per track according to max of dn2[].    *
+     *----------------------------------------------------------------*/
+
+    pos = 0;
+    for (i = 0; i < NB_TRACK; i++)
+    {
+        for (k = 0; k < NB_MAX; k++)
+        {
+            ps = -1;                       move16();
+            for (j = i; j < L_SUBFR; j += STEP)
+            {
+                test();
+                if (sub(dn2[j], ps) > 0)
+                {
+                    ps = dn2[j];           move16();
+                    pos = j;               move16();
+                }
+            }
+            move16();
+            dn2[pos] = sub(k, NB_MAX);     /* dn2 < 0 when position is selected */
+            test();
+            if (k == 0)
+            {
+                pos_max[i] = pos;          move16();
+            }
+        }
+    }
+
+    /*--------------------------------------------------------------*
+     * Scale h[] to avoid overflow and to get maximum of precision  *
+     * on correlation.                                              *
+     *                                                              *
+     * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16).         *
+     *  ==> This allow addition of 16 pulses without saturation.    *
+     *                                                              *
+     * Energy worst case (on resonant impulse response),            *
+     * - energy of h[] is approximately MAX/16.                     *
+     * - During search, the energy is divided by 8 to avoid         *
+     *   overflow on "alp". (energy of h[] = MAX/128).              *
+     *  ==> "alp" worst case detected is 22854 on sinusoidal wave.  *
+     *--------------------------------------------------------------*/
+
+    /* impulse response buffer for fast computation */
+
+    h = h_buf;                             move16();
+    h_inv = h_buf + (2 * L_SUBFR);         move16();
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        *h++ = 0;                          move16();
+        *h_inv++ = 0;                      move16();
+    }
+
+    /* scale h[] down (/2) when energy of h[] is high with many pulses used */
+    L_tmp = 0;
+    for (i = 0; i < L_SUBFR; i++)
+        L_tmp = L_mac(L_tmp, H[i], H[i]);
+    val = extract_h(L_tmp);
+
+    h_shift = 0;                           move16();
+
+    test();test();
+    if ((sub(nb_pulse, 12) >= 0) && (sub(val, 1024) > 0))
+    {
+        h_shift = 1;                       move16();
+    }
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        h[i] = shr(H[i], h_shift);         move16();
+        h_inv[i] = negate(h[i]);           move16();
+    }
+
+    /*------------------------------------------------------------*
+     * Compute rrixix[][] needed for the codebook search.         *
+     * This algorithm compute impulse response energy of all      *
+     * positions (16) in each track (4).       Total = 4x16 = 64. *
+     *------------------------------------------------------------*/
+
+    /* storage order --> i3i3, i2i2, i1i1, i0i0 */
+
+    /* Init pointers to last position of rrixix[] */
+    p0 = &rrixix[0][NB_POS - 1];           move16();
+    p1 = &rrixix[1][NB_POS - 1];           move16();
+    p2 = &rrixix[2][NB_POS - 1];           move16();
+    p3 = &rrixix[3][NB_POS - 1];           move16();
+
+    ptr_h1 = h;                            move16();
+    cor = 0x00008000L;                     move32();  /* for rounding */
+    for (i = 0; i < NB_POS; i++)
+    {
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p3-- = extract_h(cor);            move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p2-- = extract_h(cor);            move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p1-- = extract_h(cor);            move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h1);
+        ptr_h1++;
+        *p0-- = extract_h(cor);            move16();
+    }
+
+    /*------------------------------------------------------------*
+     * Compute rrixiy[][] needed for the codebook search.         *
+     * This algorithm compute correlation between 2 pulses        *
+     * (2 impulses responses) in 4 possible adjacents tracks.     *
+     * (track 0-1, 1-2, 2-3 and 3-0).     Total = 4x16x16 = 1024. *
+     *------------------------------------------------------------*/
+
+    /* storage order --> i2i3, i1i2, i0i1, i3i0 */
+
+    pos = MSIZE - 1;                       move16();
+    ptr_hf = h + 1;                        move16();
+
+    for (k = 0; k < NB_POS; k++)
+    {
+        p3 = &rrixiy[2][pos];              move16();
+        p2 = &rrixiy[1][pos];              move16();
+        p1 = &rrixiy[0][pos];              move16();
+        p0 = &rrixiy[3][pos - NB_POS];     move16();
+
+        cor = 0x00008000L;                 move32();  /* for rounding */
+        ptr_h1 = h;                        move16();
+        ptr_h2 = ptr_hf;                   move16();
+
+        for (i = add(k, 1); i < NB_POS; i++)
+        {
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p3 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p2 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p1 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p0 = extract_h(cor);          move16();
+
+            p3 -= (NB_POS + 1);
+            p2 -= (NB_POS + 1);
+            p1 -= (NB_POS + 1);
+            p0 -= (NB_POS + 1);
+        }
+        cor = L_mac(cor, *ptr_h1, *ptr_h2);
+        ptr_h1++;
+        ptr_h2++;
+        *p3 = extract_h(cor);              move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h2);
+        ptr_h1++;
+        ptr_h2++;
+        *p2 = extract_h(cor);              move16();
+        cor = L_mac(cor, *ptr_h1, *ptr_h2);
+        ptr_h1++;
+        ptr_h2++;
+        *p1 = extract_h(cor);              move16();
+
+        pos -= NB_POS;
+        ptr_hf += STEP;
+    }
+
+    /* storage order --> i3i0, i2i3, i1i2, i0i1 */
+
+    pos = MSIZE - 1;                       move16();
+    ptr_hf = h + 3;                        move16();
+
+    for (k = 0; k < NB_POS; k++)
+    {
+        p3 = &rrixiy[3][pos];              move16();
+        p2 = &rrixiy[2][pos - 1];          move16();
+        p1 = &rrixiy[1][pos - 1];          move16();
+        p0 = &rrixiy[0][pos - 1];          move16();
+
+        cor = 0x00008000L;                 move32();  /* for rounding */
+        ptr_h1 = h;                        move16();
+        ptr_h2 = ptr_hf;                   move16();
+
+        for (i = add(k, 1); i < NB_POS; i++)
+        {
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p3 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p2 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p1 = extract_h(cor);          move16();
+            cor = L_mac(cor, *ptr_h1, *ptr_h2);
+            ptr_h1++;
+            ptr_h2++;
+            *p0 = extract_h(cor);          move16();
+
+            p3 -= (NB_POS + 1);
+            p2 -= (NB_POS + 1);
+            p1 -= (NB_POS + 1);
+            p0 -= (NB_POS + 1);
+        }
+        cor = L_mac(cor, *ptr_h1, *ptr_h2);
+        ptr_h1++;
+        ptr_h2++;
+        *p3 = extract_h(cor);              move16();
+
+        pos--;
+        ptr_hf += STEP;
+    }
+
+    /*------------------------------------------------------------*
+     * Modification of rrixiy[][] to take signs into account.     *
+     *------------------------------------------------------------*/
+
+    p0 = &rrixiy[0][0];                    move16();
+
+    for (k = 0; k < NB_TRACK; k++)
+    {
+        for (i = k; i < L_SUBFR; i += STEP)
+        {
+            psign = sign;                  move16();
+            test();
+            if (psign[i] < 0)
+            {
+                psign = vec;               move16();
+            }
+            for (j = (Word16) ((k + 1) % NB_TRACK); j < L_SUBFR; j += STEP)
+            {
+                *p0 = mult(*p0, psign[j]);    move16();
+                p0++;
+            }
+        }
+    }
+
+    /*-------------------------------------------------------------------*
+     *                       Deep first search                           *
+     *-------------------------------------------------------------------*/
+
+    psk = -1;                              move16();
+    alpk = 1;                              move16();
+
+    for (k = 0; k < nbiter; k++)
+    {
+        for (i = 0; i < nb_pulse; i++)
+            ipos[i] = tipos[(k * 4) + i];
+
+        test();test();test();
+        if (sub(nbbits, 20) == 0)
+        {
+            pos = 0;                       move16();
+            ps = 0;                        move16();
+            alp = 0;                       move16();
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                vec[i] = 0;                move16();
+            }
+        } else if ((sub(nbbits, 36) == 0) || (sub(nbbits, 44) == 0))
+        {
+            /* first stage: fix 2 pulses */
+            pos = 2;
+
+            ix = ind[0] = pos_max[ipos[0]];move16();move16();
+            iy = ind[1] = pos_max[ipos[1]];move16();move16();
+            ps = add(dn[ix], dn[iy]);
+            i = shr(ix, 2);                /* ix / STEP */
+            j = shr(iy, 2);                /* iy / STEP */
+            s = L_mult(rrixix[ipos[0]][i], 4096);
+            s = L_mac(s, rrixix[ipos[1]][j], 4096);
+            i = add(shl(i, 4), j);         /* (ix/STEP)*NB_POS + (iy/STEP) */
+            s = L_mac(s, rrixiy[ipos[0]][i], 8192);
+            alp = round(s);
+            test();move16();move16();
+            if (sign[ix] < 0)
+                p0 = h_inv - ix;
+            else
+                p0 = h - ix;
+            test();move16();move16();
+            if (sign[iy] < 0)
+                p1 = h_inv - iy;
+            else
+                p1 = h - iy;
+
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                vec[i] = add(*p0++, *p1++);move16();
+            }
+
+            test();
+            if (sub(nbbits, 44) == 0)
+            {
+                ipos[8] = 0;               move16();
+                ipos[9] = 1;               move16();
+            }
+        } else
+        {
+            /* first stage: fix 4 pulses */
+            pos = 4;
+
+            ix = ind[0] = pos_max[ipos[0]];  move16();move16();
+            iy = ind[1] = pos_max[ipos[1]];  move16();move16();
+            i = ind[2] = pos_max[ipos[2]];   move16();move16();
+            j = ind[3] = pos_max[ipos[3]];   move16();move16();
+            ps = add(add(add(dn[ix], dn[iy]), dn[i]), dn[j]);
+
+            test();move16();move16();
+            if (sign[ix] < 0)
+                p0 = h_inv - ix;
+            else
+                p0 = h - ix;
+            test();move16();move16();
+            if (sign[iy] < 0)
+                p1 = h_inv - iy;
+            else
+                p1 = h - iy;
+            test();move16();move16();
+            if (sign[i] < 0)
+                p2 = h_inv - i;
+            else
+                p2 = h - i;
+            test();move16();move16();
+            if (sign[j] < 0)
+                p3 = h_inv - j;
+            else
+                p3 = h - j;
+
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                vec[i] = add(add(add(*p0++, *p1++), *p2++), *p3++);
+                move16();
+            }
+
+            L_tmp = 0L;                    move32();
+            for (i = 0; i < L_SUBFR; i++)
+                L_tmp = L_mac(L_tmp, vec[i], vec[i]);
+
+            alp = round(L_shr(L_tmp, 3));
+
+            if (sub(nbbits, 72) == 0)
+            {
+                ipos[16] = 0;              move16();
+                ipos[17] = 1;              move16();
+            }
+        }
+
+        /* other stages of 2 pulses */
+
+        for (j = pos, st = 0; j < nb_pulse; j += 2, st++)
+        {
+            /*--------------------------------------------------*
+            * Calculate correlation of all possible positions  *
+            * of the next 2 pulses with previous fixed pulses. *
+            * Each pulse can have 16 possible positions.       *
+            *--------------------------------------------------*/
+
+            cor_h_vec(h, vec, ipos[j], sign, rrixix, cor_x);
+            cor_h_vec(h, vec, ipos[j + 1], sign, rrixix, cor_y);
+
+            /*--------------------------------------------------*
+            * Find best positions of 2 pulses.                 *
+            *--------------------------------------------------*/
+
+            search_ixiy(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
+                &ix, &iy, dn, dn2, cor_x, cor_y, rrixiy);
+
+            ind[j] = ix;                   move16();
+            ind[j + 1] = iy;               move16();
+
+            test();move16();move16();
+            if (sign[ix] < 0)
+                p0 = h_inv - ix;
+            else
+                p0 = h - ix;
+            test();move16();move16();
+            if (sign[iy] < 0)
+                p1 = h_inv - iy;
+            else
+                p1 = h - iy;
+
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                vec[i] = add(vec[i], add(*p0++, *p1++));        /* can saturate here. */
+                move16();
+            }
+        }
+
+        /* memorise the best codevector */
+
+        ps = mult(ps, ps);
+        s = L_msu(L_mult(alpk, ps), psk, alp);
+        test();
+        if (s > 0)
+        {
+            psk = ps;                      move16();
+            alpk = alp;                    move16();
+            for (i = 0; i < nb_pulse; i++)
+            {
+                codvec[i] = ind[i];        move16();
+            }
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                y[i] = vec[i];             move16();
+            }
+        }
+    }
+
+    /*-------------------------------------------------------------------*
+     * Build the codeword, the filtered codeword and index of codevector.*
+     *-------------------------------------------------------------------*/
+
+    for (i = 0; i < NPMAXPT * NB_TRACK; i++)
+    {
+        ind[i] = -1;                       move16();
+    }
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        code[i] = 0;                       move16();
+        y[i] = shr_r(y[i], 3);             move16();  /* Q12 to Q9 */
+    }
+
+    val = shr(512, h_shift);               /* codeword in Q9 format */
+
+    for (k = 0; k < nb_pulse; k++)
+    {
+        i = codvec[k];                     move16();  /* read pulse position */
+        j = sign[i];                       move16();  /* read sign           */
+
+        index = shr(i, 2);                 /* index = pos of pulse (0..15) */
+        track = (Word16) (i & 0x03);       logic16();  /* track = i % NB_TRACK (0..3)  */
+
+        if (j > 0)
+        {
+            code[i] = add(code[i], val);   move16();
+            codvec[k] = add(codvec[k], (2 * L_SUBFR));  move16();
+        } else
+        {
+            code[i] = sub(code[i], val);   move16();
+            index = add(index, NB_POS);    move16();
+        }
+
+        i = extract_l(L_shr(L_mult(track, NPMAXPT), 1));
+
+        test();move16();
+        while (ind[i] >= 0)
+        {
+            i = add(i, 1);
+        }
+        ind[i] = index;                    move16();
+    }
+
+    k = 0;                                 move16();
+    /* Build index of codevector */
+    test();test();test();test();test();test();test();
+    if (sub(nbbits, 20) == 0)
+    {
+        for (track = 0; track < NB_TRACK; track++)
+        {
+            _index[track] = extract_l(quant_1p_N1(ind[k], 4));
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 36) == 0)
+    {
+        for (track = 0; track < NB_TRACK; track++)
+        {
+            _index[track] = extract_l(quant_2p_2N1(ind[k], ind[k + 1], 4));
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 44) == 0)
+    {
+        for (track = 0; track < NB_TRACK - 2; track++)
+        {
+            _index[track] = extract_l(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
+            k += NPMAXPT;
+        }
+        for (track = 2; track < NB_TRACK; track++)
+        {
+            _index[track] = extract_l(quant_2p_2N1(ind[k], ind[k + 1], 4));
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 52) == 0)
+    {
+        for (track = 0; track < NB_TRACK; track++)
+        {
+            _index[track] = extract_l(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 64) == 0)
+    {
+        for (track = 0; track < NB_TRACK; track++)
+        {
+            L_index = quant_4p_4N(&ind[k], 4);
+            _index[track] = extract_l(L_shr(L_index, 14) & 3);
+            _index[track + NB_TRACK] = extract_l(L_index & 0x3FFF);
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 72) == 0)
+    {
+        for (track = 0; track < NB_TRACK - 2; track++)
+        {
+            L_index = quant_5p_5N(&ind[k], 4);
+            _index[track] = extract_l(L_shr(L_index, 10) & 0x03FF);
+            _index[track + NB_TRACK] = extract_l(L_index & 0x03FF);
+            k += NPMAXPT;
+        }
+        for (track = 2; track < NB_TRACK; track++)
+        {
+            L_index = quant_4p_4N(&ind[k], 4);
+            _index[track] = extract_l(L_shr(L_index, 14) & 3);
+            _index[track + NB_TRACK] = extract_l(L_index & 0x3FFF);
+            k += NPMAXPT;
+        }
+    } else if (sub(nbbits, 88) == 0)
+    {
+        for (track = 0; track < NB_TRACK; track++)
+        {
+            L_index = quant_6p_6N_2(&ind[k], 4);
+            _index[track] = extract_l(L_shr(L_index, 11) & 0x07FF);
+            _index[track + NB_TRACK] = extract_l(L_index & 0x07FF);
+            k += NPMAXPT;
+        }
+    }
+    return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function  cor_h_vec()                                             *
+ * ~~~~~~~~~~~~~~~~~~~~~                                             *
+ * Compute correlations of h[] with vec[] for the specified track.   *
+ *-------------------------------------------------------------------*/
+static void cor_h_vec(
+     Word16 h[],                           /* (i) scaled impulse response                 */
+     Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
+     Word16 track,                         /* (i) track to use                            */
+     Word16 sign[],                        /* (i) sign vector                             */
+     Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
+     Word16 cor[]                          /* (o) result of correlation (NB_POS elements) */
+)
+{
+    Word16 i, j, pos, corr;
+    Word16 *p0, *p1, *p2;
+    Word32 L_sum;
+
+    p0 = rrixix[track];                    move16();
+
+    pos = track;                           move16();
+    for (i = 0; i < NB_POS; i++, pos += STEP)
+    {
+        L_sum = 0L;                        move32();
+        p1 = h;                            move16();
+        p2 = &vec[pos];                    move16();
+        for (j = pos; j < L_SUBFR; j++)
+            L_sum = L_mac(L_sum, *p1++, *p2++);
+
+        L_sum = L_shl(L_sum, 1);
+
+        corr = round(L_sum);
+
+        cor[i] = add(mult(corr, sign[pos]), *p0++);     move16();
+
+    }
+
+    return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function  search_ixiy()                                           *
+ * ~~~~~~~~~~~~~~~~~~~~~~~                                           *
+ * Find the best positions of 2 pulses in a subframe.                *
+ *-------------------------------------------------------------------*/
+
+static void search_ixiy(
+     Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
+     Word16 track_x,                       /* (i) track of pulse 1                   */
+     Word16 track_y,                       /* (i) track of pulse 2                   */
+     Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
+     Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
+     Word16 * ix,                          /* (o) position of pulse 1                */
+     Word16 * iy,                          /* (o) position of pulse 2                */
+     Word16 dn[],                          /* (i) corr. between target and h[]       */
+     Word16 dn2[],                         /* (i) vector of selected positions       */
+     Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
+     Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
+     Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
+)
+{
+    Word16 x, y, pos, thres_ix;
+    Word16 ps1, ps2, sq, sqk;
+    Word16 alp_16, alpk;
+    Word16 *p0, *p1, *p2;
+    Word32 s, alp0, alp1, alp2;
+
+    p0 = cor_x;                            move16();
+    p1 = cor_y;                            move16();
+    p2 = rrixiy[track_x];                  move16();
+
+    thres_ix = sub(nb_pos_ix, NB_MAX);
+
+    alp0 = L_deposit_h(*alp);
+    alp0 = L_add(alp0, 0x00008000L);       /* for rounding */
+
+    sqk = -1;                              move16();
+    alpk = 1;                              move16();
+
+    for (x = track_x; x < L_SUBFR; x += STEP)
+    {
+        ps1 = add(*ps, dn[x]);
+        alp1 = L_mac(alp0, *p0++, 4096);
+
+        test();
+        if (sub(dn2[x], thres_ix) < 0)
+        {
+            pos = -1;                      move16();
+            for (y = track_y; y < L_SUBFR; y += STEP)
+            {
+                ps2 = add(ps1, dn[y]);
+                alp2 = L_mac(alp1, *p1++, 4096);
+                alp2 = L_mac(alp2, *p2++, 8192);
+                alp_16 = extract_h(alp2);
+
+                sq = mult(ps2, ps2);
+
+                s = L_msu(L_mult(alpk, sq), sqk, alp_16);
+
+                test();
+                if (s > 0)
+                {
+                    sqk = sq;              move16();
+                    alpk = alp_16;         move16();
+                    pos = y;               move16();
+                }
+            }
+            p1 -= NB_POS;
+
+            test();
+            if (pos >= 0)
+            {
+                *ix = x;                   move16();
+                *iy = pos;                 move16();
+            }
+        } else
+        {
+            p2 += NB_POS;
+        }
+    }
+
+    *ps = add(*ps, add(dn[*ix], dn[*iy])); move16();
+    *alp = alpk;                           move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/cnst.h
@@ -1,0 +1,60 @@
+/*--------------------------------------------------------------------------*
+ *                         CNST.H                                           *
+ *--------------------------------------------------------------------------*
+ *       Codec constant parameters (coder and decoder)                      *
+ *--------------------------------------------------------------------------*/
+
+#define CODEC_VERSION "6.1.0"
+
+#define L_FRAME16k   320                   /* Frame size at 16kHz                        */
+#define L_FRAME      256                   /* Frame size                                 */
+#define L_SUBFR16k   80                    /* Subframe size at 16kHz                     */
+
+#define L_SUBFR      64                    /* Subframe size                              */
+#define NB_SUBFR     4                     /* Number of subframe per frame               */
+
+#define L_NEXT       64                    /* Overhead in LP analysis                    */
+#define L_WINDOW     384                   /* window size in LP analysis                 */
+#define L_TOTAL      384                   /* Total size of speech buffer.               */
+#define M            16                    /* Order of LP filter                         */
+#define M16k             20
+
+#define L_FILT16k    15                    /* Delay of down-sampling filter              */
+#define L_FILT       12                    /* Delay of up-sampling filter                */
+
+#define GP_CLIP      15565                 /* Pitch gain clipping = 0.95 Q14             */
+#define PIT_SHARP    27853                 /* pitch sharpening factor = 0.85 Q15         */
+
+#define PIT_MIN      34                    /* Minimum pitch lag with resolution 1/4      */
+#define PIT_FR2      128                   /* Minimum pitch lag with resolution 1/2      */
+#define PIT_FR1_9b   160                   /* Minimum pitch lag with resolution 1        */
+#define PIT_FR1_8b   92                    /* Minimum pitch lag with resolution 1        */
+#define PIT_MAX      231                   /* Maximum pitch lag                          */
+#define L_INTERPOL   (16+1)                /* Length of filter for interpolation         */
+
+#define OPL_DECIM    2                     /* Decimation in open-loop pitch analysis     */
+
+#define PREEMPH_FAC  22282                 /* preemphasis factor (0.68 in Q15)           */
+#define GAMMA1       30147                 /* Weighting factor (numerator) (0.92 in Q15) */
+#define TILT_FAC     22282                 /* tilt factor (denominator) (0.68 in Q15)    */
+
+#define Q_MAX        8                     /* scaling max for signal (see syn_filt_32)   */
+
+#define RANDOM_INITSEED  21845             /* own random init value                      */
+
+#define L_MEANBUF        3
+#define ONE_PER_MEANBUF 10923
+
+#define MODE_7k       0
+#define MODE_9k       1
+#define MODE_12k      2
+#define MODE_14k      3
+#define MODE_16k      4
+#define MODE_18k      5
+#define MODE_20k      6
+#define MODE_23k      7
+#define MODE_24k      8
+#define MRDTX         9
+#define NUM_OF_MODES  10                   /* see bits.h for bits definition             */
+
+#define EHF_MASK (Word16)0x0008            /* homing frame pattern                       */
--- /dev/null
+++ b/amr-wb/cod_main.c
@@ -1,0 +1,1621 @@
+/*------------------------------------------------------------------------*
+ *                         COD_MAIN.C                                     *
+ *------------------------------------------------------------------------*
+ * Performs the main encoder routine                                      *
+ *------------------------------------------------------------------------*/
+
+/*___________________________________________________________________________
+ |                                                                           |
+ | Fixed-point C simulation of AMR WB ACELP coding algorithm with 20 ms      |
+ | speech frames for wideband speech signals.                                |
+ |___________________________________________________________________________|
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "cod_main.h"
+#include "bits.h"
+#include "count.h"
+#include "main.h"
+
+
+/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
+static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
+
+/* isp tables for initialization */
+
+static Word16 isp_init[M] =
+{
+   32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
+   -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
+};
+
+static Word16 isf_init[M] =
+{
+   1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
+   9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
+};
+
+/* High Band encoding */
+static const Word16 HP_gain[16] =
+{
+   3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
+   11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
+};
+
+static Word16 synthesis(
+     Word16 Aq[],                          /* A(z)  : quantized Az               */
+     Word16 exc[],                         /* (i)   : excitation at 12kHz        */
+     Word16 Q_new,                         /* (i)   : scaling performed on exc   */
+     Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
+     Coder_State * st                      /* (i/o) : State structure            */
+);
+
+/*-----------------------------------------------------------------*
+ *   Funtion  init_coder                                           *
+ *            ~~~~~~~~~~                                           *
+ *   ->Initialization of variables for the coder section.          *
+ *-----------------------------------------------------------------*/
+
+void Init_coder(void **spe_state)
+{
+    Coder_State *st;
+
+    *spe_state = NULL;
+
+    /*-------------------------------------------------------------------------*
+     * Memory allocation for coder state.                                      *
+     *-------------------------------------------------------------------------*/
+
+    if ((st = (Coder_State *) malloc(sizeof(Coder_State))) == NULL)
+    {
+        printf("Can not malloc Coder_State structure!\n");
+        return;
+    }
+    st->vadSt = NULL;                      move16();
+    st->dtx_encSt = NULL;                  move16();
+
+    wb_vad_init(&(st->vadSt));
+    dtx_enc_init(&(st->dtx_encSt), isf_init);
+
+    Reset_encoder((void *) st, 1);
+
+    *spe_state = (void *) st;
+
+    return;
+}
+
+
+void Reset_encoder(void *st, Word16 reset_all)
+{
+    Word16 i;
+
+    Coder_State *cod_state;
+
+    cod_state = (Coder_State *) st;
+
+    Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL);
+    Set_zero(cod_state->mem_syn, M);
+    Set_zero(cod_state->past_isfq, M);
+
+    cod_state->mem_w0 = 0;                 move16();
+    cod_state->tilt_code = 0;              move16();
+    cod_state->first_frame = 1;            move16();
+
+    Init_gp_clip(cod_state->gp_clip);
+
+    cod_state->L_gc_thres = 0;             move16();
+
+    if (reset_all != 0)
+    {
+        /* Static vectors to zero */
+
+        Set_zero(cod_state->old_speech, L_TOTAL - L_FRAME);
+        Set_zero(cod_state->old_wsp, (PIT_MAX / OPL_DECIM));
+        Set_zero(cod_state->mem_decim2, 3);
+
+        /* routines initialization */
+
+        Init_Decim_12k8(cod_state->mem_decim);
+        Init_HP50_12k8(cod_state->mem_sig_in);
+        Init_Levinson(cod_state->mem_levinson);
+        Init_Q_gain2(cod_state->qua_gain);
+        Init_Hp_wsp(cod_state->hp_wsp_mem);
+
+        /* isp initialization */
+
+        Copy(isp_init, cod_state->ispold, M);
+        Copy(isp_init, cod_state->ispold_q, M);
+
+        /* variable initialization */
+
+        cod_state->mem_preemph = 0;        move16();
+        cod_state->mem_wsp = 0;            move16();
+        cod_state->Q_old = 15;             move16();
+        cod_state->Q_max[0] = 15;          move16();
+        cod_state->Q_max[1] = 15;          move16();
+        cod_state->old_wsp_max = 0;        move16();
+        cod_state->old_wsp_shift = 0;      move16();
+
+        /* pitch ol initialization */
+
+        cod_state->old_T0_med = 40;        move16();
+        cod_state->ol_gain = 0;            move16();
+        cod_state->ada_w = 0;              move16();
+        cod_state->ol_wght_flg = 0;        move16();
+        for (i = 0; i < 5; i++)
+        {
+            cod_state->old_ol_lag[i] = 40; move16();
+        }
+        Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM));
+
+        Set_zero(cod_state->mem_syn_hf, M);
+        Set_zero(cod_state->mem_syn_hi, M);
+        Set_zero(cod_state->mem_syn_lo, M);
+
+        Init_HP50_12k8(cod_state->mem_sig_out);
+        Init_Filt_6k_7k(cod_state->mem_hf);
+        Init_HP400_12k8(cod_state->mem_hp400);
+
+        Copy(isf_init, cod_state->isfold, M);
+
+        cod_state->mem_deemph = 0;         move16();
+
+        cod_state->seed2 = 21845;          move16();
+
+        Init_Filt_6k_7k(cod_state->mem_hf2);
+        cod_state->gain_alpha = 32767;     move16();
+
+        cod_state->vad_hist = 0;
+
+        wb_vad_reset(cod_state->vadSt);
+        dtx_enc_reset(cod_state->dtx_encSt, isf_init);
+    }
+    return;
+}
+
+void Close_coder(void *spe_state)
+{
+    wb_vad_exit(&(((Coder_State *) spe_state)->vadSt));
+    dtx_enc_exit(&(((Coder_State *) spe_state)->dtx_encSt));
+    free(spe_state);
+
+    return;
+}
+
+/*-----------------------------------------------------------------*
+ *   Funtion  coder                                                *
+ *            ~~~~~                                                *
+ *   ->Main coder routine.                                         *
+ *                                                                 *
+ *-----------------------------------------------------------------*/
+
+void coder(
+     Word16 * mode,                        /* input :  used mode                             */
+     Word16 speech16k[],                   /* input :  320 new speech samples (at 16 kHz)    */
+     Word16 prms[],                        /* output:  output parameters                     */
+     Word16 * ser_size,                    /* output:  bit rate of the used mode             */
+     void *spe_state,                      /* i/o   :  State structure                       */
+     Word16 allow_dtx                      /* input :  DTX ON/OFF                            */
+)
+{
+
+    /* Coder states */
+    Coder_State *st;
+
+    /* Speech vector */
+    Word16 old_speech[L_TOTAL];
+    Word16 *new_speech, *speech, *p_window;
+
+    /* Weighted speech vector */
+    Word16 old_wsp[L_FRAME + (PIT_MAX / OPL_DECIM)];
+    Word16 *wsp;
+
+    /* Excitation vector */
+    Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];
+    Word16 *exc;
+
+    /* LPC coefficients */
+
+    Word16 r_h[M + 1], r_l[M + 1];         /* Autocorrelations of windowed speech  */
+    Word16 rc[M];                          /* Reflection coefficients.             */
+    Word16 Ap[M + 1];                      /* A(z) with spectral expansion         */
+    Word16 ispnew[M];                      /* immittance spectral pairs at 4nd sfr */
+    Word16 ispnew_q[M];                    /* quantized ISPs at 4nd subframe       */
+    Word16 isf[M];                         /* ISF (frequency domain) at 4nd sfr    */
+    Word16 *p_A, *p_Aq;                    /* ptr to A(z) for the 4 subframes      */
+    Word16 A[NB_SUBFR * (M + 1)];          /* A(z) unquantized for the 4 subframes */
+    Word16 Aq[NB_SUBFR * (M + 1)];         /* A(z)   quantized for the 4 subframes */
+
+    /* Other vectors */
+
+    Word16 xn[L_SUBFR];                    /* Target vector for pitch search     */
+    Word16 xn2[L_SUBFR];                   /* Target vector for codebook search  */
+    Word16 dn[L_SUBFR];                    /* Correlation between xn2 and h1     */
+    Word16 cn[L_SUBFR];                    /* Target vector in residual domain   */
+
+    Word16 h1[L_SUBFR];                    /* Impulse response vector            */
+    Word16 h2[L_SUBFR];                    /* Impulse response vector            */
+    Word16 code[L_SUBFR];                  /* Fixed codebook excitation          */
+    Word16 y1[L_SUBFR];                    /* Filtered adaptive excitation       */
+    Word16 y2[L_SUBFR];                    /* Filtered adaptive excitation       */
+    Word16 error[M + L_SUBFR];             /* error of quantization              */
+    Word16 synth[L_SUBFR];                 /* 12.8kHz synthesis vector           */
+    Word16 exc2[L_FRAME];                  /* excitation vector                  */
+    Word16 buf[L_FRAME];                   /* VAD buffer                         */
+
+    /* Scalars */
+
+    Word16 i, j, i_subfr, select, pit_flag, clip_gain, vad_flag;
+    Word16 codec_mode;
+    Word16 T_op, T_op2, T0, T0_min, T0_max, T0_frac, index;
+    Word16 gain_pit, gain_code, g_coeff[4], g_coeff2[4];
+    Word16 tmp, gain1, gain2, exp, Q_new, mu, shift, max;
+    Word16 voice_fac;
+    Word16 indice[8];
+
+    Word32 L_tmp, L_gain_code, L_max;
+
+    Word16 code2[L_SUBFR];                 /* Fixed codebook excitation  */
+    Word16 stab_fac, fac, gain_code_lo;
+
+    Word16 corr_gain;
+
+    st = (Coder_State *) spe_state;
+
+    *ser_size = nb_of_bits[*mode];         move16();
+    codec_mode = *mode;                    move16();
+
+    /*--------------------------------------------------------------------------*
+     *          Initialize pointers to speech vector.                           *
+     *                                                                          *
+     *                                                                          *
+     *                    |-------|-------|-------|-------|-------|-------|     *
+     *                     past sp   sf1     sf2     sf3     sf4    L_NEXT      *
+     *                    <-------  Total speech buffer (L_TOTAL)   ------>     *
+     *              old_speech                                                  *
+     *                    <-------  LPC analysis window (L_WINDOW)  ------>     *
+     *                    |       <-- present frame (L_FRAME) ---->             *
+     *                   p_window |       <----- new speech (L_FRAME) ---->     *
+     *                            |       |                                     *
+     *                          speech    |                                     *
+     *                                 new_speech                               *
+     *--------------------------------------------------------------------------*/
+
+    new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT;       move16();  /* New speech     */
+    speech = old_speech + L_TOTAL - L_FRAME - L_NEXT;   move16();  /* Present frame  */
+    p_window = old_speech + L_TOTAL - L_WINDOW; move16();
+
+    exc = old_exc + PIT_MAX + L_INTERPOL;  move16();
+    wsp = old_wsp + (PIT_MAX / OPL_DECIM); move16();
+
+    /* copy coder memory state into working space (internal memory for DSP) */
+
+    Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME);
+    Copy(st->old_wsp, old_wsp, PIT_MAX / OPL_DECIM);
+    Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL);
+
+    /*---------------------------------------------------------------*
+     * Down sampling signal from 16kHz to 12.8kHz                    *
+     * -> The signal is extended by L_FILT samples (padded to zero)  *
+     * to avoid additional delay (L_FILT samples) in the coder.      *
+     * The last L_FILT samples are approximated after decimation and *
+     * are used (and windowed) only in autocorrelations.             *
+     *---------------------------------------------------------------*/
+
+    Decim_12k8(speech16k, L_FRAME16k, new_speech, st->mem_decim);
+
+    /* last L_FILT samples for autocorrelation window */
+    Copy(st->mem_decim, code, 2 * L_FILT16k);
+    Set_zero(error, L_FILT16k);            /* set next sample to zero */
+    Decim_12k8(error, L_FILT16k, new_speech + L_FRAME, code);
+
+    /*---------------------------------------------------------------*
+     * Perform 50Hz HP filtering of input signal.                    *
+     *---------------------------------------------------------------*/
+
+    HP50_12k8(new_speech, L_FRAME, st->mem_sig_in);
+
+    /* last L_FILT samples for autocorrelation window */
+    Copy(st->mem_sig_in, code, 6);
+    HP50_12k8(new_speech + L_FRAME, L_FILT, code);
+
+    /*---------------------------------------------------------------*
+     * Perform fixed preemphasis through 1 - g z^-1                  *
+     * Scale signal to get maximum of precision in filtering         *
+     *---------------------------------------------------------------*/
+
+    mu = shr(PREEMPH_FAC, 1);              /* Q15 --> Q14 */
+
+    /* get max of new preemphased samples (L_FRAME+L_FILT) */
+
+    L_tmp = L_mult(new_speech[0], 16384);
+    L_tmp = L_msu(L_tmp, st->mem_preemph, mu);
+    L_max = L_abs(L_tmp);
+
+    for (i = 1; i < L_FRAME + L_FILT; i++)
+    {
+        L_tmp = L_mult(new_speech[i], 16384);
+        L_tmp = L_msu(L_tmp, new_speech[i - 1], mu);
+        L_tmp = L_abs(L_tmp);
+        test();
+        if (L_sub(L_tmp, L_max) > (Word32) 0)
+        {
+            L_max = L_tmp;                 move32();
+        }
+    }
+
+    /* get scaling factor for new and previous samples */
+    /* limit scaling to Q_MAX to keep dynamic for ringing in low signal */
+    /* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */
+    tmp = extract_h(L_max);
+    test();
+    if (tmp == 0)
+    {
+        shift = Q_MAX;                     move16();
+    } else
+    {
+        shift = sub(norm_s(tmp), 1);
+        test();
+        if (shift < 0)
+        {
+            shift = 0;                     move16();
+        }
+        test();
+        if (sub(shift, Q_MAX) > 0)
+        {
+            shift = Q_MAX;                 move16();
+        }
+    }
+    Q_new = shift;                         move16();
+    test();
+    if (sub(Q_new, st->Q_max[0]) > 0)
+    {
+        Q_new = st->Q_max[0];              move16();
+    }
+    test();
+    if (sub(Q_new, st->Q_max[1]) > 0)
+    {
+        Q_new = st->Q_max[1];              move16();
+    }
+    exp = sub(Q_new, st->Q_old);
+    st->Q_old = Q_new;                     move16();
+    st->Q_max[1] = st->Q_max[0];           move16();
+    st->Q_max[0] = shift;                  move16();
+
+    /* preemphasis with scaling (L_FRAME+L_FILT) */
+
+    tmp = new_speech[L_FRAME - 1];         move16();
+
+    for (i = L_FRAME + L_FILT - 1; i > 0; i--)
+    {
+        L_tmp = L_mult(new_speech[i], 16384);
+        L_tmp = L_msu(L_tmp, new_speech[i - 1], mu);
+        L_tmp = L_shl(L_tmp, Q_new);
+        new_speech[i] = round(L_tmp);      move16();
+    }
+
+    L_tmp = L_mult(new_speech[0], 16384);
+    L_tmp = L_msu(L_tmp, st->mem_preemph, mu);
+    L_tmp = L_shl(L_tmp, Q_new);
+    new_speech[0] = round(L_tmp);          move16();
+
+    st->mem_preemph = tmp;                 move16();
+
+    /* scale previous samples and memory */
+
+    Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp);
+    Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp);
+
+    Scale_sig(st->mem_syn, M, exp);
+    Scale_sig(st->mem_decim2, 3, exp);
+    Scale_sig(&(st->mem_wsp), 1, exp);
+    Scale_sig(&(st->mem_w0), 1, exp);
+
+    /*------------------------------------------------------------------------*
+     *  Call VAD                                                              *
+     *  Preemphesis scale down signal in low frequency and keep dynamic in HF.*
+     *  Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT).   *
+     *------------------------------------------------------------------------*/
+
+    Copy(new_speech, buf, L_FRAME);
+
+    Scale_sig(buf, L_FRAME, sub(1, Q_new));
+
+    vad_flag = wb_vad(st->vadSt, buf);
+    if (vad_flag == 0)
+    {
+        st->vad_hist = add(st->vad_hist, 1);        move16();
+    } else
+    {
+        st->vad_hist = 0;              move16();
+    }
+
+    /* DTX processing */
+    test();
+    if (allow_dtx != 0)
+    {
+        /* Note that mode may change here */
+        tx_dtx_handler(st->dtx_encSt, vad_flag, mode);
+        *ser_size = nb_of_bits[*mode]; move16();
+    }
+
+    test();
+    if (sub(*mode, MRDTX) != 0)
+    {
+        Parm_serial(vad_flag, 1, &prms);
+    }
+    /*------------------------------------------------------------------------*
+     *  Perform LPC analysis                                                  *
+     *  ~~~~~~~~~~~~~~~~~~~~                                                  *
+     *   - autocorrelation + lag windowing                                    *
+     *   - Levinson-durbin algorithm to find a[]                              *
+     *   - convert a[] to isp[]                                               *
+     *   - convert isp[] to isf[] for quantization                            *
+     *   - quantize and code the isf[]                                        *
+     *   - convert isf[] to isp[] for interpolation                           *
+     *   - find the interpolated ISPs and convert to a[] for the 4 subframes  *
+     *------------------------------------------------------------------------*/
+
+    /* LP analysis centered at 4nd subframe */
+    Autocorr(p_window, M, r_h, r_l);       /* Autocorrelations */
+    Lag_window(r_h, r_l);                  /* Lag windowing    */
+    Levinson(r_h, r_l, A, rc, st->mem_levinson);        /* Levinson Durbin  */
+    Az_isp(A, ispnew, st->ispold);         /* From A(z) to ISP */
+
+    /* Find the interpolated ISPs and convert to a[] for all subframes */
+    Int_isp(st->ispold, ispnew, interpol_frac, A);
+
+    /* update ispold[] for the next frame */
+    Copy(ispnew, st->ispold, M);
+
+    /* Convert ISPs to frequency domain 0..6400 */
+    Isp_isf(ispnew, isf, M);
+
+    /* check resonance for pitch clipping algorithm */
+    Gp_clip_test_isf(isf, st->gp_clip);
+
+    /*----------------------------------------------------------------------*
+     *  Perform PITCH_OL analysis                                           *
+     *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                           *
+     * - Find the residual res[] for the whole speech frame                 *
+     * - Find the weighted input speech wsp[] for the whole speech frame    *
+     * - scale wsp[] to avoid overflow in pitch estimation                  *
+     * - Find open loop pitch lag for whole speech frame                    *
+     *----------------------------------------------------------------------*/
+
+    p_A = A;                               move16();
+    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+    {
+        Weight_a(p_A, Ap, GAMMA1, M);
+        Residu(Ap, M, &speech[i_subfr], &wsp[i_subfr], L_SUBFR);
+        p_A += (M + 1);                    move16();
+    }
+    Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp));
+
+    /* find maximum value on wsp[] for 12 bits scaling */
+    max = 0;                               move16();
+    for (i = 0; i < L_FRAME; i++)
+    {
+        tmp = abs_s(wsp[i]);
+        test();
+        if (sub(tmp, max) > 0)
+        {
+            max = tmp;                     move16();
+        }
+    }
+    tmp = st->old_wsp_max;                 move16();
+    test();
+    if (sub(max, tmp) > 0)
+    {
+        tmp = max;                         /* tmp = max(wsp_max, old_wsp_max) */
+        move16();
+    }
+    st->old_wsp_max = max;                 move16();
+
+    shift = sub(norm_s(tmp), 3);
+    test();
+    if (shift > 0)
+    {
+        shift = 0;                         /* shift = 0..-3 */
+        move16();
+    }
+    /* decimation of wsp[] to search pitch in LF and to reduce complexity */
+    LP_Decim2(wsp, L_FRAME, st->mem_decim2);
+
+    /* scale wsp[] in 12 bits to avoid overflow */
+    Scale_sig(wsp, L_FRAME / OPL_DECIM, shift);
+
+    /* scale old_wsp (warning: exp must be Q_new-Q_old) */
+    exp = add(exp, sub(shift, st->old_wsp_shift));
+    st->old_wsp_shift = shift;
+    Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp);
+    Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp);
+    scale_mem_Hp_wsp(st->hp_wsp_mem, exp);
+
+    /* Find open loop pitch lag for whole speech frame */
+
+    test();
+    if (sub(*ser_size, NBBITS_7k) == 0)
+    {
+        /* Find open loop pitch lag for whole speech frame */
+        T_op = Pitch_med_ol(wsp, PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
+            L_FRAME / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
+    } else
+    {
+        /* Find open loop pitch lag for first 1/2 frame */
+        T_op = Pitch_med_ol(wsp, PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
+            (L_FRAME / 2) / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
+    }
+
+    test();
+    if (sub(st->ol_gain, 19661) > 0)       /* 0.6 in Q15 */
+    {
+        st->old_T0_med = Med_olag(T_op, st->old_ol_lag);        move16();
+        st->ada_w = 32767;                 move16();
+    } else
+    {
+        st->ada_w = mult(st->ada_w, 29491);move16();
+    }
+
+    test();move16();
+    if (sub(st->ada_w, 26214) < 0)
+        st->ol_wght_flg = 0;
+    else
+        st->ol_wght_flg = 1;
+
+    wb_vad_tone_detection(st->vadSt, st->ol_gain);
+
+    T_op *= OPL_DECIM;                     move16();
+
+    test();
+    if (sub(*ser_size, NBBITS_7k) != 0)
+    {
+        /* Find open loop pitch lag for second 1/2 frame */
+        T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), PIT_MIN / OPL_DECIM, PIT_MAX / OPL_DECIM,
+            (L_FRAME / 2) / OPL_DECIM, st->old_T0_med, &(st->ol_gain), st->hp_wsp_mem, st->old_hp_wsp, st->ol_wght_flg);
+
+        test();
+        if (sub(st->ol_gain, 19661) > 0)   /* 0.6 in Q15 */
+        {
+            st->old_T0_med = Med_olag(T_op2, st->old_ol_lag);   move16();
+            st->ada_w = 32767;             move16();
+        } else
+        {
+            st->ada_w = mult(st->ada_w, 29491); move16();
+        }
+
+        test();move16();
+        if (sub(st->ada_w, 26214) < 0)
+            st->ol_wght_flg = 0;
+        else
+            st->ol_wght_flg = 1;
+
+        wb_vad_tone_detection(st->vadSt, st->ol_gain);
+
+        T_op2 *= OPL_DECIM;                move16();
+
+    } else
+    {
+        T_op2 = T_op;                      move16();
+    }
+
+
+    /*----------------------------------------------------------------------*
+     *                              DTX-CNG                                 *
+     *----------------------------------------------------------------------*/
+
+    test();
+    if (sub(*mode, MRDTX) == 0)            /* CNG mode */
+    {
+        /* Buffer isf's and energy */
+        Residu(&A[3 * (M + 1)], M, speech, exc, L_FRAME);
+
+        for (i = 0; i < L_FRAME; i++)
+        {
+            exc2[i] = shr(exc[i], Q_new);  move16();
+        }
+
+        L_tmp = 0;                         move32();
+        for (i = 0; i < L_FRAME; i++)
+            L_tmp = L_mac(L_tmp, exc2[i], exc2[i]);
+        L_tmp = L_shr(L_tmp, 1);
+
+        dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
+
+        /* Quantize and code the ISFs */
+        dtx_enc(st->dtx_encSt, isf, exc2, &prms);
+
+        /* Convert ISFs to the cosine domain */
+        Isf_isp(isf, ispnew_q, M);
+        Isp_Az(ispnew_q, Aq, M, 0);
+
+        for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+        {
+            corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st);
+        }
+        Copy(isf, st->isfold, M);
+
+
+        /* reset speech coder memories */
+        Reset_encoder(st, 0);
+
+        /*--------------------------------------------------*
+         * Update signal for next frame.                    *
+         * -> save past of speech[] and wsp[].              *
+         *--------------------------------------------------*/
+
+        Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
+        Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
+
+        return;
+    }
+    /*----------------------------------------------------------------------*
+     *                               ACELP                                  *
+     *----------------------------------------------------------------------*/
+
+    /* Quantize and code the ISFs */
+
+    test();
+    if (sub(*ser_size, NBBITS_7k) <= 0)
+    {
+        Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4);
+
+        Parm_serial(indice[0], 8, &prms);
+        Parm_serial(indice[1], 8, &prms);
+        Parm_serial(indice[2], 7, &prms);
+        Parm_serial(indice[3], 7, &prms);
+        Parm_serial(indice[4], 6, &prms);
+    } else
+    {
+        Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4);
+
+        Parm_serial(indice[0], 8, &prms);
+        Parm_serial(indice[1], 8, &prms);
+        Parm_serial(indice[2], 6, &prms);
+        Parm_serial(indice[3], 7, &prms);
+        Parm_serial(indice[4], 7, &prms);
+        Parm_serial(indice[5], 5, &prms);
+        Parm_serial(indice[6], 5, &prms);
+    }
+
+    /* Check stability on isf : distance between old isf and current isf */
+
+    L_tmp = 0;                             move32();
+    for (i = 0; i < M - 1; i++)
+    {
+        tmp = sub(isf[i], st->isfold[i]);
+        L_tmp = L_mac(L_tmp, tmp, tmp);
+    }
+
+    tmp = extract_h(L_shl(L_tmp, 8));      /* saturation can occur here */
+
+    tmp = mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */
+    tmp = sub(20480, tmp);                 /* 1.25 - tmp (in Q14) */
+
+    stab_fac = shl(tmp, 1);                /* saturation can occur here */
+
+    test();
+    if (stab_fac < 0)
+    {
+        stab_fac = 0;                      move16();
+    }
+    Copy(isf, st->isfold, M);
+
+    /* Convert ISFs to the cosine domain */
+    Isf_isp(isf, ispnew_q, M);
+
+    test();
+    if (st->first_frame != 0)
+    {
+        st->first_frame = 0;               move16();
+        Copy(ispnew_q, st->ispold_q, M);
+    }
+    /* Find the interpolated ISPs and convert to a[] for all subframes */
+
+    Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq);
+
+    /* update ispold[] for the next frame */
+    Copy(ispnew_q, st->ispold_q, M);
+
+    p_Aq = Aq;
+    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+    {
+        Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+        p_Aq += (M + 1);                   move16();
+    }
+
+    /* Buffer isf's and energy for dtx on non-speech frame */
+
+    test();
+    if (vad_flag == 0)
+    {
+        for (i = 0; i < L_FRAME; i++)
+        {
+            exc2[i] = shr(exc[i], Q_new);  move16();
+        }
+        L_tmp = 0;                         move32();
+        for (i = 0; i < L_FRAME; i++)
+            L_tmp = L_mac(L_tmp, exc2[i], exc2[i]);
+        L_tmp = L_shr(L_tmp, 1);
+
+        dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
+    }
+    /* range for closed loop pitch search in 1st subframe */
+
+    T0_min = sub(T_op, 8);
+    test();
+    if (sub(T0_min, PIT_MIN) < 0)
+    {
+        T0_min = PIT_MIN;                  move16();
+    }
+    T0_max = add(T0_min, 15);
+    test();
+    if (sub(T0_max, PIT_MAX) > 0)
+    {
+        T0_max = PIT_MAX;                  move16();
+        T0_min = sub(T0_max, 15);          move16();
+    }
+    /*------------------------------------------------------------------------*
+     *          Loop for every subframe in the analysis frame                 *
+     *------------------------------------------------------------------------*
+     *  To find the pitch and innovation parameters. The subframe size is     *
+     *  L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times.               *
+     *     - compute the target signal for pitch search                       *
+     *     - compute impulse response of weighted synthesis filter (h1[])     *
+     *     - find the closed-loop pitch parameters                            *
+     *     - encode the pitch dealy                                           *
+     *     - find 2 lt prediction (with / without LP filter for lt pred)      *
+     *     - find 2 pitch gains and choose the best lt prediction.            *
+     *     - find target vector for codebook search                           *
+     *     - update the impulse response h1[] for codebook search             *
+     *     - correlation between target vector and impulse response           *
+     *     - codebook search and encoding                                     *
+     *     - VQ of pitch and codebook gains                                   *
+     *     - find voicing factor and tilt of code for next subframe.          *
+     *     - update states of weighting filter                                *
+     *     - find excitation and synthesis speech                             *
+     *------------------------------------------------------------------------*/
+
+    p_A = A;                               move16();
+    p_Aq = Aq;                             move16();
+
+    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+    {
+        pit_flag = i_subfr;                move16();
+        test();test();
+        if ((sub(i_subfr, 2 * L_SUBFR) == 0) && (sub(*ser_size, NBBITS_7k) > 0))
+        {
+            pit_flag = 0;                  move16();
+
+            /* range for closed loop pitch search in 3rd subframe */
+
+            T0_min = sub(T_op2, 8);
+            test();
+            if (sub(T0_min, PIT_MIN) < 0)
+            {
+                T0_min = PIT_MIN;          move16();
+            }
+            T0_max = add(T0_min, 15);
+            test();
+            if (sub(T0_max, PIT_MAX) > 0)
+            {
+                T0_max = PIT_MAX;          move16();
+                T0_min = sub(T0_max, 15);
+            }
+        }
+        /*-----------------------------------------------------------------------*
+         *                                                                       *
+         *        Find the target vector for pitch search:                       *
+         *        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                        *
+         *                                                                       *
+         *             |------|  res[n]                                          *
+         * speech[n]---| A(z) |--------                                          *
+         *             |------|       |   |--------| error[n]  |------|          *
+         *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
+         *                   exc          |--------|           |------|          *
+         *                                                                       *
+         * Instead of subtracting the zero-input response of filters from        *
+         * the weighted input speech, the above configuration is used to         *
+         * compute the target vector.                                            *
+         *                                                                       *
+         *-----------------------------------------------------------------------*/
+
+        for (i = 0; i < M; i++)
+        {
+            error[i] = sub(speech[i + i_subfr - M], st->mem_syn[i]);    move16();
+        }
+        Residu(p_Aq, M, &speech[i_subfr], &exc[i_subfr], L_SUBFR);
+
+        Syn_filt(p_Aq, M, &exc[i_subfr], error + M, L_SUBFR, error, 0);
+
+        Weight_a(p_A, Ap, GAMMA1, M);
+        Residu(Ap, M, error + M, xn, L_SUBFR);
+
+        Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0));
+
+        /*----------------------------------------------------------------------*
+         * Find approx. target in residual domain "cn[]" for inovation search.  *
+         *----------------------------------------------------------------------*/
+
+        /* first half: xn[] --> cn[] */
+        Set_zero(code, M);
+        Copy(xn, code + M, L_SUBFR / 2);
+        tmp = 0;                           move16();
+        Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp);
+        Weight_a(p_A, Ap, GAMMA1, M);
+        Syn_filt(Ap, M, code + M, code + M, L_SUBFR / 2, code, 0);
+        Residu(p_Aq, M, code + M, cn, L_SUBFR / 2);
+
+        /* second half: res[] --> cn[] (approximated and faster) */
+        Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2);
+
+        /*---------------------------------------------------------------*
+         * Compute impulse response, h1[], of weighted synthesis filter  *
+         *---------------------------------------------------------------*/
+
+        Set_zero(error, M + L_SUBFR);
+        Weight_a(p_A, error + M, GAMMA1, M);
+
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            L_tmp = L_mult(error[i + M], 16384);        /* x4 (Q12 to Q14) */
+            for (j = 1; j <= M; j++)
+                L_tmp = L_msu(L_tmp, p_Aq[j], error[i + M - j]);
+
+            h1[i] = error[i + M] = round(L_shl(L_tmp, 3));      move16();move16();
+        }
+        /* deemph without division by 2 -> Q14 to Q15 */
+        tmp = 0;                           move16();
+        Deemph2(h1, TILT_FAC, L_SUBFR, &tmp);   /* h1 in Q14 */
+
+        /* h2 in Q12 for codebook search */
+        Copy(h1, h2, L_SUBFR);
+        Scale_sig(h2, L_SUBFR, -2);
+
+        /*---------------------------------------------------------------*
+         * scale xn[] and h1[] to avoid overflow in dot_product12()      *
+         *---------------------------------------------------------------*/
+
+        Scale_sig(xn, L_SUBFR, shift);     /* scaling of xn[] to limit dynamic at 12 bits */
+        Scale_sig(h1, L_SUBFR, add(1, shift));  /* set h1[] in Q15 with scaling for convolution */
+
+        /*----------------------------------------------------------------------*
+         *                 Closed-loop fractional pitch search                  *
+         *----------------------------------------------------------------------*/
+
+        /* find closed loop fractional pitch  lag */
+
+        test();
+        if (sub(*ser_size, NBBITS_9k) <= 0)
+        {
+            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
+                pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR);
+
+            /* encode pitch lag */
+
+            test();
+            if (pit_flag == 0)             /* if 1st/3rd subframe */
+            {
+                /*--------------------------------------------------------------*
+                 * The pitch range for the 1st/3rd subframe is encoded with     *
+                 * 8 bits and is divided as follows:                            *
+                 *   PIT_MIN to PIT_FR1-1  resolution 1/2 (frac = 0 or 2)       *
+                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
+                 *--------------------------------------------------------------*/
+
+                test();
+                if (sub(T0, PIT_FR1_8b) < 0)
+                {
+                    index = sub(add(shl(T0, 1), shr(T0_frac, 1)), (PIT_MIN * 2));
+                } else
+                {
+                    index = add(sub(T0, PIT_FR1_8b), ((PIT_FR1_8b - PIT_MIN) * 2));
+                }
+
+                Parm_serial(index, 8, &prms);
+
+                /* find T0_min and T0_max for subframe 2 and 4 */
+
+                T0_min = sub(T0, 8);
+                test();
+                if (sub(T0_min, PIT_MIN) < 0)
+                {
+                    T0_min = PIT_MIN;      move16();
+                }
+                T0_max = add(T0_min, 15);
+                test();
+                if (sub(T0_max, PIT_MAX) > 0)
+                {
+                    T0_max = PIT_MAX;      move16();
+                    T0_min = sub(T0_max, 15);
+                }
+            } else
+            {                              /* if subframe 2 or 4 */
+                /*--------------------------------------------------------------*
+                 * The pitch range for subframe 2 or 4 is encoded with 5 bits:  *
+                 *   T0_min  to T0_max     resolution 1/2 (frac = 0 or 2)       *
+                 *--------------------------------------------------------------*/
+
+                i = sub(T0, T0_min);
+                index = add(shl(i, 1), shr(T0_frac, 1));
+
+                Parm_serial(index, 5, &prms);
+            }
+        } else
+        {
+            T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac,
+                pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR);
+
+            /* encode pitch lag */
+
+            test();
+            if (pit_flag == 0)             /* if 1st/3rd subframe */
+            {
+                /*--------------------------------------------------------------*
+                 * The pitch range for the 1st/3rd subframe is encoded with     *
+                 * 9 bits and is divided as follows:                            *
+                 *   PIT_MIN to PIT_FR2-1  resolution 1/4 (frac = 0,1,2 or 3)   *
+                 *   PIT_FR2 to PIT_FR1-1  resolution 1/2 (frac = 0 or 1)       *
+                 *   PIT_FR1 to PIT_MAX    resolution 1   (frac = 0)            *
+                 *--------------------------------------------------------------*/
+
+                test();test();
+                if (sub(T0, PIT_FR2) < 0)
+                {
+                    index = sub(add(shl(T0, 2), T0_frac), (PIT_MIN * 4));
+                } else if (sub(T0, PIT_FR1_9b) < 0)
+                {
+                    index = add(sub(add(shl(T0, 1), shr(T0_frac, 1)), (PIT_FR2 * 2)), ((PIT_FR2 - PIT_MIN) * 4));
+                } else
+                {
+                    index = add(add(sub(T0, PIT_FR1_9b), ((PIT_FR2 - PIT_MIN) * 4)), ((PIT_FR1_9b - PIT_FR2) * 2));
+                }
+
+                Parm_serial(index, 9, &prms);
+
+                /* find T0_min and T0_max for subframe 2 and 4 */
+
+                T0_min = sub(T0, 8);
+                test();
+                if (sub(T0_min, PIT_MIN) < 0)
+                {
+                    T0_min = PIT_MIN;      move16();
+                }
+                T0_max = add(T0_min, 15);
+                test();
+                if (sub(T0_max, PIT_MAX) > 0)
+                {
+                    T0_max = PIT_MAX;      move16();
+                    T0_min = sub(T0_max, 15);
+                }
+            } else
+            {                              /* if subframe 2 or 4 */
+                /*--------------------------------------------------------------*
+                 * The pitch range for subframe 2 or 4 is encoded with 6 bits:  *
+                 *   T0_min  to T0_max     resolution 1/4 (frac = 0,1,2 or 3)   *
+                 *--------------------------------------------------------------*/
+
+                i = sub(T0, T0_min);
+                index = add(shl(i, 2), T0_frac);
+
+                Parm_serial(index, 6, &prms);
+            }
+        }
+
+        /*-----------------------------------------------------------------*
+         * Gain clipping test to avoid unstable synthesis on frame erasure *
+         *-----------------------------------------------------------------*/
+
+        clip_gain = Gp_clip(st->gp_clip);
+
+        /*-----------------------------------------------------------------*
+         * - find unity gain pitch excitation (adaptive codebook entry)    *
+         *   with fractional interpolation.                                *
+         * - find filtered pitch exc. y1[]=exc[] convolved with h1[])      *
+         * - compute pitch gain1                                           *
+         *-----------------------------------------------------------------*/
+
+        /* find pitch exitation */
+
+        Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
+        test();
+        if (sub(*ser_size, NBBITS_9k) > 0)
+        {
+            Convolve(&exc[i_subfr], h1, y1, L_SUBFR);
+            gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR);
+
+            /* clip gain if necessary to avoid problem at decoder */
+            test();test();
+            if ((clip_gain != 0) && (sub(gain1, GP_CLIP) > 0))
+            {
+                gain1 = GP_CLIP;           move16();
+            }
+            /* find energy of new target xn2[] */
+            Updt_tar(xn, dn, y1, gain1, L_SUBFR);       /* dn used temporary */
+        } else
+        {
+            gain1 = 0;                     move16();
+        }
+
+        /*-----------------------------------------------------------------*
+         * - find pitch excitation filtered by 1st order LP filter.        *
+         * - find filtered pitch exc. y2[]=exc[] convolved with h1[])      *
+         * - compute pitch gain2                                           *
+         *-----------------------------------------------------------------*/
+
+        /* find pitch excitation with lp filter */
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            L_tmp = L_mult(5898, exc[i - 1 + i_subfr]);
+            L_tmp = L_mac(L_tmp, 20972, exc[i + i_subfr]);
+            L_tmp = L_mac(L_tmp, 5898, exc[i + 1 + i_subfr]);
+            code[i] = round(L_tmp);        move16();
+        }
+
+        Convolve(code, h1, y2, L_SUBFR);
+        gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR);
+
+        /* clip gain if necessary to avoid problem at decoder */
+        test();test();
+        if ((clip_gain != 0) && (sub(gain2, GP_CLIP) > 0))
+        {
+            gain2 = GP_CLIP;               move16();
+        }
+        /* find energy of new target xn2[] */
+        Updt_tar(xn, xn2, y2, gain2, L_SUBFR);
+
+        /*-----------------------------------------------------------------*
+         * use the best prediction (minimise quadratic error).             *
+         *-----------------------------------------------------------------*/
+
+        select = 0;                        move16();
+        test();
+        if (sub(*ser_size, NBBITS_9k) > 0)
+        {
+            L_tmp = 0L;                    move32();
+            for (i = 0; i < L_SUBFR; i++)
+                L_tmp = L_mac(L_tmp, dn[i], dn[i]);
+            for (i = 0; i < L_SUBFR; i++)
+                L_tmp = L_msu(L_tmp, xn2[i], xn2[i]);
+
+            test();
+            if (L_tmp <= 0)
+            {
+                select = 1;                move16();
+            }
+            Parm_serial(select, 1, &prms);
+        }
+        test();
+        if (select == 0)
+        {
+            /* use the lp filter for pitch excitation prediction */
+            gain_pit = gain2;              move16();
+            Copy(code, &exc[i_subfr], L_SUBFR);
+            Copy(y2, y1, L_SUBFR);
+            Copy(g_coeff2, g_coeff, 4);
+        } else
+        {
+            /* no filter used for pitch excitation prediction */
+            gain_pit = gain1;              move16();
+            Copy(dn, xn2, L_SUBFR);        /* target vector for codebook search */
+        }
+
+        /*-----------------------------------------------------------------*
+         * - update cn[] for codebook search                               *
+         *-----------------------------------------------------------------*/
+
+        Updt_tar(cn, cn, &exc[i_subfr], gain_pit, L_SUBFR);
+
+        Scale_sig(cn, L_SUBFR, shift);     /* scaling of cn[] to limit dynamic at 12 bits */
+
+        /*-----------------------------------------------------------------*
+         * - include fixed-gain pitch contribution into impulse resp. h1[] *
+         *-----------------------------------------------------------------*/
+
+        tmp = 0;                           move16();
+        Preemph(h2, st->tilt_code, L_SUBFR, &tmp);
+
+        test();
+        if (T0_frac > 2)
+            T0 = add(T0, 1);
+        Pit_shrp(h2, T0, PIT_SHARP, L_SUBFR);
+
+        /*-----------------------------------------------------------------*
+         * - Correlation between target xn2[] and impulse response h1[]    *
+         * - Innovative codebook search                                    *
+         *-----------------------------------------------------------------*/
+
+        cor_h_x(h2, xn2, dn);
+
+        test();test();test();test();test();test();test();
+        if (sub(*ser_size, NBBITS_7k) <= 0)
+        {
+            ACELP_2t64_fx(dn, cn, h2, code, y2, indice);
+
+            Parm_serial(indice[0], 12, &prms);
+        } else if (sub(*ser_size, NBBITS_9k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 20, *ser_size, indice);
+
+            Parm_serial(indice[0], 5, &prms);
+            Parm_serial(indice[1], 5, &prms);
+            Parm_serial(indice[2], 5, &prms);
+            Parm_serial(indice[3], 5, &prms);
+        } else if (sub(*ser_size, NBBITS_12k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 36, *ser_size, indice);
+
+            Parm_serial(indice[0], 9, &prms);
+            Parm_serial(indice[1], 9, &prms);
+            Parm_serial(indice[2], 9, &prms);
+            Parm_serial(indice[3], 9, &prms);
+        } else if (sub(*ser_size, NBBITS_14k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 44, *ser_size, indice);
+
+            Parm_serial(indice[0], 13, &prms);
+            Parm_serial(indice[1], 13, &prms);
+            Parm_serial(indice[2], 9, &prms);
+            Parm_serial(indice[3], 9, &prms);
+        } else if (sub(*ser_size, NBBITS_16k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 52, *ser_size, indice);
+
+            Parm_serial(indice[0], 13, &prms);
+            Parm_serial(indice[1], 13, &prms);
+            Parm_serial(indice[2], 13, &prms);
+            Parm_serial(indice[3], 13, &prms);
+        } else if (sub(*ser_size, NBBITS_18k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 64, *ser_size, indice);
+
+            Parm_serial(indice[0], 2, &prms);
+            Parm_serial(indice[1], 2, &prms);
+            Parm_serial(indice[2], 2, &prms);
+            Parm_serial(indice[3], 2, &prms);
+            Parm_serial(indice[4], 14, &prms);
+            Parm_serial(indice[5], 14, &prms);
+            Parm_serial(indice[6], 14, &prms);
+            Parm_serial(indice[7], 14, &prms);
+        } else if (sub(*ser_size, NBBITS_20k) <= 0)
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 72, *ser_size, indice);
+
+            Parm_serial(indice[0], 10, &prms);
+            Parm_serial(indice[1], 10, &prms);
+            Parm_serial(indice[2], 2, &prms);
+            Parm_serial(indice[3], 2, &prms);
+            Parm_serial(indice[4], 10, &prms);
+            Parm_serial(indice[5], 10, &prms);
+            Parm_serial(indice[6], 14, &prms);
+            Parm_serial(indice[7], 14, &prms);
+        } else
+        {
+            ACELP_4t64_fx(dn, cn, h2, code, y2, 88, *ser_size, indice);
+
+            Parm_serial(indice[0], 11, &prms);
+            Parm_serial(indice[1], 11, &prms);
+            Parm_serial(indice[2], 11, &prms);
+            Parm_serial(indice[3], 11, &prms);
+            Parm_serial(indice[4], 11, &prms);
+            Parm_serial(indice[5], 11, &prms);
+            Parm_serial(indice[6], 11, &prms);
+            Parm_serial(indice[7], 11, &prms);
+        }
+
+        /*-------------------------------------------------------*
+         * - Add the fixed-gain pitch contribution to code[].    *
+         *-------------------------------------------------------*/
+
+        tmp = 0;                           move16();
+        Preemph(code, st->tilt_code, L_SUBFR, &tmp);
+
+        Pit_shrp(code, T0, PIT_SHARP, L_SUBFR);
+
+        /*----------------------------------------------------------*
+         *  - Compute the fixed codebook gain                       *
+         *  - quantize fixed codebook gain                          *
+         *----------------------------------------------------------*/
+
+        test();
+        if (sub(*ser_size, NBBITS_9k) <= 0)
+        {
+            index = Q_gain2(xn, y1, add(Q_new, shift), y2, code, g_coeff, L_SUBFR, 6,
+                &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
+            Parm_serial(index, 6, &prms);
+        } else
+        {
+            index = Q_gain2(xn, y1, add(Q_new, shift), y2, code, g_coeff, L_SUBFR, 7,
+                &gain_pit, &L_gain_code, clip_gain, st->qua_gain);
+            Parm_serial(index, 7, &prms);
+        }
+
+        /* test quantized gain of pitch for pitch clipping algorithm */
+        Gp_clip_test_gain_pit(gain_pit, st->gp_clip);
+
+        L_tmp = L_shl(L_gain_code, Q_new); /* saturation can occur here */
+        gain_code = round(L_tmp);          /* scaled gain_code with Qnew */
+
+        /*----------------------------------------------------------*
+         * Update parameters for the next subframe.                 *
+         * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)           *
+         *----------------------------------------------------------*/
+
+        /* find voice factor in Q15 (1=voiced, -1=unvoiced) */
+
+        Copy(&exc[i_subfr], exc2, L_SUBFR);
+        Scale_sig(exc2, L_SUBFR, shift);
+
+        voice_fac = voice_factor(exc2, shift, gain_pit, code, gain_code, L_SUBFR);
+
+        /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
+
+        st->tilt_code = add(shr(voice_fac, 2), 8192);   move16();
+
+        /*------------------------------------------------------*
+         * - Update filter's memory "mem_w0" for finding the    *
+         *   target vector in the next subframe.                *
+         * - Find the total excitation                          *
+         * - Find synthesis speech to update mem_syn[].         *
+         *------------------------------------------------------*/
+
+        /* y2 in Q9, gain_pit in Q14 */
+        L_tmp = L_mult(gain_code, y2[L_SUBFR - 1]);
+        L_tmp = L_shl(L_tmp, add(5, shift));
+        L_tmp = L_negate(L_tmp);
+        L_tmp = L_mac(L_tmp, xn[L_SUBFR - 1], 16384);
+        L_tmp = L_msu(L_tmp, y1[L_SUBFR - 1], gain_pit);
+        L_tmp = L_shl(L_tmp, sub(1, shift));
+        st->mem_w0 = round(L_tmp);         move16();
+
+        if (sub(*ser_size, NBBITS_24k) >= 0)
+            Copy(&exc[i_subfr], exc2, L_SUBFR);
+
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            /* code in Q9, gain_pit in Q14 */
+            L_tmp = L_mult(gain_code, code[i]);
+            L_tmp = L_shl(L_tmp, 5);
+            L_tmp = L_mac(L_tmp, exc[i + i_subfr], gain_pit);
+            L_tmp = L_shl(L_tmp, 1);       /* saturation can occur here */
+            exc[i + i_subfr] = round(L_tmp);    move16();
+        }
+
+        Syn_filt(p_Aq, M, &exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1);
+
+        if (sub(*ser_size, NBBITS_24k) >= 0)
+        {
+            /*------------------------------------------------------------*
+             * phase dispersion to enhance noise in low bit rate          *
+             *------------------------------------------------------------*/
+
+            /* L_gain_code in Q16 */
+            L_Extract(L_gain_code, &gain_code, &gain_code_lo);
+
+            /*------------------------------------------------------------*
+             * noise enhancer                                             *
+             * ~~~~~~~~~~~~~~                                             *
+             * - Enhance excitation on noise. (modify gain of code)       *
+             *   If signal is noisy and LPC filter is stable, move gain   *
+             *   of code 1.5 dB toward gain of code threshold.            *
+             *   This decrease by 3 dB noise energy variation.            *
+             *------------------------------------------------------------*/
+
+            tmp = sub(16384, shr(voice_fac, 1));        /* 1=unvoiced, 0=voiced */
+            fac = mult(stab_fac, tmp);
+
+            L_tmp = L_gain_code;           move32();
+            test();
+            if (L_sub(L_tmp, st->L_gc_thres) < 0)
+            {
+                L_tmp = L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
+                test();
+                if (L_sub(L_tmp, st->L_gc_thres) > 0)
+                {
+                    L_tmp = st->L_gc_thres;move32();
+                }
+            } else
+            {
+                L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
+                test();
+                if (L_sub(L_tmp, st->L_gc_thres) < 0)
+                {
+                    L_tmp = st->L_gc_thres;move32();
+                }
+            }
+            st->L_gc_thres = L_tmp;        move32();
+
+            L_gain_code = Mpy_32_16(gain_code, gain_code_lo, sub(32767, fac));
+            L_Extract(L_tmp, &gain_code, &gain_code_lo);
+            L_gain_code = L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
+
+            /*------------------------------------------------------------*
+             * pitch enhancer                                             *
+             * ~~~~~~~~~~~~~~                                             *
+             * - Enhance excitation on voice. (HP filtering of code)      *
+             *   On voiced signal, filtering of code by a smooth fir HP   *
+             *   filter to decrease energy of code in low frequency.      *
+             *------------------------------------------------------------*/
+
+            tmp = add(shr(voice_fac, 3), 4096); /* 0.25=voiced, 0=unvoiced */
+
+            L_tmp = L_deposit_h(code[0]);
+            L_tmp = L_msu(L_tmp, code[1], tmp);
+            code2[0] = round(L_tmp);       move16();
+
+            for (i = 1; i < L_SUBFR - 1; i++)
+            {
+                L_tmp = L_deposit_h(code[i]);
+                L_tmp = L_msu(L_tmp, code[i + 1], tmp);
+                L_tmp = L_msu(L_tmp, code[i - 1], tmp);
+                code2[i] = round(L_tmp);   move16();
+            }
+
+            L_tmp = L_deposit_h(code[L_SUBFR - 1]);
+            L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);
+            code2[L_SUBFR - 1] = round(L_tmp);  move16();
+
+            /* build excitation */
+
+            gain_code = round(L_shl(L_gain_code, Q_new));
+
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                L_tmp = L_mult(code2[i], gain_code);
+                L_tmp = L_shl(L_tmp, 5);
+                L_tmp = L_mac(L_tmp, exc2[i], gain_pit);
+                L_tmp = L_shl(L_tmp, 1);   /* saturation can occur here */
+                exc2[i] = round(L_tmp);    move16();
+            }
+
+            corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
+            Parm_serial(corr_gain, 4, &prms);
+        }
+        p_A += (M + 1);
+        move16();
+        p_Aq += (M + 1);
+        move16();
+
+    }                                      /* end of subframe loop */
+
+    /*--------------------------------------------------*
+     * Update signal for next frame.                    *
+     * -> save past of speech[], wsp[] and exc[].       *
+     *--------------------------------------------------*/
+
+    Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME);
+    Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM);
+    Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
+
+    return;
+}
+
+/*-----------------------------------------------------*
+ * Function synthesis()                                *
+ *                                                     *
+ * Synthesis of signal at 16kHz with HF extension.     *
+ *                                                     *
+ *-----------------------------------------------------*/
+
+static Word16 synthesis(
+     Word16 Aq[],                          /* A(z)  : quantized Az               */
+     Word16 exc[],                         /* (i)   : excitation at 12kHz        */
+     Word16 Q_new,                         /* (i)   : scaling performed on exc   */
+     Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
+     Coder_State * st                      /* (i/o) : State structure            */
+)
+{
+    Word16 i, fac, tmp, exp;
+    Word16 ener, exp_ener;
+    Word32 L_tmp;
+
+    Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
+    Word16 synth[L_SUBFR];
+    Word16 HF[L_SUBFR16k];                 /* High Frequency vector      */
+    Word16 Ap[M + 1];
+
+    Word16 HF_SP[L_SUBFR16k];              /* High Frequency vector (from original signal) */
+
+    Word16 HP_est_gain, HP_calc_gain, HP_corr_gain;
+    Word16 dist_min, dist;
+    Word16 HP_gain_ind = 0;
+    Word16 gain1, gain2;
+    Word16 weight1, weight2;
+
+    /*------------------------------------------------------------*
+     * speech synthesis                                           *
+     * ~~~~~~~~~~~~~~~~                                           *
+     * - Find synthesis speech corresponding to exc2[].           *
+     * - Perform fixed deemphasis and hp 50hz filtering.          *
+     * - Oversampling from 12.8kHz to 16kHz.                      *
+     *------------------------------------------------------------*/
+
+
+    Copy(st->mem_syn_hi, synth_hi, M);
+    Copy(st->mem_syn_lo, synth_lo, M);
+
+    Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
+
+    Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
+    Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
+
+    Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
+
+    HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
+
+    /* Original speech signal as reference for high band gain quantisation */
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        HF_SP[i] = synth16k[i];            move16();
+    }
+
+    /*------------------------------------------------------*
+     * HF noise synthesis                                   *
+     * ~~~~~~~~~~~~~~~~~~                                   *
+     * - Generate HF noise between 5.5 and 7.5 kHz.         *
+     * - Set energy of noise according to synthesis tilt.   *
+     *     tilt > 0.8 ==> - 14 dB (voiced)                  *
+     *     tilt   0.5 ==> - 6 dB  (voiced or noise)         *
+     *     tilt < 0.0 ==>   0 dB  (noise)                   *
+     *------------------------------------------------------*/
+
+    /* generate white noise vector */
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        HF[i] = shr(Random(&(st->seed2)), 3);   move16();
+    }
+
+    /* energy of excitation */
+
+    Scale_sig(exc, L_SUBFR, -3);
+    Q_new = sub(Q_new, 3);
+
+    ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
+    exp_ener = sub(exp_ener, add(Q_new, Q_new));
+
+    /* set energy of white noise to energy of excitation */
+
+    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
+
+    test();
+    if (sub(tmp, ener) > 0)
+    {
+        tmp = shr(tmp, 1);                 /* Be sure tmp < ener */
+        exp = add(exp, 1);
+    }
+    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
+    exp = sub(exp, exp_ener);
+    Isqrt_n(&L_tmp, &exp);
+    L_tmp = L_shl(L_tmp, add(exp, 1));     /* L_tmp x 2, L_tmp in Q31 */
+    tmp = extract_h(L_tmp);                /* tmp = 2 x sqrt(ener_exc/ener_hf) */
+
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        HF[i] = mult(HF[i], tmp);          move16();
+    }
+
+    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
+
+    HP400_12k8(synth, L_SUBFR, st->mem_hp400);
+
+    L_tmp = 1L;                            move32();
+    for (i = 0; i < L_SUBFR; i++)
+        L_tmp = L_mac(L_tmp, synth[i], synth[i]);
+
+    exp = norm_l(L_tmp);
+    ener = extract_h(L_shl(L_tmp, exp));   /* ener = r[0] */
+
+    L_tmp = 1L;                            move32();
+    for (i = 1; i < L_SUBFR; i++)
+        L_tmp = L_mac(L_tmp, synth[i], synth[i - 1]);
+
+    tmp = extract_h(L_shl(L_tmp, exp));    /* tmp = r[1] */
+
+    test();
+    if (tmp > 0)
+    {
+        fac = div_s(tmp, ener);
+    } else
+    {
+        fac = 0;                           move16();
+    }
+
+
+    /* modify energy of white noise according to synthesis tilt */
+    gain1 = sub(32767, fac);
+    gain2 = mult(sub(32767, fac), 20480);
+    gain2 = shl(gain2, 1);
+
+    test();
+    if (st->vad_hist > 0)
+    {
+        weight1 = 0;
+        weight2 = 32767;
+    } else
+    {
+        weight1 = 32767;
+        weight2 = 0;
+    }
+    tmp = mult(weight1, gain1);
+    tmp = add(tmp, mult(weight2, gain2));
+
+    test();
+    if (tmp != 0)
+    {
+        tmp = add(tmp, 1);
+    }
+    HP_est_gain = tmp;
+
+    test();
+    if (sub(HP_est_gain, 3277) < 0)
+    {
+        HP_est_gain = 3277;                /* 0.1 in Q15 */
+        move16();
+    }
+    /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
+    Weight_a(Aq, Ap, 19661, M);            /* fac=0.6 */
+    Syn_filt(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
+
+    /* noise High Pass filtering (1ms of delay) */
+    Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
+
+    /* filtering of the original signal */
+    Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2);
+
+    /* check the gain difference */
+    Scale_sig(HF_SP, L_SUBFR16k, -1);
+
+    ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener));
+
+    /* set energy of white noise to energy of excitation */
+    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
+
+    test();
+    if (sub(tmp, ener) > 0)
+    {
+        tmp = shr(tmp, 1);                 /* Be sure tmp < ener */
+        exp = add(exp, 1);
+    }
+    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
+    exp = sub(exp, exp_ener);
+    Isqrt_n(&L_tmp, &exp);
+    L_tmp = L_shl(L_tmp, exp);             /* L_tmp, L_tmp in Q31 */
+    HP_calc_gain = extract_h(L_tmp);       /* tmp = sqrt(ener_input/ener_hf) */
+
+    /* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */
+    L_tmp = L_shl(L_mult(st->dtx_encSt->dtxHangoverCount, 4681), 15);
+    st->gain_alpha = mult(st->gain_alpha, extract_h(L_tmp));
+
+    test();
+    if (sub(st->dtx_encSt->dtxHangoverCount, 6) > 0)
+        st->gain_alpha = 32767;
+    HP_est_gain = shr(HP_est_gain, 1);     /* From Q15 to Q14 */
+    HP_corr_gain = add(mult(HP_calc_gain, st->gain_alpha), mult(sub(32767, st->gain_alpha), HP_est_gain));
+
+    /* Quantise the correction gain */
+    dist_min = 32767;
+    for (i = 0; i < 16; i++)
+    {
+        dist = mult(sub(HP_corr_gain, HP_gain[i]), sub(HP_corr_gain, HP_gain[i]));
+        test();
+        if (dist_min > dist)
+        {
+            dist_min = dist;
+            HP_gain_ind = i;
+        }
+    }
+
+    HP_corr_gain = HP_gain[HP_gain_ind];
+
+    /* return the quantised gain index when using the highest mode, otherwise zero */
+    return (HP_gain_ind);
+
+}
--- /dev/null
+++ b/amr-wb/cod_main.h
@@ -1,0 +1,63 @@
+/*--------------------------------------------------------------------------*
+ *                         COD_MAIN.H                                       *
+ *--------------------------------------------------------------------------*
+ *       Static memory in the encoder                                       *
+ *--------------------------------------------------------------------------*/
+
+#include "cnst.h"                          /* coder constant parameters */
+
+#include "wb_vad.h"
+#include "dtx.h"
+
+typedef struct
+{
+    Word16 mem_decim[2 * L_FILT16k];       /* speech decimated filter memory */
+    Word16 mem_sig_in[6];                  /* hp50 filter memory */
+    Word16 mem_preemph;                    /* speech preemph filter memory */
+    Word16 old_speech[L_TOTAL - L_FRAME];  /* old speech vector at 12.8kHz */
+    Word16 old_wsp[PIT_MAX / OPL_DECIM];   /* old decimated weighted speech vector */
+    Word16 old_exc[PIT_MAX + L_INTERPOL];  /* old excitation vector */
+    Word16 mem_levinson[M + 2];            /* levinson routine memory */
+    Word16 ispold[M];                      /* old isp (immittance spectral pairs) */
+    Word16 ispold_q[M];                    /* quantized old isp */
+    Word16 past_isfq[M];                   /* past isf quantizer */
+    Word16 mem_wsp;                        /* wsp vector memory */
+    Word16 mem_decim2[3];                  /* wsp decimation filter memory */
+    Word16 mem_w0;                         /* target vector memory */
+    Word16 mem_syn[M];                     /* synthesis memory */
+    Word16 tilt_code;                      /* tilt of code */
+    Word16 old_wsp_max;                    /* old wsp maximum value */
+    Word16 old_wsp_shift;                  /* old wsp shift */
+    Word16 Q_old;                          /* old scaling factor */
+    Word16 Q_max[2];                       /* old maximum scaling factor */
+    Word16 gp_clip[2];                     /* gain of pitch clipping memory */
+    Word16 qua_gain[4];                    /* gain quantizer memory */
+
+    Word16 old_T0_med;
+    Word16 ol_gain;
+    Word16 ada_w;
+    Word16 ol_wght_flg;
+    Word16 old_ol_lag[5];
+    Word16 hp_wsp_mem[9];
+    Word16 old_hp_wsp[L_FRAME / OPL_DECIM + (PIT_MAX / OPL_DECIM)];
+    VadVars *vadSt;
+    dtx_encState *dtx_encSt;
+    Word16 first_frame;
+
+    Word16 isfold[M];                      /* old isf (frequency domain) */
+    Word32 L_gc_thres;                     /* threshold for noise enhancer */
+    Word16 mem_syn_hi[M];                  /* modified synthesis memory (MSB) */
+    Word16 mem_syn_lo[M];                  /* modified synthesis memory (LSB) */
+    Word16 mem_deemph;                     /* speech deemph filter memory */
+    Word16 mem_sig_out[6];                 /* hp50 filter memory for synthesis */
+    Word16 mem_hp400[6];                   /* hp400 filter memory for synthesis */
+    Word16 mem_oversamp[2 * L_FILT];       /* synthesis oversampled filter memory */
+    Word16 mem_syn_hf[M];                  /* HF synthesis memory */
+    Word16 mem_hf[2 * L_FILT16k];          /* HF band-pass filter memory */
+    Word16 mem_hf2[2 * L_FILT16k];         /* HF band-pass filter memory */
+    Word16 seed2;                          /* random memory for HF generation */
+    Word16 vad_hist;
+
+    Word16 gain_alpha;
+
+} Coder_State;
--- /dev/null
+++ b/amr-wb/convolve.c
@@ -1,0 +1,33 @@
+/*------------------------------------------------------------------------*
+ *                         CONVOLVE.C                                     *
+ *------------------------------------------------------------------------*
+ * Perform the convolution between two vectors x[] and h[] and            *
+ * write the result in the vector y[].                                    *
+ * All vectors are of length L.                                           *
+ *------------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+void Convolve(
+     Word16 x[],                           /* (i)        : input vector                           */
+     Word16 h[],                           /* (i) Q15    : impulse response                       */
+     Word16 y[],                           /* (o) 12 bits: output vector                          */
+     Word16 L                              /* (i)        : vector size                            */
+)
+{
+    Word16 i, n;
+    Word32 L_sum;
+
+    for (n = 0; n < L; n++)
+    {
+        L_sum = 0L;                        move32();
+        for (i = 0; i <= n; i++)
+            L_sum = L_mac(L_sum, x[i], h[n - i]);
+
+        y[n] = round(L_sum);               move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/cor_h_x.c
@@ -1,0 +1,66 @@
+/*-------------------------------------------------------------------*
+ *                         cor_h_x.C                                 *
+ *-------------------------------------------------------------------*
+ * Compute correlation between target "x[]" and "h[]".               *
+ * Designed for codebook search (24 pulses, 4 tracks, 4 pulses per   *
+ *    track, 16 positions in each track) to avoid saturation.        *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+
+#define L_SUBFR   64
+#define NB_TRACK  4
+#define STEP      4
+
+
+void cor_h_x(
+     Word16 h[],                           /* (i) Q12 : impulse response of weighted synthesis filter */
+     Word16 x[],                           /* (i) Q0  : target vector                                 */
+     Word16 dn[]                           /* (o) <12bit : correlation between target and h[]         */
+)
+{
+    Word16 i, j, k;
+    Word32 L_tmp, y32[L_SUBFR], L_max, L_tot;
+
+    /* first keep the result on 32 bits and find absolute maximum */
+
+    L_tot = 1L;                            move32();
+
+    for (k = 0; k < NB_TRACK; k++)
+    {
+        L_max = 0;                         move32();
+        for (i = k; i < L_SUBFR; i += STEP)
+        {
+            L_tmp = 1L;                    move32();  /* 1 -> to avoid null dn[] */
+            for (j = i; j < L_SUBFR; j++)
+                L_tmp = L_mac(L_tmp, x[j], h[j - i]);
+
+            y32[i] = L_tmp;                move32();
+            L_tmp = L_abs(L_tmp);
+            test();
+            if (L_sub(L_tmp, L_max) > (Word32) 0)
+            {
+                L_max = L_tmp;             move32();
+            }
+        }
+        /* tot += 3*max / 8 */
+        L_max = L_shr(L_max, 2);
+        L_tot = L_add(L_tot, L_max);       /* +max/4 */
+        L_tot = L_add(L_tot, L_shr(L_max, 1));  /* +max/8 */
+    }
+
+    /* Find the number of right shifts to do on y32[] so that    */
+    /* 6.0 x sumation of max of dn[] in each track not saturate. */
+
+    j = sub(norm_l(L_tot), 4);             /* 4 -> 16 x tot */
+
+    for (i = 0; i < L_SUBFR; i++)
+    {
+        dn[i] = round(L_shl(y32[i], j));   move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/count.c
@@ -1,0 +1,295 @@
+/***********************************************************************
+ *
+ *   This file contains functions for the automatic complexity calculation
+ * $Id: count.c,v 1.1 2007/02/15 23:22:35 robs Exp $
+ *************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "typedef.h"
+#include "count.h"
+
+/* Global counter variable for calculation of complexity weight */
+
+BASIC_OP multiCounter[MAXCOUNTERS];
+int currCounter=0; /* Zero equals global counter */
+
+/*BASIC_OP counter;*/
+const BASIC_OP op_weight =
+{
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    3, 3, 3, 4, 15, 18, 30, 1, 2, 1, 2, 2
+};
+
+/* function prototypes */
+Word32 TotalWeightedOperation (void);
+Word32 DeltaWeightedOperation (void);
+
+/* local variable */
+#if WMOPS
+
+/* Counters for separating counting for different objects */
+static int maxCounter=0;
+static char* objectName[MAXCOUNTERS+1];
+static Word16 fwc_corr[MAXCOUNTERS+1];
+
+#define NbFuncMax  1024
+
+static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS];
+static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax];
+static float total_wmops[MAXCOUNTERS];
+
+static Word32 LastWOper[MAXCOUNTERS];
+
+static char* my_strdup(const char *s)
+/*
+ * duplicates UNIX function strdup() which is not ANSI standard:
+ * -- malloc() memory area big enough to hold the string s
+ * -- copy string into new area
+ * -- return pointer to new area
+ *
+ * returns NULL if either s==NULL or malloc() fails
+ */
+{
+    char *dup;
+    
+    if (s == NULL)
+        return NULL;
+
+    /* allocate memory for copy of ID string (including string terminator) */
+    /* NOTE: the ID strings will never be deallocated because there is no
+             way to "destroy" a counter that is not longer needed          */
+    if ((dup = (char *) malloc(strlen(s)+1)) == NULL)
+        return NULL;
+
+    return strcpy(dup, s);
+}
+
+#endif
+
+int getCounterId(char *objectNameArg)
+{
+#if WMOPS
+  if(maxCounter>=MAXCOUNTERS-1) return 0;
+  objectName[++maxCounter]=my_strdup(objectNameArg);
+  return maxCounter;
+#else
+  return 0; /* Dummy */
+#endif
+}
+
+void setCounter(int counterId)
+{
+#if WMOPS
+  if(counterId>maxCounter || counterId<0)
+    {
+      currCounter=0;
+      return;
+    }
+  currCounter=counterId;
+#endif
+}
+
+#if WMOPS
+static Word32 WMOPS_frameStat()
+/* calculate the WMOPS seen so far and update the global
+   per-frame maximum (glob_wc)
+ */
+{
+    Word32 tot;
+
+    tot = TotalWeightedOperation ();
+    if (tot > glob_wc[currCounter])
+        glob_wc[currCounter] = tot;
+
+    /* check if fwc() was forgotten at end of last frame */
+    if (tot > LastWOper[currCounter]) {
+        if (!fwc_corr[currCounter]) {
+            fprintf(stderr,
+                    "count: operations counted after last fwc() for '%s'; "
+                    "-> fwc() called\n",
+                    objectName[currCounter]?objectName[currCounter]:"");
+        }
+        fwc();
+    }
+    
+    return tot;
+}
+
+static void WMOPS_clearMultiCounter()
+{
+    Word16 i;
+    
+    Word32 *ptr = (Word32 *) &multiCounter[currCounter];
+    for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++)
+    {
+        *ptr++ = 0;
+    }
+}
+#endif
+
+Word32 TotalWeightedOperation ()
+{
+#if WMOPS
+    Word16 i;
+    Word32 tot, *ptr, *ptr2;
+
+    tot = 0;
+    ptr = (Word32 *) &multiCounter[currCounter];
+    ptr2 = (Word32 *) &op_weight;
+    for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++)
+    {
+        tot += ((*ptr++) * (*ptr2++));
+    }
+
+    return ((Word32) tot);
+#else
+    return 0; /* Dummy */
+#endif
+}
+
+Word32 DeltaWeightedOperation ()
+{
+#if WMOPS
+    Word32 NewWOper, delta;
+
+    NewWOper = TotalWeightedOperation ();
+    delta = NewWOper - LastWOper[currCounter];
+    LastWOper[currCounter] = NewWOper;
+    return (delta);
+#else
+    return 0; /* Dummy */
+#endif
+}
+
+void move16 (void)
+{
+#if WMOPS
+    multiCounter[currCounter].DataMove16++;
+#endif
+}
+
+void move32 (void)
+{
+#if WMOPS
+    multiCounter[currCounter].DataMove32++;
+#endif
+}
+
+void test (void)
+{
+#if WMOPS
+    multiCounter[currCounter].Test++;
+#endif
+}
+
+void logic16 (void)
+{
+#if WMOPS
+    multiCounter[currCounter].Logic16++;
+#endif
+}
+
+void logic32 (void)
+{
+#if WMOPS
+    multiCounter[currCounter].Logic32++;
+#endif
+}
+
+void Init_WMOPS_counter (void)
+{
+#if WMOPS
+    Word16 i;
+
+    /* reset function weight operation counter variable */
+
+    for (i = 0; i < NbFuncMax; i++)
+        wc[currCounter][i] = (Word32) 0;
+    glob_wc[currCounter] = 0;
+    nbframe[currCounter] = 0;
+    total_wmops[currCounter] = 0.0;
+
+    /* initially clear all counters */
+    WMOPS_clearMultiCounter();
+    LastWOper[currCounter] = 0;
+    funcid[currCounter] = 0;
+#endif
+}
+
+
+void Reset_WMOPS_counter (void)
+{
+#if WMOPS
+    Word32 tot = WMOPS_frameStat();
+        
+    /* increase the frame counter --> a frame is counted WHEN IT BEGINS */
+    nbframe[currCounter]++;
+    /* add wmops used in last frame to count, then reset counter */
+    /* (in first frame, this is a no-op                          */
+    total_wmops[currCounter] += ((float) tot) * 0.00005f;
+    
+    /* clear counter before new frame starts */
+    WMOPS_clearMultiCounter();
+    LastWOper[currCounter] = 0;
+    funcid[currCounter] = 0;           /* new frame, set function id to zero */
+#endif
+}
+
+Word32 fwc (void)                      /* function worst case */
+{
+#if WMOPS
+    Word32 tot;
+
+    tot = DeltaWeightedOperation ();
+    if (tot > wc[currCounter][funcid[currCounter]])
+        wc[currCounter][funcid[currCounter]] = tot;
+
+    funcid[currCounter]++;
+
+    return (tot);
+#else
+    return 0; /* Dummy */
+#endif
+}
+
+void WMOPS_output (Word16 dtx_mode)
+{
+#if WMOPS
+    Word16 i;
+    Word32 tot, tot_wm, tot_wc;
+
+    /* get operations since last reset (or init),
+       but do not update the counters (except the glob_wc[] maximum)
+       so output CAN be called in each frame without problems.
+       The frame counter is NOT updated!
+     */
+    tot = WMOPS_frameStat();
+    tot_wm = (Word32)(total_wmops[currCounter] + ((float) tot) * 0.00005f);
+
+    fprintf (stdout, "%10s:WMOPS=%.3f",
+         objectName[currCounter]?objectName[currCounter]:"",
+         ((float) tot) * 0.00005);
+
+    if (nbframe[currCounter] != 0)
+        fprintf (stdout, "  Average=%.3f",
+                 tot_wm / (float) nbframe[currCounter]);
+    
+    fprintf (stdout, "  WorstCase=%.3f",
+             ((float) glob_wc[currCounter]) * 0.00005);
+
+    /* Worst worst case printed only when not in DTX mode */
+    if (dtx_mode == 0)
+    {
+        tot_wc = 0L;
+        for (i = 0; i < funcid[currCounter]; i++)
+            tot_wc += wc[currCounter][i];
+        fprintf (stdout, "  WorstWC=%.3f", ((float) tot_wc) * 0.00005);
+    }
+    fprintf (stdout, " (%d frames)\n", nbframe[currCounter]);
+    
+#endif
+}
+
--- /dev/null
+++ b/amr-wb/count.h
@@ -1,0 +1,175 @@
+/*
+ * functions for counting operations
+ *
+ * These functions, and the ones in basic_op.h, makes it possible to measure
+ * the wMOPS of a codec.
+ *
+ * All functions in this file, and in basic_op.h, uppdates a structure so that
+ * it will be possible the see how many calls to add, mul mulAdd ... that the
+ * code made, and estimate the wMOPS (and MIPS) for a sertain part of code
+ *
+ * It is also possible to measure the wMOPS separatly for different parts
+ * of the codec.
+ *
+ * This is done by creating a counter group (getCounterId) for each part of the
+ * code that one wants a separte measure for. Before a part of the code
+ * is executed a call to the "setCounter" function is needed to identify
+ * which counter group to use.
+ *
+ * Currently there is a limit of 255 different counter groups.
+ *
+ * In the end of this file there is a pice of code illustration how the
+ * functions can be used.
+ */
+#ifndef count_h
+#define count_h "$Id: count.h,v 1.1 2007/02/15 23:22:35 robs Exp $"
+
+#define MAXCOUNTERS 256
+
+int getCounterId(char *objectName);
+/*
+ * Create a counter group, the "objectname" will be used when printing
+ * statistics for this counter group.
+ *
+ * Returns 0 if no more counter groups are available.
+ */
+
+void setCounter(int counterId);
+/*
+ * Defines which counter group to use, default is zero.
+ */
+
+void Init_WMOPS_counter (void);
+/*
+ * Initiates the current counter group.
+ */
+
+void Reset_WMOPS_counter (void);
+/*
+ * Resets the current counter group.
+ */
+
+void WMOPS_output (Word16 notPrintWorstWorstCase);
+/*
+ * Prints the statistics to the screen, if the argument if non zero
+ * the statistics for worst worst case will not be printed. This is typically
+ * done for dtx frames.
+ *
+ */
+
+Word32 fwc (void);
+/*
+ * worst worst case counter.
+ *
+ * This function calculates the worst possible case that can be reached.
+ *
+ * This is done by calling this function for each subpart of the calculations
+ * for a frame. This function then stores the maximum wMOPS for each part.
+ *
+ * The WMOPS_output function add together all parts and presents the sum.
+ */
+
+void move16 (void);
+void move32 (void);
+void logic16 (void);
+void logic32 (void);
+void test (void);
+/*
+ * The functions above increases the corresponding operation counter for
+ * the current counter group.
+ */
+
+typedef struct
+{
+    Word32 add;        /* Complexity Weight of 1 */
+    Word32 sub;
+    Word32 abs_s;
+    Word32 shl;
+    Word32 shr;
+    Word32 extract_h;
+    Word32 extract_l;
+    Word32 mult;
+    Word32 L_mult;
+    Word32 negate;
+    Word32 round;
+    Word32 L_mac;
+    Word32 L_msu;
+    Word32 L_macNs;
+    Word32 L_msuNs;
+    Word32 L_add;      /* Complexity Weight of 2 */
+    Word32 L_sub;
+    Word32 L_add_c;
+    Word32 L_sub_c;
+    Word32 L_negate;
+    Word32 L_shl;
+    Word32 L_shr;
+    Word32 mult_r;
+    Word32 shr_r;
+    Word32 shift_r;
+    Word32 mac_r;
+    Word32 msu_r;
+    Word32 L_deposit_h;
+    Word32 L_deposit_l;
+    Word32 L_shr_r;    /* Complexity Weight of 3 */
+    Word32 L_shift_r;
+    Word32 L_abs;
+    Word32 L_sat;      /* Complexity Weight of 4 */
+    Word32 norm_s;     /* Complexity Weight of 15 */
+    Word32 div_s;      /* Complexity Weight of 18 */
+    Word32 norm_l;     /* Complexity Weight of 30 */
+    Word32 DataMove16; /* Complexity Weight of 1 */
+    Word32 DataMove32; /* Complexity Weight of 2 */
+    Word32 Logic16;    /* Complexity Weight of 1 */
+    Word32 Logic32;    /* Complexity Weight of 2 */
+    Word32 Test;       /* Complexity Weight of 2 */
+}
+BASIC_OP;
+
+/*
+ * Example of how count.h could be used.
+ *
+ * In the example below it is assumed that the init_OBJECT functions
+ * does not use any calls to counter.h or basic_op.h. If this is the case
+ * a call to the function Reset_WMOPS_counter() must be done after each call
+ * to init_OBJECT if these operations is not to be included in the statistics.
+
+int main(){ 
+ int spe1Id,spe2Id,cheId;
+ 
+ // initiate counters and objects 
+ spe1Id=getCounterId("Spe 5k8"); 
+ setCounter(spe1Id); 
+ Init_WMOPS_counter (); 
+ init_spe1(...);
+ 
+ spe2Id=getCounterId("Spe 12k2"); 
+ setCounter(spe2Id); 
+ Init_WMOPS_counter (); 
+ init_spe2(...);
+ 
+ cheId=getCounterId("Channel encoder"); 
+ setCounter(cheId); 
+ Init_WMOPS_counter (); 
+ init_che(...); 
+ ... 
+ while(data){ 
+    test();             // Note this call to test();
+    if(useSpe1)
+        setCounter(spe1Id); 
+    else 
+        setCounter(spe2Id); 
+    Reset_WMOPS_counter();
+    speEncode(...);
+    WMOPS_output(0);    // Normal routine for displaying WMOPS info
+    
+    setCounter(cheId); 
+    Reset_WMOPS_counter();
+    preChannelInter(...); fwc(); // Note the call to fwc() for each part
+    convolve(...); fwc();        // of the channel encoder.
+    interleave(...); fwc();
+    WMOPS_output(0);    // Normal routine for displaying WMOPS info
+}
+*/
+
+#endif
+
--- /dev/null
+++ b/amr-wb/d2t64fx.c
@@ -1,0 +1,53 @@
+/*-------------------------------------------------------------------*
+ *                         D2T64FX.C                                 *
+ *-------------------------------------------------------------------*
+ * 12 bits algebraic codebook decoder.                               *
+ * 2 tracks x 32 positions per track = 64 samples.                   *
+ *                                                                   *
+ * 12 bits --> 2 pulses in a frame of 64 samples.                    *
+ *                                                                   *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.        *
+ * Each pulse can have 32 possible positions.                        *
+ *                                                                   *
+ * See dec2t64.c for more details of the algebraic code.             *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "cnst.h"
+
+#define L_CODE    64                       /* codevector length  */
+#define NB_TRACK  2                        /* number of track    */
+#define NB_POS    32                       /* number of position */
+
+
+void DEC_ACELP_2t64_fx(
+     Word16 index,                         /* (i) :    12 bits index                                  */
+     Word16 code[]                         /* (o) :Q9  algebraic (fixed) codebook excitation          */
+)
+{
+    Word16 i, i0, i1;
+
+    for (i = 0; i < L_CODE; i++)
+    {
+        code[i] = 0;                       move16();
+    }
+
+    /* decode the positions and signs of pulses and build the codeword */
+
+    i0 = (Word16) (shr(index, 5) & 0x003E);logic16();
+    i1 = (Word16) (add(shl((Word16) (index & 0x001F), 1), 1));  logic16();
+    test();logic16();
+    if ((shr(index, 6) & NB_POS) == 0)
+        code[i0] = 512;
+    else
+        code[i0] = -512;
+
+    test();logic16();
+    if ((index & NB_POS) == 0)
+        code[i1] = 512;
+    else
+        code[i1] = -512;
+    return;
+}
--- /dev/null
+++ b/amr-wb/d4t64fx.c
@@ -1,0 +1,147 @@
+/*-------------------------------------------------------------------*
+ *                         D2T64FX.C                                 *
+ *-------------------------------------------------------------------*
+ * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook decoder.       *
+ * 4 tracks x 16 positions per track = 64 samples.                   *
+ *                                                                   *
+ * 20 bits --> 4 pulses in a frame of 64 samples.                    *
+ * 36 bits --> 8 pulses in a frame of 64 samples.                    *
+ * 44 bits --> 10 pulses in a frame of 64 samples.                   *
+ * 52 bits --> 12 pulses in a frame of 64 samples.                   *
+ * 64 bits --> 16 pulses in a frame of 64 samples.                   *
+ * 72 bits --> 18 pulses in a frame of 64 samples.                   *
+ * 88 bits --> 24 pulses in a frame of 64 samples.                   *
+ *                                                                   *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.        *
+ * Each pulse can have sixteen (16) possible positions.              *
+ *                                                                   *
+ * See c36_64fx.c for more details of the algebraic code.            *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "cnst.h"
+
+#include "q_pulse.h"
+
+#define L_CODE    64                       /* codevector length  */
+#define NB_TRACK  4                        /* number of track    */
+#define NB_POS    16                       /* number of position */
+
+/* local function */
+
+static void add_pulses(Word16 pos[], Word16 nb_pulse, Word16 track, Word16 code[]);
+void DEC_ACELP_4t64_fx(
+     Word16 index[],                       /* (i) : index (20): 5+5+5+5 = 20 bits.                 */
+                                           /* (i) : index (36): 9+9+9+9 = 36 bits.                 */
+                                           /* (i) : index (44): 13+9+13+9 = 44 bits.               */
+                                           /* (i) : index (52): 13+13+13+13 = 52 bits.             */
+                                           /* (i) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.     */
+                                           /* (i) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.   */
+                                           /* (i) : index (88): 11+11+11+11+11+11+11+11 = 88 bits. */
+     Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits              */
+     Word16 code[]                         /* (o) Q9: algebraic (fixed) codebook excitation        */
+)
+{
+    Word16 i, k, pos[6];
+    Word32 L_index;
+
+    for (i = 0; i < L_CODE; i++)
+    {
+        code[i] = 0;                       move16();
+    }
+
+    /* decode the positions and signs of pulses and build the codeword */
+    test();test();test();test();test();test();test();
+    if (sub(nbbits, 20) == 0)
+    {
+        for (k = 0; k < NB_TRACK; k++)
+        {
+            L_index = index[k];            move32();
+            dec_1p_N1(L_index, 4, 0, pos);
+            add_pulses(pos, 1, k, code);
+        }
+    } else if (sub(nbbits, 36) == 0)
+    {
+        for (k = 0; k < NB_TRACK; k++)
+        {
+            L_index = index[k];            move32();
+            dec_2p_2N1(L_index, 4, 0, pos);
+            add_pulses(pos, 2, k, code);
+        }
+    } else if (sub(nbbits, 44) == 0)
+    {
+        for (k = 0; k < NB_TRACK - 2; k++)
+        {
+            L_index = index[k];            move32();
+            dec_3p_3N1(L_index, 4, 0, pos);
+            add_pulses(pos, 3, k, code);
+        }
+        for (k = 2; k < NB_TRACK; k++)
+        {
+            L_index = index[k];            move32();
+            dec_2p_2N1(L_index, 4, 0, pos);
+            add_pulses(pos, 2, k, code);
+        }
+    } else if (sub(nbbits, 52) == 0)
+    {
+        for (k = 0; k < NB_TRACK; k++)
+        {
+            L_index = index[k];            move32();
+            dec_3p_3N1(L_index, 4, 0, pos);
+            add_pulses(pos, 3, k, code);
+        }
+    } else if (sub(nbbits, 64) == 0)
+    {
+        for (k = 0; k < NB_TRACK; k++)
+        {
+            L_index = L_add(L_shl(index[k], 14), index[k + NB_TRACK]);
+            dec_4p_4N(L_index, 4, 0, pos);
+            add_pulses(pos, 4, k, code);
+        }
+    } else if (sub(nbbits, 72) == 0)
+    {
+        for (k = 0; k < NB_TRACK - 2; k++)
+        {
+            L_index = L_add(L_shl(index[k], 10), index[k + NB_TRACK]);
+            dec_5p_5N(L_index, 4, 0, pos);
+            add_pulses(pos, 5, k, code);
+        }
+        for (k = 2; k < NB_TRACK; k++)
+        {
+            L_index = L_add(L_shl(index[k], 14), index[k + NB_TRACK]);
+            dec_4p_4N(L_index, 4, 0, pos);
+            add_pulses(pos, 4, k, code);
+        }
+    } else if (sub(nbbits, 88) == 0)
+    {
+        for (k = 0; k < NB_TRACK; k++)
+        {
+            L_index = L_add(L_shl(index[k], 11), index[k + NB_TRACK]);
+            dec_6p_6N_2(L_index, 4, 0, pos);
+            add_pulses(pos, 6, k, code);
+        }
+    }
+    return;
+}
+
+
+
+static void add_pulses(Word16 pos[], Word16 nb_pulse, Word16 track, Word16 code[])
+{
+    Word16 i, k;
+
+    for (k = 0; k < nb_pulse; k++)
+    {
+        /* i = ((pos[k] & (NB_POS-1))*NB_TRACK) + track; */
+        i = (Word16) (add(shl((Word16) (pos[k] & (NB_POS - 1)), 2), track));    logic16();
+        test();logic16();
+        if ((pos[k] & NB_POS) == 0)
+            code[i] = add(code[i], 512);
+        else
+            code[i] = sub(code[i], 512);
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/d_gain2.c
@@ -1,0 +1,290 @@
+/*-------------------------------------------------------------------*
+ *                         D_GAIN2.C                                 *
+ *-------------------------------------------------------------------*
+ * Decode the pitch and codebook gains                               *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "log2.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+#include "q_gain2.tab"
+
+#define MEAN_ENER    30
+#define PRED_ORDER   4
+
+#define L_LTPHIST 5
+
+const Word16 pdown_unusable[7] = {32767, 31130, 29491, 24576, 7537, 1638, 328};
+const Word16 cdown_unusable[7] = {32767, 16384, 8192, 8192, 8192, 4915, 3277};
+
+const Word16 pdown_usable[7] = {32767, 32113, 31457, 24576, 7537, 1638, 328};
+const Word16 cdown_usable[7] = {32767, 32113, 32113, 32113, 32113, 32113, 22938};
+
+
+/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */
+static Word16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};
+
+void Init_D_gain2(
+     Word16 * mem                          /* output  :static memory (4 words)      */
+)
+{
+    Word16 i;
+
+    /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */
+    mem[0] = -14336;                       move16();  /* past_qua_en[0] */
+    mem[1] = -14336;                       move16();  /* past_qua_en[1] */
+    mem[2] = -14336;                       move16();  /* past_qua_en[2] */
+    mem[3] = -14336;                       move16();  /* past_qua_en[3] */
+
+    mem[4] = 0;                            move16();  /* *past_gain_pit  */
+    mem[5] = 0;                            move16();  /* *past_gain_code */
+    mem[6] = 0;                            move16();  /* *prev_gc */
+
+    for (i = 0; i < 5; i++)
+    {
+        mem[i + 7] = 0;                    move16();  /* pbuf[i] */
+    }
+    for (i = 0; i < 5; i++)
+    {
+        mem[i + 12] = 0;                   move16();  /* gbuf[i] */
+    }
+    for (i = 0; i < 5; i++)
+    {
+        mem[i + 17] = 0;                   move16();  /* pbuf2[i] */
+    }
+    mem[22] = 21845;                       /* seed */
+
+    return;
+}
+
+
+void D_gain2(
+     Word16 index,                         /* (i)     : index of quantization.      */
+     Word16 nbits,                         /* (i)     : number of bits (6 or 7)     */
+     Word16 code[],                        /* (i) Q9  : Innovative vector.          */
+     Word16 L_subfr,                       /* (i)     : Subframe lenght.            */
+     Word16 * gain_pit,                    /* (o) Q14 : Pitch gain.                 */
+     Word32 * gain_cod,                    /* (o) Q16 : Code gain.                  */
+     Word16 bfi,                           /* (i)     : bad frame indicator         */
+     Word16 prev_bfi,                      /* (i)     : Previous BF indicator       */
+     Word16 state,                         /* (i)     : State of BFH                */
+     Word16 unusable_frame,                /* (i)     : UF indicator                */
+     Word16 vad_hist,                      /* (i)     : number of non-speech frames */
+     Word16 * mem                          /* (i/o)   : static memory (4 words)     */
+)
+{
+    Word16 *p, *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;
+    Word16 *pbuf2, *seed;
+    Word16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;
+    Word16 g_code;
+    Word32 L_tmp;
+
+    past_qua_en = mem;                     move16();
+    past_gain_pit = mem + 4;               move16();
+    past_gain_code = mem + 5;              move16();
+    prev_gc = mem + 6;                     move16();
+    pbuf = mem + 7;                        move16();
+    gbuf = mem + 12;                       move16();
+    pbuf2 = mem + 17;                      move16();
+    seed = mem + 22;                       move16();
+
+    /*-----------------------------------------------------------------*
+     *  Find energy of code and compute:                               *
+     *                                                                 *
+     *    L_tmp = 1.0 / sqrt(energy of code/ L_subfr)                  *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = Dot_product12(code, code, L_subfr, &exp);
+    exp = sub(exp, 18 + 6);                /* exp: -18 (code in Q9), -6 (/L_subfr) */
+
+    Isqrt_n(&L_tmp, &exp);
+
+    gcode_inov = extract_h(L_shl(L_tmp, sub(exp, 3)));  /* g_code_inov in Q12 */
+
+    /*-------------------------------*
+     * Case of erasure.              *
+     *-------------------------------*/
+    test();
+    if (bfi != 0)
+    {
+        tmp = median5(&pbuf[2]);
+        *past_gain_pit = tmp;              move16();
+        test();move16();
+        if (sub(*past_gain_pit, 15565) > 0)
+        {
+            *past_gain_pit = 15565;        /* 0.95 in Q14 */
+            move16();
+        }
+        test();
+        if (unusable_frame != 0)
+        {
+            *gain_pit = mult(pdown_unusable[state], *past_gain_pit);    move16();
+        } else
+        {
+            *gain_pit = mult(pdown_usable[state], *past_gain_pit);      move16();
+        }
+        tmp = median5(&gbuf[2]);
+        test();
+        if (sub(vad_hist, 2) > 0)
+        {
+            *past_gain_code = tmp;         move16();
+        } else
+        {
+            test();
+            if (unusable_frame != 0)
+            {
+                *past_gain_code = mult(cdown_unusable[state], tmp);     move16();
+            } else
+            {
+                *past_gain_code = mult(cdown_usable[state], tmp);       move16();
+            }
+        }
+
+        /* update table of past quantized energies */
+
+        L_tmp = L_mult(past_qua_en[0], 8192);   /* x 0.25 */
+        L_tmp = L_mac(L_tmp, past_qua_en[1], 8192);     /* x 0.25 */
+        L_tmp = L_mac(L_tmp, past_qua_en[2], 8192);     /* x 0.25 */
+        L_tmp = L_mac(L_tmp, past_qua_en[3], 8192);     /* x 0.25 */
+        qua_ener = extract_h(L_tmp);
+
+        qua_ener = sub(qua_ener, 3072);    /* -3 in Q10 */
+        test();
+        if (sub(qua_ener, -14336) < 0)
+            qua_ener = -14336;             move16();  /* -14 in Q10 */
+
+        past_qua_en[3] = past_qua_en[2];   move16();
+        past_qua_en[2] = past_qua_en[1];   move16();
+        past_qua_en[1] = past_qua_en[0];   move16();
+        past_qua_en[0] = qua_ener;         move16();
+
+        for (i = 1; i < 5; i++)
+        {
+            gbuf[i - 1] = gbuf[i];         move16();
+        }
+        gbuf[4] = *past_gain_code;         move16();
+
+        for (i = 1; i < 5; i++)
+        {
+            pbuf[i - 1] = pbuf[i];         move16();
+        }
+        pbuf[4] = *past_gain_pit;          move16();
+
+        /* adjust gain according to energy of code */
+        /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */
+        *gain_cod = L_mult(*past_gain_code, gcode_inov);        move32();
+
+        return;
+    }
+    /*-----------------------------------------------------------------*
+     * Compute gcode0.                                                 *
+     *  = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code    *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = L_deposit_h(MEAN_ENER);        /* MEAN_ENER in Q16 */
+    L_tmp = L_shl(L_tmp, 8);               /* From Q16 to Q24 */
+    L_tmp = L_mac(L_tmp, pred[0], past_qua_en[0]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[1], past_qua_en[1]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[2], past_qua_en[2]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[3], past_qua_en[3]);      /* Q13*Q10 -> Q24 */
+
+    gcode0 = extract_h(L_tmp);             /* From Q24 to Q8  */
+
+    /*-----------------------------------------------------------------*
+     * gcode0 = pow(10.0, gcode0/20)                                   *
+     *        = pow(2, 3.321928*gcode0/20)                             *
+     *        = pow(2, 0.166096*gcode0)                                *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = L_mult(gcode0, 5443);          /* *0.166096 in Q15 -> Q24     */
+    L_tmp = L_shr(L_tmp, 8);               /* From Q24 to Q16             */
+    L_Extract(L_tmp, &exp_gcode0, &frac);  /* Extract exponant of gcode0  */
+
+    gcode0 = extract_l(Pow2(14, frac));    /* Put 14 as exponant so that  */
+    /* output of Pow2() will be:   */
+    /* 16384 < Pow2() <= 32767     */
+    exp_gcode0 = sub(exp_gcode0, 14);
+
+    /* Read the quantized gains */
+    test();
+    if (sub(nbits, 6) == 0)
+    {
+        p = &t_qua_gain6b[add(index, index)];   move16();
+    } else
+    {
+        p = &t_qua_gain7b[add(index, index)];   move16();
+    }
+    *gain_pit = *p++;                      move16();  /* selected pitch gain in Q14 */
+    g_code = *p++;                         move16();  /* selected code gain in Q11  */
+
+    L_tmp = L_mult(g_code, gcode0);        /* Q11*Q0 -> Q12 */
+    L_tmp = L_shl(L_tmp, add(exp_gcode0, 4));   /* Q12 -> Q16 */
+
+    *gain_cod = L_tmp;                     move16();  /* gain of code in Q16 */
+    test();
+    if ((sub(prev_bfi, 1) == 0))
+    {
+        L_tmp = L_mult(*prev_gc, 5120);    /* prev_gc(Q3) * 1.25(Q12) = Q16 */
+        /* if((*gain_cod > ((*prev_gc) * 1.25)) && (*gain_cod > 100.0)) */
+        test();test();
+        if ((L_sub(*gain_cod, L_tmp) > 0) && (L_sub(*gain_cod, 6553600) > 0))
+        {
+            *gain_cod = L_tmp;             move32();
+        }
+    }
+    /* keep past gain code in Q3 for frame erasure (can saturate) */
+    *past_gain_code = round(L_shl(*gain_cod, 3));       move16();
+    *past_gain_pit = *gain_pit;            move16();
+
+    *prev_gc = *past_gain_code;            move16();
+    for (i = 1; i < 5; i++)
+    {
+        gbuf[i - 1] = gbuf[i];             move16();
+    }
+    gbuf[4] = *past_gain_code;             move16();
+
+    for (i = 1; i < 5; i++)
+    {
+        pbuf[i - 1] = pbuf[i];             move16();
+    }
+    pbuf[4] = *past_gain_pit;              move16();
+
+    for (i = 1; i < 5; i++)
+    {
+        pbuf2[i - 1] = pbuf2[i];           move16();
+    }
+    pbuf2[4] = *past_gain_pit;             move16();
+
+    /* adjust gain according to energy of code */
+    L_Extract(*gain_cod, &exp, &frac);
+    L_tmp = Mpy_32_16(exp, frac, gcode_inov);
+    *gain_cod = L_shl(L_tmp, 3);           move32();  /* gcode_inov in Q12 */
+
+    /*---------------------------------------------------*
+     * qua_ener = 20*log10(g_code)                       *
+     *          = 6.0206*log2(g_code)                    *
+     *          = 6.0206*(log2(g_codeQ11) - 11)          *
+     *---------------------------------------------------*/
+
+    L_tmp = L_deposit_l(g_code);
+    Log2(L_tmp, &exp, &frac);
+    exp = sub(exp, 11);
+    L_tmp = Mpy_32_16(exp, frac, 24660);   /* x 6.0206 in Q12 */
+
+    qua_ener = extract_l(L_shr(L_tmp, 3)); /* result in Q10 */
+
+    /* update table of past quantized energies */
+
+    past_qua_en[3] = past_qua_en[2];       move16();
+    past_qua_en[2] = past_qua_en[1];       move16();
+    past_qua_en[1] = past_qua_en[0];       move16();
+    past_qua_en[0] = qua_ener;             move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/dec_main.c
@@ -1,0 +1,1145 @@
+/*------------------------------------------------------------------------*
+ *                         DEC_MAIN.C                                     *
+ *------------------------------------------------------------------------*
+ * Performs the main decoder routine                                      *
+ *------------------------------------------------------------------------*/
+
+/*___________________________________________________________________________
+ |                                                                           |
+ | Fixed-point C simulation of AMR WB ACELP coding algorithm with 20 ms      |
+ | speech frames for wideband speech signals.                                |
+ |___________________________________________________________________________|
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "dec_main.h"
+#include "bits.h"
+#include "count.h"
+#include "math_op.h"
+#include "main.h"
+
+
+/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
+static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
+
+/* High Band encoding */
+static const Word16 HP_gain[16] =
+{
+   3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
+   11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
+};
+
+/* isp tables for initialization */
+
+static Word16 isp_init[M] =
+{
+   32138, 30274, 27246, 23170, 18205, 12540, 6393, 0,
+   -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475
+};
+
+static Word16 isf_init[M] =
+{
+   1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
+   9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840
+};
+
+static void synthesis(
+     Word16 Aq[],                          /* A(z)  : quantized Az               */
+     Word16 exc[],                         /* (i)   : excitation at 12kHz        */
+     Word16 Q_new,                         /* (i)   : scaling performed on exc   */
+     Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
+     Word16 prms,                          /* (i)   : parameter                  */
+     Word16 HfIsf[],
+     Word16 nb_bits,
+     Word16 newDTXState,
+     Decoder_State * st,                   /* (i/o) : State structure            */
+     Word16 bfi                            /* (i)   : bad frame indicator        */
+);
+
+/*-----------------------------------------------------------------*
+ *   Funtion  init_decoder                                         *
+ *            ~~~~~~~~~~~~                                         *
+ *   ->Initialization of variables for the decoder section.        *
+ *-----------------------------------------------------------------*/
+
+void Init_decoder(void **spd_state)
+{
+    /* Decoder states */
+    Decoder_State *st;
+
+    *spd_state = NULL;
+
+    /*-------------------------------------------------------------------------*
+     * Memory allocation for coder state.                                      *
+     *-------------------------------------------------------------------------*/
+
+    test();
+    if ((st = (Decoder_State *) malloc(sizeof(Decoder_State))) == NULL)
+    {
+        printf("Can not malloc Decoder_State structure!\n");
+        return;
+    }
+    st->dtx_decSt = NULL;
+    dtx_dec_init(&st->dtx_decSt, isf_init);
+
+    Reset_decoder((void *) st, 1);
+
+    *spd_state = (void *) st;
+
+    return;
+}
+
+void Reset_decoder(void *st, Word16 reset_all)
+{
+    Word16 i;
+
+    Decoder_State *dec_state;
+
+    dec_state = (Decoder_State *) st;
+
+    Set_zero(dec_state->old_exc, PIT_MAX + L_INTERPOL);
+    Set_zero(dec_state->past_isfq, M);
+
+    dec_state->old_T0_frac = 0;            move16();  /* old pitch value = 64.0 */
+    dec_state->old_T0 = 64;                move16();
+    dec_state->first_frame = 1;            move16();
+    dec_state->L_gc_thres = 0;             move16();
+    dec_state->tilt_code = 0;              move16();
+
+    Init_Phase_dispersion(dec_state->disp_mem);
+
+    /* scaling memories for excitation */
+    dec_state->Q_old = Q_MAX;              move16();
+    dec_state->Qsubfr[3] = Q_MAX;          move16();
+    dec_state->Qsubfr[2] = Q_MAX;          move16();
+    dec_state->Qsubfr[1] = Q_MAX;          move16();
+    dec_state->Qsubfr[0] = Q_MAX;          move16();
+
+    if (reset_all != 0)
+    {
+        /* routines initialization */
+
+        Init_D_gain2(dec_state->dec_gain);
+        Init_Oversamp_16k(dec_state->mem_oversamp);
+        Init_HP50_12k8(dec_state->mem_sig_out);
+        Init_Filt_6k_7k(dec_state->mem_hf);
+        Init_Filt_7k(dec_state->mem_hf3);
+        Init_HP400_12k8(dec_state->mem_hp400);
+        Init_Lagconc(dec_state->lag_hist);
+
+        /* isp initialization */
+
+        Copy(isp_init, dec_state->ispold, M);
+        Copy(isf_init, dec_state->isfold, M);
+        for (i = 0; i < L_MEANBUF; i++)
+            Copy(isf_init, &dec_state->isf_buf[i * M], M);
+        /* variable initialization */
+
+        dec_state->mem_deemph = 0;         move16();
+
+        dec_state->seed = 21845;           move16();  /* init random with 21845 */
+        dec_state->seed2 = 21845;          move16();
+        dec_state->seed3 = 21845;          move16();
+
+        dec_state->state = 0;              move16();
+        dec_state->prev_bfi = 0;           move16();
+
+        /* Static vectors to zero */
+
+        Set_zero(dec_state->mem_syn_hf, M16k);
+        Set_zero(dec_state->mem_syn_hi, M);
+        Set_zero(dec_state->mem_syn_lo, M);
+
+        dtx_dec_reset(dec_state->dtx_decSt, isf_init);
+        dec_state->vad_hist = 0;           move16();
+
+    }
+    return;
+}
+
+void Close_decoder(void *spd_state)
+{
+    dtx_dec_exit(&(((Decoder_State *) spd_state)->dtx_decSt));
+    free(spd_state);
+    return;
+}
+
+/*-----------------------------------------------------------------*
+ *   Funtion decoder                                               *
+ *           ~~~~~~~                                               *
+ *   ->Main decoder routine.                                       *
+ *                                                                 *
+ *-----------------------------------------------------------------*/
+
+void decoder(
+     Word16 mode,                          /* input : used mode                     */
+     Word16 prms[],                        /* input : parameter vector              */
+     Word16 synth16k[],                    /* output: synthesis speech              */
+     Word16 * frame_length,                /* output:  lenght of the frame          */
+     void *spd_state,                      /* i/o   : State structure               */
+     Word16 frame_type                     /* input : received frame type           */
+)
+{
+
+    /* Decoder states */
+    Decoder_State *st;
+
+    /* Excitation vector */
+    Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL];
+    Word16 *exc;
+
+    /* LPC coefficients */
+
+    Word16 *p_Aq;                          /* ptr to A(z) for the 4 subframes      */
+    Word16 Aq[NB_SUBFR * (M + 1)];         /* A(z)   quantized for the 4 subframes */
+    Word16 ispnew[M];                      /* immittance spectral pairs at 4nd sfr */
+    Word16 isf[M];                         /* ISF (frequency domain) at 4nd sfr    */
+    Word16 code[L_SUBFR];                  /* algebraic codevector                 */
+    Word16 code2[L_SUBFR];                 /* algebraic codevector                 */
+    Word16 exc2[L_FRAME];                  /* excitation vector                    */
+
+    Word16 fac, stab_fac, voice_fac, Q_new = 0;
+    Word32 L_tmp, L_gain_code;
+
+    /* Scalars */
+
+    Word16 i, j, i_subfr, index, ind[8], max, tmp;
+    Word16 T0, T0_frac, pit_flag, T0_max, select, T0_min = 0;
+    Word16 gain_pit, gain_code, gain_code_lo;
+    Word16 newDTXState, bfi, unusable_frame, nb_bits;
+    Word16 vad_flag;
+    Word16 pit_sharp;
+    Word16 excp[L_SUBFR];
+    Word16 isf_tmp[M];
+    Word16 HfIsf[M16k];
+
+    Word16 corr_gain = 0;
+
+    st = (Decoder_State *) spd_state;
+
+    /* mode verification */
+
+    nb_bits = nb_of_bits[mode];            move16();
+
+    *frame_length = L_FRAME16k;            move16();
+
+    /* find the new  DTX state  SPEECH OR DTX */
+    newDTXState = rx_dtx_handler(st->dtx_decSt, frame_type);
+
+    test();
+    if (sub(newDTXState, SPEECH) != 0)
+    {
+        dtx_dec(st->dtx_decSt, exc2, newDTXState, isf, &prms);
+    }
+    /* SPEECH action state machine  */
+    test();test();
+    if ((sub(frame_type, RX_SPEECH_BAD) == 0) ||
+        (sub(frame_type, RX_SPEECH_PROBABLY_DEGRADED) == 0))
+    {
+        /* bfi only for lsf, gains and pitch period */
+        bfi = 1;                           move16();
+        unusable_frame = 0;                move16();
+    } else if ((sub(frame_type, RX_NO_DATA) == 0) ||
+               (sub(frame_type, RX_SPEECH_LOST) == 0))
+    {
+        /* bfi for all index, bits are not usable */
+        bfi = 1;                           move16();
+        unusable_frame = 1;                move16();
+    } else
+    {
+        bfi = 0;                           move16();
+        unusable_frame = 0;                move16();
+    }
+    test();
+    if (bfi != 0)
+    {
+        st->state = add(st->state, 1);     move16();
+        test();
+        if (sub(st->state, 6) > 0)
+        {
+            st->state = 6;                 move16();
+        }
+    } else
+    {
+        st->state = shr(st->state, 1);     move16();
+    }
+
+    /* If this frame is the first speech frame after CNI period,     */
+    /* set the BFH state machine to an appropriate state depending   */
+    /* on whether there was DTX muting before start of speech or not */
+    /* If there was DTX muting, the first speech frame is muted.     */
+    /* If there was no DTX muting, the first speech frame is not     */
+    /* muted. The BFH state machine starts from state 5, however, to */
+    /* keep the audible noise resulting from a SID frame which is    */
+    /* erroneously interpreted as a good speech frame as small as    */
+    /* possible (the decoder output in this case is quickly muted)   */
+    test();test();
+    if (sub(st->dtx_decSt->dtxGlobalState, DTX) == 0)
+    {
+        st->state = 5;                     move16();
+        st->prev_bfi = 0;                  move16();
+    } else if (sub(st->dtx_decSt->dtxGlobalState, DTX_MUTE) == 0)
+    {
+        st->state = 5;                     move16();
+        st->prev_bfi = 1;                  move16();
+    }
+    test();
+    if (sub(newDTXState, SPEECH) == 0)
+    {
+        vad_flag = Serial_parm(1, &prms);
+        test();
+        if (bfi == 0)
+        {
+            test();
+            if (vad_flag == 0)
+            {
+                st->vad_hist = add(st->vad_hist, 1);    move16();
+            } else
+            {
+                st->vad_hist = 0;          move16();
+            }
+        }
+    }
+    /*----------------------------------------------------------------------*
+     *                              DTX-CNG                                 *
+     *----------------------------------------------------------------------*/
+    test();
+    if (sub(newDTXState, SPEECH) != 0)     /* CNG mode */
+    {
+        /* increase slightly energy of noise below 200 Hz */
+
+        /* Convert ISFs to the cosine domain */
+        Isf_isp(isf, ispnew, M);
+
+        Isp_Az(ispnew, Aq, M, 1);
+
+        Copy(st->isfold, isf_tmp, M);
+
+        for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+        {
+            j = shr(i_subfr, 6);
+            for (i = 0; i < M; i++)
+            {
+                L_tmp = L_mult(isf_tmp[i], sub(32767, interpol_frac[j]));
+                L_tmp = L_mac(L_tmp, isf[i], interpol_frac[j]);
+                HfIsf[i] = round(L_tmp);   move16();
+            }
+            synthesis(Aq, &exc2[i_subfr], 0, &synth16k[i_subfr * 5 / 4], (short) 1, HfIsf, nb_bits, newDTXState, st, bfi);
+        }
+
+        /* reset speech coder memories */
+        Reset_decoder(st, 0);
+
+        Copy(isf, st->isfold, M);
+
+        st->prev_bfi = bfi;                move16();
+        st->dtx_decSt->dtxGlobalState = newDTXState;    move16();
+
+        return;
+    }
+    /*----------------------------------------------------------------------*
+     *                               ACELP                                  *
+     *----------------------------------------------------------------------*/
+
+    /* copy coder memory state into working space (internal memory for DSP) */
+
+    Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL);
+    exc = old_exc + PIT_MAX + L_INTERPOL;  move16();
+
+    /* Decode the ISFs */
+    test();
+    if (sub(nb_bits, NBBITS_7k) <= 0)
+    {
+        ind[0] = Serial_parm(8, &prms);    move16();
+        ind[1] = Serial_parm(8, &prms);    move16();
+        ind[2] = Serial_parm(7, &prms);    move16();
+        ind[3] = Serial_parm(7, &prms);    move16();
+        ind[4] = Serial_parm(6, &prms);    move16();
+
+        Dpisf_2s_36b(ind, isf, st->past_isfq, st->isfold, st->isf_buf, bfi, 1);
+    } else
+    {
+        ind[0] = Serial_parm(8, &prms);    move16();
+        ind[1] = Serial_parm(8, &prms);    move16();
+        ind[2] = Serial_parm(6, &prms);    move16();
+        ind[3] = Serial_parm(7, &prms);    move16();
+        ind[4] = Serial_parm(7, &prms);    move16();
+        ind[5] = Serial_parm(5, &prms);    move16();
+        ind[6] = Serial_parm(5, &prms);    move16();
+
+        Dpisf_2s_46b(ind, isf, st->past_isfq, st->isfold, st->isf_buf, bfi, 1);
+    }
+
+    /* Convert ISFs to the cosine domain */
+
+    Isf_isp(isf, ispnew, M);
+    test();
+    if (st->first_frame != 0)
+    {
+        st->first_frame = 0;               move16();
+        Copy(ispnew, st->ispold, M);
+    }
+    /* Find the interpolated ISPs and convert to a[] for all subframes */
+    Int_isp(st->ispold, ispnew, interpol_frac, Aq);
+
+    /* update ispold[] for the next frame */
+    Copy(ispnew, st->ispold, M);
+
+    /* Check stability on isf : distance between old isf and current isf */
+
+    L_tmp = 0;                             move32();
+    for (i = 0; i < M - 1; i++)
+    {
+        tmp = sub(isf[i], st->isfold[i]);
+        L_tmp = L_mac(L_tmp, tmp, tmp);
+    }
+    tmp = extract_h(L_shl(L_tmp, 8));
+    tmp = mult(tmp, 26214);                /* tmp = L_tmp*0.8/256 */
+
+    tmp = sub(20480, tmp);                 /* 1.25 - tmp */
+    stab_fac = shl(tmp, 1);                /* Q14 -> Q15 with saturation */
+    test();
+    if (stab_fac < 0)
+    {
+        stab_fac = 0;                      move16();
+    }
+    Copy(st->isfold, isf_tmp, M);
+    Copy(isf, st->isfold, M);
+
+    /*------------------------------------------------------------------------*
+     *          Loop for every subframe in the analysis frame                 *
+     *------------------------------------------------------------------------*
+     * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR  *
+     *  times                                                                 *
+     *     - decode the pitch delay and filter mode                           *
+     *     - decode algebraic code                                            *
+     *     - decode pitch and codebook gains                                  *
+     *     - find voicing factor and tilt of code for next subframe.          *
+     *     - find the excitation and compute synthesis speech                 *
+     *------------------------------------------------------------------------*/
+
+    p_Aq = Aq;                             move16();  /* pointer to interpolated LPC parameters */
+
+    for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
+    {
+        pit_flag = i_subfr;                move16();
+
+        test();test();
+        if ((sub(i_subfr, 2 * L_SUBFR) == 0) && (sub(nb_bits, NBBITS_7k) > 0))
+        {
+            pit_flag = 0;                  move16();
+        }
+        /*-------------------------------------------------*
+         * - Decode pitch lag                              *
+         * Lag indeces received also in case of BFI,       *
+         * so that the parameter pointer stays in sync.    *
+         *-------------------------------------------------*/
+        test();
+        if (pit_flag == 0)
+        {
+            test();
+            if (sub(nb_bits, NBBITS_9k) <= 0)
+            {
+                index = Serial_parm(8, &prms);
+                test();
+                if (sub(index, (PIT_FR1_8b - PIT_MIN) * 2) < 0)
+                {
+                    T0 = add(PIT_MIN, shr(index, 1));
+                    T0_frac = sub(index, shl(sub(T0, PIT_MIN), 1));
+                    T0_frac = shl(T0_frac, 1);
+                } else
+                {
+                    T0 = add(index, PIT_FR1_8b - ((PIT_FR1_8b - PIT_MIN) * 2));
+                    T0_frac = 0;           move16();
+                }
+            } else
+            {
+                index = Serial_parm(9, &prms);
+                test();test();
+                if (sub(index, (PIT_FR2 - PIT_MIN) * 4) < 0)
+                {
+                    T0 = add(PIT_MIN, shr(index, 2));
+                    T0_frac = sub(index, shl(sub(T0, PIT_MIN), 2));
+                } else if (sub(index, (((PIT_FR2 - PIT_MIN) * 4) + ((PIT_FR1_9b - PIT_FR2) * 2))) < 0)
+                {
+                    index = sub(index, (PIT_FR2 - PIT_MIN) * 4);
+                    T0 = add(PIT_FR2, shr(index, 1));
+                    T0_frac = sub(index, shl(sub(T0, PIT_FR2), 1));
+                    T0_frac = shl(T0_frac, 1);
+                } else
+                {
+                    T0 = add(index, (PIT_FR1_9b - ((PIT_FR2 - PIT_MIN) * 4) - ((PIT_FR1_9b - PIT_FR2) * 2)));
+                    T0_frac = 0;           move16();
+                }
+            }
+
+            /* find T0_min and T0_max for subframe 2 and 4 */
+
+            T0_min = sub(T0, 8);
+            test();
+            if (sub(T0_min, PIT_MIN) < 0)
+            {
+                T0_min = PIT_MIN;          move16();
+            }
+            T0_max = add(T0_min, 15);
+            test();
+            if (sub(T0_max, PIT_MAX) > 0)
+            {
+                T0_max = PIT_MAX;          move16();
+                T0_min = sub(T0_max, 15);
+            }
+        } else
+        {                                  /* if subframe 2 or 4 */
+            test();
+            if (sub(nb_bits, NBBITS_9k) <= 0)
+            {
+                index = Serial_parm(5, &prms);
+
+                T0 = add(T0_min, shr(index, 1));
+                T0_frac = sub(index, shl(sub(T0, T0_min), 1));
+                T0_frac = shl(T0_frac, 1);
+            } else
+            {
+                index = Serial_parm(6, &prms);
+
+                T0 = add(T0_min, shr(index, 2));
+                T0_frac = sub(index, shl(sub(T0, T0_min), 2));
+            }
+        }
+
+        /* check BFI after pitch lag decoding */
+        test();
+        if (bfi != 0)                      /* if frame erasure */
+        {
+            lagconc(&(st->dec_gain[17]), st->lag_hist, &T0, &(st->old_T0), &(st->seed3), unusable_frame);
+            T0_frac = 0;                   move16();
+        }
+        /*-------------------------------------------------*
+         * - Find the pitch gain, the interpolation filter *
+         *   and the adaptive codebook vector.             *
+         *-------------------------------------------------*/
+
+        Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1);
+
+        test();
+        if (unusable_frame)
+        {
+            select = 1;                    move16();
+        } else
+        {
+            test();
+            if (sub(nb_bits, NBBITS_9k) <= 0)
+            {
+                select = 0;                move16();
+            } else
+            {
+                select = Serial_parm(1, &prms);
+            }
+        }
+
+        test();
+        if (select == 0)
+        {
+            /* find pitch excitation with lp filter */
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                L_tmp = L_mult(5898, exc[i - 1 + i_subfr]);
+                L_tmp = L_mac(L_tmp, 20972, exc[i + i_subfr]);
+                L_tmp = L_mac(L_tmp, 5898, exc[i + 1 + i_subfr]);
+                code[i] = round(L_tmp);    move16();
+            }
+            Copy(code, &exc[i_subfr], L_SUBFR);
+        }
+        /*-------------------------------------------------------*
+         * - Decode innovative codebook.                         *
+         * - Add the fixed-gain pitch contribution to code[].    *
+         *-------------------------------------------------------*/
+        test();test();test();test();test();test();test();test();
+        if (unusable_frame != 0)
+        {
+            /* the innovative code doesn't need to be scaled (see Q_gain2) */
+            for (i = 0; i < L_SUBFR; i++)
+            {
+                code[i] = shr(Random(&(st->seed)), 3);  move16();
+            }
+        } else if (sub(nb_bits, NBBITS_7k) <= 0)
+        {
+            ind[0] = Serial_parm(12, &prms);    move16();
+            DEC_ACELP_2t64_fx(ind[0], code);
+        } else if (sub(nb_bits, NBBITS_9k) <= 0)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                ind[i] = Serial_parm(5, &prms); move16();
+            }
+            DEC_ACELP_4t64_fx(ind, 20, code);
+        } else if (sub(nb_bits, NBBITS_12k) <= 0)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                ind[i] = Serial_parm(9, &prms); move16();
+            }
+            DEC_ACELP_4t64_fx(ind, 36, code);
+        } else if (sub(nb_bits, NBBITS_14k) <= 0)
+        {
+            ind[0] = Serial_parm(13, &prms);    move16();
+            ind[1] = Serial_parm(13, &prms);    move16();
+            ind[2] = Serial_parm(9, &prms);move16();
+            ind[3] = Serial_parm(9, &prms);move16();
+            DEC_ACELP_4t64_fx(ind, 44, code);
+        } else if (sub(nb_bits, NBBITS_16k) <= 0)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                ind[i] = Serial_parm(13, &prms);        move16();
+            }
+            DEC_ACELP_4t64_fx(ind, 52, code);
+        } else if (sub(nb_bits, NBBITS_18k) <= 0)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                ind[i] = Serial_parm(2, &prms); move16();
+            }
+            for (i = 4; i < 8; i++)
+            {
+                ind[i] = Serial_parm(14, &prms);        move16();
+            }
+            DEC_ACELP_4t64_fx(ind, 64, code);
+        } else if (sub(nb_bits, NBBITS_20k) <= 0)
+        {
+            ind[0] = Serial_parm(10, &prms);    move16();
+            ind[1] = Serial_parm(10, &prms);    move16();
+            ind[2] = Serial_parm(2, &prms);move16();
+            ind[3] = Serial_parm(2, &prms);move16();
+            ind[4] = Serial_parm(10, &prms);    move16();
+            ind[5] = Serial_parm(10, &prms);    move16();
+            ind[6] = Serial_parm(14, &prms);    move16();
+            ind[7] = Serial_parm(14, &prms);    move16();
+            DEC_ACELP_4t64_fx(ind, 72, code);
+        } else
+        {
+            for (i = 0; i < 4; i++)
+            {
+                ind[i] = Serial_parm(11, &prms);        move16();
+            }
+            for (i = 4; i < 8; i++)
+            {
+                ind[i] = Serial_parm(11, &prms);        move16();
+            }
+            DEC_ACELP_4t64_fx(ind, 88, code);
+        }
+
+        tmp = 0;                           move16();
+        Preemph(code, st->tilt_code, L_SUBFR, &tmp);
+
+        tmp = T0;                          move16();
+        test();
+        if (sub(T0_frac, 2) > 0)
+        {
+            tmp = add(tmp, 1);
+        }
+        Pit_shrp(code, tmp, PIT_SHARP, L_SUBFR);
+
+        /*-------------------------------------------------*
+         * - Decode codebooks gains.                       *
+         *-------------------------------------------------*/
+        test();
+        if (sub(nb_bits, NBBITS_9k) <= 0)
+        {
+            index = Serial_parm(6, &prms); /* codebook gain index */
+
+            D_gain2(index, 6, code, L_SUBFR, &gain_pit, &L_gain_code, bfi, st->prev_bfi, st->state, unusable_frame, st->vad_hist, st->dec_gain);
+        } else
+        {
+            index = Serial_parm(7, &prms); /* codebook gain index */
+
+            D_gain2(index, 7, code, L_SUBFR, &gain_pit, &L_gain_code, bfi, st->prev_bfi, st->state, unusable_frame, st->vad_hist, st->dec_gain);
+        }
+
+        /* find best scaling to perform on excitation (Q_new) */
+
+        tmp = st->Qsubfr[0];
+        for (i = 1; i < 4; i++)
+        {
+            test();move16();
+            if (sub(st->Qsubfr[i], tmp) < 0)
+            {
+                tmp = st->Qsubfr[i];       move16();
+            }
+        }
+
+        /* limit scaling (Q_new) to Q_MAX: see cnst.h and syn_filt_32() */
+        test();
+        if (sub(tmp, Q_MAX) > 0)
+        {
+            tmp = Q_MAX;                   move16();
+        }
+        Q_new = 0;                         move16();
+        L_tmp = L_gain_code;               move32();  /* L_gain_code in Q16 */
+
+        test();test();
+        while ((L_sub(L_tmp, 0x08000000L) < 0) && (sub(Q_new, tmp) < 0))
+        {
+            L_tmp = L_shl(L_tmp, 1);
+            Q_new = add(Q_new, 1);
+            test();test();
+        }
+        gain_code = round(L_tmp);          /* scaled gain_code with Qnew */
+
+        Scale_sig(exc + i_subfr - (PIT_MAX + L_INTERPOL),
+            PIT_MAX + L_INTERPOL + L_SUBFR, sub(Q_new, st->Q_old));
+        st->Q_old = Q_new;                 move16();
+
+
+        /*----------------------------------------------------------*
+         * Update parameters for the next subframe.                 *
+         * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced)           *
+         *----------------------------------------------------------*/
+
+        test();
+        if (bfi == 0)
+        {
+            /* LTP-Lag history update */
+            for (i = 4; i > 0; i--)
+            {
+                st->lag_hist[i] = st->lag_hist[i - 1];  move16();
+            }
+            st->lag_hist[0] = T0;          move16();
+
+            st->old_T0 = T0;               move16();
+            st->old_T0_frac = 0;           move16();  /* Remove fraction in case of BFI */
+        }
+        /* find voice factor in Q15 (1=voiced, -1=unvoiced) */
+
+        Copy(&exc[i_subfr], exc2, L_SUBFR);
+        Scale_sig(exc2, L_SUBFR, -3);
+
+        /* post processing of excitation elements */
+        test();
+        if (sub(nb_bits, NBBITS_9k) <= 0)
+        {
+            pit_sharp = shl(gain_pit, 1);
+            test();
+            if (sub(pit_sharp, 16384) > 0)
+            {
+                for (i = 0; i < L_SUBFR; i++)
+                {
+                    tmp = mult(exc2[i], pit_sharp);
+                    L_tmp = L_mult(tmp, gain_pit);
+                    L_tmp = L_shr(L_tmp, 1);
+                    excp[i] = round(L_tmp);
+                    move16();
+                }
+            }
+        } else
+        {
+            pit_sharp = 0;                 move16();
+        }
+
+        voice_fac = voice_factor(exc2, -3, gain_pit, code, gain_code, L_SUBFR);
+
+        /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
+
+        st->tilt_code = add(shr(voice_fac, 2), 8192);   move16();
+
+        /*-------------------------------------------------------*
+         * - Find the total excitation.                          *
+         * - Find synthesis speech corresponding to exc[].       *
+         *-------------------------------------------------------*/
+
+        Copy(&exc[i_subfr], exc2, L_SUBFR);
+
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            L_tmp = L_mult(code[i], gain_code);
+            L_tmp = L_shl(L_tmp, 5);
+            L_tmp = L_mac(L_tmp, exc[i + i_subfr], gain_pit);
+            L_tmp = L_shl(L_tmp, 1);
+            exc[i + i_subfr] = round(L_tmp);    move16();
+        }
+
+        /* find maximum value of excitation for next scaling */
+
+        max = 1;                           move16();
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            tmp = abs_s(exc[i + i_subfr]);
+            test();
+            if (sub(tmp, max) > 0)
+            {
+                max = tmp;                 move16();
+            }
+        }
+
+        /* tmp = scaling possible according to max value of excitation */
+        tmp = sub(add(norm_s(max), Q_new), 1);
+
+        st->Qsubfr[3] = st->Qsubfr[2];     move16();
+        st->Qsubfr[2] = st->Qsubfr[1];     move16();
+        st->Qsubfr[1] = st->Qsubfr[0];     move16();
+        st->Qsubfr[0] = tmp;               move16();
+
+        /*------------------------------------------------------------*
+         * phase dispersion to enhance noise in low bit rate          *
+         *------------------------------------------------------------*/
+
+        /* L_gain_code in Q16 */
+        L_Extract(L_gain_code, &gain_code, &gain_code_lo);
+        test();test();move16();
+        if (sub(nb_bits, NBBITS_7k) <= 0)
+            j = 0;                         /* high dispersion for rate <= 7.5 kbit/s */
+        else if (sub(nb_bits, NBBITS_9k) <= 0)
+            j = 1;                         /* low dispersion for rate <= 9.6 kbit/s */
+        else
+            j = 2;                         /* no dispersion for rate > 9.6 kbit/s */
+
+        Phase_dispersion(gain_code, gain_pit, code, j, st->disp_mem);
+
+        /*------------------------------------------------------------*
+         * noise enhancer                                             *
+         * ~~~~~~~~~~~~~~                                             *
+         * - Enhance excitation on noise. (modify gain of code)       *
+         *   If signal is noisy and LPC filter is stable, move gain   *
+         *   of code 1.5 dB toward gain of code threshold.            *
+         *   This decrease by 3 dB noise energy variation.            *
+         *------------------------------------------------------------*/
+
+        tmp = sub(16384, shr(voice_fac, 1));    /* 1=unvoiced, 0=voiced */
+        fac = mult(stab_fac, tmp);
+
+        L_tmp = L_gain_code;               move32();
+        test();
+        if (L_sub(L_tmp, st->L_gc_thres) < 0)
+        {
+            L_tmp = L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226));
+            test();
+            if (L_sub(L_tmp, st->L_gc_thres) > 0)
+            {
+                L_tmp = st->L_gc_thres;    move32();
+            }
+        } else
+        {
+            L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536);
+            test();
+            if (L_sub(L_tmp, st->L_gc_thres) < 0)
+            {
+                L_tmp = st->L_gc_thres;    move32();
+            }
+        }
+        st->L_gc_thres = L_tmp;            move32();
+
+        L_gain_code = Mpy_32_16(gain_code, gain_code_lo, sub(32767, fac));
+        L_Extract(L_tmp, &gain_code, &gain_code_lo);
+        L_gain_code = L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac));
+
+        /*------------------------------------------------------------*
+         * pitch enhancer                                             *
+         * ~~~~~~~~~~~~~~                                             *
+         * - Enhance excitation on voice. (HP filtering of code)      *
+         *   On voiced signal, filtering of code by a smooth fir HP   *
+         *   filter to decrease energy of code in low frequency.      *
+         *------------------------------------------------------------*/
+
+        tmp = add(shr(voice_fac, 3), 4096);/* 0.25=voiced, 0=unvoiced */
+
+        L_tmp = L_deposit_h(code[0]);
+        L_tmp = L_msu(L_tmp, code[1], tmp);
+        code2[0] = round(L_tmp);
+        move16();
+
+        for (i = 1; i < L_SUBFR - 1; i++)
+        {
+            L_tmp = L_deposit_h(code[i]);
+            L_tmp = L_msu(L_tmp, code[i + 1], tmp);
+            L_tmp = L_msu(L_tmp, code[i - 1], tmp);
+            code2[i] = round(L_tmp);
+            move16();
+        }
+
+        L_tmp = L_deposit_h(code[L_SUBFR - 1]);
+        L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);
+        code2[L_SUBFR - 1] = round(L_tmp);
+        move16();
+
+        /* build excitation */
+
+        gain_code = round(L_shl(L_gain_code, Q_new));
+
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            L_tmp = L_mult(code2[i], gain_code);
+            L_tmp = L_shl(L_tmp, 5);
+            L_tmp = L_mac(L_tmp, exc2[i], gain_pit);
+            L_tmp = L_shl(L_tmp, 1);       /* saturation can occur here */
+            exc2[i] = round(L_tmp);
+            move16();
+        }
+
+        if (sub(nb_bits, NBBITS_9k) <= 0)
+        {
+            if (sub(pit_sharp, 16384) > 0)
+            {
+                for (i = 0; i < L_SUBFR; i++)
+                {
+                    excp[i] = add(excp[i], exc2[i]);
+                    move16();
+                }
+                agc2(exc2, excp, L_SUBFR);
+                Copy(excp, exc2, L_SUBFR);
+            }
+        }
+        if (sub(nb_bits, NBBITS_7k) <= 0)
+        {
+            j = shr(i_subfr, 6);
+            for (i = 0; i < M; i++)
+            {
+                L_tmp = L_mult(isf_tmp[i], sub(32767, interpol_frac[j]));
+                L_tmp = L_mac(L_tmp, isf[i], interpol_frac[j]);
+                HfIsf[i] = round(L_tmp);
+            }
+        } else
+        {
+            Set_zero(st->mem_syn_hf, M16k - M);
+        }
+
+        if (sub(nb_bits, NBBITS_24k) >= 0)
+        {
+            corr_gain = Serial_parm(4, &prms);
+            synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], corr_gain, HfIsf, nb_bits, newDTXState, st, bfi);
+        } else
+            synthesis(p_Aq, exc2, Q_new, &synth16k[i_subfr * 5 / 4], 0, HfIsf, nb_bits, newDTXState, st, bfi);
+
+        p_Aq += (M + 1);                   /* interpolated LPC parameters for next subframe */
+    }
+
+    /*--------------------------------------------------*
+     * Update signal for next frame.                    *
+     * -> save past of exc[].                           *
+     * -> save pitch parameters.                        *
+     *--------------------------------------------------*/
+
+    Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL);
+
+    Scale_sig(exc, L_FRAME, sub(0, Q_new));
+    dtx_dec_activity_update(st->dtx_decSt, isf, exc);
+
+    st->dtx_decSt->dtxGlobalState = newDTXState;        move16();
+
+    st->prev_bfi = bfi;                    move16();
+
+    return;
+}
+
+
+
+/*-----------------------------------------------------*
+ * Function synthesis()                                *
+ *                                                     *
+ * Synthesis of signal at 16kHz with HF extension.     *
+ *                                                     *
+ *-----------------------------------------------------*/
+
+static void synthesis(
+     Word16 Aq[],                          /* A(z)  : quantized Az               */
+     Word16 exc[],                         /* (i)   : excitation at 12kHz        */
+     Word16 Q_new,                         /* (i)   : scaling performed on exc   */
+     Word16 synth16k[],                    /* (o)   : 16kHz synthesis signal     */
+     Word16 prms,                          /* (i)   : parameter                  */
+     Word16 HfIsf[],
+     Word16 nb_bits,
+     Word16 newDTXState,
+     Decoder_State * st,                   /* (i/o) : State structure            */
+     Word16 bfi                            /* (i)   : bad frame indicator        */
+)
+{
+    Word16 i, fac, tmp, exp;
+    Word16 ener, exp_ener;
+    Word32 L_tmp;
+
+    Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
+    Word16 synth[L_SUBFR];
+    Word16 HF[L_SUBFR16k];                 /* High Frequency vector      */
+    Word16 Ap[M16k + 1];
+    Word16 HfA[M16k + 1];
+    Word16 HF_corr_gain;
+    Word16 HF_gain_ind;
+    Word16 gain1, gain2;
+    Word16 weight1, weight2;
+
+    /*------------------------------------------------------------*
+     * speech synthesis                                           *
+     * ~~~~~~~~~~~~~~~~                                           *
+     * - Find synthesis speech corresponding to exc2[].           *
+     * - Perform fixed deemphasis and hp 50hz filtering.          *
+     * - Oversampling from 12.8kHz to 16kHz.                      *
+     *------------------------------------------------------------*/
+
+    Copy(st->mem_syn_hi, synth_hi, M);
+    Copy(st->mem_syn_lo, synth_lo, M);
+
+    Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
+
+    Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M);
+    Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M);
+
+    Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph));
+
+    HP50_12k8(synth, L_SUBFR, st->mem_sig_out);
+
+    Oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp);
+
+    /*------------------------------------------------------*
+    * HF noise synthesis                                   *
+    * ~~~~~~~~~~~~~~~~~~                                   *
+    * - Generate HF noise between 5.5 and 7.5 kHz.         *
+    * - Set energy of noise according to synthesis tilt.   *
+    *     tilt > 0.8 ==> - 14 dB (voiced)                  *
+    *     tilt   0.5 ==> - 6 dB  (voiced or noise)         *
+    *     tilt < 0.0 ==>   0 dB  (noise)                   *
+    *------------------------------------------------------*/
+
+    /* generate white noise vector */
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        HF[i] = shr(Random(&(st->seed2)), 3);   move16();
+    }
+    /* energy of excitation */
+
+    Scale_sig(exc, L_SUBFR, -3);
+    Q_new = sub(Q_new, 3);
+
+    ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener));
+    exp_ener = sub(exp_ener, add(Q_new, Q_new));
+
+    /* set energy of white noise to energy of excitation */
+
+    tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp));
+    test();
+    if (sub(tmp, ener) > 0)
+    {
+        tmp = shr(tmp, 1);                 /* Be sure tmp < ener */
+        exp = add(exp, 1);
+    }
+    L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */
+    exp = sub(exp, exp_ener);
+    Isqrt_n(&L_tmp, &exp);
+    L_tmp = L_shl(L_tmp, add(exp, 1));     /* L_tmp x 2, L_tmp in Q31 */
+    tmp = extract_h(L_tmp);                /* tmp = 2 x sqrt(ener_exc/ener_hf) */
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        HF[i] = mult(HF[i], tmp);          move16();
+    }
+    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
+
+    HP400_12k8(synth, L_SUBFR, st->mem_hp400);
+
+    L_tmp = 1L;                            move32();
+    for (i = 0; i < L_SUBFR; i++)
+        L_tmp = L_mac(L_tmp, synth[i], synth[i]);
+
+    exp = norm_l(L_tmp);
+    ener = extract_h(L_shl(L_tmp, exp));   /* ener = r[0] */
+
+    L_tmp = 1L;                            move32();
+    for (i = 1; i < L_SUBFR; i++)
+        L_tmp = L_mac(L_tmp, synth[i], synth[i - 1]);
+
+    tmp = extract_h(L_shl(L_tmp, exp));    /* tmp = r[1] */
+    test();
+    if (tmp > 0)
+    {
+        fac = div_s(tmp, ener);
+    } else
+    {
+        fac = 0;                           move16();
+    }
+
+    /* modify energy of white noise according to synthesis tilt */
+    gain1 = sub(32767, fac);
+    gain2 = mult(sub(32767, fac), 20480);
+    gain2 = shl(gain2, 1);
+
+    test();
+    if (st->vad_hist > 0)
+    {
+        weight1 = 0;                       move16();
+        weight2 = 32767;                   move16();
+    } else
+    {
+        weight1 = 32767;                   move16();
+        weight2 = 0;                       move16();
+    }
+    tmp = mult(weight1, gain1);
+    tmp = add(tmp, mult(weight2, gain2));
+
+    test();
+    if (tmp != 0)
+    {
+        tmp = add(tmp, 1);
+    }
+    test();
+    if (sub(tmp, 3277) < 0)
+    {
+        tmp = 3277;                        /* 0.1 in Q15 */
+        move16();
+    }
+    test(); test();
+    if ((sub(nb_bits, NBBITS_24k) >= 0 ) && (bfi == 0))
+    {
+        /* HF correction gain */
+        HF_gain_ind = prms;
+        HF_corr_gain = HP_gain[HF_gain_ind];
+
+        /* HF gain */
+        for (i = 0; i < L_SUBFR16k; i++)
+        {
+            HF[i] = shl(mult(HF[i], HF_corr_gain), 1);  move16();
+        }
+    } else
+    {
+        for (i = 0; i < L_SUBFR16k; i++)
+        {
+            HF[i] = mult(HF[i], tmp);      move16();
+        }
+    }
+
+    test();test();
+    if ((sub(nb_bits, NBBITS_7k) <= 0) && (sub(newDTXState, SPEECH) == 0))
+    {
+        Isf_Extrapolation(HfIsf);
+        Isp_Az(HfIsf, HfA, M16k, 0);
+
+        Weight_a(HfA, Ap, 29491, M16k);    /* fac=0.9 */
+        Syn_filt(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
+    } else
+    {
+        /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
+        Weight_a(Aq, Ap, 19661, M);        /* fac=0.6 */
+        Syn_filt(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1);
+    }
+
+    /* noise High Pass filtering (1ms of delay) */
+    Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf);
+
+    test();
+    if (sub(nb_bits, NBBITS_24k) >= 0)
+    {
+        /* Low Pass filtering (7 kHz) */
+        Filt_7k(HF, L_SUBFR16k, st->mem_hf3);
+    }
+    /* add filtered HF noise to speech synthesis */
+    for (i = 0; i < L_SUBFR16k; i++)
+    {
+        synth16k[i] = add(synth16k[i], HF[i]);  move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/dec_main.h
@@ -1,0 +1,46 @@
+/*--------------------------------------------------------------------------*
+ *                         DEC_MAIN.H                                       *
+ *--------------------------------------------------------------------------*
+ *       Static memory in the decoder                                       *
+ *--------------------------------------------------------------------------*/
+
+#include "cnst.h"                          /* coder constant parameters */
+#include "dtx.h"
+
+typedef struct
+{
+    Word16 old_exc[PIT_MAX + L_INTERPOL];  /* old excitation vector */
+    Word16 ispold[M];                      /* old isp (immittance spectral pairs) */
+    Word16 isfold[M];                      /* old isf (frequency domain) */
+    Word16 isf_buf[L_MEANBUF * M];         /* isf buffer(frequency domain) */
+    Word16 past_isfq[M];                   /* past isf quantizer */
+    Word16 tilt_code;                      /* tilt of code */
+    Word16 Q_old;                          /* old scaling factor */
+    Word16 Qsubfr[4];                      /* old maximum scaling factor */
+    Word32 L_gc_thres;                     /* threshold for noise enhancer */
+    Word16 mem_syn_hi[M];                  /* modified synthesis memory (MSB) */
+    Word16 mem_syn_lo[M];                  /* modified synthesis memory (LSB) */
+    Word16 mem_deemph;                     /* speech deemph filter memory */
+    Word16 mem_sig_out[6];                 /* hp50 filter memory for synthesis */
+    Word16 mem_oversamp[2 * L_FILT];       /* synthesis oversampled filter memory */
+    Word16 mem_syn_hf[M16k];               /* HF synthesis memory */
+    Word16 mem_hf[2 * L_FILT16k];          /* HF band-pass filter memory */
+    Word16 mem_hf2[2 * L_FILT16k];         /* HF band-pass filter memory */
+    Word16 mem_hf3[2 * L_FILT16k];         /* HF band-pass filter memory */
+    Word16 seed;                           /* random memory for frame erasure */
+    Word16 seed2;                          /* random memory for HF generation */
+    Word16 old_T0;                         /* old pitch lag */
+    Word16 old_T0_frac;                    /* old pitch fraction lag */
+    Word16 lag_hist[5];
+    Word16 dec_gain[23];                   /* gain decoder memory */
+    Word16 seed3;                          /* random memory for lag concealment */
+    Word16 disp_mem[8];                    /* phase dispersion memory */
+    Word16 mem_hp400[6];                   /* hp400 filter memory for synthesis */
+
+    Word16 prev_bfi;
+    Word16 state;
+    Word16 first_frame;
+    dtx_decState *dtx_decSt;
+    Word16 vad_hist;
+
+} Decoder_State;
--- /dev/null
+++ b/amr-wb/decim54.c
@@ -1,0 +1,243 @@
+/*-------------------------------------------------------------------*
+ *                         DECIM54.C                                 *
+ *-------------------------------------------------------------------*
+ * Decim_12k8   : decimation of 16kHz signal to 12.8kHz.             *
+ * Oversamp_16k : oversampling from 12.8kHz to 16kHz.                *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "count.h"
+#include "cnst.h"
+
+#define FAC4   4
+#define FAC5   5
+#define INV_FAC5   6554                    /* 1/5 in Q15 */
+#define DOWN_FAC  26215                    /* 4/5 in Q15 */
+#define UP_FAC    20480                    /* 5/4 in Q14 */
+
+#define NB_COEF_DOWN  15
+#define NB_COEF_UP    12
+
+/* Local functions */
+static void Down_samp(
+     Word16 * sig,                         /* input:  signal to downsampling  */
+     Word16 * sig_d,                       /* output: downsampled signal      */
+     Word16 L_frame_d                      /* input:  length of output        */
+);
+static void Up_samp(
+     Word16 * sig_d,                       /* input:  signal to oversampling  */
+     Word16 * sig_u,                       /* output: oversampled signal      */
+     Word16 L_frame                        /* input:  length of output        */
+);
+static Word16 Interpol(                    /* return result of interpolation */
+     Word16 * x,                           /* input vector                   */
+     Word16 * fir,                         /* filter coefficient             */
+     Word16 frac,                          /* fraction (0..resol)            */
+     Word16 resol,                         /* resolution                     */
+     Word16 nb_coef                        /* number of coefficients         */
+);
+
+
+/* 1/5 resolution interpolation filter  (in Q14)  */
+/* -1.5dB @ 6kHz, -6dB @ 6.4kHz, -10dB @ 6.6kHz, -20dB @ 6.9kHz, -25dB @ 7kHz, -55dB @ 8kHz */
+
+static Word16 fir_up[120] =
+{
+    -1, -4, -7, -6, 0,
+    12, 24, 30, 23, 0,
+    -33, -62, -73, -52, 0,
+    68, 124, 139, 96, 0,
+    -119, -213, -235, -160, 0,
+    191, 338, 368, 247, 0,
+    -291, -510, -552, -369, 0,
+    430, 752, 812, 542, 0,
+    -634, -1111, -1204, -809, 0,
+    963, 1708, 1881, 1288, 0,
+    -1616, -2974, -3432, -2496, 0,
+    3792, 8219, 12368, 15317, 16384,
+    15317, 12368, 8219, 3792, 0,
+    -2496, -3432, -2974, -1616, 0,
+    1288, 1881, 1708, 963, 0,
+    -809, -1204, -1111, -634, 0,
+    542, 812, 752, 430, 0,
+    -369, -552, -510, -291, 0,
+    247, 368, 338, 191, 0,
+    -160, -235, -213, -119, 0,
+    96, 139, 124, 68, 0,
+    -52, -73, -62, -33, 0,
+    23, 30, 24, 12, 0,
+    -6, -7, -4, -1, 0
+};
+
+static Word16 fir_down[120] =
+{            /* table x4/5 */
+    -1, -3, -6, -5,
+    0, 9, 19, 24,
+    18, 0, -26, -50,
+    -58, -41, 0, 54,
+    99, 111, 77, 0,
+    -95, -170, -188, -128,
+    0, 153, 270, 294,
+    198, 0, -233, -408,
+    -441, -295, 0, 344,
+    601, 649, 434, 0,
+    -507, -888, -964, -647,
+    0, 770, 1366, 1505,
+    1030, 0, -1293, -2379,
+    -2746, -1997, 0, 3034,
+    6575, 9894, 12254, 13107,
+    12254, 9894, 6575, 3034,
+    0, -1997, -2746, -2379,
+    -1293, 0, 1030, 1505,
+    1366, 770, 0, -647,
+    -964, -888, -507, 0,
+    434, 649, 601, 344,
+    0, -295, -441, -408,
+    -233, 0, 198, 294,
+    270, 153, 0, -128,
+    -188, -170, -95, 0,
+    77, 111, 99, 54,
+    0, -41, -58, -50,
+    -26, 0, 18, 24,
+    19, 9, 0, -5,
+    -6, -3, -1, 0
+};
+
+
+
+void Init_Decim_12k8(
+     Word16 mem[]                          /* output: memory (2*NB_COEF_DOWN) set to zeros */
+)
+{
+    Set_zero(mem, 2 * NB_COEF_DOWN);
+    return;
+}
+
+void Decim_12k8(
+     Word16 sig16k[],                      /* input:  signal to downsampling  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 sig12k8[],                     /* output: decimated signal        */
+     Word16 mem[]                          /* in/out: memory (2*NB_COEF_DOWN) */
+)
+{
+    Word16 lg_down;
+    Word16 signal[L_FRAME16k + (2 * NB_COEF_DOWN)];
+
+    Copy(mem, signal, 2 * NB_COEF_DOWN);
+
+    Copy(sig16k, signal + (2 * NB_COEF_DOWN), lg);
+
+    lg_down = mult(lg, DOWN_FAC);
+
+    Down_samp(signal + NB_COEF_DOWN, sig12k8, lg_down);
+
+    Copy(signal + lg, mem, 2 * NB_COEF_DOWN);
+
+    return;
+}
+
+
+void Init_Oversamp_16k(
+     Word16 mem[]                          /* output: memory (2*NB_COEF_UP) set to zeros  */
+)
+{
+    Set_zero(mem, 2 * NB_COEF_UP);
+    return;
+}
+
+void Oversamp_16k(
+     Word16 sig12k8[],                     /* input:  signal to oversampling  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 sig16k[],                      /* output: oversampled signal      */
+     Word16 mem[]                          /* in/out: memory (2*NB_COEF_UP)   */
+)
+{
+    Word16 lg_up;
+    Word16 signal[L_SUBFR + (2 * NB_COEF_UP)];
+
+    Copy(mem, signal, 2 * NB_COEF_UP);
+
+    Copy(sig12k8, signal + (2 * NB_COEF_UP), lg);
+
+    lg_up = shl(mult(lg, UP_FAC), 1);
+
+    Up_samp(signal + NB_COEF_UP, sig16k, lg_up);
+
+    Copy(signal + lg, mem, 2 * NB_COEF_UP);
+
+    return;
+}
+
+
+static void Down_samp(
+     Word16 * sig,                         /* input:  signal to downsampling  */
+     Word16 * sig_d,                       /* output: downsampled signal      */
+     Word16 L_frame_d                      /* input:  length of output        */
+)
+{
+    Word16 i, j, frac, pos;
+
+    pos = 0;                               move16();  /* position is in Q2 -> 1/4 resolution  */
+    for (j = 0; j < L_frame_d; j++)
+    {
+        i = shr(pos, 2);                   /* integer part     */
+        frac = (Word16) (pos & 3);         logic16();  /* fractional part */
+
+        sig_d[j] = Interpol(&sig[i], fir_down, frac, FAC4, NB_COEF_DOWN);       move16();
+
+        pos = add(pos, FAC5);              /* pos + 5/4 */
+    }
+
+    return;
+}
+
+
+static void Up_samp(
+     Word16 * sig_d,                       /* input:  signal to oversampling  */
+     Word16 * sig_u,                       /* output: oversampled signal      */
+     Word16 L_frame                        /* input:  length of output        */
+)
+{
+    Word16 i, j, pos, frac;
+
+    pos = 0;                               move16();  /* position with 1/5 resolution */
+
+    for (j = 0; j < L_frame; j++)
+    {
+        i = mult(pos, INV_FAC5);           /* integer part = pos * 1/5 */
+        frac = sub(pos, add(shl(i, 2), i));/* frac = pos - (pos/5)*5   */
+
+        sig_u[j] = Interpol(&sig_d[i], fir_up, frac, FAC5, NB_COEF_UP); move16();
+
+        pos = add(pos, FAC4);              /* position + 4/5 */
+    }
+
+    return;
+}
+
+/* Fractional interpolation of signal at position (frac/resol) */
+
+static Word16 Interpol(                    /* return result of interpolation */
+     Word16 * x,                           /* input vector                   */
+     Word16 * fir,                         /* filter coefficient             */
+     Word16 frac,                          /* fraction (0..resol)            */
+     Word16 resol,                         /* resolution                     */
+     Word16 nb_coef                        /* number of coefficients         */
+)
+{
+    Word16 i, k;
+    Word32 L_sum;
+
+    x = x - nb_coef + 1;                   move16();
+
+    L_sum = 0L;                            move32();
+    for (i = 0, k = sub(sub(resol, 1), frac); i < 2 * nb_coef; i++, k = (Word16) (k + resol))
+    {
+        L_sum = L_mac(L_sum, x[i], fir[k]);
+    }
+    L_sum = L_shl(L_sum, 1);               /* saturation can occur here */
+
+    return (round(L_sum));
+}
--- /dev/null
+++ b/amr-wb/deemph.c
@@ -1,0 +1,108 @@
+/*-------------------------------------------------------------------*
+ *                         DEEMPH.C                                  *
+ *-------------------------------------------------------------------*
+ * Deemphasis: filtering through 1/(1-mu z^-1)                       *
+ *                                                                   *
+ * Deemph2   --> signal is divided by 2.                             *
+ * Deemph_32 --> for 32 bits signal.                                 *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+
+
+void Deemph(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor                      */
+     Word16 L,                             /* (i)     : vector size                            */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])                         */
+)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    L_tmp = L_deposit_h(x[0]);
+    L_tmp = L_mac(L_tmp, *mem, mu);
+    x[0] = round(L_tmp);                   move16();
+
+    for (i = 1; i < L; i++)
+    {
+        L_tmp = L_deposit_h(x[i]);
+        L_tmp = L_mac(L_tmp, x[i - 1], mu);
+        x[i] = round(L_tmp);               move16();
+    }
+
+    *mem = x[L - 1];                       move16();
+
+    return;
+}
+
+
+void Deemph2(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor                      */
+     Word16 L,                             /* (i)     : vector size                            */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])                         */
+)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    /* saturation can occur in L_mac() */
+
+    L_tmp = L_mult(x[0], 16384);
+    L_tmp = L_mac(L_tmp, *mem, mu);
+    x[0] = round(L_tmp);                   move16();
+
+    for (i = 1; i < L; i++)
+    {
+        L_tmp = L_mult(x[i], 16384);
+        L_tmp = L_mac(L_tmp, x[i - 1], mu);
+        x[i] = round(L_tmp);               move16();
+    }
+
+    *mem = x[L - 1];                       move16();
+
+    return;
+}
+
+
+void Deemph_32(
+     Word16 x_hi[],                        /* (i)     : input signal (bit31..16) */
+     Word16 x_lo[],                        /* (i)     : input signal (bit15..4)  */
+     Word16 y[],                           /* (o)     : output signal (x16)      */
+     Word16 mu,                            /* (i) Q15 : deemphasis factor        */
+     Word16 L,                             /* (i)     : vector size              */
+     Word16 * mem                          /* (i/o)   : memory (y[-1])           */
+)
+{
+    Word16 i, fac;
+    Word32 L_tmp;
+
+    fac = shr(mu, 1);                      /* Q15 --> Q14 */
+
+    /* L_tmp = hi<<16 + lo<<4 */
+
+    L_tmp = L_deposit_h(x_hi[0]);
+    L_tmp = L_mac(L_tmp, x_lo[0], 8);
+    L_tmp = L_shl(L_tmp, 3);
+    L_tmp = L_mac(L_tmp, *mem, fac);
+    L_tmp = L_shl(L_tmp, 1);               /* saturation can occur here */
+    y[0] = round(L_tmp);                   move16();
+
+    for (i = 1; i < L; i++)
+    {
+        L_tmp = L_deposit_h(x_hi[i]);
+        L_tmp = L_mac(L_tmp, x_lo[i], 8);
+        L_tmp = L_shl(L_tmp, 3);
+        L_tmp = L_mac(L_tmp, y[i - 1], fac);
+        L_tmp = L_shl(L_tmp, 1);           /* saturation can occur here */
+        y[i] = round(L_tmp);               move16();
+    }
+
+    *mem = y[L - 1];                       move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/dtx.c
@@ -1,0 +1,1276 @@
+/*-------------------------------------------------------------------*
+ *                         DTX.C                                     *
+ *-------------------------------------------------------------------*
+ * DTX functions                                                     *
+ *-------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "cnst.h"
+#include "acelp.h"                         /* prototype of functions    */
+#include "bits.h"
+#include "dtx.h"
+#include "count.h"
+#include "log2.h"
+
+static void aver_isf_history(
+     Word16 isf_old[],
+     Word16 indices[],
+     Word32 isf_aver[]
+);
+static void find_frame_indices(
+     Word16 isf_old_tx[],
+     Word16 indices[],
+     dtx_encState * st
+);
+
+static Word16 dithering_control(
+     dtx_encState * st
+);
+static void CN_dithering(
+     Word16 isf[M],
+     Word32 * L_log_en_int,
+     Word16 * dither_seed
+);
+
+/* excitation energy adjustment depending on speech coder mode used, Q7 */
+static Word16 en_adjust[9] =
+{
+    230,                                   /* mode0 = 7k  :  -5.4dB  */
+    179,                                   /* mode1 = 9k  :  -4.2dB  */
+    141,                                   /* mode2 = 12k :  -3.3dB  */
+    128,                                   /* mode3 = 14k :  -3.0dB  */
+    122,                                   /* mode4 = 16k :  -2.85dB */
+    115,                                   /* mode5 = 18k :  -2.7dB  */
+    115,                                   /* mode6 = 20k :  -2.7dB  */
+    115,                                   /* mode7 = 23k :  -2.7dB  */
+    115                                    /* mode8 = 24k :  -2.7dB  */
+};
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_enc_init
+ *
+ *
+ **************************************************************************/
+Word16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[])
+{
+    dtx_encState *s;
+
+    test();
+    if (st == (dtx_encState **) NULL)
+    {
+        fprintf(stderr, "dtx_enc_init: invalid parameter\n");
+        return -1;
+    }
+    *st = NULL;
+
+    /* allocate memory */
+    test();
+    if ((s = (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL)
+    {
+        fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
+        return -1;
+    }
+    dtx_enc_reset(s, isf_init);
+    *st = s;
+
+    return 0;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_enc_reset
+ *
+ *
+ **************************************************************************/
+Word16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[])
+{
+    Word16 i;
+
+    test();
+    if (st == (dtx_encState *) NULL)
+    {
+        fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
+        return -1;
+    }
+    st->hist_ptr = 0;                      move16();
+    st->log_en_index = 0;                  move16();
+
+    /* Init isf_hist[] */
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        Copy(isf_init, &st->isf_hist[i * M], M);
+    }
+    st->cng_seed = RANDOM_INITSEED;        move16();
+
+    /* Reset energy history */
+    Set_zero(st->log_en_hist, DTX_HIST_SIZE);
+
+    st->dtxHangoverCount = DTX_HANG_CONST; move16();
+    st->decAnaElapsedCount = 32767;        move16();
+
+    for (i = 0; i < 28; i++)
+    {
+        st->D[i] = 0;                      move16();
+    }
+
+    for (i = 0; i < DTX_HIST_SIZE - 1; i++)
+    {
+        st->sumD[i] = 0;                   move32();
+    }
+
+    return 1;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_enc_exit
+ *
+ *
+ **************************************************************************/
+void dtx_enc_exit(dtx_encState ** st)
+{
+    test();
+    if (st == NULL || *st == NULL)
+        return;
+
+    /* deallocate memory */
+    free(*st);
+    *st = NULL;
+
+    return;
+}
+
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_enc
+ *
+ *
+ **************************************************************************/
+Word16 dtx_enc(
+     dtx_encState * st,                    /* i/o : State struct                                         */
+     Word16 isf[M],                        /* o   : CN ISF vector                                        */
+     Word16 * exc2,                        /* o   : CN excitation                                        */
+     Word16 ** prms
+)
+{
+    Word16 i, j;
+    Word16 indice[7];
+    Word16 log_en, gain, level, exp, exp0, tmp;
+    Word16 log_en_int_e, log_en_int_m;
+    Word32 L_isf[M], ener32, level32;
+    Word16 isf_order[3];
+    Word16 CN_dith;
+
+    /* VOX mode computation of SID parameters */
+    log_en = 0;
+    move16();
+    for (i = 0; i < M; i++)
+    {
+        L_isf[i] = 0;
+        move32();
+    }
+    /* average energy and isf */
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */
+        log_en = add(log_en, st->log_en_hist[i]);
+
+    }
+    find_frame_indices(st->isf_hist, isf_order, st);
+    aver_isf_history(st->isf_hist, isf_order, L_isf);
+
+    for (j = 0; j < M; j++)
+    {
+        isf[j] = extract_l(L_shr(L_isf[j], 3)); move16();  /* divide by 8 */
+    }
+
+    /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E).  */
+    /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */
+
+    /* increase dynamics to 7 bits (Q8) */
+    log_en = shr(log_en, 2);
+
+    /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */
+    log_en = add(log_en, 512);
+
+    /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */
+    log_en = mult(log_en, 21504);
+
+    /* Quantize Energy */
+    st->log_en_index = shr(log_en, 6);
+
+    test();
+    if (sub(st->log_en_index, 63) > 0)
+    {
+        st->log_en_index = 63;
+        move16();
+    }
+    test();
+    if (st->log_en_index < 0)
+    {
+        st->log_en_index = 0;
+        move16();
+    }
+    /* Quantize ISFs */
+    Qisf_ns(isf, isf, indice);
+
+
+    Parm_serial(indice[0], 6, prms);
+    Parm_serial(indice[1], 6, prms);
+    Parm_serial(indice[2], 6, prms);
+    Parm_serial(indice[3], 5, prms);
+    Parm_serial(indice[4], 5, prms);
+
+    Parm_serial((st->log_en_index), 6, prms);
+
+    CN_dith = dithering_control(st);
+    Parm_serial(CN_dith, 1, prms);
+
+    /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) );    */
+    /* log2(E) in Q9 (log2(E) lies in between -2:22) */
+    log_en = shl(st->log_en_index, 15 - 6);
+
+    /* Divide by 2.625; log_en will be between 0:24  */
+    log_en = mult(log_en, 12483);
+    /* the result corresponds to log2(gain) in Q10 */
+
+    /* Find integer part  */
+    log_en_int_e = shr(log_en, 10);
+
+    /* Find fractional part */
+    log_en_int_m = (Word16) (log_en & 0x3ff);   logic16();
+    log_en_int_m = shl(log_en_int_m, 5);
+
+    /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */
+    /* Add 16 in order to have the result of pow2 in Q16 */
+    log_en_int_e = add(log_en_int_e, 16 - 1);
+
+    level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
+    exp0 = norm_l(level32);
+    level32 = L_shl(level32, exp0);        /* level in Q31 */
+    exp0 = sub(15, exp0);
+    level = extract_h(level32);            /* level in Q15 */
+
+    /* generate white noise vector */
+    for (i = 0; i < L_FRAME; i++)
+    {
+        exc2[i] = shr(Random(&(st->cng_seed)), 4);      move16();
+    }
+
+    /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
+
+    /* energy of generated excitation */
+    ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
+
+    Isqrt_n(&ener32, &exp);
+
+    gain = extract_h(ener32);
+
+    gain = mult(level, gain);              /* gain in Q15 */
+
+    exp = add(exp0, exp);
+
+    /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
+    exp = add(exp, 4);
+
+    for (i = 0; i < L_FRAME; i++)
+    {
+        tmp = mult(exc2[i], gain);         /* Q0 * Q15 */
+        exc2[i] = shl(tmp, exp);           move16();
+    }
+
+    return 0;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_buffer Purpose     : handles the DTX buffer
+ *
+ *
+ **************************************************************************/
+Word16 dtx_buffer(
+     dtx_encState * st,                    /* i/o : State struct                    */
+     Word16 isf_new[],                     /* i   : isf vector                      */
+     Word32 enr,                           /* i   : residual energy (in L_FRAME)    */
+     Word16 codec_mode
+)
+{
+    Word16 log_en;
+
+    Word16 log_en_e;
+    Word16 log_en_m;
+
+    st->hist_ptr = add(st->hist_ptr, 1);   move16();
+    test();
+    if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
+    {
+        st->hist_ptr = 0;
+        move16();
+    }
+    /* copy lsp vector into buffer */
+    Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M);
+
+    /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f);  */
+    Log2(enr, &log_en_e, &log_en_m);
+
+    /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
+    log_en = shl(log_en_e, 7);             /* Q7 */
+    log_en = add(log_en, shr(log_en_m, 15 - 7));
+
+    /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The
+     * constant 0.0059322 takes into account windowings and analysis length from autocorrelation
+     * computations; 7.39722 in Q7 = 947  */
+    /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+    /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */
+
+    /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0  (1024 in Q7) */
+    /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+
+    log_en = sub(log_en, add(1024, en_adjust[codec_mode]));
+
+    /* Insert into the buffer */
+    st->log_en_hist[st->hist_ptr] = log_en;move16();
+    return 0;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : tx_dtx_handler Purpose     : adds extra speech hangover
+ *                                            to analyze speech on
+ *                                            the decoding side.
+ *
+ **************************************************************************/
+void tx_dtx_handler(dtx_encState * st,     /* i/o : State struct           */
+     Word16 vad_flag,                      /* i   : vad decision           */
+     Word16 * usedMode                     /* i/o : mode changed or not    */
+)
+{
+
+    /* this state machine is in synch with the GSMEFR txDtx machine      */
+    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);    move16();
+
+    test();
+    if (vad_flag != 0)
+    {
+        st->dtxHangoverCount = DTX_HANG_CONST;  move16();
+    } else
+    {                                      /* non-speech */
+        test();
+        if (st->dtxHangoverCount == 0)
+        {                                  /* out of decoder analysis hangover  */
+            st->decAnaElapsedCount = 0;    move16();
+            *usedMode = MRDTX;             move16();
+        } else
+        {                                  /* in possible analysis hangover */
+            st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);        move16();
+
+            /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
+            test();
+            if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
+                    DTX_ELAPSED_FRAMES_THRESH) < 0)
+            {
+                *usedMode = MRDTX;         move16();
+                /* if short time since decoder update, do not add extra HO */
+            }
+            /* else override VAD and stay in speech mode *usedMode and add extra hangover */
+        }
+    }
+
+    return;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_dec_init
+ *
+ *
+ **************************************************************************/
+Word16 dtx_dec_init(dtx_decState ** st, Word16 isf_init[])
+{
+    dtx_decState *s;
+
+    test();
+    if (st == (dtx_decState **) NULL)
+    {
+        fprintf(stderr, "dtx_dec_init: invalid parameter\n");
+        return -1;
+    }
+    *st = NULL;
+
+    /* allocate memory */
+    test();
+    if ((s = (dtx_decState *) malloc(sizeof(dtx_decState))) == NULL)
+    {
+        fprintf(stderr, "dtx_dec_init: can not malloc state structure\n");
+        return -1;
+    }
+    dtx_dec_reset(s, isf_init);
+    *st = s;
+
+    return 0;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_dec_reset
+ *
+ *
+ **************************************************************************/
+Word16 dtx_dec_reset(dtx_decState * st, Word16 isf_init[])
+{
+    Word16 i;
+
+    test();
+    if (st == (dtx_decState *) NULL)
+    {
+        fprintf(stderr, "dtx_dec_reset: invalid parameter\n");
+        return -1;
+    }
+    st->since_last_sid = 0;                move16();
+    st->true_sid_period_inv = (1 << 13);   move16();  /* 0.25 in Q15 */
+
+    st->log_en = 3500;                     move16();
+    st->old_log_en = 3500;                 move16();
+    /* low level noise for better performance in  DTX handover cases */
+
+    st->cng_seed = RANDOM_INITSEED;        move16();
+
+    st->hist_ptr = 0;                      move16();
+
+    /* Init isf_hist[] and decoder log frame energy */
+    Copy(isf_init, st->isf, M);
+    Copy(isf_init, st->isf_old, M);
+
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        Copy(isf_init, &st->isf_hist[i * M], M);
+        st->log_en_hist[i] = st->log_en;   move16();
+    }
+
+    st->dtxHangoverCount = DTX_HANG_CONST; move16();
+    st->decAnaElapsedCount = 32767;        move16();
+
+    st->sid_frame = 0;                     move16();
+    st->valid_data = 0;                    move16();
+    st->dtxHangoverAdded = 0;              move16();
+
+    st->dtxGlobalState = SPEECH;           move16();
+    st->data_updated = 0;                  move16();
+
+    st->dither_seed = RANDOM_INITSEED;     move16();
+    st->CN_dith = 0;
+
+    return 0;
+}
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_dec_exit
+ *
+ *
+ **************************************************************************/
+void dtx_dec_exit(dtx_decState ** st)
+{
+    test();
+    if (st == NULL || *st == NULL)
+        return;
+
+    /* deallocate memory */
+    free(*st);
+    *st = NULL;
+
+    return;
+}
+
+/*
+     Table of new SPD synthesis states
+
+                           |     previous SPD_synthesis_state
+     Incoming              |
+     frame_type            | SPEECH       | DTX           | DTX_MUTE
+     ---------------------------------------------------------------
+     RX_SPEECH_GOOD ,      |              |               |
+     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
+     ----------------------------------------------------------------
+     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
+     ----------------------------------------------------------------
+     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
+     ----------------------------------------------------------------
+     RX_SID_UPDATE,        | DTX          | DTX           | DTX
+     ----------------------------------------------------------------
+     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
+     ----------------------------------------------------------------
+     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
+     RX_SPARE              |(class2 garb.)|               |
+     ----------------------------------------------------------------
+*/
+
+/**************************************************************************
+ *
+ *
+ * Function    : dtx_dec
+ *
+ *
+ **************************************************************************/
+Word16 dtx_dec(
+     dtx_decState * st,                    /* i/o : State struct                                          */
+     Word16 * exc2,                        /* o   : CN excitation                                          */
+     Word16 new_state,                     /* i   : New DTX state                                          */
+     Word16 isf[],                         /* o   : CN ISF vector                                          */
+     Word16 ** prms
+)
+{
+    Word16 log_en_index;
+    Word16 ind[7];
+    Word16 i, j;
+    Word16 int_fac;
+    Word16 gain;
+
+    Word32 L_isf[M], L_log_en_int, level32, ener32;
+    Word16 ptr;
+    Word16 tmp_int_length;
+    Word16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level;
+
+    /* This function is called if synthesis state is not SPEECH the globally passed  inputs to this function
+     * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state  (SPEECH, DTX, DTX_MUTE) */
+    test();test();
+    if ((st->dtxHangoverAdded != 0) &&
+        (st->sid_frame != 0))
+    {
+        /* sid_first after dtx hangover period */
+        /* or sid_upd after dtxhangover        */
+
+        /* consider  twice the last frame */
+        ptr = add(st->hist_ptr, 1);
+        test();
+        if (sub(ptr, DTX_HIST_SIZE) == 0)
+            ptr = 0;                       move16();
+
+        Copy(&st->isf_hist[st->hist_ptr * M], &st->isf_hist[ptr * M], M);
+
+        st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr];   move16();
+
+        /* compute mean log energy and isf from decoded signal (SID_FIRST) */
+        st->log_en = 0;                    move16();
+        for (i = 0; i < M; i++)
+        {
+            L_isf[i] = 0;                  move32();
+        }
+
+        /* average energy and isf */
+        for (i = 0; i < DTX_HIST_SIZE; i++)
+        {
+            /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */
+            st->log_en = add(st->log_en, st->log_en_hist[i]);   move16();
+
+            for (j = 0; j < M; j++)
+            {
+                L_isf[j] = L_add(L_isf[j], L_deposit_l(st->isf_hist[i * M + j]));       move32();
+            }
+        }
+
+        /* st->log_en in Q9 */
+        st->log_en = shr(st->log_en, 1);   move16();
+
+        /* Add 2 in Q9, in order to have only positive values for Pow2 */
+        /* this value is subtracted back after Pow2 function */
+        st->log_en = add(st->log_en, 1024);move16();
+        test();
+        if (st->log_en < 0)
+            st->log_en = 0;                move16();
+
+        for (j = 0; j < M; j++)
+        {
+            st->isf[j] = extract_l(L_shr(L_isf[j], 3)); move32();  /* divide by 8 */
+        }
+
+    }
+    test();
+    if (st->sid_frame != 0)
+    {
+        /* Set old SID parameters, always shift */
+        /* even if there is no new valid_data   */
+
+        Copy(st->isf, st->isf_old, M);
+        st->old_log_en = st->log_en;       move16();
+        test();
+        if (st->valid_data != 0)           /* new data available (no CRC) */
+        {
+            /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */
+            /* Compute interpolation factor, since the division only works * for values of since_last_sid <
+             * 32 we have to limit the      * interpolation to 32 frames                                  */
+            tmp_int_length = st->since_last_sid;        move16();
+
+            test();
+            if (sub(tmp_int_length, 32) > 0)
+            {
+                tmp_int_length = 32;       move16();
+            }
+            test();
+            if (sub(tmp_int_length, 2) >= 0)
+            {
+                move16();
+                st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10));
+            } else
+            {
+                st->true_sid_period_inv = 1 << 14;      /* 0.5 it Q15 */move16();
+            }
+
+            ind[0] = Serial_parm(6, prms); move16();
+            ind[1] = Serial_parm(6, prms); move16();
+            ind[2] = Serial_parm(6, prms); move16();
+            ind[3] = Serial_parm(5, prms); move16();
+            ind[4] = Serial_parm(5, prms); move16();
+
+            Disf_ns(ind, st->isf);
+
+            log_en_index = Serial_parm(6, prms);
+
+            /* read background noise stationarity information */
+            st->CN_dith = Serial_parm(1, prms); move16();
+
+            /* st->log_en = (float)log_en_index / 2.625 - 2.0;  */
+            /* log2(E) in Q9 (log2(E) lies in between -2:22) */
+            st->log_en = shl(log_en_index, 15 - 6);     move16();
+
+            /* Divide by 2.625  */
+            st->log_en = mult(st->log_en, 12483);       move16();
+            /* Subtract 2 in Q9 is done later, after Pow2 function  */
+
+            /* no interpolation at startup after coder reset        */
+            /* or when SID_UPD has been received right after SPEECH */
+            test();test();
+            if ((st->data_updated == 0) ||
+                (sub(st->dtxGlobalState, SPEECH) == 0))
+            {
+                Copy(st->isf, st->isf_old, M);
+                st->old_log_en = st->log_en;    move16();
+            }
+        }                                  /* endif valid_data */
+    }                                      /* endif sid_frame */
+    test();
+    test();
+    if ((st->sid_frame != 0) && (st->valid_data != 0))
+    {
+        st->since_last_sid = 0;            move16();
+    }
+    /* Interpolate SID info */
+    int_fac = shl(st->since_last_sid, 10); /* Q10 */move16();
+    int_fac = mult(int_fac, st->true_sid_period_inv);   /* Q10 * Q15 -> Q10 */
+
+    /* Maximize to 1.0 in Q10 */
+    test();
+    if (sub(int_fac, 1024) > 0)
+    {
+        int_fac = 1024;                    move16();
+    }
+    int_fac = shl(int_fac, 4);             /* Q10 -> Q14 */
+
+    L_log_en_int = L_mult(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */
+
+    for (i = 0; i < M; i++)
+    {
+        isf[i] = mult(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */move16();
+    }
+
+    int_fac = sub(16384, int_fac);         /* 1-k in Q14 */move16();
+
+    /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */
+    L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en);
+
+    for (i = 0; i < M; i++)
+    {
+        /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
+        isf[i] = add(isf[i], mult(int_fac, st->isf_old[i]));    move16();
+        isf[i] = shl(isf[i], 1);           /* Q14 -> Q15 */move16();
+    }
+
+    /* If background noise is non-stationary, insert comfort noise dithering */
+    if (st->CN_dith != 0)
+    {
+        CN_dithering(isf, &L_log_en_int, &st->dither_seed);
+    }
+    /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */
+    /* Q25 -> Q16 */
+    L_log_en_int = L_shr(L_log_en_int, 9);
+
+    /* Find integer part  */
+    log_en_int_e = extract_h(L_log_en_int);
+
+    /* Find fractional part */
+    log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, L_deposit_h(log_en_int_e)), 1));
+
+    /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */
+    /* Add 16 in order to have the result of pow2 in Q16 */
+    log_en_int_e = add(log_en_int_e, 16 - 1);
+
+    /* level = (float)( pow( 2.0f, log_en ) );  */
+    level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
+    exp0 = norm_l(level32);
+    level32 = L_shl(level32, exp0);        /* level in Q31 */
+    exp0 = sub(15, exp0);
+    level = extract_h(level32);            /* level in Q15 */
+
+    /* generate white noise vector */
+    for (i = 0; i < L_FRAME; i++)
+    {
+        exc2[i] = shr(Random(&(st->cng_seed)), 4);      move16();
+    }
+
+    /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
+
+    /* energy of generated excitation */
+    ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
+
+    Isqrt_n(&ener32, &exp);
+
+    gain = extract_h(ener32);
+
+    gain = mult(level, gain);              /* gain in Q15 */
+
+    exp = add(exp0, exp);
+
+    /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
+    exp = add(exp, 4);
+
+    for (i = 0; i < L_FRAME; i++)
+    {
+        tmp = mult(exc2[i], gain);         /* Q0 * Q15 */
+        exc2[i] = shl(tmp, exp);           move16();
+    }
+
+    test();
+    if (sub(new_state, DTX_MUTE) == 0)
+    {
+        /* mute comfort noise as it has been quite a long time since last SID update  was performed                            */
+
+        tmp_int_length = st->since_last_sid;    move16();
+        test();
+        if (sub(tmp_int_length, 32) > 0)
+        {
+            tmp_int_length = 32;           move16();
+        }
+        move16();
+        st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10));
+
+        st->since_last_sid = 0;            move16();
+        st->old_log_en = st->log_en;       move16();
+        /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */
+        st->log_en = sub(st->log_en, 64);  move16();
+    }
+    /* reset interpolation length timer if data has been updated.        */
+    test();test();test();test();
+    if ((st->sid_frame != 0) &&
+        ((st->valid_data != 0) ||
+            ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0)))
+    {
+        st->since_last_sid = 0;            move16();
+        st->data_updated = 1;              move16();
+    }
+    return 0;
+}
+
+
+void dtx_dec_activity_update(
+     dtx_decState * st,
+     Word16 isf[],
+     Word16 exc[])
+{
+    Word16 i;
+
+    Word32 L_frame_en;
+    Word16 log_en_e, log_en_m, log_en;
+
+
+    st->hist_ptr = add(st->hist_ptr, 1);   move16();
+    test();
+    if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
+    {
+        st->hist_ptr = 0;                  move16();
+    }
+    Copy(isf, &st->isf_hist[st->hist_ptr * M], M);
+
+    /* compute log energy based on excitation frame energy in Q0 */
+    L_frame_en = 0;                        move32();
+    for (i = 0; i < L_FRAME; i++)
+    {
+        L_frame_en = L_mac(L_frame_en, exc[i], exc[i]);
+    }
+    L_frame_en = L_shr(L_frame_en, 1);
+
+    /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */
+    Log2(L_frame_en, &log_en_e, &log_en_m);
+
+    /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
+    log_en = shl(log_en_e, 7);             /* Q7 */
+    log_en = add(log_en, shr(log_en_m, 15 - 7));
+
+    /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */
+    log_en = sub(log_en, 1024);
+
+    /* insert into log energy buffer */
+    st->log_en_hist[st->hist_ptr] = log_en;move16();
+
+    return;
+}
+
+
+/*
+     Table of new SPD synthesis states
+
+                           |     previous SPD_synthesis_state
+     Incoming              |
+     frame_type            | SPEECH       | DTX           | DTX_MUTE
+     ---------------------------------------------------------------
+     RX_SPEECH_GOOD ,      |              |               |
+     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
+     ----------------------------------------------------------------
+     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
+     ----------------------------------------------------------------
+     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
+     ----------------------------------------------------------------
+     RX_SID_UPDATE,        | DTX          | DTX           | DTX
+     ----------------------------------------------------------------
+     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
+     ----------------------------------------------------------------
+     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
+     RX_SPARE              |(class2 garb.)|               |
+     ----------------------------------------------------------------
+*/
+
+Word16 rx_dtx_handler(
+     dtx_decState * st,                    /* i/o : State struct     */
+     Word16 frame_type                     /* i   : Frame type       */
+)
+{
+    Word16 newState;
+    Word16 encState;
+
+    /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
+    test();test();test();
+    test();test();test();
+    test();test();
+    if ((sub(frame_type, RX_SID_FIRST) == 0) ||
+        (sub(frame_type, RX_SID_UPDATE) == 0) ||
+        (sub(frame_type, RX_SID_BAD) == 0) ||
+        (((sub(st->dtxGlobalState, DTX) == 0) ||
+                (sub(st->dtxGlobalState, DTX_MUTE) == 0)) &&
+            ((sub(frame_type, RX_NO_DATA) == 0) ||
+                (sub(frame_type, RX_SPEECH_BAD) == 0) ||
+                (sub(frame_type, RX_SPEECH_LOST) == 0))))
+    {
+        newState = DTX;                    move16();
+
+        /* stay in mute for these input types */
+        test();test();test();test();test();
+        if ((sub(st->dtxGlobalState, DTX_MUTE) == 0) &&
+            ((sub(frame_type, RX_SID_BAD) == 0) ||
+                (sub(frame_type, RX_SID_FIRST) == 0) ||
+                (sub(frame_type, RX_SPEECH_LOST) == 0) ||
+                (sub(frame_type, RX_NO_DATA) == 0)))
+        {
+            newState = DTX_MUTE;           move16();
+        }
+        /* evaluate if noise parameters are too old                     */
+        /* since_last_sid is reset when CN parameters have been updated */
+        st->since_last_sid = add(st->since_last_sid, 1);        move16();
+
+        /* no update of sid parameters in DTX for a long while */
+        test();
+        if (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0)
+        {
+            newState = DTX_MUTE;           move16();
+        }
+    } else
+    {
+        newState = SPEECH;                 move16();
+        st->since_last_sid = 0;            move16();
+    }
+
+    /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch
+     * after handover this might delay the bwd CNI analysis in the new decoder slightly. */
+    test();test();
+    if ((st->data_updated == 0) &&
+        (sub(frame_type, RX_SID_UPDATE) == 0))
+    {
+        st->decAnaElapsedCount = 0;        move16();
+    }
+    /* update the SPE-SPD DTX hangover synchronization */
+    /* to know when SPE has added dtx hangover         */
+    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);    move16();
+    st->dtxHangoverAdded = 0;              move16();
+
+    test();test();test();test();
+    if ((sub(frame_type, RX_SID_FIRST) == 0) ||
+        (sub(frame_type, RX_SID_UPDATE) == 0) ||
+        (sub(frame_type, RX_SID_BAD) == 0) ||
+        (sub(frame_type, RX_NO_DATA) == 0))
+    {
+        encState = DTX;                    move16();
+    } else
+    {
+        encState = SPEECH;                 move16();
+    }
+
+    test();
+    if (sub(encState, SPEECH) == 0)
+    {
+        st->dtxHangoverCount = DTX_HANG_CONST;  move16();
+    } else
+    {
+        test();test();
+        if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0)
+        {
+            st->dtxHangoverAdded = 1;      move16();
+            st->decAnaElapsedCount = 0;    move16();
+            st->dtxHangoverCount = 0;      move16();
+        } else if (test(), st->dtxHangoverCount == 0)
+        {
+            st->decAnaElapsedCount = 0;    move16();
+        } else
+        {
+            st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);        move16();
+        }
+    }
+    test();
+    if (sub(newState, SPEECH) != 0)
+    {
+        /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
+         * backwards analysis if a hangover period has been added according to the state machine above */
+
+        st->sid_frame = 0;                 move16();
+        st->valid_data = 0;                move16();
+
+        test();test();test();
+        if (sub(frame_type, RX_SID_FIRST) == 0)
+        {
+            st->sid_frame = 1;             move16();
+        } else if (test(), sub(frame_type, RX_SID_UPDATE) == 0)
+        {
+            st->sid_frame = 1;             move16();
+            st->valid_data = 1;            move16();
+        } else if (test(), sub(frame_type, RX_SID_BAD) == 0)
+        {
+            st->sid_frame = 1;             move16();
+            st->dtxHangoverAdded = 0;      /* use old data */move16();
+        }
+    }
+    return newState;
+    /* newState is used by both SPEECH AND DTX synthesis routines */
+}
+
+static void aver_isf_history(
+     Word16 isf_old[],
+     Word16 indices[],
+     Word32 isf_aver[]
+)
+{
+    Word16 i, j, k;
+    Word16 isf_tmp[2 * M];
+    Word32 L_tmp;
+
+    /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
+    /* the median ISF vector prior to the averaging               */
+    for (k = 0; k < 2; k++)
+    {
+        test();
+        if (add(indices[k], 1) != 0)
+        {
+            for (i = 0; i < M; i++)
+            {
+                isf_tmp[k * M + i] = isf_old[indices[k] * M + i];       move16();
+                isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];      move16();
+            }
+        }
+    }
+
+    /* Perform the ISF averaging */
+    for (j = 0; j < M; j++)
+    {
+        L_tmp = 0;                         move32();
+
+        for (i = 0; i < DTX_HIST_SIZE; i++)
+        {
+            L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
+        }
+        isf_aver[j] = L_tmp;               move32();
+    }
+
+    /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
+    for (k = 0; k < 2; k++)
+    {
+        test();
+        if (add(indices[k], 1) != 0)
+        {
+            for (i = 0; i < M; i++)
+            {
+                isf_old[indices[k] * M + i] = isf_tmp[k * M + i];       move16();
+            }
+        }
+    }
+
+    return;
+}
+
+static void find_frame_indices(
+     Word16 isf_old_tx[],
+     Word16 indices[],
+     dtx_encState * st
+)
+{
+    Word32 L_tmp, summin, summax, summax2nd;
+    Word16 i, j, tmp;
+    Word16 ptr;
+
+    /* Remove the effect of the oldest frame from the column */
+    /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is    */
+    /* not updated since it will be removed later.           */
+
+    tmp = DTX_HIST_SIZE_MIN_ONE;           move16();
+    j = -1;                                move16();
+    for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
+    {
+        j = add(j, tmp);
+        st->sumD[i] = L_sub(st->sumD[i], st->D[j]);     move16();
+        tmp = sub(tmp, 1);
+    }
+
+    /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1]    */
+    /* corresponding to the oldest frame is removed. The sum of     */
+    /* the distances between the latest isf and other isfs, */
+    /* i.e. the element sumD[0], will be computed during this call. */
+    /* Hence this element is initialized to zero.                   */
+
+    for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
+    {
+        st->sumD[i] = st->sumD[i - 1];     move32();
+    }
+    st->sumD[0] = 0;                       move32();
+
+    /* Remove the oldest frame from the distance matrix.           */
+    /* Note that the distance matrix is replaced by a one-         */
+    /* dimensional array to save static memory.                    */
+
+    tmp = 0;                               move16();
+    for (i = 27; i >= 12; i = (Word16) (i - tmp))
+    {
+        tmp = add(tmp, 1);
+        for (j = tmp; j > 0; j--)
+        {
+            st->D[i - j + 1] = st->D[i - j - tmp];      move32();
+        }
+    }
+
+    /* Compute the first column of the distance matrix D            */
+    /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
+
+    ptr = st->hist_ptr;                    move16();
+    for (i = 1; i < DTX_HIST_SIZE; i++)
+    {
+        /* Compute the distance between the latest isf and the other isfs. */
+        ptr = sub(ptr, 1);
+        test();
+        if (ptr < 0)
+        {
+            ptr = DTX_HIST_SIZE_MIN_ONE;   move16();
+        }
+        L_tmp = 0;                         move32();
+        for (j = 0; j < M; j++)
+        {
+            tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
+            L_tmp = L_mac(L_tmp, tmp, tmp);
+        }
+        st->D[i - 1] = L_tmp;              move32();
+
+        /* Update also the column sums. */
+        st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]); move32();
+        st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]); move32();
+    }
+
+    /* Find the minimum and maximum distances */
+    summax = st->sumD[0];                  move32();
+    summin = st->sumD[0];                  move32();
+    indices[0] = 0;                        move16();
+    indices[2] = 0;                        move16();
+    for (i = 1; i < DTX_HIST_SIZE; i++)
+    {
+        test();
+        if (L_sub(st->sumD[i], summax) > 0)
+        {
+            indices[0] = i;                move16();
+            summax = st->sumD[i];          move32();
+        }
+        test();
+        if (L_sub(st->sumD[i], summin) < 0)
+        {
+            indices[2] = i;                move16();
+            summin = st->sumD[i];          move32();
+        }
+    }
+
+    /* Find the second largest distance */
+    summax2nd = -2147483647L;              move32();
+    indices[1] = -1;                       move16();
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        test();
+        if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
+        {
+            indices[1] = i;                move16();
+            summax2nd = st->sumD[i];       move32();
+        }
+    }
+
+    for (i = 0; i < 3; i++)
+    {
+        indices[i] = sub(st->hist_ptr, indices[i]);     move16();
+        test();
+        if (indices[i] < 0)
+        {
+            indices[i] = add(indices[i], DTX_HIST_SIZE);        move16();
+        }
+    }
+
+    /* If maximum distance/MED_THRESH is smaller than minimum distance */
+    /* then the median ISF vector replacement is not performed         */
+    tmp = norm_l(summax);
+    summax = L_shl(summax, tmp);
+    summin = L_shl(summin, tmp);
+    L_tmp = L_mult(round(summax), INV_MED_THRESH);
+    test();
+    if (L_sub(L_tmp, summin) <= 0)
+    {
+        indices[0] = -1;                   move16();
+    }
+    /* If second largest distance/MED_THRESH is smaller than     */
+    /* minimum distance then the median ISF vector replacement is    */
+    /* not performed                                                 */
+    summax2nd = L_shl(summax2nd, tmp);
+    L_tmp = L_mult(round(summax2nd), INV_MED_THRESH);
+    test();
+    if (L_sub(L_tmp, summin) <= 0)
+    {
+        indices[1] = -1;                   move16();
+    }
+    return;
+}
+
+static Word16 dithering_control(
+     dtx_encState * st
+)
+{
+    Word16 i, tmp, mean, CN_dith, gain_diff;
+    Word32 ISF_diff;
+
+    /* determine how stationary the spectrum of background noise is */
+    ISF_diff = 0;
+    for (i = 0; i < 8; i++)
+    {
+        ISF_diff = L_add(ISF_diff, st->sumD[i]);
+    }
+    if (L_shr(ISF_diff, 26) > 0)
+    {
+        CN_dith = 1;
+    } else
+    {
+        CN_dith = 0;
+    }
+
+    /* determine how stationary the energy of background noise is */
+    mean = 0;
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        mean = add(mean, st->log_en_hist[i]);
+    }
+    mean = shr(mean, 3);
+    gain_diff = 0;
+    for (i = 0; i < DTX_HIST_SIZE; i++)
+    {
+        tmp = abs_s(sub(st->log_en_hist[i], mean));
+        gain_diff = add(gain_diff, tmp);
+    }
+    if (sub(gain_diff, GAIN_THR) > 0)
+    {
+        CN_dith = 1;
+    }
+    return CN_dith;
+}
+
+static void CN_dithering(
+     Word16 isf[M],
+     Word32 * L_log_en_int,
+     Word16 * dither_seed
+)
+{
+    Word16 temp, temp1, i, dither_fac, rand_dith;
+    Word16 rand_dith2;
+
+    /* Insert comfort noise dithering for energy parameter */
+    rand_dith = shr(Random(dither_seed), 1);
+    rand_dith2 = shr(Random(dither_seed), 1);
+    rand_dith = add(rand_dith, rand_dith2);
+    *L_log_en_int = L_add(*L_log_en_int, L_mult(rand_dith, GAIN_FACTOR));
+    if (*L_log_en_int < 0)
+    {
+        *L_log_en_int = 0;
+    }
+    /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
+    dither_fac = ISF_FACTOR_LOW;
+
+    rand_dith = shr(Random(dither_seed), 1);
+    rand_dith2 = shr(Random(dither_seed), 1);
+    rand_dith = add(rand_dith, rand_dith2);
+    temp = add(isf[0], mult_r(rand_dith, dither_fac));
+
+    /* Make sure that isf[0] will not get negative values */
+    if (sub(temp, ISF_GAP) < 0)
+    {
+        isf[0] = ISF_GAP;
+    } else
+    {
+        isf[0] = temp;
+    }
+
+    for (i = 1; i < M - 1; i++)
+    {
+        dither_fac = add(dither_fac, ISF_FACTOR_STEP);
+
+        rand_dith = shr(Random(dither_seed), 1);
+        rand_dith2 = shr(Random(dither_seed), 1);
+        rand_dith = add(rand_dith, rand_dith2);
+        temp = add(isf[i], mult_r(rand_dith, dither_fac));
+        temp1 = sub(temp, isf[i - 1]);
+
+        /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */
+        if (sub(temp1, ISF_DITH_GAP) < 0)
+        {
+            isf[i] = add(isf[i - 1], ISF_DITH_GAP);
+        } else
+        {
+            isf[i] = temp;
+        }
+    }
+
+    /* Make sure that isf[M-2] will not get values above 16384 */
+    if (sub(isf[M - 2], 16384) > 0)
+    {
+        isf[M - 2] = 16384;
+    }
+    return;
+}
--- /dev/null
+++ b/amr-wb/dtx.h
@@ -1,0 +1,156 @@
+/*--------------------------------------------------------------------------*
+ *                         DTX.H                                            *
+ *--------------------------------------------------------------------------*
+ *       Static memory, constants and frametypes for the DTX                *
+ *--------------------------------------------------------------------------*/
+
+
+#ifndef dtx_h
+#define dtx_h
+
+#define DTX_MAX_EMPTY_THRESH 50
+#define DTX_HIST_SIZE 8
+#define DTX_HIST_SIZE_MIN_ONE 7
+#define DTX_ELAPSED_FRAMES_THRESH (24 + 7 -1)
+#define DTX_HANG_CONST 7                   /* yields eight frames of SP HANGOVER  */
+#define INV_MED_THRESH 14564
+#define ISF_GAP  128                       /* 50 */
+#define ONE_MINUS_ISF_GAP 16384 - ISF_GAP
+
+#define ISF_GAP   128
+#define ISF_DITH_GAP   448
+#define ISF_FACTOR_LOW 256
+#define ISF_FACTOR_STEP 2
+
+#define GAIN_THR 180
+#define GAIN_FACTOR 75
+
+typedef struct
+{
+    Word16 isf_hist[M * DTX_HIST_SIZE];
+    Word16 log_en_hist[DTX_HIST_SIZE];
+    Word16 hist_ptr;
+    Word16 log_en_index;
+    Word16 cng_seed;
+
+    /* DTX handler stuff */
+    Word16 dtxHangoverCount;
+    Word16 decAnaElapsedCount;
+    Word32 D[28];
+    Word32 sumD[DTX_HIST_SIZE];
+} dtx_encState;
+
+#define SPEECH 0
+#define DTX 1
+#define DTX_MUTE 2
+
+#define TX_SPEECH 0
+#define TX_SID_FIRST 1
+#define TX_SID_UPDATE 2
+#define TX_NO_DATA 3
+
+#define RX_SPEECH_GOOD 0
+#define RX_SPEECH_PROBABLY_DEGRADED 1
+#define RX_SPEECH_LOST 2
+#define RX_SPEECH_BAD 3
+#define RX_SID_FIRST 4
+#define RX_SID_UPDATE 5
+#define RX_SID_BAD 6
+#define RX_NO_DATA 7
+
+/*****************************************************************************
+ *
+ * DEFINITION OF DATA TYPES
+ *****************************************************************************/
+
+typedef struct
+{
+    Word16 since_last_sid;
+    Word16 true_sid_period_inv;
+    Word16 log_en;
+    Word16 old_log_en;
+    Word16 level;
+    Word16 isf[M];
+    Word16 isf_old[M];
+    Word16 cng_seed;
+
+    Word16 isf_hist[M * DTX_HIST_SIZE];
+    Word16 log_en_hist[DTX_HIST_SIZE];
+    Word16 hist_ptr;
+
+    Word16 dtxHangoverCount;
+    Word16 decAnaElapsedCount;
+
+    Word16 sid_frame;
+    Word16 valid_data;
+    Word16 dtxHangoverAdded;
+
+    Word16 dtxGlobalState;                 /* contains previous state */
+    /* updated in main decoder */
+
+    Word16 data_updated;                   /* marker to know if CNI data is ever renewed */
+
+    Word16 dither_seed;
+    Word16 CN_dith;
+
+} dtx_decState;
+
+Word16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[]);
+Word16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[]);
+void dtx_enc_exit(dtx_encState ** st);
+
+Word16 dtx_enc(
+     dtx_encState * st,                    /* i/o : State struct                                         */
+     Word16 isf[M],                        /* o   : CN ISF vector                                        */
+     Word16 * exc2,                        /* o   : CN excitation                                        */
+     Word16 ** prms
+);
+
+Word16 dtx_buffer(
+     dtx_encState * st,                    /* i/o : State struct                    */
+     Word16 isf_new[],                     /* i   : isf vector                      */
+     Word32 enr,                           /* i   : residual energy (in L_FRAME)    */
+     Word16 codec_mode
+);
+
+void tx_dtx_handler(dtx_encState * st,     /* i/o : State struct           */
+     Word16 vad_flag,                      /* i   : vad decision           */
+     Word16 * usedMode                     /* i/o : mode changed or not    */
+);
+
+void Qisf_ns(
+     Word16 * isf1,                        /* input : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* output: quantized ISF                        */
+     Word16 * indice                       /* output: quantization indices                 */
+);
+
+
+Word16 dtx_dec_init(dtx_decState ** st, Word16 isf_init[]);
+Word16 dtx_dec_reset(dtx_decState * st, Word16 isf_init[]);
+void dtx_dec_exit(dtx_decState ** st);
+
+Word16 dtx_dec(
+     dtx_decState * st,                    /* i/o : State struct                                          */
+     Word16 * exc2,                        /* o   : CN excitation                                          */
+     Word16 new_state,                     /* i   : New DTX state                                          */
+     Word16 isf[],                         /* o   : CN ISF vector                                          */
+     Word16 ** prms
+);
+
+void dtx_dec_activity_update(
+     dtx_decState * st,
+     Word16 isf[],
+     Word16 exc[]);
+
+
+Word16 rx_dtx_handler(
+     dtx_decState * st,                    /* i/o : State struct     */
+     Word16 frame_type                     /* i   : Frame type       */
+);
+
+void Disf_ns(
+     Word16 * indice,                      /* input:  quantization indices                  */
+     Word16 * isf_q                        /* input : ISF in the frequency domain (0..0.5)  */
+);
+
+#endif
--- /dev/null
+++ b/amr-wb/g_pitch.c
@@ -1,0 +1,60 @@
+/*-------------------------------------------------------------------*
+ *                         G_PITCH.C                                 *
+ *-------------------------------------------------------------------*
+ * Compute the gain of pitch. Result in Q12                          *
+ *  if (gain < 0)  gain =0                                           *
+ *  if (gain > 1.2) gain =1.2                                        *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+
+
+Word16 G_pitch(                            /* (o) Q14 : Gain of pitch lag saturated to 1.2   */
+     Word16 xn[],                          /* (i)     : Pitch target.                        */
+     Word16 y1[],                          /* (i)     : filtered adaptive codebook.          */
+     Word16 g_coeff[],                     /* : Correlations need for gain quantization.     */
+     Word16 L_subfr                        /* : Length of subframe.                          */
+)
+{
+    Word16 i;
+    Word16 xy, yy, exp_xy, exp_yy, gain;
+
+    /* Compute scalar product <y1[],y1[]> */
+
+    yy = extract_h(Dot_product12(y1, y1, L_subfr, &exp_yy));
+
+    /* Compute scalar product <xn[],y1[]> */
+
+    xy = extract_h(Dot_product12(xn, y1, L_subfr, &exp_xy));
+
+    g_coeff[0] = yy;                       move16();
+    g_coeff[1] = exp_yy;                   move16();
+    g_coeff[2] = xy;                       move16();
+    g_coeff[3] = exp_xy;                   move16();
+
+    /* If (xy < 0) gain = 0 */
+    test();
+    if (xy < 0)
+        return ((Word16) 0);
+
+    /* compute gain = xy/yy */
+
+    xy = shr(xy, 1);                       /* Be sure xy < yy */
+    gain = div_s(xy, yy);
+
+    i = add(exp_xy, 1 - 1);                /* -1 -> gain in Q14 */
+    i = sub(i, exp_yy);
+
+    gain = shl(gain, i);                   /* saturation can occur here */
+
+    /* if (gain > 1.2) gain = 1.2  in Q14 */
+    test();
+    if (sub(gain, 19661) > 0)
+    {
+        gain = 19661;                      move16();
+    }
+    return (gain);
+}
--- /dev/null
+++ b/amr-wb/gpclip.c
@@ -1,0 +1,97 @@
+/*-----------------------------------------------------------------*
+ *                         GPCLIP.C                                *
+ *-----------------------------------------------------------------*
+ * To avoid unstable synthesis on frame erasure, the gain need to  *
+ * be limited (gain pitch < 1.0) when the following case occurs:   *
+ *   - a resonance on LPC filter (lp_disp < 60 Hz)                 *
+ *   - a good pitch prediction (lp_gp > 0.95)                      *
+ *-----------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+#define DIST_ISF_MAX    307                /* 120 Hz (6400Hz=16384) */
+#define DIST_ISF_THRES  154                /* 60     (6400Hz=16384) */
+#define GAIN_PIT_THRES  14746              /* 0.9 in Q14 */
+#define GAIN_PIT_MIN    9830               /* 0.6 in Q14 */
+#define M               16
+
+
+void Init_gp_clip(
+     Word16 mem[]                          /* (o) : memory of gain of pitch clipping algorithm */
+)
+{
+    mem[0] = DIST_ISF_MAX;                 move16();
+    mem[1] = GAIN_PIT_MIN;                 move16();
+}
+
+
+Word16 Gp_clip(
+     Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
+)
+{
+    Word16 clip;
+
+    clip = 0;                              move16();  /* move16 */
+    test();
+    if ((sub(mem[0], DIST_ISF_THRES) < 0) && (sub(mem[1], GAIN_PIT_THRES) > 0))
+        clip = 1;                          move16();
+
+    return (clip);
+}
+
+
+void Gp_clip_test_isf(
+     Word16 isf[],                         /* (i)   : isf values (in frequency domain)           */
+     Word16 mem[]                          /* (i/o) : memory of gain of pitch clipping algorithm */
+)
+{
+    Word16 i, dist, dist_min;
+
+    dist_min = sub(isf[1], isf[0]);
+
+    for (i = 2; i < M - 1; i++)
+    {
+        dist = sub(isf[i], isf[i - 1]);
+        test();
+        if (sub(dist, dist_min) < 0)
+        {
+            dist_min = dist;               move16();
+        }
+    }
+
+    dist = extract_h(L_mac(L_mult(26214, mem[0]), 6554, dist_min));
+
+    test();
+    if (sub(dist, DIST_ISF_MAX) > 0)
+    {
+        dist = DIST_ISF_MAX;               move16();
+    }
+    mem[0] = dist;                         move16();
+
+    return;
+}
+
+
+void Gp_clip_test_gain_pit(
+     Word16 gain_pit,                      /* (i) Q14 : gain of quantized pitch                    */
+     Word16 mem[]                          /* (i/o)   : memory of gain of pitch clipping algorithm */
+)
+{
+    Word16 gain;
+    Word32 L_tmp;
+
+    L_tmp = L_mult(29491, mem[1]);
+    L_tmp = L_mac(L_tmp, 3277, gain_pit);
+    gain = extract_h(L_tmp);
+
+    test();
+    if (sub(gain, GAIN_PIT_MIN) < 0)
+    {
+        gain = GAIN_PIT_MIN;               move16();
+    }
+    mem[1] = gain;                         move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/grid100.tab
@@ -1,0 +1,35 @@
+/*-------------------------------------------------------------*
+ *  Table for az_isp()                                         *
+ *                                                             *
+ * Vector grid[] is in Q15                                     *
+ *                                                             *
+ * grid[0] = 1.0;                                              *
+ * grid[grid_points+1] = -1.0;                                 *
+ * for (i = 1; i < grid_points; i++)                           *
+ *   grid[i] = cos((6.283185307*i)/(2.0*grid_points));         *
+ *                                                             *
+ *-------------------------------------------------------------*/
+
+/* Version 101 points */
+
+#define   GRID_POINTS     100
+
+Word16 grid[GRID_POINTS+1] ={
+    32767,     32751,     32703,     32622,     32509,     32364,
+    32187,     31978,     31738,     31466,     31164,     30830,
+    30466,     30072,     29649,     29196,     28714,     28204,
+    27666,     27101,     26509,     25891,     25248,     24579,
+    23886,     23170,     22431,     21669,     20887,     20083,
+    19260,     18418,     17557,     16680,     15786,     14876,
+    13951,     13013,     12062,     11099,     10125,      9141,
+     8149,      7148,      6140,      5126,      4106,      3083,
+     2057,      1029,         0,     -1029,     -2057,     -3083,
+    -4106,     -5126,     -6140,     -7148,     -8149,     -9141,
+   -10125,    -11099,    -12062,    -13013,    -13951,    -14876,
+   -15786,    -16680,    -17557,    -18418,    -19260,    -20083,
+   -20887,    -21669,    -22431,    -23170,    -23886,    -24579,
+   -25248,    -25891,    -26509,    -27101,    -27666,    -28204,
+   -28714,    -29196,    -29649,    -30072,    -30466,    -30830,
+   -31164,    -31466,    -31738,    -31978,    -32187,    -32364,
+   -32509,    -32622,    -32703,    -32751,    -32760};
+
--- /dev/null
+++ b/amr-wb/ham_wind.tab
@@ -1,0 +1,56 @@
+/* Hamming_cos window for LPC analysis.                 */
+/*   Create with function hamm_cos(window,384-128,128)  */
+
+#define L_WINDOW 384
+
+Word16 window[L_WINDOW] = {
+    2621,    2622,    2626,    2632,    2640,    2650,    2662,    2677,
+    2694,    2714,    2735,    2759,    2785,    2814,    2844,    2877,
+    2912,    2949,    2989,    3031,    3075,    3121,    3169,    3220,
+    3273,    3328,    3385,    3444,    3506,    3569,    3635,    3703,
+    3773,    3845,    3919,    3996,    4074,    4155,    4237,    4321,
+    4408,    4496,    4587,    4680,    4774,    4870,    4969,    5069,
+    5171,    5275,    5381,    5489,    5599,    5710,    5824,    5939,
+    6056,    6174,    6295,    6417,    6541,    6666,    6793,    6922,
+    7052,    7185,    7318,    7453,    7590,    7728,    7868,    8009,
+    8152,    8296,    8442,    8589,    8737,    8887,    9038,    9191,
+    9344,    9499,    9655,    9813,    9971,   10131,   10292,   10454,
+   10617,   10781,   10946,   11113,   11280,   11448,   11617,   11787,
+   11958,   12130,   12303,   12476,   12650,   12825,   13001,   13178,
+   13355,   13533,   13711,   13890,   14070,   14250,   14431,   14612,
+   14793,   14975,   15158,   15341,   15524,   15708,   15891,   16076,
+   16260,   16445,   16629,   16814,   16999,   17185,   17370,   17555,
+   17740,   17926,   18111,   18296,   18481,   18666,   18851,   19036,
+   19221,   19405,   19589,   19773,   19956,   20139,   20322,   20504,
+   20686,   20867,   21048,   21229,   21408,   21588,   21767,   21945,
+   22122,   22299,   22475,   22651,   22825,   22999,   23172,   23344,
+   23516,   23686,   23856,   24025,   24192,   24359,   24525,   24689,
+   24853,   25016,   25177,   25337,   25496,   25654,   25811,   25967,
+   26121,   26274,   26426,   26576,   26725,   26873,   27019,   27164,
+   27308,   27450,   27590,   27729,   27867,   28003,   28137,   28270,
+   28401,   28531,   28659,   28785,   28910,   29033,   29154,   29274,
+   29391,   29507,   29622,   29734,   29845,   29953,   30060,   30165,
+   30268,   30370,   30469,   30566,   30662,   30755,   30847,   30936,
+   31024,   31109,   31193,   31274,   31354,   31431,   31506,   31579,
+   31651,   31719,   31786,   31851,   31914,   31974,   32032,   32088,
+   32142,   32194,   32243,   32291,   32336,   32379,   32419,   32458,
+   32494,   32528,   32560,   32589,   32617,   32642,   32664,   32685,
+   32703,   32719,   32733,   32744,   32753,   32760,   32764,   32767,
+   32767,   32765,   32757,   32745,   32727,   32705,   32678,   32646,
+   32609,   32567,   32520,   32468,   32411,   32349,   32283,   32211,
+   32135,   32054,   31968,   31877,   31781,   31681,   31575,   31465,
+   31351,   31231,   31107,   30978,   30844,   30706,   30563,   30415,
+   30263,   30106,   29945,   29779,   29609,   29434,   29255,   29071,
+   28883,   28691,   28494,   28293,   28087,   27878,   27664,   27446,
+   27224,   26997,   26767,   26533,   26294,   26052,   25806,   25555,
+   25301,   25043,   24782,   24516,   24247,   23974,   23698,   23418,
+   23134,   22847,   22557,   22263,   21965,   21665,   21361,   21054,
+   20743,   20430,   20113,   19794,   19471,   19146,   18817,   18486,
+   18152,   17815,   17476,   17134,   16789,   16442,   16092,   15740,
+   15385,   15028,   14669,   14308,   13944,   13579,   13211,   12841,
+   12470,   12096,   11721,   11344,   10965,   10584,   10202,    9819,
+    9433,    9047,    8659,    8270,    7879,    7488,    7095,    6701,
+    6306,    5910,    5514,    5116,    4718,    4319,    3919,    3519,
+    3118,    2716,    2315,    1913,    1510,    1108,     705,     302};
+
+
--- /dev/null
+++ b/amr-wb/homing.c
@@ -1,0 +1,121 @@
+/*------------------------------------------------------------------------*
+ *                         HOMING.C                                       *
+ *------------------------------------------------------------------------*
+ * Performs the homing routines                                           *
+ *------------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "cnst.h"
+#include "basic_op.h"
+#include "bits.h"
+
+#include "homing.tab"
+
+Word16 encoder_homing_frame_test(Word16 input_frame[])
+{
+    Word16 i, j = 0;
+    
+    /* check 320 input samples for matching EHF_MASK: defined in e_homing.h */
+    for (i = 0; i < L_FRAME16k; i++)
+    {
+        j = (Word16) (input_frame[i] ^ EHF_MASK);
+        
+        if (j)
+            break;
+    }
+    
+    return (Word16) (!j);
+}
+
+static Word16 dhf_test(Word16 input_frame[], Word16 mode, Word16 nparms)
+{
+    Word16 i, j, tmp, shift;
+    Word16 param[DHF_PARMS_MAX];
+    Word16 *prms;
+    
+    prms = input_frame;
+    j = 0;
+    i = 0;
+    
+    if (sub(mode, MRDTX) != 0)
+    {
+        if (sub(mode, MODE_24k) != 0) 
+        {
+            /* convert the received serial bits */
+            tmp = sub(nparms, 15);
+            while (sub(tmp, j) > 0)
+            {
+                param[i] = Serial_parm(15, &prms);
+                j = add(j, 15);
+                i = add(i, 1);
+            }
+            tmp = sub(nparms, j);
+            param[i] = Serial_parm(tmp, &prms);
+            shift = sub(15, tmp);
+            param[i] = shl(param[i], shift);
+        }
+        else 
+        {
+            /*If mode is 23.85Kbit/s, remove high band energy bits */
+            for (i = 0; i < 10; i++)
+            {
+                param[i] = Serial_parm(15, &prms);
+            }
+            param[10] = Serial_parm(15, &prms) & 0x61FF;
+            for (i = 11; i < 17; i++)
+            {
+                param[i] = Serial_parm(15, &prms);
+            }
+            param[17] = Serial_parm(15, &prms) & 0xE0FF;
+            for (i = 18; i < 24; i++)
+            {
+                param[i] = Serial_parm(15, &prms);
+            }
+            param[24] = Serial_parm(15, &prms) & 0x7F0F;
+            for (i = 25; i < 31; i++)
+            {
+                param[i] = Serial_parm(15, &prms);
+            }
+            tmp = Serial_parm(8, &prms);
+            param[31] = shl(tmp,7);
+            shift=0;
+        }
+        
+        /* check if the parameters matches the parameters of the corresponding decoder homing frame */
+        tmp = i;
+        j = 0;
+        for (i = 0; i < tmp; i++)
+        {
+            j = (Word16) (param[i] ^ dhf[mode][i]);
+            if (j)
+                break;
+        }
+        tmp = 0x7fff;
+        tmp = shr(tmp, shift);
+        tmp = shl(tmp, shift);
+        tmp = (Word16) (dhf[mode][i] & tmp);
+        tmp = (Word16) (param[i] ^ tmp);
+        j = (Word16) (j | tmp);
+        
+    }
+    else
+    {
+        j = 1;
+    }
+    
+    return (Word16) (!j);
+}
+
+
+Word16 decoder_homing_frame_test(Word16 input_frame[], Word16 mode)
+{
+    /* perform test for COMPLETE parameter frame */
+    return dhf_test(input_frame, mode, nb_of_bits[mode]);
+}
+
+
+Word16 decoder_homing_frame_test_first(Word16 input_frame[], Word16 mode)
+{
+    /* perform test for FIRST SUBFRAME of parameter frame ONLY */
+    return dhf_test(input_frame, mode, prmnofsf[mode]);
+}
--- /dev/null
+++ b/amr-wb/homing.tab
@@ -1,0 +1,132 @@
+/*-----------------------------------------------------*
+ | Tables for homing                                   |
+ *-----------------------------------------------------*/
+
+
+#define DHF_PARMS_MAX 32 /* homing frame pattern             */
+#define NUM_OF_SPMODES 9
+
+#define PRML 15
+#define PRMN_7k NBBITS_7k/PRML + 1
+#define PRMN_9k NBBITS_9k/PRML + 1
+#define PRMN_12k NBBITS_12k/PRML + 1
+#define PRMN_14k NBBITS_14k/PRML + 1
+#define PRMN_16k NBBITS_16k/PRML + 1
+#define PRMN_18k NBBITS_18k/PRML + 1
+#define PRMN_20k NBBITS_20k/PRML + 1
+#define PRMN_23k NBBITS_23k/PRML + 1
+#define PRMN_24k NBBITS_24k/PRML + 1
+
+Word16 prmnofsf[NUM_OF_SPMODES]=
+{
+    63,  81, 100, 
+   108, 116, 128, 
+   136, 152, 156
+};
+
+
+static const Word16 dfh_M7k[PRMN_7k] =
+{
+  3168, 29954, 29213, 16121, 
+    64, 13440, 30624, 16430, 
+ 19008
+};
+
+static const Word16 dfh_M9k[PRMN_9k] =
+{
+   3168, 31665,  9943, 9123, 
+  15599,  4358, 20248, 2048, 
+  17040, 27787, 16816, 13888
+};
+
+static const Word16 dfh_M12k[PRMN_12k] =
+{
+  3168, 31665,  9943,  9128, 
+  3647,  8129, 30930, 27926, 
+ 18880, 12319,   496,  1042, 
+  4061, 20446, 25629, 28069, 
+ 13948
+};
+
+static const Word16 dfh_M14k[PRMN_14k] =
+{
+    3168, 31665,  9943,  9131, 
+   24815,   655, 26616, 26764, 
+    7238, 19136,  6144,    88, 
+    4158, 25733, 30567, 30494, 
+    221, 20321, 17823
+};
+
+static const Word16 dfh_M16k[PRMN_16k] =
+{
+    3168, 31665,  9943,  9131, 
+   24815,   700,  3824,  7271, 
+   26400,  9528,  6594, 26112, 
+     108,  2068, 12867, 16317, 
+   23035, 24632,  7528,  1752, 
+    6759, 24576
+};
+
+static const Word16 dfh_M18k[PRMN_18k] =
+{
+     3168, 31665,  9943,  9135, 
+    14787, 14423, 30477, 24927, 
+    25345, 30154,   916,  5728, 
+    18978,  2048,   528, 16449, 
+     2436,  3581, 23527, 29479, 
+     8237, 16810, 27091, 19052, 
+        0
+};
+
+static const Word16 dfh_M20k[PRMN_20k] =
+{
+     3168, 31665,  9943,  9129, 
+     8637, 31807, 24646,   736, 
+    28643,  2977,  2566, 25564, 
+    12930, 13960,  2048,   834, 
+     3270,  4100, 26920, 16237, 
+    31227, 17667, 15059, 20589, 
+    30249, 29123, 0
+};
+
+static const Word16 dfh_M23k[PRMN_23k] =
+{
+     3168, 31665,  9943,  9132, 
+    16748,  3202, 28179, 16317, 
+    30590, 15857, 19960,  8818, 
+    21711, 21538,  4260, 16690, 
+    20224,  3666,  4194,  9497, 
+    16320, 15388,  5755, 31551, 
+    14080,  3574, 15932,    50, 
+    23392, 26053, 31216
+};
+
+static const Word16 dfh_M24k[PRMN_24k] =
+{
+     3168, 31665,  9943,  9134, 
+    24776,  5857, 18475, 28535, 
+    29662, 14321, 16725,  4396, 
+    29353, 10003, 17068, 20504, 
+      720,     0,  8465, 12581, 
+    28863, 24774,  9709, 26043, 
+     7941, 27649, 13965, 15236, 
+    18026, 22047, 16681,  3968
+};
+
+
+/* overall table with the parameters of the
+   decoder homing frames for all modes */
+
+static const Word16 *dhf[] =
+{
+  dfh_M7k,
+  dfh_M9k,
+  dfh_M12k,
+  dfh_M14k,
+  dfh_M16k,
+  dfh_M18k,
+  dfh_M20k,
+  dfh_M23k,
+  dfh_M24k,
+  dfh_M24k
+};
--- /dev/null
+++ b/amr-wb/hp400.c
@@ -1,0 +1,98 @@
+/*-----------------------------------------------------------------------*
+ *                         HP400.C                                       *
+ *-----------------------------------------------------------------------*
+ * 2nd order high pass filter with cut off frequency at 400 Hz.          *
+ * Designed with cheby2 function in MATLAB.                              *
+ * Optimized for fixed-point to get the following frequency response:    *
+ *                                                                       *
+ *  frequency:     0Hz   100Hz  200Hz  300Hz  400Hz  630Hz  1.5kHz  3kHz *
+ *  dB loss:     -infdB  -30dB  -20dB  -10dB  -3dB   +6dB    +1dB    0dB *
+ *                                                                       *
+ * Algorithm:                                                            *
+ *                                                                       *
+ *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]                         *
+ *                   + a[1]*y[i-1] + a[2]*y[i-2];                        *
+ *                                                                       *
+ *  Word16 b[3] = {3660, -7320,  3660};       in Q12                     *
+ *  Word16 a[3] = {4096,  7320, -3540};       in Q12                     *
+ *                                                                       *
+ *  float -->   b[3] = {0.893554687, -1.787109375,  0.893554687};        *
+ *              a[3] = {1.000000000,  1.787109375, -0.864257812};        *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+#include "count.h"
+
+/* filter coefficients  */
+
+static Word16 b[3] = {915, -1830, 915};         /* Q12 (/4) */
+static Word16 a[3] = {16384, 29280, -14160};    /* Q12 (x4) */
+
+
+/* Initialization of static values */
+
+void Init_HP400_12k8(Word16 mem[])
+{
+    Set_zero(mem, 6);
+}
+
+
+void HP400_12k8(
+     Word16 signal[],                      /* input signal / output is divided by 16 */
+     Word16 lg,                            /* lenght of signal    */
+     Word16 mem[]                          /* filter memory [6]   */
+)
+{
+    Word16 i, x2;
+    Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
+    Word32 L_tmp;
+
+    y2_hi = mem[0];                        move16();
+    y2_lo = mem[1];                        move16();
+    y1_hi = mem[2];                        move16();
+    y1_lo = mem[3];                        move16();
+    x0 = mem[4];                           move16();
+    x1 = mem[5];                           move16();
+
+    for (i = 0; i < lg; i++)
+    {
+        x2 = x1;                           move16();
+        x1 = x0;                           move16();
+        x0 = signal[i];                    move16();
+
+        /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2]  */
+        /* + a[1]*y[i-1] + a[2] * y[i-2];  */
+
+        move32();
+        L_tmp = 16384L;                    /* rounding to maximise precision */
+        L_tmp = L_mac(L_tmp, y1_lo, a[1]);
+        L_tmp = L_mac(L_tmp, y2_lo, a[2]);
+        L_tmp = L_shr(L_tmp, 15);
+        L_tmp = L_mac(L_tmp, y1_hi, a[1]);
+        L_tmp = L_mac(L_tmp, y2_hi, a[2]);
+        L_tmp = L_mac(L_tmp, x0, b[0]);
+        L_tmp = L_mac(L_tmp, x1, b[1]);
+        L_tmp = L_mac(L_tmp, x2, b[2]);
+
+        L_tmp = L_shl(L_tmp, 1);           /* coeff Q12 --> Q13 */
+
+        y2_hi = y1_hi;                     move16();
+        y2_lo = y1_lo;                     move16();
+        L_Extract(L_tmp, &y1_hi, &y1_lo);
+
+        /* signal is divided by 16 to avoid overflow in energy computation */
+        signal[i] = round(L_tmp);          move16();
+    }
+
+    mem[0] = y2_hi;                        move16();
+    mem[1] = y2_lo;                        move16();
+    mem[2] = y1_hi;                        move16();
+    mem[3] = y1_lo;                        move16();
+    mem[4] = x0;                           move16();
+    mem[5] = x1;                           move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/hp50.c
@@ -1,0 +1,97 @@
+/*-----------------------------------------------------------------------*
+ *                         HP50.C                                        *
+ *-----------------------------------------------------------------------*
+ * 2nd order high pass filter with cut off frequency at 31 Hz.           *
+ * Designed with cheby2 function in MATLAB.                              *
+ * Optimized for fixed-point to get the following frequency response:    *
+ *                                                                       *
+ *  frequency:     0Hz    14Hz  24Hz   31Hz   37Hz   41Hz   47Hz         *
+ *  dB loss:     -infdB  -15dB  -6dB   -3dB  -1.5dB  -1dB  -0.5dB        *
+ *                                                                       *
+ * Algorithm:                                                            *
+ *                                                                       *
+ *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]                         *
+ *                   + a[1]*y[i-1] + a[2]*y[i-2];                        *
+ *                                                                       *
+ *  Word16 b[3] = {4053, -8106, 4053};       in Q12                     *
+ *  Word16 a[3] = {8192, 16211, -8021};       in Q12                     *
+ *                                                                       *
+ *  float -->   b[3] = {0.989501953, -1.979003906,  0.989501953};        *
+ *              a[3] = {1.000000000,  1.978881836, -0.979125977};        *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+/* filter coefficients  */
+static Word16 b[3] = {4053, -8106, 4053};  /* Q12 */
+static Word16 a[3] = {8192, 16211, -8021}; /* Q12 (x2) */
+
+/* Initialization of static values */
+
+void Init_HP50_12k8(Word16 mem[])
+{
+    Set_zero(mem, 6);
+}
+
+
+void HP50_12k8(
+     Word16 signal[],                      /* input/output signal */
+     Word16 lg,                            /* lenght of signal    */
+     Word16 mem[]                          /* filter memory [6]   */
+)
+{
+    Word16 i, x2;
+    Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1;
+    Word32 L_tmp;
+
+    y2_hi = mem[0];                        move16();
+    y2_lo = mem[1];                        move16();
+    y1_hi = mem[2];                        move16();
+    y1_lo = mem[3];                        move16();
+    x0 = mem[4];                           move16();
+    x1 = mem[5];                           move16();
+
+    for (i = 0; i < lg; i++)
+    {
+        x2 = x1;                           move16();
+        x1 = x0;                           move16();
+        x0 = signal[i];                    move16();
+
+        /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2]  */
+        /* + a[1]*y[i-1] + a[2] * y[i-2];  */
+
+        move32();
+        L_tmp = 16384L;                    /* rounding to maximise precision */
+        L_tmp = L_mac(L_tmp, y1_lo, a[1]);
+        L_tmp = L_mac(L_tmp, y2_lo, a[2]);
+        L_tmp = L_shr(L_tmp, 15);
+        L_tmp = L_mac(L_tmp, y1_hi, a[1]);
+        L_tmp = L_mac(L_tmp, y2_hi, a[2]);
+        L_tmp = L_mac(L_tmp, x0, b[0]);
+        L_tmp = L_mac(L_tmp, x1, b[1]);
+        L_tmp = L_mac(L_tmp, x2, b[2]);
+
+        L_tmp = L_shl(L_tmp, 2);           /* coeff Q12 --> Q14 */
+
+        y2_hi = y1_hi;                     move16();
+        y2_lo = y1_lo;                     move16();
+        L_Extract(L_tmp, &y1_hi, &y1_lo);
+
+        L_tmp = L_shl(L_tmp, 1);           /* coeff Q14 --> Q15 with saturation */
+        signal[i] = round(L_tmp);          move16();
+    }
+
+    mem[0] = y2_hi;                        move16();
+    mem[1] = y2_lo;                        move16();
+    mem[2] = y1_hi;                        move16();
+    mem[3] = y1_lo;                        move16();
+    mem[4] = x0;                           move16();
+    mem[5] = x1;                           move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/hp6k.c
@@ -1,0 +1,66 @@
+/*-------------------------------------------------------------------*
+ *                         HP6K.C                                    *
+ *-------------------------------------------------------------------*
+ * 15th order band pass 6kHz to 7kHz FIR filter.                     *
+ *                                                                   *
+ * frequency:  4kHz   5kHz  5.5kHz  6kHz  6.5kHz 7kHz  7.5kHz  8kHz  *
+ * dB loss:   -60dB  -45dB  -13dB   -3dB   0dB   -3dB  -13dB  -45dB  *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "count.h"
+#include "cnst.h"
+
+#define L_FIR 31
+
+/* filter coefficients (gain=4.0) */
+
+static Word16 fir_6k_7k[L_FIR] =
+{
+    -32, 47, 32, -27, -369,
+    1122, -1421, 0, 3798, -8880,
+    12349, -10984, 3548, 7766, -18001,
+    22118, -18001, 7766, 3548, -10984,
+    12349, -8880, 3798, 0, -1421,
+    1122, -369, -27, 32, 47,
+    -32
+};
+
+
+void Init_Filt_6k_7k(Word16 mem[])         /* mem[30] */
+{
+    Set_zero(mem, L_FIR - 1);
+
+    return;
+}
+
+void Filt_6k_7k(
+     Word16 signal[],                      /* input:  signal                  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 mem[]                          /* in/out: memory (size=30)        */
+)
+{
+    Word16 i, j, x[L_SUBFR16k + (L_FIR - 1)];
+    Word32 L_tmp;
+
+    Copy(mem, x, L_FIR - 1);
+
+    for (i = 0; i < lg; i++)
+    {
+        x[i + L_FIR - 1] = shr(signal[i], 2);   move16();  /* gain of filter = 4 */
+    }
+
+    for (i = 0; i < lg; i++)
+    {
+        L_tmp = 0;                         move32();
+        for (j = 0; j < L_FIR; j++)
+            L_tmp = L_mac(L_tmp, x[i + j], fir_6k_7k[j]);
+        signal[i] = round(L_tmp);          move16();
+    }
+
+    Copy(x + lg, mem, L_FIR - 1);
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/hp7k.c
@@ -1,0 +1,63 @@
+/*-------------------------------------------------------------------*
+ *                         HP6K.C                                    *
+ *-------------------------------------------------------------------*
+ * 15th order high pass 7kHz FIR filter.                             *
+ *                                                                   *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+
+#define L_FIR 31
+
+static Word16 fir_7k[L_FIR] =
+{
+    -21, 47, -89, 146, -203,
+    229, -177, 0, 335, -839,
+    1485, -2211, 2931, -3542, 3953,
+    28682, 3953, -3542, 2931, -2211,
+    1485, -839, 335, 0, -177,
+    229, -203, 146, -89, 47,
+    -21
+};
+
+void Init_Filt_7k(Word16 mem[])            /* mem[30] */
+{
+    Set_zero(mem, L_FIR - 1);
+
+    return;
+}
+
+
+void Filt_7k(
+     Word16 signal[],                      /* input:  signal                  */
+     Word16 lg,                            /* input:  length of input         */
+     Word16 mem[]                          /* in/out: memory (size=30)        */
+)
+{
+    Word16 i, j, x[L_SUBFR16k + (L_FIR - 1)];
+    Word32 L_tmp;
+
+    Copy(mem, x, L_FIR - 1);
+
+    for (i = 0; i < lg; i++)
+    {
+        x[i + L_FIR - 1] = signal[i];      move16();
+    }
+
+    for (i = 0; i < lg; i++)
+    {
+        L_tmp = 0;                         move32();
+        for (j = 0; j < L_FIR; j++)
+            L_tmp = L_mac(L_tmp, x[i + j], fir_7k[j]);
+        signal[i] = round(L_tmp);          move16();
+    }
+
+    Copy(x + lg, mem, L_FIR - 1);
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/hp_wsp.c
@@ -1,0 +1,139 @@
+/*-----------------------------------------------------------------------*
+ *                         HP_WSP.C                                      *
+ *-----------------------------------------------------------------------*
+ *                                                                       *
+ * 3nd order high pass filter with cut off frequency at 180 Hz           *
+ *                                                                       *
+ * Algorithm:                                                            *
+ *                                                                       *
+ *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] + b[3]*x[i-3]           *
+ *                   + a[1]*y[i-1] + a[2]*y[i-2] + a[3]*y[i-3];          *
+ *                                                                       *
+ * float a_coef[HP_ORDER]= {                                             *
+ *    -2.64436711600664f,                                                *
+ *    2.35087386625360f,                                                 *
+ *   -0.70001156927424f};                                                *
+ *                                                                       *
+ * float b_coef[HP_ORDER+1]= {                                           *
+ *     -0.83787057505665f,                                               *
+ *    2.50975570071058f,                                                 *
+ *   -2.50975570071058f,                                                 *
+ *    0.83787057505665f};                                                *
+ *                                                                       *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+#include "count.h"
+
+
+/* filter coefficients in Q12 */
+
+static Word16 a[4] = {8192, 21663, -19258, 5734};
+static Word16 b[4] = {-3432, +10280, -10280, +3432};
+
+
+/* Initialization of static values */
+
+void Init_Hp_wsp(Word16 mem[])
+{
+    Set_zero(mem, 9);
+
+    return;
+}
+
+void scale_mem_Hp_wsp(Word16 mem[], Word16 exp)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    for (i = 0; i < 6; i += 2)
+    {
+        L_tmp = L_Comp(mem[i], mem[i + 1]);/* y_hi, y_lo */
+        L_tmp = L_shl(L_tmp, exp);
+        L_Extract(L_tmp, &mem[i], &mem[i + 1]);
+    }
+
+    for (i = 6; i < 9; i++)
+    {
+        L_tmp = L_deposit_h(mem[i]);       /* x[i] */
+        L_tmp = L_shl(L_tmp, exp);
+        mem[i] = round(L_tmp);             move16();
+    }
+
+    return;
+}
+
+
+void Hp_wsp(
+     Word16 wsp[],                         /* i   : wsp[]  signal       */
+     Word16 hp_wsp[],                      /* o   : hypass wsp[]        */
+     Word16 lg,                            /* i   : lenght of signal    */
+     Word16 mem[]                          /* i/o : filter memory [9]   */
+)
+{
+    Word16 i;
+    Word16 x0, x1, x2, x3;
+    Word16 y3_hi, y3_lo, y2_hi, y2_lo, y1_hi, y1_lo;
+    Word32 L_tmp;
+
+    y3_hi = mem[0];                        move16();
+    y3_lo = mem[1];                        move16();
+    y2_hi = mem[2];                        move16();
+    y2_lo = mem[3];                        move16();
+    y1_hi = mem[4];                        move16();
+    y1_lo = mem[5];                        move16();
+    x0 = mem[6];                           move16();
+    x1 = mem[7];                           move16();
+    x2 = mem[8];                           move16();
+
+    for (i = 0; i < lg; i++)
+    {
+        x3 = x2;                           move16();
+        x2 = x1;                           move16();
+        x1 = x0;                           move16();
+        x0 = wsp[i];                       move16();
+
+        /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] + b[3]*x[i-3]  */
+        /* + a[1]*y[i-1] + a[2] * y[i-2]  + a[3]*y[i-3]  */
+
+        move32();
+        L_tmp = 16384L;                    /* rounding to maximise precision */
+        L_tmp = L_mac(L_tmp, y1_lo, a[1]);
+        L_tmp = L_mac(L_tmp, y2_lo, a[2]);
+        L_tmp = L_mac(L_tmp, y3_lo, a[3]);
+        L_tmp = L_shr(L_tmp, 15);
+        L_tmp = L_mac(L_tmp, y1_hi, a[1]);
+        L_tmp = L_mac(L_tmp, y2_hi, a[2]);
+        L_tmp = L_mac(L_tmp, y3_hi, a[3]);
+        L_tmp = L_mac(L_tmp, x0, b[0]);
+        L_tmp = L_mac(L_tmp, x1, b[1]);
+        L_tmp = L_mac(L_tmp, x2, b[2]);
+        L_tmp = L_mac(L_tmp, x3, b[3]);
+
+        L_tmp = L_shl(L_tmp, 2);           /* coeff Q12 --> Q15 */
+
+        y3_hi = y2_hi;                     move16();
+        y3_lo = y2_lo;                     move16();
+        y2_hi = y1_hi;                     move16();
+        y2_lo = y1_lo;                     move16();
+        L_Extract(L_tmp, &y1_hi, &y1_lo);
+
+        L_tmp = L_shl(L_tmp, 1);           /* coeff Q14 --> Q15 */
+        hp_wsp[i] = round(L_tmp);          move16();
+    }
+
+    mem[0] = y3_hi;                        move16();
+    mem[1] = y3_lo;                        move16();
+    mem[2] = y2_hi;                        move16();
+    mem[3] = y2_lo;                        move16();
+    mem[4] = y1_hi;                        move16();
+    mem[5] = y1_lo;                        move16();
+    mem[6] = x0;                           move16();
+    mem[7] = x1;                           move16();
+    mem[8] = x2;                           move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/int_lpc.c
@@ -1,0 +1,47 @@
+/*-----------------------------------------------------------------------*
+ *                         HP400.C                                       *
+ *-----------------------------------------------------------------------*
+ * Interpolation of the LP parameters in 4 subframes.                    *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+#define MP1 (M+1)
+
+
+void Int_isp(
+     Word16 isp_old[],                     /* input : isps from past frame              */
+     Word16 isp_new[],                     /* input : isps from present frame           */
+     Word16 frac[],                        /* input : fraction for 3 first subfr (Q15)  */
+     Word16 Az[]                           /* output: LP coefficients in 4 subframes    */
+)
+{
+    Word16 i, k, fac_old, fac_new;
+    Word16 isp[M];
+    Word32 L_tmp;
+
+    for (k = 0; k < 3; k++)
+    {
+        fac_new = frac[k];                 move16();
+        fac_old = add(sub(32767, fac_new), 1);  /* 1.0 - fac_new */
+
+        for (i = 0; i < M; i++)
+        {
+            L_tmp = L_mult(isp_old[i], fac_old);
+            L_tmp = L_mac(L_tmp, isp_new[i], fac_new);
+            isp[i] = round(L_tmp);         move16();
+        }
+        Isp_Az(isp, Az, M, 0);
+        Az += MP1;
+    }
+
+    /* 4th subframe: isp_new (frac=1.0) */
+
+    Isp_Az(isp_new, Az, M, 0);
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/isfextrp.c
@@ -1,0 +1,167 @@
+/*-----------------------------------------------------------------------*
+ *                         ISFEXTRP.C                                    *
+ *-----------------------------------------------------------------------*
+ *  Conversion of 16th-order 12.8kHz ISF vector                          *
+ *  into 20th-order 16kHz ISF vector                                     *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+#define INV_LENGTH 2731                    /* 1/12 */
+
+void Isf_Extrapolation(Word16 HfIsf[])
+{
+    Word16 IsfDiff[M - 2];
+    Word32 IsfCorr[3];
+    Word32 L_tmp;
+    Word16 coeff, mean, tmp, tmp2, tmp3;
+    Word16 exp, exp2, hi, lo;
+    Word16 i, MaxCorr;
+
+    HfIsf[M16k - 1] = HfIsf[M - 1];        move16();
+
+    /* Difference vector */
+    for (i = 1; i < (M - 1); i++)
+    {
+        IsfDiff[i - 1] = sub(HfIsf[i], HfIsf[i - 1]);   move16();
+    }
+    L_tmp = 0;                             move32();
+
+    /* Mean of difference vector */
+    for (i = 3; i < (M - 1); i++)
+        L_tmp = L_mac(L_tmp, IsfDiff[i - 1], INV_LENGTH);
+    mean = round(L_tmp);
+
+    IsfCorr[0] = 0;                        move32();
+    IsfCorr[1] = 0;                        move32();
+    IsfCorr[2] = 0;                        move32();
+
+    tmp = 0;                               move16();
+    for (i = 0; i < (M - 2); i++)
+    {
+        test();
+        if (sub(IsfDiff[i], tmp) > 0)
+        {
+            tmp = IsfDiff[i];              move16();
+        }
+    }
+    exp = norm_s(tmp);
+    for (i = 0; i < (M - 2); i++)
+    {
+        IsfDiff[i] = shl(IsfDiff[i], exp); move16();
+    }
+    mean = shl(mean, exp);
+    for (i = 7; i < (M - 2); i++)
+    {
+        tmp2 = sub(IsfDiff[i], mean);
+        tmp3 = sub(IsfDiff[i - 2], mean);
+        L_tmp = L_mult(tmp2, tmp3);
+        L_Extract(L_tmp, &hi, &lo);
+        L_tmp = Mpy_32(hi, lo, hi, lo);
+        IsfCorr[0] = L_add(IsfCorr[0], L_tmp);  move32();
+    }
+    for (i = 7; i < (M - 2); i++)
+    {
+        tmp2 = sub(IsfDiff[i], mean);
+        tmp3 = sub(IsfDiff[i - 3], mean);
+        L_tmp = L_mult(tmp2, tmp3);
+        L_Extract(L_tmp, &hi, &lo);
+        L_tmp = Mpy_32(hi, lo, hi, lo);
+        IsfCorr[1] = L_add(IsfCorr[1], L_tmp);  move32();
+    }
+    for (i = 7; i < (M - 2); i++)
+    {
+        tmp2 = sub(IsfDiff[i], mean);
+        tmp3 = sub(IsfDiff[i - 4], mean);
+        L_tmp = L_mult(tmp2, tmp3);
+        L_Extract(L_tmp, &hi, &lo);
+        L_tmp = Mpy_32(hi, lo, hi, lo);
+        IsfCorr[2] = L_add(IsfCorr[2], L_tmp);  move32();
+    }
+    test();
+    if (L_sub(IsfCorr[0], IsfCorr[1]) > 0)
+    {
+        MaxCorr = 0;                       move16();
+    } else
+    {
+        MaxCorr = 1;                       move16();
+    }
+
+    test();
+    if (L_sub(IsfCorr[2], IsfCorr[MaxCorr]) > 0)
+        MaxCorr = 2;                       move16();
+
+    MaxCorr = add(MaxCorr, 1);             /* Maximum correlation of difference vector */
+
+    for (i = M - 1; i < (M16k - 1); i++)
+    {
+        tmp = sub(HfIsf[i - 1 - MaxCorr], HfIsf[i - 2 - MaxCorr]);
+        HfIsf[i] = add(HfIsf[i - 1], tmp); move16();
+    }
+
+    /* tmp=7965+(HfIsf[2]-HfIsf[3]-HfIsf[4])/6; */
+    tmp = add(HfIsf[4], HfIsf[3]);
+    tmp = sub(HfIsf[2], tmp);
+    tmp = mult(tmp, 5461);
+    tmp = add(tmp, 20390);
+
+    test();
+    if (sub(tmp, 19456) > 0)
+    {                                      /* Maximum value of ISF should be at most 7600 Hz */
+        tmp = 19456;                       move16();
+    }
+    tmp = sub(tmp, HfIsf[M - 2]);
+    tmp2 = sub(HfIsf[M16k - 2], HfIsf[M - 2]);
+
+    exp2 = norm_s(tmp2);
+    exp = norm_s(tmp);
+    exp = sub(exp, 1);
+    tmp = shl(tmp, exp);
+    tmp2 = shl(tmp2, exp2);
+    coeff = div_s(tmp, tmp2);              /* Coefficient for stretching the ISF vector */
+    exp = sub(exp2, exp);
+
+    for (i = M - 1; i < (M16k - 1); i++)
+    {
+        tmp = mult(sub(HfIsf[i], HfIsf[i - 1]), coeff);
+        IsfDiff[i - (M - 1)] = shl(tmp, exp);   move16();
+    }
+
+    for (i = M; i < (M16k - 1); i++)
+    {
+        /* The difference between ISF(n) and ISF(n-2) should be at least 500 Hz */
+        tmp = sub(add(IsfDiff[i - (M - 1)], IsfDiff[i - M]), 1280);
+        test();
+        if (tmp < 0)
+        {
+            test();
+            if (sub(IsfDiff[i - (M - 1)], IsfDiff[i - M]) > 0)
+            {
+                IsfDiff[i - M] = sub(1280, IsfDiff[i - (M - 1)]);       move16();
+            } else
+            {
+                IsfDiff[i - (M - 1)] = sub(1280, IsfDiff[i - M]);       move16();
+            }
+        }
+    }
+
+    for (i = M - 1; i < (M16k - 1); i++)
+    {
+        HfIsf[i] = add(HfIsf[i - 1], IsfDiff[i - (M - 1)]);     move16();
+    }
+
+    for (i = 0; i < (M16k - 1); i++)
+    {
+        move16();
+        HfIsf[i] = mult(HfIsf[i], 26214);  /* Scale the ISF vector correctly for 16000 kHz */
+    }
+
+    Isf_isp(HfIsf, HfIsf, M16k);
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/isp_az.c
@@ -1,0 +1,246 @@
+/*-----------------------------------------------------------------------*
+ *                         ISP_AZ.C                                      *
+ *-----------------------------------------------------------------------*
+ * Compute the LPC coefficients from isp (order=M)                       *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "count.h"
+#include "cnst.h"
+
+#define NC (M/2)
+#define NC16k (M16k/2)
+
+/* local function */
+
+static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n);
+static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n);
+
+void Isp_Az(
+     Word16 isp[],                         /* (i) Q15 : Immittance spectral pairs            */
+     Word16 a[],                           /* (o) Q12 : predictor coefficients (order = M)   */
+     Word16 m,
+     Word16 adaptive_scaling               /* (i) 0   : adaptive scaling disabled */
+                                           /*     1   : adaptive scaling enabled  */
+)
+{
+    Word16 i, j, hi, lo;
+    Word32 f1[NC16k + 1], f2[NC16k];
+    Word16 nc;
+    Word32 t0;
+    Word16 q, q_sug;
+    Word32 tmax;
+
+    nc = shr(m, 1);
+    test();
+    if (sub(nc, 8) > 0)
+    {
+        Get_isp_pol_16kHz(&isp[0], f1, nc);
+        for (i = 0; i <= nc; i++)
+        {
+            f1[i] = L_shl(f1[i], 2);       move32();
+        }
+    } else
+        Get_isp_pol(&isp[0], f1, nc);
+
+    test();
+    if (sub(nc, 8) > 0)
+    {
+        Get_isp_pol_16kHz(&isp[1], f2, sub(nc, 1));
+        for (i = 0; i <= nc - 1; i++)
+        {
+            f2[i] = L_shl(f2[i], 2);       move32();
+        }
+    } else
+        Get_isp_pol(&isp[1], f2, sub(nc, 1));
+
+    /*-----------------------------------------------------*
+     *  Multiply F2(z) by (1 - z^-2)                       *
+     *-----------------------------------------------------*/
+
+    for (i = sub(nc, 1); i > 1; i--)
+    {
+        f2[i] = L_sub(f2[i], f2[i - 2]);   move32();  /* f2[i] -= f2[i-2]; */
+    }
+
+    /*----------------------------------------------------------*
+     *  Scale F1(z) by (1+isp[m-1])  and  F2(z) by (1-isp[m-1]) *
+     *----------------------------------------------------------*/
+
+    for (i = 0; i < nc; i++)
+    {
+        /* f1[i] *= (1.0 + isp[M-1]); */
+
+        L_Extract(f1[i], &hi, &lo);
+        t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+        f1[i] = L_add(f1[i], t0);          move32();
+
+        /* f2[i] *= (1.0 - isp[M-1]); */
+
+        L_Extract(f2[i], &hi, &lo);
+        t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+        f2[i] = L_sub(f2[i], t0);          move32();
+    }
+
+    /*-----------------------------------------------------*
+     *  A(z) = (F1(z)+F2(z))/2                             *
+     *  F1(z) is symmetric and F2(z) is antisymmetric      *
+     *-----------------------------------------------------*/
+
+    /* a[0] = 1.0; */
+    a[0] = 4096;                           move16();
+    tmax = 1;                              move32();
+    for (i = 1, j = sub(m, 1); i < nc; i++, j--)
+    {
+        /* a[i] = 0.5*(f1[i] + f2[i]); */
+
+        t0 = L_add(f1[i], f2[i]);          /* f1[i] + f2[i]             */
+        tmax |= L_abs(t0);                 logic32();
+        a[i] = extract_l(L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
+        move16();
+
+        /* a[j] = 0.5*(f1[i] - f2[i]); */
+
+        t0 = L_sub(f1[i], f2[i]);          /* f1[i] - f2[i]             */
+        tmax |= L_abs(t0);                 logic32();
+        a[j] = extract_l(L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
+        move16();
+    }
+
+    /* rescale data if overflow has occured and reprocess the loop */
+
+    test();
+    if ( sub(adaptive_scaling, 1) == 0 )
+       q = sub(4, norm_l(tmax));        /* adaptive scaling enabled */
+    else
+       q = 0;           move16();       /* adaptive scaling disabled */
+
+    test();
+    if (q > 0)
+    {
+      q_sug = add(12, q);
+      for (i = 1, j = sub(m, 1); i < nc; i++, j--)
+        {
+          /* a[i] = 0.5*(f1[i] + f2[i]); */
+
+          t0 = L_add(f1[i], f2[i]);          /* f1[i] + f2[i]             */
+          a[i] = extract_l(L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
+          move16();
+
+          /* a[j] = 0.5*(f1[i] - f2[i]); */
+
+          t0 = L_sub(f1[i], f2[i]);          /* f1[i] - f2[i]             */
+          a[j] = extract_l(L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
+          move16();
+        }
+      a[0] = shr(a[0], q);                 move16();
+    }
+    else
+    {
+      q_sug = 12;                          move16();
+      q     = 0;                           move16();
+    }
+
+
+    /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */
+
+    L_Extract(f1[nc], &hi, &lo);
+    t0 = Mpy_32_16(hi, lo, isp[m - 1]);
+    t0 = L_add(f1[nc], t0);
+    a[nc] = extract_l(L_shr_r(t0, q_sug));    /* from Q23 to Q12 and * 0.5 */
+    move16();
+    /* a[m] = isp[m-1]; */
+
+    a[m] = shr_r(isp[m - 1], add(3,q));           /* from Q15 to Q12          */
+    move16();
+
+    return;
+}
+
+/*-----------------------------------------------------------*
+ * procedure Get_isp_pol:                                    *
+ *           ~~~~~~~~~~~                                     *
+ *   Find the polynomial F1(z) or F2(z) from the ISPs.       *
+ * This is performed by expanding the product polynomials:   *
+ *                                                           *
+ * F1(z) =   product   ( 1 - 2 isp_i z^-1 + z^-2 )           *
+ *         i=0,2,4,6,8                                       *
+ * F2(z) =   product   ( 1 - 2 isp_i z^-1 + z^-2 )           *
+ *         i=1,3,5,7                                         *
+ *                                                           *
+ * where isp_i are the ISPs in the cosine domain.            *
+ *-----------------------------------------------------------*
+ *                                                           *
+ * Parameters:                                               *
+ *  isp[]   : isp vector (cosine domaine)         in Q15     *
+ *  f[]     : the coefficients of F1 or F2        in Q23     *
+ *  n       : == NC for F1(z); == NC-1 for F2(z)             *
+ *-----------------------------------------------------------*/
+
+static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n)
+{
+    Word16 i, j, hi, lo;
+    Word32 t0;
+
+
+    /* All computation in Q23 */
+
+    f[0] = L_mult(4096, 1024);             move32();  /* f[0] = 1.0;        in Q23  */
+    f[1] = L_mult(isp[0], -256);           move32();  /* f[1] = -2.0*isp[0] in Q23  */
+
+    f += 2;                                move32();  /* Advance f pointer          */
+    isp += 2;                              move16();  /* Advance isp pointer        */
+
+    for (i = 2; i <= n; i++)
+    {
+
+        *f = f[-2];                        move32();
+
+        for (j = 1; j < i; j++, f--)
+        {
+            L_Extract(f[-1], &hi, &lo);
+            t0 = Mpy_32_16(hi, lo, *isp);  /* t0 = f[-1] * isp    */
+            t0 = L_shl(t0, 1);
+            *f = L_sub(*f, t0);            move32();  /* *f -= t0            */
+            *f = L_add(*f, f[-2]);         move32();  /* *f += f[-2]         */
+        }
+        *f = L_msu(*f, *isp, 256);         move32();  /* *f -= isp<<8        */
+        f += i;                            /* Advance f pointer   */
+        isp += 2;                          /* Advance isp pointer */
+    }
+    return;
+}
+
+static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n)
+{
+    Word16 i, j, hi, lo;
+    Word32 t0;
+
+    /* All computation in Q23 */
+
+    f[0] = L_mult(4096, 256);              move32();  /* f[0] = 1.0;        in Q23  */
+    f[1] = L_mult(isp[0], -64);            move32();  /* f[1] = -2.0*isp[0] in Q23  */
+
+    f += 2;                                move32();  /* Advance f pointer          */
+    isp += 2;                              move16();  /* Advance isp pointer        */
+
+    for (i = 2; i <= n; i++)
+    {
+        *f = f[-2];                        move32();
+
+        for (j = 1; j < i; j++, f--)
+        {
+            L_Extract(f[-1], &hi, &lo);
+            t0 = Mpy_32_16(hi, lo, *isp);  /* t0 = f[-1] * isp    */
+            t0 = L_shl(t0, 1);
+            *f = L_sub(*f, t0);            move32();  /* *f -= t0            */
+            *f = L_add(*f, f[-2]);         move32();  /* *f += f[-2]         */
+        }
+        *f = L_msu(*f, *isp, 64);          move32();  /* *f -= isp<<8        */
+        f += i;                            /* Advance f pointer   */
+        isp += 2;                          /* Advance isp pointer */
+    }
+    return;
+}
--- /dev/null
+++ b/amr-wb/isp_isf.c
@@ -1,0 +1,81 @@
+/*-------------------------------------------------------------------*
+ *                         ISP_ISF.C                                 *
+ *-------------------------------------------------------------------*
+ *   Isp_isf   Transformation isp to isf                             *
+ *   Isf_isp   Transformation isf to isp                             *
+ *                                                                   *
+ * The transformation from isp[i] to isf[i] and isf[i] to isp[i] are *
+ * approximated by a look-up table and interpolation.                *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+#include "isp_isf.tab"                     /* Look-up table for transformations */
+
+void Isp_isf(
+     Word16 isp[],                         /* (i) Q15 : isp[m] (range: -1<=val<1)                */
+     Word16 isf[],                         /* (o) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+     Word16 m                              /* (i)     : LPC order                                */
+)
+{
+    Word16 i, ind;
+    Word32 L_tmp;
+
+    ind = 127;                             move16();  /* beging at end of table -1 */
+
+    for (i = (Word16) (m - 1); i >= 0; i--)
+    {
+        test();
+        if (sub(i, sub(m, 2)) >= 0)
+        {                                  /* m-2 is a constant */
+            ind = 127;                     move16();  /* beging at end of table -1 */
+        }
+        /* find value in table that is just greater than isp[i] */
+        test();
+        while (sub(table[ind], isp[i]) < 0)
+            ind--;
+
+        /* acos(isp[i])= ind*128 + ( ( isp[i]-table[ind] ) * slope[ind] )/2048 */
+
+        L_tmp = L_mult(sub(isp[i], table[ind]), slope[ind]);
+        isf[i] = round(L_shl(L_tmp, 4));   /* (isp[i]-table[ind])*slope[ind])>>11 */
+        move16();
+        isf[i] = add(isf[i], shl(ind, 7)); move16();
+    }
+
+    isf[m - 1] = shr(isf[m - 1], 1);       move16();
+
+    return;
+}
+
+
+void Isf_isp(
+     Word16 isf[],                         /* (i) Q15 : isf[m] normalized (range: 0.0<=val<=0.5) */
+     Word16 isp[],                         /* (o) Q15 : isp[m] (range: -1<=val<1)                */
+     Word16 m                              /* (i)     : LPC order                                */
+)
+{
+    Word16 i, ind, offset;
+    Word32 L_tmp;
+
+    for (i = 0; i < m - 1; i++)
+    {
+        isp[i] = isf[i];                   move16();
+    }
+    isp[m - 1] = shl(isf[m - 1], 1);
+
+    for (i = 0; i < m; i++)
+    {
+        ind = shr(isp[i], 7);              /* ind    = b7-b15 of isf[i] */
+        offset = (Word16) (isp[i] & 0x007f);    logic16();  /* offset = b0-b6  of isf[i] */
+
+        /* isp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 128 */
+
+        L_tmp = L_mult(sub(table[ind + 1], table[ind]), offset);
+        isp[i] = add(table[ind], extract_l(L_shr(L_tmp, 8)));   move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/isp_isf.tab
@@ -1,0 +1,45 @@
+/*-----------------------------------------------------*
+ | Tables for function Isf_isp() and Isp_isf()         |
+ *-----------------------------------------------------*/
+
+/* table of cos(x) in Q15 */
+
+static Word16 table[129] = {
+  32767,
+  32758,  32729,  32679,  32610,  32522,  32413,  32286,  32138,
+  31972,  31786,  31581,  31357,  31114,  30853,  30572,  30274,
+  29957,  29622,  29269,  28899,  28511,  28106,  27684,  27246,
+  26791,  26320,  25833,  25330,  24812,  24279,  23732,  23170,
+  22595,  22006,  21403,  20788,  20160,  19520,  18868,  18205,
+  17531,  16846,  16151,  15447,  14733,  14010,  13279,  12540,
+  11793,  11039,  10279,   9512,   8740,   7962,   7180,   6393,
+   5602,   4808,   4011,   3212,   2411,   1608,    804,      0,
+   -804,  -1608,  -2411,  -3212,  -4011,  -4808,  -5602,  -6393,
+  -7180,  -7962,  -8740,  -9512, -10279, -11039, -11793, -12540,
+ -13279, -14010, -14733, -15447, -16151, -16846, -17531, -18205,
+ -18868, -19520, -20160, -20788, -21403, -22006, -22595, -23170,
+ -23732, -24279, -24812, -25330, -25833, -26320, -26791, -27246,
+ -27684, -28106, -28511, -28899, -29269, -29622, -29957, -30274,
+ -30572, -30853, -31114, -31357, -31581, -31786, -31972, -32138,
+ -32286, -32413, -32522, -32610, -32679, -32729, -32758, -32768};
+
+/* slope in Q11 used to compute y = acos(x) */
+
+static Word16 slope[128] = { 
+ -26214, -9039, -5243, -3799, -2979, -2405, -2064, -1771,
+ -1579, -1409, -1279, -1170, -1079, -1004, -933, -880,
+ -827, -783, -743, -708, -676, -647, -621, -599,
+ -576, -557, -538, -521, -506, -492, -479, -466,
+ -456, -445, -435, -426, -417, -410, -402, -395,
+ -389, -383, -377, -372, -367, -363, -359, -355,
+ -351, -348, -345, -342, -340, -337, -335, -333,
+ -331, -330, -329, -328, -327, -326, -326, -326,
+ -326, -326, -326, -327, -328, -329, -330, -331,
+ -333, -335, -337, -340, -342, -345, -348, -351,
+ -355, -359, -363, -367, -372, -377, -383, -389,
+ -395, -402, -410, -417, -426, -435, -445, -456,
+ -466, -479, -492, -506, -521, -538, -557, -576,
+ -599, -621, -647, -676, -708, -743, -783, -827,
+ -880, -933, -1004, -1079, -1170, -1279, -1409, -1579,
+ -1771, -2064, -2405, -2979, -3799, -5243, -9039, -26214};
+
--- /dev/null
+++ b/amr-wb/lag_wind.c
@@ -1,0 +1,33 @@
+/*---------------------------------------------------------*
+ *                         LAG_WIND.C                      *
+ *---------------------------------------------------------*
+ * Lag_window on autocorrelations.                         *
+ *                                                         *
+ * r[i] *= lag_wind[i]                                     *
+ *                                                         *
+ *  r[i] and lag_wind[i] are in special double precision.  *
+ *  See "oper_32b.c" for the format                        *
+ *---------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+
+#include "lag_wind.tab"
+
+
+void Lag_window(
+     Word16 r_h[],                         /* (i/o)   : Autocorrelations  (msb)          */
+     Word16 r_l[]                          /* (i/o)   : Autocorrelations  (lsb)          */
+)
+{
+    Word16 i;
+    Word32 x;
+
+    for (i = 1; i <= M; i++)
+    {
+        x = Mpy_32(r_h[i], r_l[i], lag_h[i - 1], lag_l[i - 1]);
+        L_Extract(x, &r_h[i], &r_l[i]);
+    }
+    return;
+}
--- /dev/null
+++ b/amr-wb/lag_wind.tab
@@ -1,0 +1,64 @@
+/*-----------------------------------------------------*
+ | Table of lag_window for autocorrelation.            |
+ | noise floor = 1.0001   = (0.9999  on r[1] ..r[16])  |
+ | Bandwidth expansion = 60 Hz                         |
+ | Sampling frequency  = 12800 Hz                      |
+ |                                                     |
+ | Special double precision format. See "math_op.c"    |
+ |                                                     |
+ | lag_wind[0] =  1.00000000    (not stored)           |
+ | lag_wind[1] =  0.99946642                           |
+ | lag_wind[2] =  0.99816680                           |
+ | lag_wind[3] =  0.99600452                           |
+ | lag_wind[4] =  0.99298513                           |
+ | lag_wind[5] =  0.98911655                           |
+ | lag_wind[6] =  0.98440880                           |
+ | lag_wind[7] =  0.97887397                           |
+ | lag_wind[8] =  0.97252619                           |
+ | lag_wind[9] =  0.96538186                           |
+ | lag_wind[10]=  0.95745903                           |
+ | lag_wind[11]=  0.94877797                           |
+ | lag_wind[12]=  0.93936038                           |
+ | lag_wind[13]=  0.92922986                           |
+ | lag_wind[14]=  0.91841155                           |
+ | lag_wind[15]=  0.90693212                           |
+ | lag_wind[16]=  0.89481968                           |
+ ------------------------------------------------------*/
+
+#define M 16
+
+Word16 lag_h[M] = {
+      32750,
+      32707,
+      32637,
+      32538,
+      32411,
+      32257,
+      32075,
+      31867,
+      31633,
+      31374,
+      31089,
+      30780,
+      30449,
+      30094,
+      29718,
+      29321};
+
+Word16 lag_l[M] = {
+      16896,
+      30464,
+       2496,
+       4480,
+      12160,
+       3520,
+      24320,
+      24192,
+      20736,
+        576,
+      18240,
+      31488,
+        128,
+      16704,
+      11520,
+      14784};
--- /dev/null
+++ b/amr-wb/lagconc.c
@@ -1,0 +1,244 @@
+/*---------------------------------------------------------*
+ *                         LAGCONC.C                       *
+ *---------------------------------------------------------*
+ * Concealment of LTP lags during bad frames               *
+ *---------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "cnst.h"
+#include "acelp.h"
+
+#define L_LTPHIST 5
+#define ONE_PER_3 10923
+#define ONE_PER_LTPHIST 6554
+
+void insertion_sort(Word16 array[], Word16 n);
+void insert(Word16 array[], Word16 num, Word16 x);
+
+void Init_Lagconc(Word16 lag_hist[])
+{
+    Word16 i;
+
+    for (i = 0; i < L_LTPHIST; i++)
+    {
+        lag_hist[i] = 64;
+    }
+}
+
+void lagconc(
+     Word16 gain_hist[],                   /* (i) : Gain history     */
+     Word16 lag_hist[],                    /* (i) : Subframe size    */
+     Word16 * T0,
+     Word16 * old_T0,
+     Word16 * seed,
+     Word16 unusable_frame
+)
+{
+    Word16 maxLag, minLag, lastLag, lagDif, meanLag = 0;
+    Word16 lag_hist2[L_LTPHIST] = {0};
+    Word16 i, tmp, tmp2;
+    Word16 minGain, lastGain, secLastGain;
+    Word16 D, D2;
+
+    /* Is lag index such that it can be aplied directly or does it has to be subtituted */
+
+    lastGain = gain_hist[4];               move16();
+    secLastGain = gain_hist[3];            move16();
+
+    lastLag = lag_hist[0];                 move16();
+
+    /***********SMALLEST history lag***********/
+    minLag = lag_hist[0];                  move16();
+    for (i = 1; i < L_LTPHIST; i++)
+    {
+        test();
+        if (sub(lag_hist[i], minLag) < 0)
+        {
+            minLag = lag_hist[i];          move16();
+        }
+    }
+    /*******BIGGEST history lag*******/
+    maxLag = lag_hist[0];                  move16();
+    for (i = 1; i < L_LTPHIST; i++)
+    {
+        test();
+        if (sub(lag_hist[i], maxLag) > 0)
+        {
+            maxLag = lag_hist[i];          move16();
+        }
+    }
+    /***********SMALLEST history gain***********/
+    minGain = gain_hist[0];                move16();
+    for (i = 1; i < L_LTPHIST; i++)
+    {
+        test();
+        if (sub(gain_hist[i], minGain) < 0)
+        {
+            minGain = gain_hist[i];        move16();
+        }
+    }
+    /***Difference between MAX and MIN lag**/
+    lagDif = sub(maxLag, minLag);
+
+    test();
+    if (unusable_frame != 0)
+    {
+        /* LTP-lag for RX_SPEECH_LOST */
+        /**********Recognition of the LTP-history*********/
+        test();test();test();test();
+        if ((sub(minGain, 8192) > 0) && (sub(lagDif, 10) < 0))
+        {
+            *T0 = *old_T0;                 move16();
+        } else if (sub(lastGain, 8192) > 0 && sub(secLastGain, 8192) > 0)
+        {
+            *T0 = lag_hist[0];             move16();
+        } else
+        {
+            /********SORT************/
+            /* The sorting of the lag history */
+            for (i = 0; i < L_LTPHIST; i++)
+            {
+                lag_hist2[i] = lag_hist[i];move16();
+            }
+            insertion_sort(lag_hist2, 5);
+
+            /* Lag is weighted towards bigger lags */
+            /* and random variation is added */
+            lagDif = sub(lag_hist2[4], lag_hist2[2]);
+
+            test();
+            if (sub(lagDif, 40) > 0)
+                lagDif = 40;               move16();
+
+            D = Random(seed);              /* D={-1, ...,1} */
+            /* D2={-lagDif/2..lagDif/2} */
+            tmp = shr(lagDif, 1);
+            D2 = mult(tmp, D);
+            tmp = add(add(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
+            *T0 = add(mult(tmp, ONE_PER_3), D2);        move16();
+        }
+        /* New lag is not allowed to be bigger or smaller than last lag values */
+        test();
+        if (sub(*T0, maxLag) > 0)
+        {
+            *T0 = maxLag;                  move16();
+        }
+        test();
+        if (sub(*T0, minLag) < 0)
+        {
+            *T0 = minLag;                  move16();
+        }
+    } else
+    {
+        /* LTP-lag for RX_BAD_FRAME */
+
+        /***********MEAN lag**************/
+        meanLag = 0;                       move16();
+        for (i = 0; i < L_LTPHIST; i++)
+        {
+            meanLag = add(meanLag, lag_hist[i]);
+        }
+        meanLag = mult(meanLag, ONE_PER_LTPHIST);
+
+        tmp = sub(*T0, maxLag);
+        tmp2 = sub(*T0, lastLag);
+
+        test();test();test();
+        test();test();test();test();
+        test();test();test();test();
+        test();test();test();
+        test();
+        if (sub(lagDif, 10) < 0 && (sub(*T0, sub(minLag, 5)) > 0) && (sub(tmp, 5) < 0))
+        {
+            *T0 = *T0;                     move16();
+        } else if (sub(lastGain, 8192) > 0 && sub(secLastGain, 8192) > 0 && (add(tmp2, 10) > 0 && sub(tmp2, 10) < 0))
+        {
+            *T0 = *T0;                     move16();
+        } else if (sub(minGain, 6554) < 0 && sub(lastGain, minGain) == 0 && (sub(*T0, minLag) > 0 && sub(*T0, maxLag) < 0))
+        {
+            *T0 = *T0;                     move16();
+        } else if (sub(lagDif, 70) < 0 && sub(*T0, minLag) > 0 && sub(*T0, maxLag) < 0)
+        {
+            *T0 = *T0;                     move16();
+        } else if (sub(*T0, meanLag) > 0 && sub(*T0, maxLag) < 0)
+        {
+            *T0 = *T0;                     move16();
+        } else
+        {
+            test();test();
+            test();test();
+            if ((sub(minGain, 8192) > 0) & (sub(lagDif, 10) < 0))
+            {
+                *T0 = lag_hist[0];         move16();
+            } else if (sub(lastGain, 8192) > 0 && sub(secLastGain, 8192) > 0)
+            {
+                *T0 = lag_hist[0];         move16();
+            } else
+            {
+                /********SORT************/
+                /* The sorting of the lag history */
+                for (i = 0; i < L_LTPHIST; i++)
+                {
+                    lag_hist2[i] = lag_hist[i]; move16();
+                }
+                insertion_sort(lag_hist2, 5);
+
+                /* Lag is weighted towards bigger lags */
+                /* and random variation is added */
+                lagDif = sub(lag_hist2[4], lag_hist2[2]);
+                test();
+                if (sub(lagDif, 40) > 0)
+                    lagDif = 40;           move16();
+
+                D = Random(seed);          /* D={-1,.., 1} */
+                /* D2={-lagDif/2..lagDif/2} */
+                tmp = shr(lagDif, 1);
+                D2 = mult(tmp, D);
+                tmp = add(add(lag_hist2[2], lag_hist2[3]), lag_hist2[4]);
+                *T0 = add(mult(tmp, ONE_PER_3), D2);    move16();
+            }
+            /* New lag is not allowed to be bigger or smaller than last lag values */
+            test();
+            if (sub(*T0, maxLag) > 0)
+            {
+                *T0 = maxLag;              move16();
+            }
+            test();
+            if (sub(*T0, minLag) < 0)
+            {
+                *T0 = minLag;              move16();
+            }
+        }
+    }
+}
+void insertion_sort(Word16 array[], Word16 n)
+{
+    Word16 i;
+
+    for (i = 0; i < n; i++)
+    {
+        insert(array, i, array[i]);
+    }
+}
+
+
+void insert(Word16 array[], Word16 n, Word16 x)
+{
+    Word16 i;
+
+    for (i = (Word16) (n - 1); i >= 0; i--)
+    {
+        test();
+        if (sub(x, array[i]) < 0)
+        {
+            array[i + 1] = array[i];       move16();
+        } else
+            break;
+    }
+    array[i + 1] = x;                      move16();
+}
--- /dev/null
+++ b/amr-wb/levinson.c
@@ -1,0 +1,232 @@
+/*---------------------------------------------------------------------------*
+ *                         LEVINSON.C                                        *
+ *---------------------------------------------------------------------------*
+ *                                                                           *
+ *      LEVINSON-DURBIN algorithm in double precision                        *
+ *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                        *
+ *                                                                           *
+ * Algorithm                                                                 *
+ *                                                                           *
+ *       R[i]    autocorrelations.                                           *
+ *       A[i]    filter coefficients.                                        *
+ *       K       reflection coefficients.                                    *
+ *       Alpha   prediction gain.                                            *
+ *                                                                           *
+ *       Initialization:                                                     *
+ *               A[0] = 1                                                    *
+ *               K    = -R[1]/R[0]                                           *
+ *               A[1] = K                                                    *
+ *               Alpha = R[0] * (1-K**2]                                     *
+ *                                                                           *
+ *       Do for  i = 2 to M                                                  *
+ *                                                                           *
+ *            S =  SUM ( R[j]*A[i-j] ,j=1,i-1 ) +  R[i]                      *
+ *                                                                           *
+ *            K = -S / Alpha                                                 *
+ *                                                                           *
+ *            An[j] = A[j] + K*A[i-j]   for j=1 to i-1                       *
+ *                                      where   An[i] = new A[i]             *
+ *            An[i]=K                                                        *
+ *                                                                           *
+ *            Alpha=Alpha * (1-K**2)                                         *
+ *                                                                           *
+ *       END                                                                 *
+ *                                                                           *
+ * Remarks on the dynamics of the calculations.                              *
+ *                                                                           *
+ *       The numbers used are in double precision in the following format :  *
+ *       A = AH <<16 + AL<<1.  AH and AL are 16 bit signed integers.         *
+ *       Since the LSB's also contain a sign bit, this format does not       *
+ *       correspond to standard 32 bit integers.  We use this format since   *
+ *       it allows fast execution of multiplications and divisions.          *
+ *                                                                           *
+ *       "DPF" will refer to this special format in the following text.      *
+ *       See oper_32b.c                                                      *
+ *                                                                           *
+ *       The R[i] were normalized in routine AUTO (hence, R[i] < 1.0).       *
+ *       The K[i] and Alpha are theoretically < 1.0.                         *
+ *       The A[i], for a sampling frequency of 8 kHz, are in practice        *
+ *       always inferior to 16.0.                                            *
+ *                                                                           *
+ *       These characteristics allow straigthforward fixed-point             *
+ *       implementation.  We choose to represent the parameters as           *
+ *       follows :                                                           *
+ *                                                                           *
+ *               R[i]    Q31   +- .99..                                      *
+ *               K[i]    Q31   +- .99..                                      *
+ *               Alpha   Normalized -> mantissa in Q31 plus exponent         *
+ *               A[i]    Q27   +- 15.999..                                   *
+ *                                                                           *
+ *       The additions are performed in 32 bit.  For the summation used      *
+ *       to calculate the K[i], we multiply numbers in Q31 by numbers        *
+ *       in Q27, with the result of the multiplications in Q27,              *
+ *       resulting in a dynamic of +- 16.  This is sufficient to avoid       *
+ *       overflow, since the final result of the summation is                *
+ *       necessarily < 1.0 as both the K[i] and Alpha are                    *
+ *       theoretically < 1.0.                                                *
+ *___________________________________________________________________________*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "acelp.h"
+#include "count.h"
+
+#define M   16
+#define NC  (M/2)
+
+void Init_Levinson(
+     Word16 * mem                          /* output  :static memory (18 words) */
+)
+{
+    Set_zero(mem, 18);                     /* old_A[0..M-1] = 0, old_rc[0..1] = 0 */
+    return;
+}
+
+
+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) Q12 : A[M]    LPC coefficients  (m = 16)       */
+     Word16 rc[],                          /* (o) Q15 : rc[M]   Reflection coefficients.         */
+     Word16 * mem                          /* (i/o)   :static memory (18 words)                  */
+)
+{
+    Word16 i, j;
+    Word16 hi, lo;
+    Word16 Kh, Kl;                         /* reflection coefficient; hi and lo           */
+    Word16 alp_h, alp_l, alp_exp;          /* Prediction gain; hi lo and exponent         */
+    Word16 Ah[M + 1], Al[M + 1];           /* LPC coef. in double prec.                   */
+    Word16 Anh[M + 1], Anl[M + 1];         /* LPC coef.for next iteration in double prec. */
+    Word32 t0, t1, t2;                     /* temporary variable                          */
+    Word16 *old_A, *old_rc;
+
+    /* Last A(z) for case of unstable filter */
+
+    old_A = mem;                           move16();
+    old_rc = mem + M;                      move16();
+
+    /* K = A[1] = -R[1] / R[0] */
+
+    t1 = L_Comp(Rh[1], Rl[1]);             /* R[1] in Q31      */
+    t2 = L_abs(t1);                        /* abs R[1]         */
+    t0 = Div_32(t2, Rh[0], Rl[0]);         /* R[1]/R[0] in Q31 */
+    test();
+    if (t1 > 0)
+        t0 = L_negate(t0);                 /* -R[1]/R[0]       */
+    L_Extract(t0, &Kh, &Kl);               /* K in DPF         */
+    rc[0] = Kh;                            move16();
+    t0 = L_shr(t0, 4);                     /* A[1] in Q27      */
+    L_Extract(t0, &Ah[1], &Al[1]);         /* A[1] in DPF      */
+
+    /* Alpha = R[0] * (1-K**2) */
+
+    t0 = Mpy_32(Kh, Kl, Kh, Kl);           /* K*K      in Q31 */
+    t0 = L_abs(t0);                        /* Some case <0 !! */
+    t0 = L_sub((Word32) 0x7fffffffL, t0);  /* 1 - K*K  in Q31 */
+    L_Extract(t0, &hi, &lo);               /* DPF format      */
+    t0 = Mpy_32(Rh[0], Rl[0], hi, lo);     /* Alpha in Q31    */
+
+    /* Normalize Alpha */
+
+    alp_exp = norm_l(t0);
+    t0 = L_shl(t0, alp_exp);
+    L_Extract(t0, &alp_h, &alp_l);
+    /* DPF format    */
+
+    /*--------------------------------------*
+     * ITERATIONS  I=2 to M                 *
+     *--------------------------------------*/
+
+    for (i = 2; i <= M; i++)
+    {
+
+        /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) +  R[i] */
+
+        t0 = 0;                            move32();
+        for (j = 1; j < i; j++)
+            t0 = L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i - j], Al[i - j]));
+
+        t0 = L_shl(t0, 4);                 /* result in Q27 -> convert to Q31 */
+        /* No overflow possible            */
+        t1 = L_Comp(Rh[i], Rl[i]);
+        t0 = L_add(t0, t1);                /* add R[i] in Q31                 */
+
+        /* K = -t0 / Alpha */
+
+        t1 = L_abs(t0);
+        t2 = Div_32(t1, alp_h, alp_l);     /* abs(t0)/Alpha                   */
+        test();
+        if (t0 > 0)
+            t2 = L_negate(t2);             /* K =-t0/Alpha                    */
+        t2 = L_shl(t2, alp_exp);           /* denormalize; compare to Alpha   */
+        L_Extract(t2, &Kh, &Kl);           /* K in DPF                        */
+        rc[i - 1] = Kh;                    move16();
+
+        /* Test for unstable filter. If unstable keep old A(z) */
+
+        test();
+        if (sub(abs_s(Kh), 32750) > 0)
+        {
+            A[0] = 4096;                   move16();  /* Ai[0] not stored (always 1.0) */
+            for (j = 0; j < M; j++)
+            {
+                A[j + 1] = old_A[j];       move16();
+            }
+            rc[0] = old_rc[0];             /* only two rc coefficients are needed */
+            rc[1] = old_rc[1];
+            move16();move16();
+            return;
+        }
+        /*------------------------------------------*
+         *  Compute new LPC coeff. -> An[i]         *
+         *  An[j]= A[j] + K*A[i-j]     , j=1 to i-1 *
+         *  An[i]= K                                *
+         *------------------------------------------*/
+
+        for (j = 1; j < i; j++)
+        {
+            t0 = Mpy_32(Kh, Kl, Ah[i - j], Al[i - j]);
+            t0 = L_add(t0, L_Comp(Ah[j], Al[j]));
+            L_Extract(t0, &Anh[j], &Anl[j]);
+        }
+        t2 = L_shr(t2, 4);                 /* t2 = K in Q31 ->convert to Q27  */
+        L_Extract(t2, &Anh[i], &Anl[i]);   /* An[i] in Q27                    */
+
+        /* Alpha = Alpha * (1-K**2) */
+
+        t0 = Mpy_32(Kh, Kl, Kh, Kl);       /* K*K      in Q31 */
+        t0 = L_abs(t0);                    /* Some case <0 !! */
+        t0 = L_sub((Word32) 0x7fffffffL, t0);   /* 1 - K*K  in Q31 */
+        L_Extract(t0, &hi, &lo);           /* DPF format      */
+        t0 = Mpy_32(alp_h, alp_l, hi, lo); /* Alpha in Q31    */
+
+        /* Normalize Alpha */
+
+        j = norm_l(t0);
+        t0 = L_shl(t0, j);
+        L_Extract(t0, &alp_h, &alp_l);     /* DPF format    */
+        alp_exp = add(alp_exp, j);         /* Add normalization to alp_exp */
+
+        /* A[j] = An[j] */
+
+        for (j = 1; j <= i; j++)
+        {
+            Ah[j] = Anh[j];                move16();
+            Al[j] = Anl[j];                move16();
+        }
+    }
+
+    /* Truncate A[i] in Q27 to Q12 with rounding */
+
+    A[0] = 4096;                           move16();
+    for (i = 1; i <= M; i++)
+    {
+        t0 = L_Comp(Ah[i], Al[i]);
+        old_A[i - 1] = A[i] = round(L_shl(t0, 1));      move16();move16();
+    }
+    old_rc[0] = rc[0];                     move16();
+    old_rc[1] = rc[1];                     move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/log2.c
@@ -1,0 +1,115 @@
+/********************************************************************************
+*
+*      File             : log2.c
+*      Purpose          : Computes log2(L_x)
+*
+********************************************************************************
+*/
+/*
+********************************************************************************
+*                         MODULE INCLUDE FILE AND VERSION ID
+********************************************************************************
+*/
+#include "log2.h"
+const char log2_id[] = "@(#)$Id $" log2_h;
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+ 
+/*
+********************************************************************************
+*                         LOCAL VARIABLES AND TABLES
+********************************************************************************
+*/
+#include "log2_tab.h"     /* Table for Log2() */
+ 
+/*
+********************************************************************************
+*                         PUBLIC PROGRAM CODE
+********************************************************************************
+*/
+
+/*************************************************************************
+ *
+ *   FUNCTION:   Log2_norm()
+ *
+ *   PURPOSE:   Computes log2(L_x, exp),  where   L_x is positive and
+ *              normalized, and exp is the normalisation exponent
+ *              If L_x is negative or zero, the result is 0.
+ *
+ *   DESCRIPTION:
+ *        The function Log2(L_x) is approximated by a table and linear
+ *        interpolation. The following steps are used to compute Log2(L_x)
+ *
+ *           1- exponent = 30-norm_exponent
+ *           2- i = bit25-b31 of L_x;  32<=i<=63  (because of normalization).
+ *           3- a = bit10-b24
+ *           4- i -=32
+ *           5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+ *
+ *************************************************************************/
+void Log2_norm (
+    Word32 L_x,         /* (i) : input value (normalized)                    */
+    Word16 exp,         /* (i) : norm_l (L_x)                                */
+    Word16 *exponent,   /* (o) : Integer part of Log2.   (range: 0<=val<=30) */
+    Word16 *fraction    /* (o) : Fractional part of Log2. (range: 0<=val<1)  */
+)
+{
+    Word16 i, a, tmp;
+    Word32 L_y;
+
+    test (); 
+    if (L_x <= (Word32) 0)
+    {
+        *exponent = 0;          move16 (); 
+        *fraction = 0;          move16 (); 
+        return;
+    }
+
+    *exponent = sub (30, exp);  move16 (); 
+
+    L_x = L_shr (L_x, 9);
+    i = extract_h (L_x);                /* Extract b25-b31 */
+    L_x = L_shr (L_x, 1);
+    a = extract_l (L_x);                /* Extract b10-b24 of fraction */
+    a = (Word16)(a & (Word16)0x7fff);    logic16 (); 
+
+    i = sub (i, 32);
+
+    L_y = L_deposit_h (table[i]);       /* table[i] << 16        */
+    tmp = sub (table[i], table[i + 1]); /* table[i] - table[i+1] */
+    L_y = L_msu (L_y, tmp, a);          /* L_y -= tmp*a*2        */
+
+    *fraction = extract_h (L_y);move16 (); 
+
+    return;
+}
+
+/*************************************************************************
+ *
+ *   FUNCTION:   Log2()
+ *
+ *   PURPOSE:   Computes log2(L_x),  where   L_x is positive.
+ *              If L_x is negative or zero, the result is 0.
+ *
+ *   DESCRIPTION:
+ *        normalizes L_x and then calls Log2_norm().
+ *
+ *************************************************************************/
+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) */
+)
+{
+    Word16 exp;
+
+    exp = norm_l (L_x);
+    Log2_norm (L_shl (L_x, exp), exp, exponent, fraction);
+}
--- /dev/null
+++ b/amr-wb/log2.h
@@ -1,0 +1,42 @@
+/********************************************************************************
+*
+*      File             : log2.h
+*      Purpose          : Computes log2(L_x)
+*
+********************************************************************************
+*/
+#ifndef log2_h
+#define log2_h "$Id $"
+ 
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include "typedef.h"
+ 
+/*
+********************************************************************************
+*                         DEFINITION OF DATA TYPES
+********************************************************************************
+*/
+ 
+/*
+********************************************************************************
+*                         DECLARATION OF PROTOTYPES
+********************************************************************************
+*/
+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)*/
+);
+
+void Log2_norm (
+    Word32 L_x,         /* (i) : input value (normalized)                    */
+    Word16 exp,         /* (i) : norm_l (L_x)                                */
+    Word16 *exponent,   /* (o) : Integer part of Log2.   (range: 0<=val<=30) */
+    Word16 *fraction    /* (o) : Fractional part of Log2. (range: 0<=val<1)  */
+);
+
+#endif
--- /dev/null
+++ b/amr-wb/log2_tab.h
@@ -1,0 +1,16 @@
+
+/*******************************************************************************
+*
+*      File             : log2.tab
+*      Purpose          : Table for routine Log2().
+*      $Id $
+*
+********************************************************************************
+*/
+static const Word16 table[33] =
+{
+    0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716,
+    12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033,
+    22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497,
+    31266, 32023, 32767
+};
--- /dev/null
+++ b/amr-wb/lp_dec2.c
@@ -1,0 +1,58 @@
+/*-------------------------------------------------------------------*
+ *                         LP_DEC2.C                                 *
+ *-------------------------------------------------------------------*
+ * Decimate a vector by 2 with 2nd order fir filter.                 *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "cnst.h"
+
+#define L_FIR  5
+#define L_MEM  (L_FIR-2)
+
+/* static float h_fir[L_FIR] = {0.13, 0.23, 0.28, 0.23, 0.13}; */
+/* fixed-point: sum of coef = 32767 to avoid overflow on DC */
+static Word16 h_fir[L_FIR] = {4260, 7536, 9175, 7536, 4260};
+
+
+void LP_Decim2(
+     Word16 x[],                           /* in/out: signal to process         */
+     Word16 l,                             /* input : size of filtering         */
+     Word16 mem[]                          /* in/out: memory (size=3)           */
+)
+{
+    Word16 *p_x, x_buf[L_FRAME + L_MEM];
+    Word16 i, j, k;
+    Word32 L_tmp;
+
+    /* copy initial filter states into buffer */
+
+    p_x = x_buf;                           move16();
+    for (i = 0; i < L_MEM; i++)
+    {
+        *p_x++ = mem[i];                   move16();
+    }
+    for (i = 0; i < l; i++)
+    {
+        *p_x++ = x[i];                     move16();
+    }
+    for (i = 0; i < L_MEM; i++)
+    {
+        mem[i] = x[l - L_MEM + i];         move16();
+    }
+
+    for (i = 0, j = 0; i < l; i += 2, j++)
+    {
+        p_x = &x_buf[i];                   move16();
+
+        L_tmp = 0L;                        move32();
+        for (k = 0; k < L_FIR; k++)
+            L_tmp = L_mac(L_tmp, *p_x++, h_fir[k]);
+
+        x[j] = round(L_tmp);               move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/main.h
@@ -1,0 +1,39 @@
+/*--------------------------------------------------------------------------*
+ *                         MAIN.H                                           *
+ *--------------------------------------------------------------------------*
+ *       Main functions                                                     *
+ *--------------------------------------------------------------------------*/
+
+void Init_coder(void **spe_state);
+void Close_coder(void *spe_state);
+
+void coder(
+     Word16 * mode,                        /* input :  used mode                             */
+     Word16 speech16k[],                   /* input :  320 new speech samples (at 16 kHz)    */
+     Word16 prms[],                        /* output:  output parameters           */
+     Word16 * ser_size,                    /* output:  bit rate of the used mode   */
+     void *spe_state,                      /* i/o   :  State structure                       */
+     Word16 allow_dtx                      /* input :  DTX ON/OFF                            */
+);
+
+void Init_decoder(void **spd_state);
+void Close_decoder(void *spd_state);
+
+void decoder(
+     Word16 mode,                          /* input : used mode                     */
+     Word16 prms[],                        /* input : parameter vector                     */
+     Word16 synth16k[],                    /* output: synthesis speech              */
+     Word16 * frame_length,                /* output:  lenght of the frame         */
+     void *spd_state,                      /* i/o   : State structure                      */
+     Word16 frame_type                     /* input : received frame type           */
+);
+
+void Reset_encoder(void *st, Word16 reset_all);
+
+void Reset_decoder(void *st, Word16 reset_all);
+
+Word16 encoder_homing_frame_test(Word16 input_frame[]);
+
+Word16 decoder_homing_frame_test(Word16 input_frame[], Word16 mode);
+
+Word16 decoder_homing_frame_test_first(Word16 input_frame[], Word16 mode);
--- /dev/null
+++ b/amr-wb/math_op.c
@@ -1,0 +1,212 @@
+/*___________________________________________________________________________
+ |                                                                           |
+ |  This file contains mathematic operations in fixed point.                 |
+ |                                                                           |
+ |  Isqrt()              : inverse square root (16 bits precision).          |
+ |  Pow2()               : 2^x  (16 bits precision).                         |
+ |  Log2()               : log2 (16 bits precision).                         |
+ |  Dot_product()        : scalar product of <x[],y[]>                       |
+ |                                                                           |
+ |  These operations are not standard double precision operations.           |
+ |  They are used where low complexity is important and the full 32 bits     |
+ |  precision is not necessary. For example, the function Div_32() has a     |
+ |  24 bits precision which is enough for our purposes.                      |
+ |                                                                           |
+ |  In this file, the values use theses representations:                     |
+ |                                                                           |
+ |  Word32 L_32     : standard signed 32 bits format                         |
+ |  Word16 hi, lo   : L_32 = hi<<16 + lo<<1  (DPF - Double Precision Format) |
+ |  Word32 frac, Word16 exp : L_32 = frac << exp-31  (normalised format)     |
+ |  Word16 int, frac        : L_32 = int.frac        (fractional format)     |
+ |___________________________________________________________________________|
+*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : Isqrt                                                   |
+ |                                                                           |
+ |       Compute 1/sqrt(L_x).                                                |
+ |       if L_x is negative or zero, result is 1 (7fffffff).                 |
+ |---------------------------------------------------------------------------|
+ |  Algorithm:                                                               |
+ |                                                                           |
+ |   1- Normalization of L_x.                                                |
+ |   2- call Isqrt_n(L_x, exponant)                                          |
+ |   3- L_y = L_x << exponant                                                |
+ |___________________________________________________________________________|
+*/
+Word32 Isqrt(                              /* (o) Q31 : output value (range: 0<=val<1)         */
+     Word32 L_x                            /* (i) Q0  : input value  (range: 0<=val<=7fffffff) */
+)
+{
+    Word16 exp;
+    Word32 L_y;
+
+    exp = norm_l(L_x);
+    L_x = L_shl(L_x, exp);                 /* L_x is normalized */
+    exp = sub(31, exp);
+
+    Isqrt_n(&L_x, &exp);
+
+    L_y = L_shl(L_x, exp);                 /* denormalization   */
+
+    return (L_y);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : Isqrt_n                                                 |
+ |                                                                           |
+ |       Compute 1/sqrt(value).                                              |
+ |       if value is negative or zero, result is 1 (frac=7fffffff, exp=0).   |
+ |---------------------------------------------------------------------------|
+ |  Algorithm:                                                               |
+ |                                                                           |
+ |   The function 1/sqrt(value) is approximated by a table and linear        |
+ |   interpolation.                                                          |
+ |                                                                           |
+ |   1- If exponant is odd then shift fraction right once.                   |
+ |   2- exponant = -((exponant-1)>>1)                                        |
+ |   3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. |
+ |   4- a = bit10-b24                                                        |
+ |   5- i -=16                                                               |
+ |   6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2            |
+ |___________________________________________________________________________|
+*/
+static Word16 table_isqrt[49] =
+{
+    32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
+    25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155,
+    21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539,
+    19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674,
+    17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384
+};
+
+void Isqrt_n(
+     Word32 * frac,                        /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */
+     Word16 * exp                          /* (i/o)    : exponent (value = frac x 2^exponent) */
+)
+{
+    Word16 i, a, tmp;
+
+    test();
+    if (*frac <= (Word32) 0)
+    {
+        *exp = 0;                          move16();
+        *frac = 0x7fffffffL;               move32();
+        return;
+    }
+    test();logic16();
+    if (sub((Word16) (*exp & 1), 1) == 0)  /* If exponant odd -> shift right */
+        *frac = L_shr(*frac, 1);
+
+    *exp = negate(shr(sub(*exp, 1), 1));   move16();
+
+    *frac = L_shr(*frac, 9);               move32();
+    i = extract_h(*frac);                  /* Extract b25-b31 */
+    *frac = L_shr(*frac, 1);               move32();
+    a = extract_l(*frac);                  /* Extract b10-b24 */
+    a = (Word16) (a & (Word16) 0x7fff);    logic16();
+
+    i = sub(i, 16);
+    move32();
+    *frac = L_deposit_h(table_isqrt[i]);   /* table[i] << 16         */
+    tmp = sub(table_isqrt[i], table_isqrt[i + 1]);      /* table[i] - table[i+1]) */
+    move32();
+    *frac = L_msu(*frac, tmp, a);          /* frac -=  tmp*a*2       */
+
+    return;
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : Pow2()                                                  |
+ |                                                                           |
+ |     L_x = pow(2.0, exponant.fraction)         (exponant = interger part)  |
+ |         = pow(2.0, 0.fraction) << exponant                                |
+ |---------------------------------------------------------------------------|
+ |  Algorithm:                                                               |
+ |                                                                           |
+ |   The function Pow2(L_x) is approximated by a table and linear            |
+ |   interpolation.                                                          |
+ |                                                                           |
+ |   1- i = bit10-b15 of fraction,   0 <= i <= 31                            |
+ |   2- a = bit0-b9   of fraction                                            |
+ |   3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2                 |
+ |   4- L_x = L_x >> (30-exponant)     (with rounding)                       |
+ |___________________________________________________________________________|
+*/
+static Word16 table_pow2[33] =
+{
+    16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
+    20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
+    25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
+    31379, 32066, 32767
+};
+
+Word32 Pow2(                               /* (o) Q0  : result       (range: 0<=val<=0x7fffffff) */
+     Word16 exponant,                      /* (i) Q0  : Integer part.      (range: 0<=val<=30)   */
+     Word16 fraction                       /* (i) Q15 : Fractionnal part.  (range: 0.0<=val<1.0) */
+)
+{
+    Word16 exp, i, a, tmp;
+    Word32 L_x;
+
+    L_x = L_mult(fraction, 32);            /* L_x = fraction<<6           */
+    i = extract_h(L_x);                    /* Extract b10-b16 of fraction */
+    L_x = L_shr(L_x, 1);
+    a = extract_l(L_x);                    /* Extract b0-b9   of fraction */
+    a = (Word16) (a & (Word16) 0x7fff);    logic16();
+
+    L_x = L_deposit_h(table_pow2[i]);      /* table[i] << 16        */
+    tmp = sub(table_pow2[i], table_pow2[i + 1]);        /* table[i] - table[i+1] */
+    L_x = L_msu(L_x, tmp, a);              /* L_x -= tmp*a*2        */
+
+    exp = sub(30, exponant);
+    L_x = L_shr_r(L_x, exp);
+
+    return (L_x);
+}
+
+/*___________________________________________________________________________
+ |                                                                           |
+ |   Function Name : Dot_product12()                                         |
+ |                                                                           |
+ |       Compute scalar product of <x[],y[]> using accumulator.              |
+ |                                                                           |
+ |       The result is normalized (in Q31) with exponent (0..30).            |
+ |---------------------------------------------------------------------------|
+ |  Algorithm:                                                               |
+ |                                                                           |
+ |       dot_product = sum(x[i]*y[i])     i=0..N-1                           |
+ |___________________________________________________________________________|
+*/
+
+Word32 Dot_product12(                      /* (o) Q31: normalized result (1 < val <= -1) */
+     Word16 x[],                           /* (i) 12bits: x vector                       */
+     Word16 y[],                           /* (i) 12bits: y vector                       */
+     Word16 lg,                            /* (i)    : vector length                     */
+     Word16 * exp                          /* (o)    : exponent of result (0..+30)       */
+)
+{
+    Word16 i, sft;
+    Word32 L_sum;
+
+    L_sum = 1L;                            move32();
+    for (i = 0; i < lg; i++)
+        L_sum = L_mac(L_sum, x[i], y[i]);
+
+    /* Normalize acc in Q31 */
+
+    sft = norm_l(L_sum);
+    L_sum = L_shl(L_sum, sft);
+
+    *exp = sub(30, sft);                   move16();  /* exponent = 0..30 */
+
+    return (L_sum);
+}
--- /dev/null
+++ b/amr-wb/math_op.h
@@ -1,0 +1,23 @@
+/*--------------------------------------------------------------------------*
+ *                         MATH_OP.H                                        *
+ *--------------------------------------------------------------------------*
+ *       Mathematical operations                                            *
+ *--------------------------------------------------------------------------*/
+
+Word32 Isqrt(                              /* (o) Q31 : output value (range: 0<=val<1)         */
+     Word32 L_x                            /* (i) Q0  : input value  (range: 0<=val<=7fffffff) */
+);
+void Isqrt_n(
+     Word32 * frac,                        /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */
+     Word16 * exp                          /* (i/o)    : exponent (value = frac x 2^exponent) */
+);
+Word32 Pow2(                               /* (o) Q0  : result       (range: 0<=val<=0x7fffffff) */
+     Word16 exponant,                      /* (i) Q0  : Integer part.      (range: 0<=val<=30)   */
+     Word16 fraction                       /* (i) Q15 : Fractionnal part.  (range: 0.0<=val<1.0) */
+);
+Word32 Dot_product12(                      /* (o) Q31: normalized result (1 < val <= -1) */
+     Word16 x[],                           /* (i) 12bits: x vector                       */
+     Word16 y[],                           /* (i) 12bits: y vector                       */
+     Word16 lg,                            /* (i)    : vector length                     */
+     Word16 * exp                          /* (o)    : exponent of result (0..+30)       */
+);
--- /dev/null
+++ b/amr-wb/mime_io.tab
@@ -1,0 +1,347 @@
+#include <stdio.h>
+#include "typedef.h"
+
+static UWord8 toc_byte[16] = {0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C,
+                              0x44, 0x4C, 0x54, 0x5C, 0x64, 0x6C, 0x74, 0x7C};
+
+/* number of speech bits for all modes */
+static Word16 unpacked_size[16] = {132,  177, 253, 285, 317, 365, 397, 461,
+                                   477,   35,   0,   0,   0,   0,   0,   0};
+
+/* size of packed frame for each mode, excluding TOC byte */
+static Word16 packed_size[16] = {17, 23, 32, 36, 40, 46, 50, 58,
+                                 60,  5,  0,  0,  0,  0,  0,  0};
+
+/* number of unused speech bits in packed format for each mode */
+static Word16 unused_size[16] = {4, 7, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0};
+
+/* sorting tables for all modes */
+
+static Word16 sort_660[132] = {
+     0,   5,   6,   7,  61,  84, 107, 130,  62,  85,
+     8,   4,  37,  38,  39,  40,  58,  81, 104, 127,
+    60,  83, 106, 129, 108, 131, 128,  41,  42,  80,
+   126,   1,   3,  57, 103,  82, 105,  59,   2,  63,
+   109, 110,  86,  19,  22,  23,  64,  87,  18,  20,
+    21,  17,  13,  88,  43,  89,  65, 111,  14,  24,
+    25,  26,  27,  28,  15,  16,  44,  90,  66, 112,
+     9,  11,  10,  12,  67, 113,  29,  30,  31,  32,
+    34,  33,  35,  36,  45,  51,  68,  74,  91,  97,
+   114, 120,  46,  69,  92, 115,  52,  75,  98, 121,
+    47,  70,  93, 116,  53,  76,  99, 122,  48,  71,
+    94, 117,  54,  77, 100, 123,  49,  72,  95, 118,
+    55,  78, 101, 124,  50,  73,  96, 119,  56,  79,
+   102, 125
+};
+
+static Word16 sort_885[177] = {
+     0,   4,   6,   7,   5,   3,  47,  48,  49, 112,
+   113, 114,  75, 106, 140, 171,  80, 111, 145, 176,
+    77, 108, 142, 173,  78, 109, 143, 174,  79, 110,
+   144, 175,  76, 107, 141, 172,  50, 115,  51,   2,
+     1,  81, 116, 146,  19,  21,  12,  17,  18,  20,
+    16,  25,  13,  10,  14,  24,  23,  22,  26,   8,
+    15,  52, 117,  31,  82, 147,   9,  33,  11,  83,
+   148,  53, 118,  28,  27,  84, 149,  34,  35,  29,
+    46,  32,  30,  54, 119,  37,  36,  39,  38,  40,
+    85, 150,  41,  42,  43,  44,  45,  55,  60,  65,
+    70,  86,  91,  96, 101, 120, 125, 130, 135, 151,
+   156, 161, 166,  56,  87, 121, 152,  61,  92, 126,
+   157,  66,  97, 131, 162,  71, 102, 136, 167,  57,
+    88, 122, 153,  62,  93, 127, 158,  67,  98, 132,
+   163,  72, 103, 137, 168,  58,  89, 123, 154,  63,
+    94, 128, 159,  68,  99, 133, 164,  73, 104, 138,
+   169,  59,  90, 124, 155,  64,  95, 129, 160,  69,
+   100, 134, 165,  74, 105, 139, 170
+};
+
+static Word16 sort_1265[253] = {
+     0,   4,   6,  93, 143, 196, 246,   7,   5,   3,
+    47,  48,  49,  50,  51, 150, 151, 152, 153, 154,
+    94, 144, 197, 247,  99, 149, 202, 252,  96, 146,
+   199, 249,  97, 147, 200, 250, 100, 203,  98, 148,
+   201, 251,  95, 145, 198, 248,  52,   2,   1, 101,
+   204, 155,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   156,  31, 102, 205,   9,  33,  11, 103, 206,  54,
+   157,  28,  27, 104, 207,  34,  35,  29,  46,  32,
+    30,  55, 158,  37,  36,  39,  38,  40, 105, 208,
+    41,  42,  43,  44,  45,  56, 106, 159, 209,  57,
+    66,  75,  84, 107, 116, 125, 134, 160, 169, 178,
+   187, 210, 219, 228, 237,  58, 108, 161, 211,  62,
+   112, 165, 215,  67, 117, 170, 220,  71, 121, 174,
+   224,  76, 126, 179, 229,  80, 130, 183, 233,  85,
+   135, 188, 238,  89, 139, 192, 242,  59, 109, 162,
+   212,  63, 113, 166, 216,  68, 118, 171, 221,  72,
+   122, 175, 225,  77, 127, 180, 230,  81, 131, 184,
+   234,  86, 136, 189, 239,  90, 140, 193, 243,  60,
+   110, 163, 213,  64, 114, 167, 217,  69, 119, 172,
+   222,  73, 123, 176, 226,  78, 128, 181, 231,  82,
+   132, 185, 235,  87, 137, 190, 240,  91, 141, 194,
+   244,  61, 111, 164, 214,  65, 115, 168, 218,  70,
+   120, 173, 223,  74, 124, 177, 227,  79, 129, 182,
+   232,  83, 133, 186, 236,  88, 138, 191, 241,  92,
+   142, 195, 245                         
+};
+
+static Word16 sort_1425[285] = {
+     0,   4,   6, 101, 159, 220, 278,   7,   5,   3,
+    47,  48,  49,  50,  51, 166, 167, 168, 169, 170,
+   102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
+   223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
+   225, 283, 103, 161, 222, 280,  52,   2,   1, 109,
+   228, 171,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   172,  31, 110, 229,   9,  33,  11, 111, 230,  54,
+   173,  28,  27, 112, 231,  34,  35,  29,  46,  32,
+    30,  55, 174,  37,  36,  39,  38,  40, 113, 232,
+    41,  42,  43,  44,  45,  56, 114, 175, 233,  62,
+   120, 181, 239,  75, 133, 194, 252,  57, 115, 176,
+   234,  63, 121, 182, 240,  70, 128, 189, 247,  76,
+   134, 195, 253,  83, 141, 202, 260,  92, 150, 211,
+   269,  84, 142, 203, 261,  93, 151, 212, 270,  85,
+   143, 204, 262,  94, 152, 213, 271,  86, 144, 205,
+   263,  95, 153, 214, 272,  64, 122, 183, 241,  77,
+   135, 196, 254,  65, 123, 184, 242,  78, 136, 197,
+   255,  87, 145, 206, 264,  96, 154, 215, 273,  58,
+   116, 177, 235,  66, 124, 185, 243,  71, 129, 190,
+   248,  79, 137, 198, 256,  88, 146, 207, 265,  97,
+   155, 216, 274,  59, 117, 178, 236,  67, 125, 186,
+   244,  72, 130, 191, 249,  80, 138, 199, 257,  89,
+   147, 208, 266,  98, 156, 217, 275,  60, 118, 179,
+   237,  68, 126, 187, 245,  73, 131, 192, 250,  81,
+   139, 200, 258,  90, 148, 209, 267,  99, 157, 218,
+   276,  61, 119, 180, 238,  69, 127, 188, 246,  74,
+   132, 193, 251,  82, 140, 201, 259,  91, 149, 210,
+   268, 100, 158, 219, 277
+};
+
+static Word16 sort_1585[317] = {
+     0,   4,   6, 109, 175, 244, 310,   7,   5,   3,
+    47,  48,  49,  50,  51, 182, 183, 184, 185, 186,
+   110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
+   247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
+   249, 315, 111, 177, 246, 312,  52,   2,   1, 117,
+   252, 187,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   188,  31, 118, 253,   9,  33,  11, 119, 254,  54,
+   189,  28,  27, 120, 255,  34,  35,  29,  46,  32,
+    30,  55, 190,  37,  36,  39,  38,  40, 121, 256,
+    41,  42,  43,  44,  45,  56, 122, 191, 257,  63,
+   129, 198, 264,  76, 142, 211, 277,  89, 155, 224,
+   290, 102, 168, 237, 303,  57, 123, 192, 258,  70,
+   136, 205, 271,  83, 149, 218, 284,  96, 162, 231,
+   297,  62, 128, 197, 263,  75, 141, 210, 276,  88,
+   154, 223, 289, 101, 167, 236, 302,  58, 124, 193,
+   259,  71, 137, 206, 272,  84, 150, 219, 285,  97,
+   163, 232, 298,  59, 125, 194, 260,  64, 130, 199,
+   265,  67, 133, 202, 268,  72, 138, 207, 273,  77,
+   143, 212, 278,  80, 146, 215, 281,  85, 151, 220,
+   286,  90, 156, 225, 291,  93, 159, 228, 294,  98,
+   164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
+   307,  60, 126, 195, 261,  65, 131, 200, 266,  68,
+   134, 203, 269,  73, 139, 208, 274,  78, 144, 213,
+   279,  81, 147, 216, 282,  86, 152, 221, 287,  91,
+   157, 226, 292,  94, 160, 229, 295,  99, 165, 234,
+   300, 104, 170, 239, 305, 107, 173, 242, 308,  61,
+   127, 196, 262,  66, 132, 201, 267,  69, 135, 204,
+   270,  74, 140, 209, 275,  79, 145, 214, 280,  82,
+   148, 217, 283,  87, 153, 222, 288,  92, 158, 227,
+   293,  95, 161, 230, 296, 100, 166, 235, 301, 105,
+   171, 240, 306, 108, 174, 243, 309
+};
+
+static Word16 sort_1825[365] = {
+     0,   4,   6, 121, 199, 280, 358,   7,   5,   3,
+    47,  48,  49,  50,  51, 206, 207, 208, 209, 210,
+   122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
+   283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
+   285, 363, 123, 201, 282, 360,  52,   2,   1, 129,
+   288, 211,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   212,  31, 130, 289,   9,  33,  11, 131, 290,  54,
+   213,  28,  27, 132, 291,  34,  35,  29,  46,  32,
+    30,  55, 214,  37,  36,  39,  38,  40, 133, 292,
+    41,  42,  43,  44,  45,  56, 134, 215, 293, 198,
+   299, 136, 120, 138,  60, 279,  58,  62, 357, 139,
+   140, 295, 156,  57, 219, 297,  63, 217, 137, 170,
+   300, 222,  64, 106,  61,  78, 294,  92, 142, 141,
+   135, 221, 296, 301, 343,  59, 298, 184, 329, 315,
+   220, 216, 265, 251, 218, 237, 352, 223, 157,  86,
+   171,  87, 164, 351, 111, 302,  65, 178, 115, 323,
+    72, 192, 101, 179,  93,  73, 193, 151, 337, 309,
+   143, 274,  69, 324, 165, 150,  97, 338, 110, 310,
+   330, 273,  68, 107, 175, 245, 114,  79, 113, 189,
+   246, 259, 174,  71, 185,  96, 344, 100, 322,  83,
+   334, 316, 333, 252, 161, 348, 147,  82, 269, 232,
+   260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
+   146, 177, 266, 350, 256,  85, 149, 116, 191, 160,
+   238, 258, 336, 305, 255,  88, 224,  99, 339, 230,
+   228, 227, 272, 242, 241, 319, 233, 311, 102,  74,
+   180, 275,  66, 194, 152, 325, 172, 247, 244, 261,
+   117, 158, 166, 354,  75, 144, 108, 312,  94, 186,
+   303,  80, 234,  89, 195, 112, 340, 181, 345, 317,
+   326, 276, 239, 167, 118, 313,  70, 355, 327, 253,
+   190, 176, 271, 104,  98, 153, 103,  90,  76, 267,
+   277, 248, 225, 262, 182,  84, 154, 235, 335, 168,
+   331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
+   257, 243, 229, 356, 159, 119,  67, 187, 173, 145,
+   240,  77, 304, 332, 314, 342, 109, 254,  81, 278,
+   105,  91, 346, 318, 183, 250, 197, 328,  95, 155,
+   169, 268, 226, 236, 264                 
+};
+
+static Word16 sort_1985[397] = {
+     0,   4,   6, 129, 215, 304, 390,   7,   5,   3,
+    47,  48,  49,  50,  51, 222, 223, 224, 225, 226,
+   130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
+   307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
+   309, 395, 131, 217, 306, 392,  52,   2,   1, 137,
+   312, 227,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   228,  31, 138, 313,   9,  33,  11, 139, 314,  54,
+   229,  28,  27, 140, 315,  34,  35,  29,  46,  32,
+    30,  55, 230,  37,  36,  39,  38,  40, 141, 316,
+    41,  42,  43,  44,  45,  56, 142, 231, 317,  63,
+    73,  92, 340,  82, 324, 149, 353, 159, 334, 165,
+   338, 178, 163, 254,  77, 168, 257, 153, 343,  57,
+   248, 238,  79, 252, 166,  67,  80, 201, 101, 267,
+   143, 164, 341, 255, 339, 187, 376, 318,  78, 328,
+   362, 115, 232, 242, 253, 290, 276,  62,  58, 158,
+    68,  93, 179, 319, 148, 169, 154,  72, 385, 329,
+   333, 344, 102,  83, 144, 233, 323, 124, 243, 192,
+   354, 237,  64, 247, 202, 209, 150, 116, 335, 268,
+   239, 299, 188, 196, 298,  94, 195, 258, 123, 363,
+   384, 109, 325, 371, 170, 370,  84, 110, 295, 180,
+    74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
+   355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
+   294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
+   297, 259, 125, 369, 197,  97, 194, 286, 211, 281,
+   280, 183, 372,  87, 155, 283,  59, 348, 327, 184,
+    76, 111, 330, 203, 349,  69,  98, 152, 145, 189,
+    66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
+   126, 241, 193,  88, 388, 117,  95, 387, 112, 359,
+   287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
+   373, 181, 292,  85, 378, 302, 121, 107, 364, 346,
+   356, 212, 278, 213,  65, 382, 288, 207, 113, 175,
+    99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
+   270, 264, 250, 240,  75, 350, 151,  60,  89, 321,
+   156, 274, 360, 326,  70, 282, 167, 146, 352,  81,
+    91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
+   128, 118, 303, 104, 379, 182, 114, 375, 200,  96,
+   293, 172, 214, 365, 279,  86, 289, 351, 347, 357,
+   261, 186, 176, 271,  90, 100, 147, 322, 275, 361,
+    71, 332,  61, 265, 157, 246, 236         
+};
+
+static Word16 sort_2305[461] = {
+     0,   4,   6, 145, 247, 352, 454,   7,   5,   3,
+    47,  48,  49,  50,  51, 254, 255, 256, 257, 258,
+   146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
+   355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
+   357, 459, 147, 249, 354, 456,  52,   2,   1, 153,
+   360, 259,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   260,  31, 154, 361,   9,  33,  11, 155, 362,  54,
+   261,  28,  27, 156, 363,  34,  35,  29,  46,  32,
+    30,  55, 262,  37,  36,  39,  38,  40, 157, 364,
+    41,  42,  43,  44,  45,  56, 158, 263, 365, 181,
+   192, 170,  79,  57, 399,  90, 159, 297, 377, 366,
+   275,  68, 183, 388, 286, 194, 299, 92 ,  70, 182,
+   401, 172,  59,  91,  58, 400, 368, 161,  81, 160,
+   264, 171,  80, 389, 390, 378, 379, 193, 298,  69,
+   266, 265, 367, 277, 288, 276, 287, 184,  60, 195,
+    82,  93,  71, 369, 402, 173, 162, 444, 300, 391,
+    98,  76, 278,  61, 267, 374, 135, 411, 167, 102,
+   380, 200,  87, 178,  65,  94, 204, 124,  72, 342,
+   189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
+   113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
+   370, 422, 174,  64, 392,  83, 425, 219, 134, 188,
+   432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
+   236, 229,  97, 294, 385, 230, 166, 268, 177, 443,
+   225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
+   414,  95, 140, 240, 410, 395, 209, 129, 283, 346,
+   105, 241, 437,  86, 308, 448, 203, 345, 186, 107,
+   220, 415, 334, 319, 106, 313, 118, 123,  73, 207,
+   421, 214, 384, 373, 438,  62, 371, 341,  75, 449,
+   168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
+   271,  63, 191, 325,  96, 169, 231, 280, 312, 187,
+   406,  84, 201, 100,  67, 382, 175, 336, 202, 330,
+   269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
+   302, 372, 398, 190, 180,  89,  99, 103, 232,  78,
+    88,  77, 136, 387, 165, 198, 394, 125, 176, 428,
+    74, 375, 238, 227,  66, 273, 282, 141, 306, 412,
+   114,  85, 130, 348, 119, 291, 296, 386, 233, 397,
+   303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
+   274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
+   310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
+   418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
+   417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
+   121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
+   126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
+   322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
+   213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
+   318
+};
+
+static Word16 sort_2385[477] = {
+     0,   4,   6, 145, 251, 360, 466,   7,   5,   3,
+    47,  48,  49,  50,  51, 262, 263, 264, 265, 266,
+   146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
+   363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
+   365, 471, 147, 253, 362, 468,  52,   2,   1, 157,
+   372, 267,  19,  21,  12,  17,  18,  20,  16,  25,
+    13,  10,  14,  24,  23,  22,  26,   8,  15,  53,
+   268,  31, 152, 153, 154, 155, 258, 259, 260, 261,
+   367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
+     9,  33,  11, 159, 374,  54, 269,  28,  27, 160,
+   375,  34,  35,  29,  46,  32,  30,  55, 270, 37,
+    36,  39,  38,  40, 161, 376,  41,  42,  43,  44,
+    45,  56, 162, 271, 377, 185, 196, 174,  79,  57,
+   411,  90, 163, 305, 389, 378, 283,  68, 187, 400,
+   294, 198, 307,  92,  70, 186, 413, 176,  59,  91,
+    58, 412, 380, 165,  81, 164, 272, 175,  80, 401,
+   402, 390, 391, 197, 306,  69, 274, 273, 379, 285,
+   296, 284, 295, 188,  60, 199,  82,  93,  71, 381,
+   414, 177, 166, 456, 308, 403,  98,  76, 286,  61,
+   275, 386, 135, 423, 171, 102, 392, 204,  87, 182,
+    65,  94, 208, 124,  72, 350, 193, 313, 393, 408,
+   445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
+   317, 415, 116, 328, 200, 339, 382, 434, 178,  64,
+   404,  83, 437, 223, 134, 192, 444, 112, 439, 139,
+   287, 167, 448, 212, 459, 222, 240, 233,  97, 302,
+   397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
+   138, 127, 298, 117, 355, 203, 426,  95, 140, 244,
+   422, 407, 213, 129, 291, 354, 105, 245, 449,  86,
+   316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
+   106, 321, 118, 123,  73, 211, 433, 218, 396, 385,
+   450,  62, 383, 349,  75, 461, 172, 331, 168, 246,
+   428, 332, 312, 201, 343, 416, 279,  63, 195, 333,
+    96, 173, 235, 288, 320, 191, 418,  84, 205, 100,
+    67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
+   301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
+   184,  89,  99, 103, 236,  78,  88,  77, 136, 399,
+   169, 202, 406, 125, 180, 440,  74, 387, 242, 231,
+    66, 281, 290, 141, 314, 424, 114,  85, 130, 356,
+   119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
+   435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
+   345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
+   289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
+   334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
+   452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
+   132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
+   352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
+   465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
+   239, 250, 133, 144, 432, 337, 326         
+};
+
+static Word16 sort_SID[35] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+   10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+   20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+   30, 31, 32, 33, 34
+};
+
+/* pointer table for bit sorting tables */
+static Word16 *sort_ptr[16] = { sort_660, sort_885, sort_1265, sort_1425, sort_1585, sort_1825, sort_1985, sort_2305,
+                               sort_2385, sort_SID,      NULL,      NULL,      NULL,      NULL,      NULL,      NULL};
--- /dev/null
+++ b/amr-wb/oper_32b.c
@@ -1,0 +1,210 @@
+/*****************************************************************************
+ *  $Id: oper_32b.c,v 1.1 2007/02/15 23:22:35 robs Exp $
+ *
+ *  This file contains operations in double precision.                       *
+ *  These operations are not standard double precision operations.           *
+ *  They are used where single precision is not enough but the full 32 bits  *
+ *  precision is not necessary. For example, the function Div_32() has a     *
+ *  24 bits precision which is enough for our purposes.                      *
+ *                                                                           *
+ *  The double precision numbers use a special representation:               *
+ *                                                                           *
+ *     L_32 = hi<<16 + lo<<1                                                 *
+ *                                                                           *
+ *  L_32 is a 32 bit integer.                                                *
+ *  hi and lo are 16 bit signed integers.                                    *
+ *  As the low part also contains the sign, this allows fast multiplication. *
+ *                                                                           *
+ *      0x8000 0000 <= L_32 <= 0x7fff fffe.                                  *
+ *                                                                           *
+ *  We will use DPF (Double Precision Format )in this file to specify        *
+ *  this special format.                                                     *
+ *****************************************************************************
+*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "count.h"
+
+/*****************************************************************************
+ *                                                                           *
+ *  Function L_Extract()                                                     *
+ *                                                                           *
+ *  Extract from a 32 bit integer two 16 bit DPF.                            *
+ *                                                                           *
+ *  Arguments:                                                               *
+ *                                                                           *
+ *   L_32      : 32 bit integer.                                             *
+ *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *
+ *   hi        : b16 to b31 of L_32                                          *
+ *   lo        : (L_32 - hi<<16)>>1                                          *
+ *****************************************************************************
+*/
+
+void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
+{
+    *hi = extract_h (L_32);
+    *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));
+    return;
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *  Function L_Comp()                                                        *
+ *                                                                           *
+ *  Compose from two 16 bit DPF a 32 bit integer.                            *
+ *                                                                           *
+ *     L_32 = hi<<16 + lo<<1                                                 *
+ *                                                                           *
+ *  Arguments:                                                               *
+ *                                                                           *
+ *   hi        msb                                                           *
+ *   lo        lsf (with sign)                                               *
+ *                                                                           *
+ *   Return Value :                                                          *
+ *                                                                           *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x8000 0000 <= L_32 <= 0x7fff fff0.                   *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 L_Comp (Word16 hi, Word16 lo)
+{
+    Word32 L_32;
+
+    L_32 = L_deposit_h (hi);
+    return (L_mac (L_32, lo, 1));       /* = hi<<16 + lo<<1 */
+}
+
+/*****************************************************************************
+ * Function Mpy_32()                                                         *
+ *                                                                           *
+ *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *
+ *                                                                           *
+ *   L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1              *
+ *                                                                           *
+ *   This operation can also be viewed as the multiplication of two Q31      *
+ *   number and the result is also in Q31.                                   *
+ *                                                                           *
+ * Arguments:                                                                *
+ *                                                                           *
+ *  hi1         hi part of first number                                      *
+ *  lo1         lo part of first number                                      *
+ *  hi2         hi part of second number                                     *
+ *  lo2         lo part of second number                                     *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
+{
+    Word32 L_32;
+
+    L_32 = L_mult (hi1, hi2);
+    L_32 = L_mac (L_32, mult (hi1, lo2), 1);
+    L_32 = L_mac (L_32, mult (lo1, hi2), 1);
+
+    return (L_32);
+}
+
+/*****************************************************************************
+ * Function Mpy_32_16()                                                      *
+ *                                                                           *
+ *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *
+ *   by 2**15                                                                *
+ *                                                                           *
+ *                                                                           *
+ *   L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                                *
+ *                                                                           *
+ * Arguments:                                                                *
+ *                                                                           *
+ *  hi          hi part of 32 bit number.                                    *
+ *  lo          lo part of 32 bit number.                                    *
+ *  n           16 bit number.                                               *
+ *                                                                           *
+ *****************************************************************************
+*/
+
+Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
+{
+    Word32 L_32;
+
+    L_32 = L_mult (hi, n);
+    L_32 = L_mac (L_32, mult (lo, n), 1);
+
+    return (L_32);
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *   Function Name : Div_32                                                  *
+ *                                                                           *
+ *   Purpose :                                                               *
+ *             Fractional integer division of two 32 bit numbers.            *
+ *             L_num / L_denom.                                              *
+ *             L_num and L_denom must be positive and L_num < L_denom.       *
+ *             L_denom = denom_hi<<16 + denom_lo<<1                          *
+ *             denom_hi is a normalize number.                               *
+ *                                                                           *
+ *   Inputs :                                                                *
+ *                                                                           *
+ *    L_num                                                                  *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x0000 0000 < L_num < L_denom                         *
+ *                                                                           *
+ *    L_denom = denom_hi<<16 + denom_lo<<1      (DPF)                        *
+ *                                                                           *
+ *       denom_hi                                                            *
+ *             16 bit positive normalized integer whose value falls in the   *
+ *             range : 0x4000 < hi < 0x7fff                                  *
+ *       denom_lo                                                            *
+ *             16 bit positive integer whose value falls in the              *
+ *             range : 0 < lo < 0x7fff                                       *
+ *                                                                           *
+ *   Return Value :                                                          *
+ *                                                                           *
+ *    L_div                                                                  *
+ *             32 bit long signed integer (Word32) whose value falls in the  *
+ *             range : 0x0000 0000 <= L_div <= 0x7fff ffff.                  *
+ *                                                                           *
+ *  Algorithm:                                                               *
+ *                                                                           *
+ *  - find = 1/L_denom.                                                      *
+ *      First approximation: approx = 1 / denom_hi                           *
+ *      1/L_denom = approx * (2.0 - L_denom * approx )                       *
+ *                                                                           *
+ *  -  result = L_num * (1/L_denom)                                          *
+ *****************************************************************************
+*/
+
+Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
+{
+    Word16 approx, hi, lo, n_hi, n_lo;
+    Word32 L_32;
+
+    /* First approximation: 1 / L_denom = 1/denom_hi */
+
+    approx = div_s ((Word16) 0x3fff, denom_hi);
+
+    /* 1/L_denom = approx * (2.0 - L_denom * approx) */
+
+    L_32 = Mpy_32_16 (denom_hi, denom_lo, approx);
+
+    L_32 = L_sub ((Word32) 0x7fffffffL, L_32);
+
+    L_Extract (L_32, &hi, &lo);
+
+    L_32 = Mpy_32_16 (hi, lo, approx);
+
+    /* L_num * (1/L_denom) */
+
+    L_Extract (L_32, &hi, &lo);
+    L_Extract (L_num, &n_hi, &n_lo);
+    L_32 = Mpy_32 (n_hi, n_lo, hi, lo);
+    L_32 = L_shl (L_32, 2);
+
+    return (L_32);
+}
+
--- /dev/null
+++ b/amr-wb/oper_32b.h
@@ -1,0 +1,9 @@
+/* Double precision operations */
+/* $Id: oper_32b.h,v 1.1 2007/02/15 23:22:35 robs Exp $ */
+
+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);
+
--- /dev/null
+++ b/amr-wb/p_med_o.h
@@ -1,0 +1,28 @@
+/*--------------------------------------------------------------------------*
+ *                         P_MED_O.H                                        *
+ *--------------------------------------------------------------------------*
+ *       Median open-loop lag search                                        *
+ *--------------------------------------------------------------------------*/
+
+Word16 Pitch_med_ol(                       /* output: open loop pitch lag                        */
+     Word16 wsp[],                         /* input : signal used to compute the open loop pitch */
+                                           /* wsp[-pit_max] to wsp[-1] should be known   */
+     Word16 L_min,                         /* input : minimum pitch lag                          */
+     Word16 L_max,                         /* input : maximum pitch lag                          */
+     Word16 L_frame,                       /* input : length of frame to compute pitch           */
+     Word16 L_0,                           /* input : old_ open-loop pitch                       */
+     Word16 * gain,                        /* output: normalize correlation of hp_wsp for the Lag */
+     Word16 * hp_wsp_mem,                  /* i:o   : memory of the hypass filter for hp_wsp[] (lg=9)   */
+     Word16 * old_hp_wsp,                  /* i:o   : hypass wsp[]                               */
+     Word16 wght_flg                       /* input : is weighting function used                 */
+);
+Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
+     Word16 prev_ol_lag,                   /* input  : previous open-loop lag                     */
+     Word16 old_ol_lag[5]
+);
+void Hp_wsp(
+     Word16 wsp[],                         /* i   : wsp[]  signal       */
+     Word16 hp_wsp[],                      /* o   : hypass wsp[]        */
+     Word16 lg,                            /* i   : lenght of signal    */
+     Word16 mem[]                          /* i/o : filter memory [9]   */
+);
--- /dev/null
+++ b/amr-wb/p_med_ol.c
@@ -1,0 +1,243 @@
+/*------------------------------------------------------------------------*
+ *                         P_MED_OL.C                                     *
+ *------------------------------------------------------------------------*
+ * Compute the open loop pitch lag.                                       *
+ *------------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "oper_32b.h"
+#include "count.h"
+#include "math_op.h"
+
+#include "p_med_ol.tab"
+
+
+Word16 Pitch_med_ol(                       /* output: open loop pitch lag                             */
+     Word16 wsp[],                         /* input : signal used to compute the open loop pitch      */
+                                           /*         wsp[-pit_max] to wsp[-1] should be known        */
+     Word16 L_min,                         /* input : minimum pitch lag                               */
+     Word16 L_max,                         /* input : maximum pitch lag                               */
+     Word16 L_frame,                       /* input : length of frame to compute pitch                */
+     Word16 L_0,                           /* input : old_ open-loop pitch                            */
+     Word16 * gain,                        /* output: normalize correlation of hp_wsp for the Lag     */
+     Word16 * hp_wsp_mem,                  /* i:o   : memory of the hypass filter for hp_wsp[] (lg=9) */
+     Word16 * old_hp_wsp,                  /* i:o   : hypass wsp[]                                    */
+     Word16 wght_flg                       /* input : is weighting function used                      */
+)
+{
+    Word16 i, j, Tm;
+    Word16 hi, lo;
+    Word16 *ww, *we, *hp_wsp;
+    Word16 exp_R0, exp_R1, exp_R2;
+    Word32 max, R0, R1, R2;
+
+    ww = &corrweight[198];
+    move16();
+    we = &corrweight[98 + L_max - L_0];
+    move16();
+
+    max = MIN_32;                          move32();
+    Tm = 0;                                move16();
+    for (i = L_max; i > L_min; i--)
+    {
+        /* Compute the correlation */
+
+        R0 = 0;                            move32();
+        for (j = 0; j < L_frame; j++)
+            R0 = L_mac(R0, wsp[j], wsp[j - i]);
+
+        /* Weighting of the correlation function.   */
+
+        L_Extract(R0, &hi, &lo);
+        R0 = Mpy_32_16(hi, lo, *ww);
+        ww--;
+
+        test();
+        test();
+        if ((L_0 > 0) && (wght_flg > 0))
+        {
+            /* Weight the neighbourhood of the old lag. */
+            L_Extract(R0, &hi, &lo);
+            R0 = Mpy_32_16(hi, lo, *we);
+            we--;
+            move16();
+        }
+        test();
+        if (L_sub(R0, max) >= 0)
+        {
+            max = R0;
+            move32();
+            Tm = i;
+            move16();
+        }
+    }
+
+    /* Hypass the wsp[] vector */
+
+    hp_wsp = old_hp_wsp + L_max;           move16();
+    Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
+
+    /* Compute normalize correlation at delay Tm */
+
+    R0 = 0;                                move32();
+    R1 = 1L;                               move32();
+    R2 = 1L;                               move32();
+    for (j = 0; j < L_frame; j++)
+    {
+        R0 = L_mac(R0, hp_wsp[j], hp_wsp[j - Tm]);
+        R1 = L_mac(R1, hp_wsp[j - Tm], hp_wsp[j - Tm]);
+        R2 = L_mac(R2, hp_wsp[j], hp_wsp[j]);
+    }
+
+    /* gain = R0/ sqrt(R1*R2) */
+
+    exp_R0 = norm_l(R0);
+    R0 = L_shl(R0, exp_R0);
+
+    exp_R1 = norm_l(R1);
+    R1 = L_shl(R1, exp_R1);
+
+    exp_R2 = norm_l(R2);
+    R2 = L_shl(R2, exp_R2);
+
+
+    R1 = L_mult(round(R1), round(R2));
+
+    i = norm_l(R1);
+    R1 = L_shl(R1, i);
+
+    exp_R1 = add(exp_R1, exp_R2);
+    exp_R1 = add(exp_R1, i);
+    exp_R1 = sub(62, exp_R1);
+
+    Isqrt_n(&R1, &exp_R1);
+
+    R0 = L_mult(round(R0), round(R1));
+    exp_R0 = sub(31, exp_R0);
+    exp_R0 = add(exp_R0, exp_R1);
+
+    *gain = round(L_shl(R0, exp_R0));
+    move16();
+
+    /* Shitf hp_wsp[] for next frame */
+
+    for (i = 0; i < L_max; i++)
+    {
+        old_hp_wsp[i] = old_hp_wsp[i + L_frame];
+        move16();
+    }
+
+    return (Tm);
+}
+
+/*____________________________________________________________________
+ |
+ |
+ |  FUNCTION NAME median5
+ |
+ |      Returns the median of the set {X[-2], X[-1],..., X[2]},
+ |      whose elements are 16-bit integers.
+ |
+ |  INPUT
+ |      X[-2:2]   16-bit integers.
+ |
+ |  RETURN VALUE
+ |      The median of {X[-2], X[-1],..., X[2]}.
+ |_____________________________________________________________________
+ */
+
+Word16 median5(Word16 x[])
+{
+    Word16 x1, x2, x3, x4, x5;
+    Word16 tmp;
+
+    x1 = x[-2];                            move16();
+    x2 = x[-1];                            move16();
+    x3 = x[0];                             move16();
+    x4 = x[1];                             move16();
+    x5 = x[2];                             move16();
+
+    test();test();test();test();test();test();test();test();test();
+
+    if (sub(x2, x1) < 0)
+    {
+        tmp = x1;
+        x1 = x2;
+        x2 = tmp;                          move16();move16();move16();
+    }
+    if (sub(x3, x1) < 0)
+    {
+        tmp = x1;
+        x1 = x3;
+        x3 = tmp;                          move16();move16();move16();
+    }
+    if (sub(x4, x1) < 0)
+    {
+        tmp = x1;
+        x1 = x4;
+        x4 = tmp;                          move16();move16();move16();
+    }
+    if (sub(x5, x1) < 0)
+    {
+        x5 = x1;                           move16();
+    }
+    if (sub(x3, x2) < 0)
+    {
+        tmp = x2;
+        x2 = x3;
+        x3 = tmp;                          move16();move16();move16();
+    }
+    if (sub(x4, x2) < 0)
+    {
+        tmp = x2;
+        x2 = x4;
+        x4 = tmp;                          move16();move16();move16();
+    }
+    if (sub(x5, x2) < 0)
+    {
+        x5 = x2;                           move16();
+    }
+    if (sub(x4, x3) < 0)
+    {
+        x3 = x4;                           move16();
+    }
+    if (sub(x5, x3) < 0)
+    {
+        x3 = x5;                           move16();
+    }
+    return (x3);
+}
+
+/*____________________________________________________________________
+ |
+ |
+ |  FUNCTION NAME med_olag
+ |
+ |
+ |_____________________________________________________________________
+ */
+
+
+Word16 Med_olag(                           /* output : median of  5 previous open-loop lags       */
+     Word16 prev_ol_lag,                   /* input  : previous open-loop lag                     */
+     Word16 old_ol_lag[5]
+)
+{
+    Word16 i;
+
+    /* Use median of 5 previous open-loop lags as old lag */
+
+    for (i = 4; i > 0; i--)
+    {
+        old_ol_lag[i] = old_ol_lag[i - 1]; move16();
+    }
+
+    old_ol_lag[0] = prev_ol_lag;           move16();
+
+    i = median5(&old_ol_lag[2]);
+
+    return i;
+
+}
--- /dev/null
+++ b/amr-wb/p_med_ol.tab
@@ -1,0 +1,26 @@
+/*-----------------------------------------------------*
+ | Table for function Pitch_med_ol()                   |
+ *-----------------------------------------------------*/
+
+ static Word16 corrweight[199]= {
+
+ 10772, 10794, 10816, 10839, 10862, 10885, 10908, 10932, 10955, 10980,
+ 11004, 11029, 11054, 11079, 11105, 11131, 11157, 11183, 11210, 11238,
+ 11265, 11293, 11322, 11350, 11379, 11409, 11439, 11469, 11500, 11531,
+ 11563, 11595, 11628, 11661, 11694, 11728, 11763, 11798, 11834, 11870,
+ 11907, 11945, 11983, 12022, 12061, 12101, 12142, 12184, 12226, 12270,
+ 12314, 12358, 12404, 12451, 12498, 12547, 12596, 12647, 12699, 12751,
+ 12805, 12861, 12917, 12975, 13034, 13095, 13157, 13221, 13286, 13353,
+ 13422, 13493, 13566, 13641, 13719, 13798, 13880, 13965, 14053, 14143,
+ 14237, 14334, 14435, 14539, 14648, 14761, 14879, 15002, 15130, 15265,
+ 15406, 15554, 15710, 15874, 16056, 16384, 16384, 16384, 16384, 16384,
+ 16384, 16384, 16056, 15874, 15710, 15554, 15406, 15265, 15130, 15002,
+ 14879, 14761, 14648, 14539, 14435, 14334, 14237, 14143, 14053, 13965,
+ 13880, 13798, 13719, 13641, 13566, 13493, 13422, 13353, 13286, 13221,
+ 13157, 13095, 13034, 12975, 12917, 12861, 12805, 12751, 12699, 12647,
+ 12596, 12547, 12498, 12451, 12404, 12358, 12314, 12270, 12226, 12184,
+ 12142, 12101, 12061, 12022, 11983, 11945, 11907, 11870, 11834, 11798,
+ 11763, 11728, 11694, 11661, 11628, 11595, 11563, 11531, 11500, 11469,
+ 11439, 11409, 11379, 11350, 11322, 11293, 11265, 11238, 11210, 11183,
+ 11157, 11131, 11105, 11079, 11054, 11029, 11004, 10980, 10955, 10932,
+ 10908, 10885, 10862, 10839, 10816, 10794, 10772, 10750, 10728};
--- /dev/null
+++ b/amr-wb/ph_disp.c
@@ -1,0 +1,160 @@
+/*-----------------------------------------------------------------------*
+ *                         PH_DISP.C                                     *
+ *-----------------------------------------------------------------------*
+ * post-processing to enhance noise in low bit rate.                     *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+#define pitch_0_9  14746                   /* 0.9 in Q14 */
+#define pitch_0_6  9830                    /* 0.6 in Q14 */
+
+
+#define L_SUBFR 64
+
+/* impulse response with phase dispersion */
+
+/* 2.0 - 6.4 kHz phase dispersion */
+static Word16 ph_imp_low[L_SUBFR] =
+{
+    20182, 9693, 3270, -3437, 2864, -5240, 1589, -1357,
+    600, 3893, -1497, -698, 1203, -5249, 1199, 5371,
+    -1488, -705, -2887, 1976, 898, 721, -3876, 4227,
+    -5112, 6400, -1032, -4725, 4093, -4352, 3205, 2130,
+    -1996, -1835, 2648, -1786, -406, 573, 2484, -3608,
+    3139, -1363, -2566, 3808, -639, -2051, -541, 2376,
+    3932, -6262, 1432, -3601, 4889, 370, 567, -1163,
+    -2854, 1914, 39, -2418, 3454, 2975, -4021, 3431
+};
+
+/* 3.2 - 6.4 kHz phase dispersion */
+static Word16 ph_imp_mid[L_SUBFR] =
+{
+    24098, 10460, -5263, -763, 2048, -927, 1753, -3323,
+    2212, 652, -2146, 2487, -3539, 4109, -2107, -374,
+    -626, 4270, -5485, 2235, 1858, -2769, 744, 1140,
+    -763, -1615, 4060, -4574, 2982, -1163, 731, -1098,
+    803, 167, -714, 606, -560, 639, 43, -1766,
+    3228, -2782, 665, 763, 233, -2002, 1291, 1871,
+    -3470, 1032, 2710, -4040, 3624, -4214, 5292, -4270,
+    1563, 108, -580, 1642, -2458, 957, 544, 2540
+};
+
+
+
+void Init_Phase_dispersion(
+     Word16 disp_mem[]                     /* (i/o): static memory (size = 8) */
+)
+{
+    Set_zero(disp_mem, 8);
+
+    return;
+}
+
+
+void Phase_dispersion(
+     Word16 gain_code,                     /* (i) Q0  : gain of code             */
+     Word16 gain_pit,                      /* (i) Q14 : gain of pitch            */
+     Word16 code[],                        /* (i/o)   : code vector              */
+     Word16 mode,                          /* (i)     : level, 0=hi, 1=lo, 2=off */
+     Word16 disp_mem[]                     /* (i/o)   : static memory (size = 8) */
+)
+{
+    Word16 i, j, state;
+    Word16 *prev_gain_pit, *prev_gain_code, *prev_state;
+    Word16 code2[2 * L_SUBFR];
+
+    prev_state = disp_mem;
+    prev_gain_code = disp_mem + 1;
+    prev_gain_pit = disp_mem + 2;
+
+    Set_zero(code2, 2 * L_SUBFR);
+
+    test();test();move16();
+    if (sub(gain_pit, pitch_0_6) < 0)
+        state = 0;
+    else if (sub(gain_pit, pitch_0_9) < 0)
+        state = 1;
+    else
+        state = 2;
+
+    for (i = 5; i > 0; i--)
+    {
+        prev_gain_pit[i] = prev_gain_pit[i - 1];        move16();
+    }
+    prev_gain_pit[0] = gain_pit;           move16();
+
+    if (sub(sub(gain_code, *prev_gain_code), shl(*prev_gain_code, 1)) > 0)
+    {
+        /* onset */
+        test();
+        if (sub(state, 2) < 0)
+            state = add(state, 1);
+    } else
+    {
+        j = 0;
+        for (i = 0; i < 6; i++)
+        {
+            test();
+            if (sub(prev_gain_pit[i], pitch_0_6) < 0)
+                j = add(j, 1);
+        }
+        test();
+        if (sub(j, 2) > 0)
+        {
+            state = 0;                     move16();
+        }
+        if (sub(sub(state, *prev_state), 1) > 0)
+            state = sub(state, 1);
+    }
+
+    *prev_gain_code = gain_code;           move16();
+    *prev_state = state;                   move16();
+
+    /* circular convolution */
+
+    state = add(state, mode);              /* level of dispersion */
+
+    if (state == 0)
+    {
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            test();
+            if (code[i] != 0)
+            {
+                for (j = 0; j < L_SUBFR; j++)
+                {
+                    move16();
+                    code2[i + j] = add(code2[i + j], mult_r(code[i], ph_imp_low[j]));
+                }
+            }
+        }
+    } else if (sub(state, 1) == 0)
+    {
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            test();
+            if (code[i] != 0)
+            {
+                for (j = 0; j < L_SUBFR; j++)
+                {
+                    move16();
+                    code2[i + j] = add(code2[i + j], mult_r(code[i], ph_imp_mid[j]));
+                }
+            }
+        }
+    }
+    if (sub(state, 2) < 0)
+    {
+        for (i = 0; i < L_SUBFR; i++)
+        {
+            move16();
+            code[i] = add(code2[i], code2[i + L_SUBFR]);
+        }
+    }
+    return;
+}
--- /dev/null
+++ b/amr-wb/pit_shrp.c
@@ -1,0 +1,30 @@
+/*-----------------------------------------------------------------------*
+ *                         PIT_SHRP.C                                    *
+ *-----------------------------------------------------------------------*
+ * Performs Pitch sharpening routine                                     *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+void Pit_shrp(
+     Word16 * x,                           /* in/out: impulse response (or algebraic code) */
+     Word16 pit_lag,                       /* input : pitch lag                            */
+     Word16 sharp,                         /* input : pitch sharpening factor (Q15)        */
+     Word16 L_subfr                        /* input : subframe size                        */
+)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    for (i = pit_lag; i < L_subfr; i++)
+    {
+        L_tmp = L_deposit_h(x[i]);
+        L_tmp = L_mac(L_tmp, x[i - pit_lag], sharp);
+        x[i] = round(L_tmp);
+        move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/pitch_f4.c
@@ -1,0 +1,295 @@
+/*-----------------------------------------------------------------------*
+ *                         PITCH_F4.C                                    *
+ *-----------------------------------------------------------------------*
+ * Find the closed loop pitch period with 1/4 subsample resolution.      *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "acelp.h"
+#include "cnst.h"
+#include "count.h"
+
+#define UP_SAMP      4
+#define L_INTERPOL1  4
+
+/* Local functions */
+
+static void Norm_Corr(
+     Word16 exc[],                         /* (i)     : excitation buffer                     */
+     Word16 xn[],                          /* (i)     : target vector                         */
+     Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
+     Word16 L_subfr,                       /* (i)     : Length of subframe                    */
+     Word16 t_min,                         /* (i)     : minimum value of pitch lag.           */
+     Word16 t_max,                         /* (i)     : maximum value of pitch lag.           */
+     Word16 corr_norm[]                    /* (o) Q15 : normalized correlation                */
+);
+static Word16 Interpol_4(                  /* (o)  : interpolated value  */
+     Word16 * x,                           /* (i)  : input vector        */
+     Word16 frac                           /* (i)  : fraction (-4..+3)   */
+);
+
+
+Word16 Pitch_fr4(                          /* (o)     : pitch period.                         */
+     Word16 exc[],                         /* (i)     : excitation buffer                     */
+     Word16 xn[],                          /* (i)     : target vector                         */
+     Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
+     Word16 t0_min,                        /* (i)     : minimum value in the searched range.  */
+     Word16 t0_max,                        /* (i)     : maximum value in the searched range.  */
+     Word16 * pit_frac,                    /* (o)     : chosen fraction (0, 1, 2 or 3).       */
+     Word16 i_subfr,                       /* (i)     : indicator for first subframe.         */
+     Word16 t0_fr2,                        /* (i)     : minimum value for resolution 1/2      */
+     Word16 t0_fr1,                        /* (i)     : minimum value for resolution 1        */
+     Word16 L_subfr                        /* (i)     : Length of subframe                    */
+)
+{
+    Word16 i;
+    Word16 t_min, t_max;
+    Word16 max, t0, fraction, step, temp;
+    Word16 *corr;
+    Word16 corr_v[40];                     /* Total length = t0_max-t0_min+1+2*L_inter */
+
+    /* Find interval to compute normalized correlation */
+
+    t_min = sub(t0_min, L_INTERPOL1);
+    t_max = add(t0_max, L_INTERPOL1);
+
+    corr = &corr_v[-t_min];
+    move16();
+
+    /* Compute normalized correlation between target and filtered excitation */
+
+    Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr);
+
+    /* Find integer pitch */
+
+    max = corr[t0_min];
+    move16();
+    t0 = t0_min;
+    move16();
+
+    for (i = add(t0_min, 1); i <= t0_max; i++)
+    {
+        test();
+        if (sub(corr[i], max) >= 0)
+        {
+            max = corr[i];                 move16();
+            t0 = i;                        move16();
+        }
+    }
+
+    /* If first subframe and t0 >= t0_fr1, do not search fractionnal pitch */
+    test();test();
+    if ((i_subfr == 0) && (sub(t0, t0_fr1) >= 0))
+    {
+        *pit_frac = 0;
+        move16();
+        return (t0);
+    }
+    /*------------------------------------------------------------------*
+     * Search fractionnal pitch with 1/4 subsample resolution.          *
+     * Test the fractions around t0 and choose the one which maximizes  *
+     * the interpolated normalized correlation.                         *
+     *------------------------------------------------------------------*/
+
+    step = 1;
+    move16();                              /* 1/4 subsample resolution */
+    fraction = -3;
+    move16();
+    test();test();test();
+    if (((i_subfr == 0) && (sub(t0, t0_fr2) >= 0)) || (sub(t0_fr2, PIT_MIN) == 0))
+    {
+        step = 2;
+        move16();                          /* 1/2 subsample resolution */
+        fraction = -2;
+        move16();
+    }
+    test();
+    if (sub(t0, t0_min) == 0)
+    {
+        fraction = 0;
+        move16();
+    }
+    max = Interpol_4(&corr[t0], fraction);
+
+    for (i = add(fraction, step); i <= 3; i = (Word16) (i + step))
+    {
+        temp = Interpol_4(&corr[t0], i);
+
+        test();
+        if (sub(temp, max) > 0)
+        {
+            max = temp;
+            move16();
+            fraction = i;
+            move16();
+        }
+    }
+
+    /* limit the fraction value in the interval [0,1,2,3] */
+    test();
+    if (fraction < 0)
+    {
+        fraction = add(fraction, UP_SAMP);
+        t0 = sub(t0, 1);
+    }
+    *pit_frac = fraction;
+    move16();
+
+    return (t0);
+}
+
+
+/*--------------------------------------------------------------------------*
+ * Function Norm_Corr()                                                     *
+ * ~~~~~~~~~~~~~~~~~~~~                                                     *
+ * Find the normalized correlation between the target vector and the        *
+ * filtered past excitation.                                                *
+ * (correlation between target and filtered excitation divided by the       *
+ *  square root of energy of target and filtered excitation).               *
+ *--------------------------------------------------------------------------*/
+
+static void Norm_Corr(
+     Word16 exc[],                         /* (i)     : excitation buffer                     */
+     Word16 xn[],                          /* (i)     : target vector                         */
+     Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
+     Word16 L_subfr,                       /* (i)     : Length of subframe                    */
+     Word16 t_min,                         /* (i)     : minimum value of pitch lag.           */
+     Word16 t_max,                         /* (i)     : maximum value of pitch lag.           */
+     Word16 corr_norm[])                   /* (o) Q15 : normalized correlation                */
+{
+    Word16 i, k, t;
+    Word16 corr, exp_corr, norm, exp_norm, exp, scale;
+    Word16 excf[L_SUBFR];
+    Word32 L_tmp;
+
+    /* compute the filtered excitation for the first delay t_min */
+
+    k = negate(t_min);
+    Convolve(&exc[k], h, excf, L_subfr);
+
+    /* Compute rounded down 1/sqrt(energy of xn[]) */
+
+    L_tmp = 1L;                            move32();
+    for (i = 0; i < L_subfr; i++)
+        L_tmp = L_mac(L_tmp, xn[i], xn[i]);
+
+    exp = norm_l(L_tmp);
+    exp = sub(30, exp);
+
+    exp = add(exp, 2);                     /* energy of xn[] x 2 + rounded up     */
+    scale = negate(shr(exp, 1));           /* (1<<scale) < 1/sqrt(energy rounded) */
+
+    /* loop for every possible period */
+
+    for (t = t_min; t <= t_max; t++)
+    {
+        /* Compute correlation between xn[] and excf[] */
+
+        L_tmp = 1L;                        move32();
+        for (i = 0; i < L_subfr; i++)
+            L_tmp = L_mac(L_tmp, xn[i], excf[i]);
+
+        exp = norm_l(L_tmp);
+        L_tmp = L_shl(L_tmp, exp);
+        exp_corr = sub(30, exp);
+
+        corr = extract_h(L_tmp);
+
+        /* Compute 1/sqrt(energy of excf[]) */
+
+        L_tmp = 1L;                        move32();
+        for (i = 0; i < L_subfr; i++)
+            L_tmp = L_mac(L_tmp, excf[i], excf[i]);
+
+        exp = norm_l(L_tmp);
+        L_tmp = L_shl(L_tmp, exp);
+        exp_norm = sub(30, exp);
+
+        Isqrt_n(&L_tmp, &exp_norm);
+        norm = extract_h(L_tmp);
+
+        /* Normalize correlation = correlation * (1/sqrt(energy)) */
+
+        L_tmp = L_mult(corr, norm);
+        L_tmp = L_shl(L_tmp, add(add(exp_corr, exp_norm), scale));
+
+        corr_norm[t] = round(L_tmp);       move16();
+
+        /* modify the filtered excitation excf[] for the next iteration */
+
+        test();
+        if (sub(t, t_max) != 0)
+        {
+            k--;                           move16();
+            for (i = (Word16) (L_subfr - 1); i > 0; i--)
+            {
+                /* saturation can occur in add() */
+                excf[i] = add(mult(exc[k], h[i]), excf[i - 1]); move16();
+            }
+            excf[0] = mult(exc[k], h[0]);  move16();
+        }
+    }
+
+    return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * Procedure Interpol_4()                                                   *
+ * ~~~~~~~~~~~~~~~~~~~~~~                                                   *
+ * For interpolating the normalized correlation with 1/4 resolution.        *
+ *--------------------------------------------------------------------------*/
+
+/* 1/4 resolution interpolation filter (-3 dB at 0.791*fs/2) in Q14 */
+
+static Word16 inter4_1[UP_SAMP * 2 * L_INTERPOL1] =
+{
+    -12, -26, 32, 206,
+    420, 455, 73, -766,
+    -1732, -2142, -1242, 1376,
+    5429, 9910, 13418, 14746,
+    13418, 9910, 5429, 1376,
+    -1242, -2142, -1732, -766,
+    73, 455, 420, 206,
+    32, -26, -12, 0
+};
+
+/*** Coefficients in floating point
+static float inter4_1[UP_SAMP*L_INTERPOL1+1] = {
+   0.900000,
+   0.818959,  0.604850,  0.331379,  0.083958,
+  -0.075795, -0.130717, -0.105685, -0.046774,
+   0.004467,  0.027789,  0.025642,  0.012571,
+   0.001927, -0.001571, -0.000753,  0.000000};
+***/
+
+static Word16 Interpol_4(                  /* (o)  : interpolated value  */
+     Word16 * x,                           /* (i)  : input vector        */
+     Word16 frac                           /* (i)  : fraction (-4..+3)   */
+)
+{
+    Word16 i, k, sum;
+    Word32 L_sum;
+
+    test();
+    if (frac < 0)
+    {
+        frac = add(frac, UP_SAMP);
+        x--;
+        move16();
+    }
+    x = x - L_INTERPOL1 + 1;
+    move16();
+
+    L_sum = 0L;                            move32();
+    for (i = 0, k = sub(sub(UP_SAMP, 1), frac); i < 2 * L_INTERPOL1; i++, k += UP_SAMP)
+    {
+        L_sum = L_mac(L_sum, x[i], inter4_1[k]);
+    }
+
+    sum = round(L_shl(L_sum, 1));
+
+    return (sum);
+}
--- /dev/null
+++ b/amr-wb/pred_lt4.c
@@ -1,0 +1,116 @@
+/*-------------------------------------------------------------------*
+ *                         PRED_LT4.C                                *
+ *-------------------------------------------------------------------*
+ * Compute the result of long term prediction with fractionnal       *
+ * interpolation of resolution 1/4.                                  *
+ *                                                                   *
+ * On return exc[0..L_subfr-1] contains the interpolated signal      *
+ *   (adaptive codebook excitation)                                  *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+#define UP_SAMP      4
+#define L_INTERPOL2  16
+
+/* 1/4 resolution interpolation filter (-3 dB at 0.856*fs/2) in Q14 */
+
+static Word16 inter4_2[UP_SAMP * 2 * L_INTERPOL2] =
+{
+    0, 1, 2, 1,
+    -2, -7, -10, -7,
+    4, 19, 28, 22,
+    -2, -33, -55, -49,
+    -10, 47, 91, 92,
+    38, -52, -133, -153,
+    -88, 43, 175, 231,
+    165, -9, -209, -325,
+    -275, -60, 226, 431,
+    424, 175, -213, -544,
+    -619, -355, 153, 656,
+    871, 626, -16, -762,
+    -1207, -1044, -249, 853,
+    1699, 1749, 780, -923,
+    -2598, -3267, -2147, 968,
+    5531, 10359, 14031, 15401,
+    14031, 10359, 5531, 968,
+    -2147, -3267, -2598, -923,
+    780, 1749, 1699, 853,
+    -249, -1044, -1207, -762,
+    -16, 626, 871, 656,
+    153, -355, -619, -544,
+    -213, 175, 424, 431,
+    226, -60, -275, -325,
+    -209, -9, 165, 231,
+    175, 43, -88, -153,
+    -133, -52, 38, 92,
+    91, 47, -10, -49,
+    -55, -33, -2, 22,
+    28, 19, 4, -7,
+    -10, -7, -2, 1,
+    2, 1, 0, 0
+};
+
+/*** Coefficients in floating point
+static float inter4_2[UP_SAMP*L_INTERPOL2+1] = {
+   0.940000,
+   0.856390,   0.632268,   0.337560,   0.059072,
+  -0.131059,  -0.199393,  -0.158569,  -0.056359,
+   0.047606,   0.106749,   0.103705,   0.052062,
+  -0.015182,  -0.063705,  -0.073660,  -0.046497,
+  -0.000983,   0.038227,   0.053143,   0.040059,
+   0.009308,  -0.021674,  -0.037767,  -0.033186,
+  -0.013028,   0.010702,   0.025901,   0.026318,
+   0.013821,  -0.003645,  -0.016813,  -0.019855,
+  -0.012766,  -0.000530,   0.010080,   0.014122,
+   0.010657,   0.002594,  -0.005363,  -0.009344,
+  -0.008101,  -0.003182,   0.002330,   0.005635,
+   0.005562,   0.002844,  -0.000627,  -0.002993,
+  -0.003362,  -0.002044,  -0.000116,   0.001315,
+   0.001692,   0.001151,   0.000259,  -0.000417,
+  -0.000618,  -0.000434,  -0.000133,   0.000063,
+   0.000098,   0.000048,   0.000007,   0.000000};
+***/
+
+void Pred_lt4(
+     Word16 exc[],                         /* in/out: excitation buffer */
+     Word16 T0,                            /* input : integer pitch lag */
+     Word16 frac,                          /* input : fraction of lag   */
+     Word16 L_subfr                        /* input : subframe size     */
+)
+{
+    Word16 i, j, k, *x;
+    Word32 L_sum;
+
+    x = &exc[-T0];
+    move16();
+
+    frac = negate(frac);
+    test();
+    if (frac < 0)
+    {
+        frac = add(frac, UP_SAMP);
+        x--;
+        move16();
+    }
+    x = x - L_INTERPOL2 + 1;
+    move16();
+
+    for (j = 0; j < L_subfr; j++)
+    {
+        L_sum = 0L;                        move32();
+        for (i = 0, k = sub(sub(UP_SAMP, 1), frac); i < 2 * L_INTERPOL2; i++, k += UP_SAMP)
+        {
+            L_sum = L_mac(L_sum, x[i], inter4_2[k]);
+        }
+        L_sum = L_shl(L_sum, 1);
+
+        exc[j] = round(L_sum);
+        move16();
+        x++;
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/preemph.c
@@ -1,0 +1,71 @@
+/*-------------------------------------------------------------------*
+ *                         PREEMPH.C                                 *
+ *-------------------------------------------------------------------*
+ * Preemphasis: filtering through 1 - g z^-1                         *
+ *                                                                   *
+ * Preemph2 --> signal is multiplied by 2.                           *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+
+void Preemph(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : preemphasis coefficient                */
+     Word16 lg,                            /* (i)     : lenght of filtering                    */
+     Word16 * mem                          /* (i/o)   : memory (x[-1])                         */
+)
+{
+    Word16 i, temp;
+    Word32 L_tmp;
+
+    temp = x[lg - 1];                      move16();
+
+    for (i = (Word16) (lg - 1); i > 0; i--)
+    {
+        L_tmp = L_deposit_h(x[i]);
+        L_tmp = L_msu(L_tmp, x[i - 1], mu);
+        x[i] = round(L_tmp);               move16();
+    }
+
+    L_tmp = L_deposit_h(x[0]);
+    L_tmp = L_msu(L_tmp, *mem, mu);
+    x[0] = round(L_tmp);                   move16();
+
+    *mem = temp;                           move16();
+
+    return;
+}
+
+
+void Preemph2(
+     Word16 x[],                           /* (i/o)   : input signal overwritten by the output */
+     Word16 mu,                            /* (i) Q15 : preemphasis coefficient                */
+     Word16 lg,                            /* (i)     : lenght of filtering                    */
+     Word16 * mem                          /* (i/o)   : memory (x[-1])                         */
+)
+{
+    Word16 i, temp;
+    Word32 L_tmp;
+
+    temp = x[lg - 1];                      move16();
+
+    for (i = (Word16) (lg - 1); i > 0; i--)
+    {
+        L_tmp = L_deposit_h(x[i]);
+        L_tmp = L_msu(L_tmp, x[i - 1], mu);
+        L_tmp = L_shl(L_tmp, 1);
+        x[i] = round(L_tmp);               move16();
+    }
+
+    L_tmp = L_deposit_h(x[0]);
+    L_tmp = L_msu(L_tmp, *mem, mu);
+    L_tmp = L_shl(L_tmp, 1);
+    x[0] = round(L_tmp);                   move16();
+
+    *mem = temp;                           move16();
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/q_gain2.c
@@ -1,0 +1,326 @@
+/*--------------------------------------------------------------------------*
+ *                         Q_GAIN2.C                                        *
+ *--------------------------------------------------------------------------*
+ * Quantization of pitch and codebook gains.                                *
+ * MA prediction is performed on the innovation energy (in dB with mean     *
+ * removed).                                                                *
+ * An initial predicted gain, g_0, is first determined and the correction   *
+ * factor     alpha = gain / g_0    is quantized.                           *
+ * The pitch gain and the correction factor are vector quantized and the    *
+ * mean-squared weighted error criterion is used in the quantizer search.   *
+ *--------------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "oper_32b.h"
+#include "math_op.h"
+#include "count.h"
+#include "log2.h"
+
+#include "acelp.h"
+
+#include "q_gain2.tab"
+
+#define MEAN_ENER    30
+#define RANGE        64
+#define PRED_ORDER   4
+
+
+/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */
+static Word16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};
+
+
+void Init_Q_gain2(
+     Word16 * mem                          /* output  :static memory (2 words)      */
+)
+{
+    Word16 i;
+
+    /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */
+    for (i = 0; i < PRED_ORDER; i++)
+    {
+        mem[i] = -14336;                   move16();  /* past_qua_en[i] */
+    }
+
+    return;
+}
+
+
+Word16 Q_gain2(                            /* Return index of quantization.          */
+     Word16 xn[],                          /* (i) Q_xn: Target vector.               */
+     Word16 y1[],                          /* (i) Q_xn: Adaptive codebook.           */
+     Word16 Q_xn,                          /* (i)     : xn and y1 format             */
+     Word16 y2[],                          /* (i) Q9  : Filtered innovative vector.  */
+     Word16 code[],                        /* (i) Q9  : Innovative vector.           */
+     Word16 g_coeff[],                     /* (i)     : Correlations <xn y1> <y1 y1> */
+                                           /*           Compute in G_pitch().        */
+     Word16 L_subfr,                       /* (i)     : Subframe lenght.             */
+     Word16 nbits,                         /* (i)     : number of bits (6 or 7)      */
+     Word16 * gain_pit,                    /* (i/o)Q14: Pitch gain.                  */
+     Word32 * gain_cod,                    /* (o) Q16 : Code gain.                   */
+     Word16 gp_clip,                       /* (i)     : Gp Clipping flag             */
+     Word16 * mem                          /* (i/o)   : static memory (2 words)      */
+)
+{
+    Word16 i, j, index, *p, min_ind, size;
+    Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, qua_ener;
+    Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
+    Word16 coeff[5], coeff_lo[5], exp_coeff[5];
+    Word16 exp_max[5];
+    Word32 L_tmp, dist_min;
+    Word16 *past_qua_en, *t_qua_gain;
+
+    past_qua_en = mem;                     move16();
+
+    /*-----------------------------------------------------------------*
+     * - Find the initial quantization pitch index                     *
+     * - Set gains search range                                        *
+     *-----------------------------------------------------------------*/
+    test();
+    if (sub(nbits, 6) == 0)
+    {
+        t_qua_gain = t_qua_gain6b;         move16();
+        min_ind = 0;                       move16();
+        size = RANGE;                      move16();
+
+        test();
+        if (sub(gp_clip, 1) == 0)
+        {
+            size = sub(size, 16);          /* limit gain pitch to 1.0 */
+        }
+    } else
+    {
+        t_qua_gain = t_qua_gain7b;         move16();
+
+        p = t_qua_gain7b + RANGE;          move16();  /* pt at 1/4th of table */
+
+        j = nb_qua_gain7b - RANGE;         move16();
+        test();
+        if (sub(gp_clip, 1) == 0)
+        {
+            j = sub(j, 27);                /* limit gain pitch to 1.0 */
+        }
+        min_ind = 0;                       move16();
+        g_pitch = *gain_pit;               move16();
+
+        for (i = 0; i < j; i++, p += 2)
+        {
+            test();
+            if (sub(g_pitch, *p) > 0)
+            {
+                min_ind = add(min_ind, 1);
+            }
+        }
+        size = RANGE;                      move16();
+    }
+
+    /*------------------------------------------------------------------*
+     *  Compute coefficient need for the quantization.                  *
+     *                                                                  *
+     *  coeff[0] =    y1 y1                                             *
+     *  coeff[1] = -2 xn y1                                             *
+     *  coeff[2] =    y2 y2                                             *
+     *  coeff[3] = -2 xn y2                                             *
+     *  coeff[4] =  2 y1 y2                                             *
+     *                                                                  *
+     * Product <y1 y1> and <xn y1> have been compute in G_pitch() and   *
+     * are in vector g_coeff[].                                         *
+     *------------------------------------------------------------------*/
+
+    coeff[0] = g_coeff[0];                 move16();
+    exp_coeff[0] = g_coeff[1];             move16();
+    coeff[1] = negate(g_coeff[2]);         move16();  /* coeff[1] = -2 xn y1 */
+    exp_coeff[1] = add(g_coeff[3], 1);     move16();
+
+    /* Compute scalar product <y2[],y2[]> */
+    move16();move16();
+    coeff[2] = extract_h(Dot_product12(y2, y2, L_subfr, &exp));
+    exp_coeff[2] = add(sub(exp, 18), shl(Q_xn, 1));     /* -18 (y2 Q9) */
+
+    /* Compute scalar product -2*<xn[],y2[]> */
+    move16();move16();
+    coeff[3] = extract_h(L_negate(Dot_product12(xn, y2, L_subfr, &exp)));
+    exp_coeff[3] = add(sub(exp, 9 - 1), Q_xn);  /* -9 (y2 Q9), +1 (2 xn y2) */
+
+    /* Compute scalar product 2*<y1[],y2[]> */
+    move16();move16();
+    coeff[4] = extract_h(Dot_product12(y1, y2, L_subfr, &exp));
+    exp_coeff[4] = add(sub(exp, 9 - 1), Q_xn);  /* -9 (y2 Q9), +1 (2 y1 y2) */
+
+    /*-----------------------------------------------------------------*
+     *  Find energy of code and compute:                               *
+     *                                                                 *
+     *    L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)         *
+     *          = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)     *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = Dot_product12(code, code, L_subfr, &exp_code);
+    /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
+    exp_code = sub(exp_code, 18 + 6 + 31);
+
+    Log2(L_tmp, &exp, &frac);
+    exp = add(exp, exp_code);
+    L_tmp = Mpy_32_16(exp, frac, -24660);  /* x -3.0103(Q13) -> Q14 */
+
+    L_tmp = L_mac(L_tmp, MEAN_ENER, 8192); /* + MEAN_ENER in Q14 */
+
+    /*-----------------------------------------------------------------*
+     * Compute gcode0.                                                 *
+     *  = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code    *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = L_shl(L_tmp, 10);              /* From Q14 to Q24 */
+    L_tmp = L_mac(L_tmp, pred[0], past_qua_en[0]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[1], past_qua_en[1]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[2], past_qua_en[2]);      /* Q13*Q10 -> Q24 */
+    L_tmp = L_mac(L_tmp, pred[3], past_qua_en[3]);      /* Q13*Q10 -> Q24 */
+
+    gcode0 = extract_h(L_tmp);             /* From Q24 to Q8  */
+
+    /*-----------------------------------------------------------------*
+     * gcode0 = pow(10.0, gcode0/20)                                   *
+     *        = pow(2, 3.321928*gcode0/20)                             *
+     *        = pow(2, 0.166096*gcode0)                                *
+     *-----------------------------------------------------------------*/
+
+    L_tmp = L_mult(gcode0, 5443);          /* *0.166096 in Q15 -> Q24     */
+    L_tmp = L_shr(L_tmp, 8);               /* From Q24 to Q16             */
+    L_Extract(L_tmp, &exp_gcode0, &frac);  /* Extract exponent of gcode0  */
+
+    gcode0 = extract_l(Pow2(14, frac));    /* Put 14 as exponent so that  */
+    /* output of Pow2() will be:   */
+    /* 16384 < Pow2() <= 32767     */
+    exp_gcode0 = sub(exp_gcode0, 14);
+
+    /*-------------------------------------------------------------------------*
+     * Find the best quantizer                                                 *
+     * ~~~~~~~~~~~~~~~~~~~~~~~                                                 *
+     * Before doing the computation we need to aling exponents of coeff[]      *
+     * to be sure to have the maximum precision.                               *
+     *                                                                         *
+     * In the table the pitch gains are in Q14, the code gains are in Q11 and  *
+     * are multiply by gcode0 which have been multiply by 2^exp_gcode0.        *
+     * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code  *
+     * we divide by 2^15.                                                      *
+     * Considering all the scaling above we have:                              *
+     *                                                                         *
+     *   exp_code = exp_gcode0-11+15 = exp_gcode0+4                            *
+     *                                                                         *
+     *   g_pitch*g_pitch  = -14-14+15                                          *
+     *   g_pitch          = -14                                                *
+     *   g_code*g_code    = (2*exp_code)+15                                    *
+     *   g_code           = exp_code                                           *
+     *   g_pitch*g_code   = -14 + exp_code +15                                 *
+     *                                                                         *
+     *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13             *
+     *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14             *
+     *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code) *
+     *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code       *
+     *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code   *
+     *-------------------------------------------------------------------------*/
+
+    exp_code = add(exp_gcode0, 4);
+
+    exp_max[0] = sub(exp_coeff[0], 13);    move16();
+    exp_max[1] = sub(exp_coeff[1], 14);    move16();
+    exp_max[2] = add(exp_coeff[2], add(15, shl(exp_code, 1)));  move16();
+    exp_max[3] = add(exp_coeff[3], exp_code);   move16();
+    exp_max[4] = add(exp_coeff[4], add(1, exp_code));   move16();
+
+    /* Find maximum exponant */
+
+    e_max = exp_max[0];                    move16();
+    for (i = 1; i < 5; i++)
+    {
+        test();
+        if (sub(exp_max[i], e_max) > 0)
+        {
+            e_max = exp_max[i];            move16();
+        }
+    }
+
+    /* align coeff[] and save in special 32 bit double precision */
+
+    for (i = 0; i < 5; i++)
+    {
+        j = add(sub(e_max, exp_max[i]), 2);/* /4 to avoid overflow */
+        L_tmp = L_deposit_h(coeff[i]);
+        L_tmp = L_shr(L_tmp, j);
+        L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
+        coeff_lo[i] = shr(coeff_lo[i], 3); move16();  /* lo >> 3 */
+    }
+
+    /* Codebook search */
+
+    dist_min = MAX_32;                     move32();
+    p = &t_qua_gain[shl(min_ind, 1)];      move16();
+
+    index = 0;                             move16();
+    for (i = 0; i < size; i++)
+    {
+        g_pitch = *p++;                    move16();
+        g_code = *p++;                     move16();
+
+        g_code = mult_r(g_code, gcode0);
+        g2_pitch = mult_r(g_pitch, g_pitch);
+        g_pit_cod = mult_r(g_code, g_pitch);
+        L_tmp = L_mult(g_code, g_code);
+        L_Extract(L_tmp, &g2_code, &g2_code_lo);
+
+        L_tmp = L_mult(coeff[2], g2_code_lo);
+        L_tmp = L_shr(L_tmp, 3);
+        L_tmp = L_mac(L_tmp, coeff_lo[0], g2_pitch);
+        L_tmp = L_mac(L_tmp, coeff_lo[1], g_pitch);
+        L_tmp = L_mac(L_tmp, coeff_lo[2], g2_code);
+        L_tmp = L_mac(L_tmp, coeff_lo[3], g_code);
+        L_tmp = L_mac(L_tmp, coeff_lo[4], g_pit_cod);
+        L_tmp = L_shr(L_tmp, 12);
+        L_tmp = L_mac(L_tmp, coeff[0], g2_pitch);
+        L_tmp = L_mac(L_tmp, coeff[1], g_pitch);
+        L_tmp = L_mac(L_tmp, coeff[2], g2_code);
+        L_tmp = L_mac(L_tmp, coeff[3], g_code);
+        L_tmp = L_mac(L_tmp, coeff[4], g_pit_cod);
+
+        test();
+        if (L_sub(L_tmp, dist_min) < (Word32) 0)
+        {
+            dist_min = L_tmp;              move32();
+            index = i;                     move16();
+        }
+    }
+
+    /* Read the quantized gains */
+
+    index = add(index, min_ind);
+
+    p = &t_qua_gain[add(index, index)];    move16();
+    *gain_pit = *p++;                      move16();  /* selected pitch gain in Q14 */
+    g_code = *p++;                         move16();  /* selected code gain in Q11  */
+
+    L_tmp = L_mult(g_code, gcode0);             /* Q11*Q0 -> Q12 */
+    L_tmp = L_shl(L_tmp, add(exp_gcode0, 4));   /* Q12 -> Q16 */
+
+    *gain_cod = L_tmp;                     move16();  /* gain of code in Q16 */
+
+    /*---------------------------------------------------*
+     * qua_ener = 20*log10(g_code)                       *
+     *          = 6.0206*log2(g_code)                    *
+     *          = 6.0206*(log2(g_codeQ11) - 11)          *
+     *---------------------------------------------------*/
+
+    L_tmp = L_deposit_l(g_code);
+    Log2(L_tmp, &exp, &frac);
+    exp = sub(exp, 11);
+    L_tmp = Mpy_32_16(exp, frac, 24660);   /* x 6.0206 in Q12 */
+
+    qua_ener = extract_l(L_shr(L_tmp, 3)); /* result in Q10 */
+
+    /* update table of past quantized energies */
+
+    past_qua_en[3] = past_qua_en[2];       move16();
+    past_qua_en[2] = past_qua_en[1];       move16();
+    past_qua_en[1] = past_qua_en[0];       move16();
+    past_qua_en[0] = qua_ener;             move16();
+
+    return (index);
+}
--- /dev/null
+++ b/amr-wb/q_gain2.tab
@@ -1,0 +1,210 @@
+/*------------------------------------------------------*
+ * Tables for function q_gain2()                        *
+ *                                                      *
+ *  g_pitch(Q14),  g_code(Q11)                          *
+ *                                                      *
+ * pitch gain are ordered in table to reduce complexity *
+ * during quantization of gains.                        *
+ *------------------------------------------------------*/
+
+#define nb_qua_gain6b  64     /* Number of quantization level */
+#define nb_qua_gain7b  128    /* Number of quantization level */
+
+
+static Word16 t_qua_gain6b[64*2] = {
+   1566,  1332,
+   1577,  3557,
+   3071,  6490,
+   4193, 10163,
+   4496,  2534,
+   5019,  4488,
+   5586, 15614,
+   5725,  1422,
+   6453,   580,
+   6724,  6831,
+   7657,  3527,
+   8072,  2099,
+   8232,  5319,
+   8827,  8775,
+   9740,  2868,
+   9856,  1465,
+  10087, 12488,
+  10241,  4453,
+  10859,  6618,
+  11321,  3587,
+  11417,  1800,
+  11643,  2428,
+  11718,   988,
+  12312,  5093,
+  12523,  8413,
+  12574, 26214,
+  12601,  3396,
+  13172,  1623,
+  13285,  2423,
+  13418,  6087,
+  13459, 12810,
+  13656,  3607,
+  14111,  4521,
+  14144,  1229,
+  14425,  1871,
+  14431,  7234,
+  14445,  2834,
+  14628, 10036,
+  14860, 17496,
+  15161,  3629,
+  15209,  5819,
+  15299,  2256,
+  15518,  4722,
+  15663,  1060,
+  15759,  7972,
+  15939, 11964,
+  16020,  2996,
+  16086,  1707,
+  16521,  4254,
+  16576,  6224,
+  16894,  2380,
+  16906,   681,
+  17213,  8406,
+  17610,  3418,
+  17895,  5269,
+  18168, 11748,
+  18230,  1575,
+  18607, 32767,
+  18728, 21684,
+  19137,  2543,
+  19422,  6577,
+  19446,  4097,
+  19450,  9056,
+  20371, 14885};
+
+static Word16 t_qua_gain7b[128*2] = {
+    204,   441,
+    464,  1977,
+    869,  1077,
+   1072,  3062,
+   1281,  4759,
+   1647,  1539,
+   1845,  7020,
+   1853,   634,
+   1995,  2336,
+   2351, 15400,
+   2661,  1165,
+   2702,  3900,
+   2710, 10133,
+   3195,  1752,
+   3498,  2624,
+   3663,   849,
+   3984,  5697,
+   4214,  3399,
+   4415,  1304,
+   4695,  2056,
+   5376,  4558,
+   5386,   676,
+   5518, 23554,
+   5567,  7794,
+   5644,  3061,
+   5672,  1513,
+   5957,  2338,
+   6533,  1060,
+   6804,  5998,
+   6820,  1767,
+   6937,  3837,
+   7277,   414,
+   7305,  2665,
+   7466, 11304,
+   7942,   794,
+   8007,  1982,
+   8007,  1366,
+   8326,  3105,
+   8336,  4810,
+   8708,  7954,
+   8989,  2279,
+   9031,  1055,
+   9247,  3568,
+   9283,  1631,
+   9654,  6311,
+   9811,  2605,
+  10120,   683,
+  10143,  4179,
+  10245,  1946,
+  10335,  1218,
+  10468,  9960,
+  10651,  3000,
+  10951,  1530,
+  10969,  5290,
+  11203,  2305,
+  11325,  3562,
+  11771,  6754,
+  11839,  1849,
+  11941,  4495,
+  11954,  1298,
+  11975, 15223,
+  11977,   883,
+  11986,  2842,
+  12438,  2141,
+  12593,  3665,
+  12636,  8367,
+  12658,  1594,
+  12886,  2628,
+  12984,  4942,
+  13146,  1115,
+  13224,   524,
+  13341,  3163,
+  13399,  1923,
+  13549,  5961,
+  13606,  1401,
+  13655,  2399,
+  13782,  3909,
+  13868, 10923,
+  14226,  1723,
+  14232,  2939,
+  14278,  7528,
+  14439,  4598,
+  14451,   984,
+  14458,  2265,
+  14792,  1403,
+  14818,  3445,
+  14899,  5709,
+  15017, 15362,
+  15048,  1946,
+  15069,  2655,
+  15405,  9591,
+  15405,  4079,
+  15570,  7183,
+  15687,  2286,
+  15691,  1624,
+  15699,  3068,
+  15772,  5149,
+  15868,  1205,
+  15970,   696,
+  16249,  3584,
+  16338,  1917,
+  16424,  2560,
+  16483,  4438,
+  16529,  6410,
+  16620, 11966,
+  16839,  8780,
+  17030,  3050,
+  17033, 18325,
+  17092,  1568,
+  17123,  5197,
+  17351,  2113,
+  17374,   980,
+  17566, 26214,
+  17609,  3912,
+  17639, 32767,
+  18151,  7871,
+  18197,  2516,
+  18202,  5649,
+  18679,  3283,
+  18930,  1370,
+  19271, 13757,
+  19317,  4120,
+  19460,  1973,
+  19654, 10018,
+  19764,  6792,
+  19912,  5135,
+  20040,  2841,
+  21234, 19833};
+
+
--- /dev/null
+++ b/amr-wb/q_pulse.c
@@ -1,0 +1,637 @@
+/*--------------------------------------------------------------------------*
+ *                         Q_PULSE.C                                        *
+ *--------------------------------------------------------------------------*
+ * Coding and decodeing of algebraic codebook                               *
+ *--------------------------------------------------------------------------*/
+
+#include <stdio.h>
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+#include "q_pulse.h"
+
+
+#define NB_POS 16                          /* pos in track, mask for sign bit */
+
+
+Word32 quant_1p_N1(                        /* (o) return N+1 bits             */
+     Word16 pos,                           /* (i) position of the pulse       */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 mask;
+    Word32 index;
+
+    mask = sub(shl(1, N), 1);              /* mask = ((1<<N)-1); */
+    /*-------------------------------------------------------*
+     * Quantization of 1 pulse with N+1 bits:                *
+     *-------------------------------------------------------*/
+    index = L_deposit_l((Word16) (pos & mask));
+    test();
+    if ((pos & NB_POS) != 0)
+    {
+        index = L_add(index, L_deposit_l(shl(1, N)));   /* index += 1 << N; */
+    }
+    return (index);
+}
+
+void dec_1p_N1(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 pos1;
+    Word32 mask, i;
+
+    mask = L_deposit_l(sub(shl(1, N), 1));   /* mask = ((1<<N)-1); */
+    /*-------------------------------------------------------*
+     * Decode 1 pulse with N+1 bits:                         *
+     *-------------------------------------------------------*/
+    pos1 = add(extract_l(index & mask), offset);        /* pos1 = ((index & mask) + offset); */
+    i = (L_shr(index, N) & 1L);              /* i = ((index >> N) & 1); */
+    test();
+    if (L_sub(i, 1) == 0)
+    {
+        pos1 = add(pos1, NB_POS);
+    }
+    pos[0] = pos1;                         move16();
+
+    return;
+}
+
+
+Word32 quant_2p_2N1(                       /* (o) return (2*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 mask, tmp;
+    Word32 index;
+
+    mask = sub(shl(1, N), 1);              /* mask = ((1<<N)-1); */
+    /*-------------------------------------------------------*
+     * Quantization of 2 pulses with 2*N+1 bits:             *
+     *-------------------------------------------------------*/
+    test();logic16();logic16();
+    if (((pos2 ^ pos1) & NB_POS) == 0)
+    {
+        /* sign of 1st pulse == sign of 2th pulse */
+        test();
+        if (sub(pos1, pos2) <= 0)          /* ((pos1 - pos2) <= 0) */
+        {
+            /* index = ((pos1 & mask) << N) + (pos2 & mask); */
+            index = L_deposit_l(add(shl(((Word16) (pos1 & mask)), N), ((Word16) (pos2 & mask))));
+        } else
+        {
+            /* ((pos2 & mask) << N) + (pos1 & mask); */
+            index = L_deposit_l(add(shl(((Word16) (pos2 & mask)), N), ((Word16) (pos1 & mask))));
+        }
+        test();logic16();
+        if ((pos1 & NB_POS) != 0)
+        {
+            tmp = shl(N, 1);
+            index = L_add(index, L_shl(1L, tmp));       /* index += 1 << (2*N); */
+        }
+    } else
+    {
+        /* sign of 1st pulse != sign of 2th pulse */
+        test();logic16();logic16();
+        if (sub((Word16) (pos1 & mask), (Word16) (pos2 & mask)) <= 0)
+        {
+            /* index = ((pos2 & mask) << N) + (pos1 & mask); */
+            index = L_deposit_l(add(shl(((Word16) (pos2 & mask)), N), ((Word16) (pos1 & mask))));       logic16();logic16();
+            test();logic16();
+            if ((pos2 & NB_POS) != 0)
+            {
+                tmp = shl(N, 1);           /* index += 1 << (2*N); */
+                index = L_add(index, L_shl(1L, tmp));
+            }
+        } else
+        {
+            /* index = ((pos1 & mask) << N) + (pos2 & mask);     */
+            index = L_deposit_l(add(shl(((Word16) (pos1 & mask)), N), ((Word16) (pos2 & mask))));       logic16();logic16();
+            test();logic16();
+            if ((pos1 & NB_POS) != 0)
+            {
+                tmp = shl(N, 1);
+                index = L_add(index, L_shl(1, tmp));    /* index += 1 << (2*N); */
+            }
+        }
+    }
+    return (index);
+}
+
+void dec_2p_2N1(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 pos1, pos2, tmp;
+    Word32 mask, i;
+
+    mask = L_deposit_l(sub(shl(1, N), 1)); /* mask = ((1<<N)-1); */
+    /*-------------------------------------------------------*
+     * Decode 2 pulses with 2*N+1 bits:                      *
+     *-------------------------------------------------------*/
+    /* pos1 = (((index >> N) & mask) + offset); */
+    pos1 = extract_l(L_add((L_shr(index, N) & mask), L_deposit_l(offset)));     logic16();
+    tmp = shl(N, 1);
+    i = (L_shr(index, tmp) & 1L);          logic16();/* i = (index >> (2*N)) & 1; */
+    pos2 = add(extract_l(index & mask), offset);        logic16();/* pos2 = ((index & mask) + offset); */
+    test();
+    if (sub(pos2, pos1) < 0)               /* ((pos2 - pos1) < 0) */
+    {
+        test();
+        if (L_sub(i, 1L) == 0)
+        {                                  /* (i == 1) */
+            pos1 = add(pos1, NB_POS);      /* pos1 += NB_POS; */
+        } else
+        {
+            pos2 = add(pos2, NB_POS);      /* pos2 += NB_POS;    */
+        }
+    } else
+    {
+        test();
+        if (L_sub(i, 1L) == 0)
+        {                                  /* (i == 1) */
+            pos1 = add(pos1, NB_POS);      /* pos1 += NB_POS; */
+            pos2 = add(pos2, NB_POS);      /* pos2 += NB_POS; */
+        }
+    }
+
+    pos[0] = pos1;                         move16();
+    pos[1] = pos2;                         move16();
+
+    return;
+}
+
+
+Word32 quant_3p_3N1(                       /* (o) return (3*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 pos3,                          /* (i) position of the pulse 3     */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 nb_pos;
+    Word32 index;
+
+    nb_pos = shl(1, sub(N, 1));            /* nb_pos = (1<<(N-1)); */
+    /*-------------------------------------------------------*
+     * Quantization of 3 pulses with 3*N+1 bits:             *
+     *-------------------------------------------------------*/
+    test();test();logic16();logic16();logic16();logic16();
+    if (((pos1 ^ pos2) & nb_pos) == 0)
+    {
+        index = quant_2p_2N1(pos1, pos2, sub(N, 1));    /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
+        /* index += (pos1 & nb_pos) << N; */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos1 & nb_pos)), N));  logic16();
+        /* index += quant_1p_N1(pos3, N) << (2*N); */
+        index = L_add(index, L_shl(quant_1p_N1(pos3, N), shl(N, 1)));
+
+    } else if (((pos1 ^ pos3) & nb_pos) == 0)
+    {
+        index = quant_2p_2N1(pos1, pos3, sub(N, 1));    /* index = quant_2p_2N1(pos1, pos3, (N-1)); */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos1 & nb_pos)), N));  logic16();
+        /* index += (pos1 & nb_pos) << N; */
+        index = L_add(index, L_shl(quant_1p_N1(pos2, N), shl(N, 1)));
+        /* index += quant_1p_N1(pos2, N) <<
+                                                                         * (2*N); */
+    } else
+    {
+        index = quant_2p_2N1(pos2, pos3, sub(N, 1));    /* index = quant_2p_2N1(pos2, pos3, (N-1)); */
+        /* index += (pos2 & nb_pos) << N;            */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos2 & nb_pos)), N));  logic16();
+        /* index += quant_1p_N1(pos1, N) << (2*N);   */
+        index = L_add(index, L_shl(quant_1p_N1(pos1, N), shl(N, 1)));
+    }
+    return (index);
+}
+
+void dec_3p_3N1(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 j, tmp;
+    Word32 mask, idx;
+
+    /*-------------------------------------------------------*
+     * Decode 3 pulses with 3*N+1 bits:                      *
+     *-------------------------------------------------------*/
+    tmp = sub(shl(N, 1), 1);               /* mask = ((1<<((2*N)-1))-1); */
+    mask = L_sub(L_shl(1L, tmp), 1L);
+
+    idx = index & mask;                    logic16();
+    j = offset;
+    tmp = sub(shl(N, 1), 1);
+
+    test();logic16();
+    if ((L_shr(index, tmp) & 1L) != 0L)
+    {                                      /* if (((index >> ((2*N)-1)) & 1) == 1){ */
+        j = add(j, shl(1, sub(N, 1)));     /* j += (1<<(N-1)); */
+    }
+    dec_2p_2N1(idx, (Word16) (N - 1), j, pos);
+
+    mask = sub(shl(1, add(N, 1)), 1);      /* mask = ((1<<(N+1))-1); */
+    tmp = shl(N, 1);                       /* idx = (index >> (2*N)) & mask; */
+    idx = L_shr(index, tmp) & mask;        logic16();
+
+    dec_1p_N1(idx, N, offset, pos + 2);    move16();
+
+    return;
+}
+
+
+Word32 quant_4p_4N1(                       /* (o) return (4*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 pos3,                          /* (i) position of the pulse 3     */
+     Word16 pos4,                          /* (i) position of the pulse 4     */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 nb_pos;
+    Word32 index;
+
+    nb_pos = shl(1, sub(N, 1));            /* nb_pos = (1<<(N-1));  */
+    /*-------------------------------------------------------*
+     * Quantization of 4 pulses with 4*N+1 bits:             *
+     *-------------------------------------------------------*/
+    test();test();logic16();logic16();logic16();logic16();
+    if (((pos1 ^ pos2) & nb_pos) == 0)
+    {
+        index = quant_2p_2N1(pos1, pos2, sub(N, 1));    /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
+        /* index += (pos1 & nb_pos) << N;    */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos1 & nb_pos)), N));  logic16();
+        /* index += quant_2p_2N1(pos3, pos4, N) << (2*N); */
+        index = L_add(index, L_shl(quant_2p_2N1(pos3, pos4, N), shl(N, 1)));
+    } else if (((pos1 ^ pos3) & nb_pos) == 0)
+    {
+        index = quant_2p_2N1(pos1, pos3, sub(N, 1));
+        /* index += (pos1 & nb_pos) << N; */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos1 & nb_pos)), N));  logic16();
+        /* index += quant_2p_2N1(pos2, pos4, N) << (2*N); */
+        index = L_add(index, L_shl(quant_2p_2N1(pos2, pos4, N), shl(N, 1)));
+    } else
+    {
+        index = quant_2p_2N1(pos2, pos3, sub(N, 1));
+        /* index += (pos2 & nb_pos) << N; */
+        index = L_add(index, L_shl(L_deposit_l((Word16) (pos2 & nb_pos)), N));  logic16();
+        /* index += quant_2p_2N1(pos1, pos4, N) << (2*N); */
+        index = L_add(index, L_shl(quant_2p_2N1(pos1, pos4, N), shl(N, 1)));
+    }
+    return (index);
+}
+
+void dec_4p_4N1(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 j, tmp;
+    Word32 mask, idx;
+
+    /*-------------------------------------------------------*
+     * Decode 4 pulses with 4*N+1 bits:                      *
+     *-------------------------------------------------------*/
+    tmp = sub(shl(N, 1), 1);               /* mask = ((1<<((2*N)-1))-1); */
+    mask = L_sub(L_shl(1L, tmp), 1L);
+    idx = index & mask;                    logic16();
+    j = offset;                            move16();
+    tmp = sub(shl(N, 1), 1);
+
+    test();logic16();
+    if ((L_shr(index, tmp) & 1L) != 0L)
+    {                                      /* (((index >> ((2*N)-1)) & 1) == 1) */
+        j = add(j, shl(1, sub(N, 1)));     /* j += (1<<(N-1)); */
+    }
+    dec_2p_2N1(idx, (Word16) (N - 1), j, pos);
+
+
+    tmp = add(shl(N, 1), 1);               /* mask = ((1<<((2*N)+1))-1); */
+    mask = L_sub(L_shl(1L, tmp), 1L);
+    idx = L_shr(index, shl(N, 1)) & mask;  logic16();/* idx = (index >> (2*N)) & mask; */
+    dec_2p_2N1(idx, N, offset, pos + 2);   move16();  /* dec_2p_2N1(idx, N, offset, pos+2); */
+
+    return;
+}
+
+
+Word32 quant_4p_4N(                        /* (o) return 4*N bits             */
+     Word16 pos[],                         /* (i) position of the pulse 1..4  */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 i, j, k, nb_pos, mask, n_1, tmp;
+    Word16 posA[4], posB[4];
+    Word32 index;
+
+    n_1 = (Word16) (N - 1);                move16();
+    nb_pos = shl(1, n_1);                  /* nb_pos = (1<<n_1); */
+    mask = sub(shl(1, N), 1);              /* mask = ((1<<N)-1); */
+
+    i = 0;                                 move16();
+    j = 0;                                 move16();
+    for (k = 0; k < 4; k++)
+    {
+        test();logic16();
+        if ((pos[k] & nb_pos) == 0)
+        {
+            posA[i++] = pos[k];            move16();
+        } else
+        {
+            posB[j++] = pos[k];            move16();
+        }
+    }
+
+    switch (i)
+    {
+    case 0:
+        tmp = sub(shl(N, 2), 3);           /* index = 1 << ((4*N)-3); */
+        index = L_shl(1L, tmp);
+        /* index += quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1); */
+        index = L_add(index, quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1));
+        break;
+    case 1:
+        /* index = quant_1p_N1(posA[0], n_1) << ((3*n_1)+1); */
+        tmp = add(extract_l(L_shr(L_mult(3, n_1), 1)), 1);
+        index = L_shl(quant_1p_N1(posA[0], n_1), tmp);
+        /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
+        index = L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
+        break;
+    case 2:
+        tmp = add(shl(n_1, 1), 1);         /* index = quant_2p_2N1(posA[0], posA[1], n_1) << ((2*n_1)+1); */
+        index = L_shl(quant_2p_2N1(posA[0], posA[1], n_1), tmp);
+        /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
+        index = L_add(index, quant_2p_2N1(posB[0], posB[1], n_1));
+        break;
+    case 3:
+        /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N; */
+        index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), N);
+        index = L_add(index, quant_1p_N1(posB[0], n_1));        /* index += quant_1p_N1(posB[0], n_1); */
+        break;
+    case 4:
+        index = quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1);
+        break;
+    default:
+        index = 0;
+        fprintf(stderr, "Error in function quant_4p_4N\n");
+    }
+    tmp = sub(shl(N, 2), 2);               /* index += (i & 3) << ((4*N)-2); */
+    index = L_add(index, L_shl((L_deposit_l(i) & (3L)), tmp));  logic16();
+
+    return (index);
+}
+
+void dec_4p_4N(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 j, n_1, tmp;
+
+    /*-------------------------------------------------------*
+     * Decode 4 pulses with 4*N bits:                        *
+     *-------------------------------------------------------*/
+
+    n_1 = (Word16) (N - 1);                move16();
+    j = add(offset, shl(1, n_1));          /* j = offset + (1 << n_1); */
+
+    tmp = sub(shl(N, 2), 2);
+    test();logic16();
+    switch (L_shr(index, tmp) & 3)
+    {                                      /* ((index >> ((4*N)-2)) & 3) */
+    case 0:
+        tmp = add(shl(n_1, 2), 1);
+
+        test();logic16();
+        if ((L_shr(index, tmp) & 1) == 0)
+        {                                  /* (((index >> ((4*n_1)+1)) & 1) == 0) */
+            dec_4p_4N1(index, n_1, offset, pos);
+        } else
+        {
+            dec_4p_4N1(index, n_1, j, pos);
+        }
+        break;
+    case 1:
+        tmp = add(extract_l(L_shr(L_mult(3, n_1), 1)), 1); /* dec_1p_N1((index>>((3*n_1)+1)), n_1, offset, pos) */
+        dec_1p_N1(L_shr(index, tmp), n_1, offset, pos);
+        dec_3p_3N1(index, n_1, j, pos + 1);move16();
+        break;
+    case 2:
+        tmp = add(shl(n_1, 1), 1);         /* dec_2p_2N1((index>>((2*n_1)+1)), n_1, offset, pos); */
+        dec_2p_2N1(L_shr(index, tmp), n_1, offset, pos);
+        dec_2p_2N1(index, n_1, j, pos + 2);move16();
+        break;
+    case 3:
+        tmp = add(n_1, 1);                 /* dec_3p_3N1((index>>(n_1+1)), n_1, offset, pos); */
+        dec_3p_3N1(L_shr(index, tmp), n_1, offset, pos);
+        dec_1p_N1(index, n_1, j, pos + 3); move16();
+        break;
+    }
+    return;
+}
+
+
+Word32 quant_5p_5N(                        /* (o) return 5*N bits             */
+     Word16 pos[],                         /* (i) position of the pulse 1..5  */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 i, j, k, nb_pos, n_1, tmp;
+    Word16 posA[5], posB[5];
+    Word32 index, tmp2;
+
+    n_1 = (Word16) (N - 1);                move16();
+    nb_pos = shl(1, n_1);                  /* nb_pos = (1<<n_1); */
+
+    i = 0;                                 move16();
+    j = 0;                                 move16();
+    for (k = 0; k < 5; k++)
+    {
+        test();logic16();
+        if ((pos[k] & nb_pos) == 0)
+        {
+            posA[i++] = pos[k];            move16();
+        } else
+        {
+            posB[j++] = pos[k];            move16();
+        }
+    }
+
+    switch (i)
+    {
+    case 0:
+        tmp = sub(extract_l(L_shr(L_mult(5, N), 1)), 1);        /* ((5*N)-1)) */
+        index = L_shl(1L, tmp);   /* index = 1 << ((5*N)-1); */
+        tmp = add(shl(N, 1), 1);  /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2*N)+1);*/
+        tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+        index = L_add(index, tmp2);
+        index = L_add(index, quant_2p_2N1(posB[3], posB[4], N));        /* index += quant_2p_2N1(posB[3], posB[4], N); */
+        break;
+    case 1:
+        tmp = sub(extract_l(L_shr(L_mult(5, N), 1)), 1);        /* index = 1 << ((5*N)-1); */
+        index = L_shl(1L, tmp);
+        tmp = add(shl(N, 1), 1);   /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) <<((2*N)+1);  */
+        tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+        index = L_add(index, tmp2);
+        index = L_add(index, quant_2p_2N1(posB[3], posA[0], N));        /* index += quant_2p_2N1(posB[3], posA[0], N); */
+        break;
+    case 2:
+        tmp = sub(extract_l(L_shr(L_mult(5, N), 1)), 1);        /* ((5*N)-1)) */
+        index = L_shl(1L, tmp);            /* index = 1 << ((5*N)-1); */
+        tmp = add(shl(N, 1), 1);           /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1) << ((2*N)+1);  */
+        tmp2 = L_shl(quant_3p_3N1(posB[0], posB[1], posB[2], n_1), tmp);
+        index = L_add(index, tmp2);
+        index = L_add(index, quant_2p_2N1(posA[0], posA[1], N));        /* index += quant_2p_2N1(posA[0], posA[1], N); */
+        break;
+    case 3:
+        tmp = add(shl(N, 1), 1);           /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1);  */
+        index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+        index = L_add(index, quant_2p_2N1(posB[0], posB[1], N));        /* index += quant_2p_2N1(posB[0], posB[1], N); */
+        break;
+    case 4:
+        tmp = add(shl(N, 1), 1);           /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1);  */
+        index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+        index = L_add(index, quant_2p_2N1(posA[3], posB[0], N));        /* index += quant_2p_2N1(posA[3], posB[0], N); */
+        break;
+    case 5:
+        tmp = add(shl(N, 1), 1);           /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((2*N)+1);  */
+        index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), tmp);
+        index = L_add(index, quant_2p_2N1(posA[3], posA[4], N));        /* index += quant_2p_2N1(posA[3], posA[4], N); */
+        break;
+    default:
+        index = 0;
+        fprintf(stderr, "Error in function quant_5p_5N\n");
+    }
+
+    return (index);
+}
+
+void dec_5p_5N(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 j, n_1, tmp;
+    Word32 idx;
+
+    /*-------------------------------------------------------*
+     * Decode 5 pulses with 5*N bits:                        *
+     *-------------------------------------------------------*/
+
+    n_1 = (Word16) (N - 1);                move16();
+    j = add(offset, shl(1, n_1));          /* j = offset + (1 << n_1); */
+    tmp = add(shl(N, 1), 1);               /* idx = (index >> ((2*N)+1)); */
+    idx = L_shr(index, tmp);
+    tmp = sub(extract_l(L_shr(L_mult(5, N), 1)), 1);    /* ((5*N)-1)) */
+
+    test();logic16();
+    if ((L_shr(index, tmp) & 1) == 0)      /* ((index >> ((5*N)-1)) & 1)  */
+    {
+        dec_3p_3N1(idx, n_1, offset, pos);
+        dec_2p_2N1(index, N, offset, pos + 3);  move16();
+    } else
+    {
+        dec_3p_3N1(idx, n_1, j, pos);
+        dec_2p_2N1(index, N, offset, pos + 3);  move16();
+    }
+    return;
+}
+
+
+Word32 quant_6p_6N_2(                      /* (o) return (6*N)-2 bits         */
+     Word16 pos[],                         /* (i) position of the pulse 1..6  */
+     Word16 N)                             /* (i) number of bits for position */
+{
+    Word16 i, j, k, nb_pos, n_1;
+    Word16 posA[6], posB[6];
+    Word32 index;
+
+    /* !!  N and n_1 are constants -> it doesn't need to be operated by Basic Operators */
+
+    n_1 = (Word16) (N - 1);                move16();
+    nb_pos = shl(1, n_1);                  /* nb_pos = (1<<n_1); */
+
+    i = 0;                                 move16();
+    j = 0;                                 move16();
+    for (k = 0; k < 6; k++)
+    {
+        test();logic16();
+        if ((pos[k] & nb_pos) == 0)
+        {
+            posA[i++] = pos[k];            move16();
+        } else
+        {
+            posB[j++] = pos[k];            move16();
+        }
+    }
+
+    switch (i)
+    {
+    case 0:
+        index = L_shl(1L, (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
+        index = L_add(index, L_shl(quant_5p_5N(posB, n_1), N)); /* index += quant_5p_5N(posB, n_1) << N; */
+        index = L_add(index, quant_1p_N1(posB[5], n_1));        /* index += quant_1p_N1(posB[5], n_1); */
+        break;
+    case 1:
+        index = L_shl(1L, (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
+        index = L_add(index, L_shl(quant_5p_5N(posB, n_1), N)); /* index += quant_5p_5N(posB, n_1) << N; */
+        index = L_add(index, quant_1p_N1(posA[0], n_1));        /* index += quant_1p_N1(posA[0], n_1); */
+        break;
+    case 2:
+        index = L_shl(1L, (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
+        /* index += quant_4p_4N(posB, n_1) << ((2*n_1)+1); */
+        index = L_add(index, L_shl(quant_4p_4N(posB, n_1), (Word16) (2 * n_1 + 1)));
+        index = L_add(index, quant_2p_2N1(posA[0], posA[1], n_1));      /* index += quant_2p_2N1(posA[0], posA[1], n_1); */
+        break;
+    case 3:
+        index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), (Word16) (3 * n_1 + 1));    /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((3*n_1)+1); */
+        index = L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));     /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
+        break;
+    case 4:
+        i = 2;                             move16();
+        index = L_shl(quant_4p_4N(posA, n_1), (Word16) (2 * n_1 + 1));  /* index = quant_4p_4N(posA, n_1) << ((2*n_1)+1); */
+        index = L_add(index, quant_2p_2N1(posB[0], posB[1], n_1));      /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
+        break;
+    case 5:
+        i = 1;                             move16();
+        index = L_shl(quant_5p_5N(posA, n_1), N);       /* index = quant_5p_5N(posA, n_1) << N; */
+        index = L_add(index, quant_1p_N1(posB[0], n_1));        /* index += quant_1p_N1(posB[0], n_1); */
+        break;
+    case 6:
+        i = 0;                             move16();
+        index = L_shl(quant_5p_5N(posA, n_1), N);       /* index = quant_5p_5N(posA, n_1) << N; */
+        index = L_add(index, quant_1p_N1(posA[5], n_1));        /* index += quant_1p_N1(posA[5], n_1); */
+        break;
+    default:
+        index = 0;
+        fprintf(stderr, "Error in function quant_6p_6N_2\n");
+    }
+    index = L_add(index, L_shl((L_deposit_l(i) & 3L), (Word16) (6 * N - 4)));   logic16();/* index += (i & 3) << ((6*N)-4); */
+
+    return (index);
+}
+
+void dec_6p_6N_2(Word32 index, Word16 N, Word16 offset, Word16 pos[])
+{
+    Word16 j, n_1, offsetA, offsetB;
+
+    n_1 = (Word16) (N - 1);                move16();
+    j = add(offset, shl(1, n_1));          /* j = offset + (1 << n_1); */
+
+
+    /* !!  N and n_1 are constants -> it doesn't need to be operated by Basic Operators */
+
+    offsetA = offsetB = j;                 move16();move16();
+    test();logic16();
+    if ((L_shr(index, (Word16) (6 * N - 5)) & 1L) == 0)
+    {                                      /* if (((index >> ((6*N)-5)) & 1) == 0) */
+        offsetA = offset;                  move16();
+    } else
+    {
+        offsetB = offset;                  move16();
+    }
+
+    test();logic16();
+    switch (L_shr(index, (Word16) (6 * N - 4)) & 3)
+    {                                      /* (index >> ((6*N)-4)) & 3 */
+    case 0:
+        dec_5p_5N(L_shr(index, N), n_1, offsetA, pos);  /* dec_5p_5N(index>>N, n_1, offsetA, pos); */
+        dec_1p_N1(index, n_1, offsetA, pos + 5);        move16();
+        break;
+    case 1:
+        dec_5p_5N(L_shr(index, N), n_1, offsetA, pos);  /* dec_5p_5N(index>>N, n_1, offsetA, pos); */
+        dec_1p_N1(index, n_1, offsetB, pos + 5);        move16();
+        break;
+    case 2:
+        dec_4p_4N(L_shr(index, (Word16) (2 * n_1 + 1)), n_1, offsetA, pos); /* dec_4p_4N(index>>((2*n_1)+1 ), n_1, offsetA, pos); */
+        dec_2p_2N1(index, n_1, offsetB, pos + 4);       move16();
+        break;
+    case 3:
+        dec_3p_3N1(L_shr(index, (Word16) (3 * n_1 + 1)), n_1, offset, pos); /* dec_3p_3N1(index>>((3*n_1)+ 1), n_1, offset, pos); */
+        dec_3p_3N1(index, n_1, j, pos + 3);move16();
+        break;
+    }
+    return;
+}
--- /dev/null
+++ b/amr-wb/q_pulse.h
@@ -1,0 +1,50 @@
+/*--------------------------------------------------------------------------*
+ *                         Q_PULSE.H                                        *
+ *--------------------------------------------------------------------------*
+ * Coding and decoding of algebraic codebook                                *
+ *--------------------------------------------------------------------------*/
+
+#include "typedef.h"
+
+Word32 quant_1p_N1(                        /* (o) return (N+1) bits           */
+     Word16 pos,                           /* (i) position of the pulse       */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_2p_2N1(                       /* (o) return (2*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_3p_3N1(                       /* (o) return (3*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 pos3,                          /* (i) position of the pulse 3     */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_4p_4N1(                       /* (o) return (4*N)+1 bits         */
+     Word16 pos1,                          /* (i) position of the pulse 1     */
+     Word16 pos2,                          /* (i) position of the pulse 2     */
+     Word16 pos3,                          /* (i) position of the pulse 3     */
+     Word16 pos4,                          /* (i) position of the pulse 4     */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_4p_4N(                        /* (o) return 4*N bits             */
+     Word16 pos[],                         /* (i) position of the pulse 1..4  */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_5p_5N(                        /* (o) return 5*N bits             */
+     Word16 pos[],                         /* (i) position of the pulse 1..5  */
+     Word16 N);                            /* (i) number of bits for position */
+
+Word32 quant_6p_6N_2(                      /* (o) return (6*N)-2 bits         */
+     Word16 pos[],                         /* (i) position of the pulse 1..6  */
+     Word16 N);                            /* (i) number of bits for position */
+
+
+void dec_1p_N1(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_2p_2N1(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_3p_3N1(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_4p_4N1(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_4p_4N(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_5p_5N(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
+void dec_6p_6N_2(Word32 index, Word16 N, Word16 offset, Word16 pos[]);
--- /dev/null
+++ b/amr-wb/qisf_ns.c
@@ -1,0 +1,95 @@
+/*-------------------------------------------------------------------*
+ *                         QISF_NS.C                                 *
+ *-------------------------------------------------------------------*
+ *                                                                   *
+ * Coding/Decoding of ISF parameters for background noise.           *
+ *                                                                   *
+ * The ISF vector is quantized using VQ with split-by-5              *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "acelp.h"
+#include "count.h"
+
+#include "qisf_ns.tab"                     /* Codebooks of ISFs */
+
+/*------------------------------------------------------------------*
+ * routine:   Qisf_ns()                                             *
+ *            ~~~~~~~~~                                             *
+ *------------------------------------------------------------------*/
+
+void Qisf_ns(
+     Word16 * isf1,                        /* input : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* output: quantized ISF                        */
+     Word16 * indice                       /* output: quantization indices                 */
+)
+{
+    Word16 i;
+    Word32 tmp;
+
+    for (i = 0; i < ORDER; i++)
+    {
+        isf_q[i] = sub(isf1[i], mean_isf_noise[i]);     move16();
+    }
+
+    indice[0] = Sub_VQ(&isf_q[0], dico1_isf_noise, 2, SIZE_BK_NOISE1, &tmp);    move16();
+    indice[1] = Sub_VQ(&isf_q[2], dico2_isf_noise, 3, SIZE_BK_NOISE2, &tmp);    move16();
+    indice[2] = Sub_VQ(&isf_q[5], dico3_isf_noise, 3, SIZE_BK_NOISE3, &tmp);    move16();
+    indice[3] = Sub_VQ(&isf_q[8], dico4_isf_noise, 4, SIZE_BK_NOISE4, &tmp);    move16();
+    indice[4] = Sub_VQ(&isf_q[12], dico5_isf_noise, 4, SIZE_BK_NOISE5, &tmp);   move16();
+
+    /* decoding the ISFs */
+
+    Disf_ns(indice, isf_q);
+
+    return;
+}
+
+/*-------------------------------------------------------------------*
+ * routine:   Disf_ns()                                              *
+ *            ~~~~~~~~~                                              *
+ * Decoding of ISF parameters                                        *
+ *-------------------------------------------------------------------*
+ *  Arguments:                                                       *
+ *    indice[] : indices of the selected codebook entries            *
+ *    isf[]    : quantized ISFs (in frequency domain)                *
+ *-------------------------------------------------------------------*/
+
+void Disf_ns(
+     Word16 * indice,                      /* input:  quantization indices                  */
+     Word16 * isf_q                        /* input : ISF in the frequency domain (0..0.5)  */
+)
+{
+    Word16 i;
+
+    for (i = 0; i < 2; i++)
+    {
+        isf_q[i] = dico1_isf_noise[indice[0] * 2 + i];  move16();
+    }
+    for (i = 0; i < 3; i++)
+    {
+        isf_q[i + 2] = dico2_isf_noise[indice[1] * 3 + i];      move16();
+    }
+    for (i = 0; i < 3; i++)
+    {
+        isf_q[i + 5] = dico3_isf_noise[indice[2] * 3 + i];      move16();
+    }
+    for (i = 0; i < 4; i++)
+    {
+        isf_q[i + 8] = dico4_isf_noise[indice[3] * 4 + i];      move16();
+    }
+    for (i = 0; i < 4; i++)
+    {
+        isf_q[i + 12] = dico5_isf_noise[indice[4] * 4 + i];     move16();
+    }
+
+    for (i = 0; i < ORDER; i++)
+    {
+        isf_q[i] = add(isf_q[i], mean_isf_noise[i]);    move16();
+    }
+
+    Reorder_isf(isf_q, ISF_GAP, ORDER);
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/qisf_ns.tab
@@ -1,0 +1,329 @@
+/*-------------------------------------------------------------------*
+ *                         qisf_ns.h
+ *-------------------------------------------------------------------*
+ * Quantization tables for split by 5 VQ of ISFs for a background noise database
+ * Version whith no prediction
+ *-------------------------------------------------------------------*/
+
+#define ORDER   16            /* order of linear prediction filter */
+#define ISF_GAP 128
+
+#define SIZE_BK_NOISE1  64
+#define SIZE_BK_NOISE2  64
+#define SIZE_BK_NOISE3  64
+#define SIZE_BK_NOISE4  32
+#define SIZE_BK_NOISE5  32
+
+
+/* means of ISFs */
+ static Word16 mean_isf_noise[ORDER] = {
+
+   478,  1100,  2213,  3267,  4219,  5222,  6198,  7240,
+  8229,  9153, 10098, 11108, 12144, 13184, 14165,  3803};
+
+
+/* 28 bits */
+/*-------------------------------------------------------------------*
+ *  isf codebooks:  split-by-5 VQ                                    *
+ *                                                                   *
+ *  codebook   vector dimension    number of vectors                 *
+ *  ~~~~~~~~   ~~~~~~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~                 *
+ *     1            2                  64                            *
+ *     2            3                  64                            *
+ *     3            3                  64                            *
+ *     4            4                  32                            *
+ *     5            4                  32                            *
+ *-------------------------------------------------------------------*/
+
+/*------------------------------------------------*
+ * 1st split:   isf0 to isf1
+ *------------------------------------------------*/
+
+
+ static Word16 dico1_isf_noise[SIZE_BK_NOISE1*2] = {
+
+  -269,  -673,
+  -222,  -537,
+  -233,  -430,
+  -138,  -451,
+  -212,  -331,
+  -192,  -241,
+   -87,  -231,
+  -191,  -128,
+   -70,  -106,
+  -164,    -6,
+    74,  -179,
+    27,   -33,
+  -102,    74,
+  -162,   115,
+   -94,   172,
+    -6,   130,
+  -143,   234,
+    14,   218,
+   -65,   270,
+    88,   182,
+  -124,   341,
+   -44,   381,
+    38,   335,
+   117,   274,
+  -112,   454,
+    74,   431,
+    -5,   488,
+   175,   384,
+   -83,   561,
+   122,   529,
+    21,   601,
+   229,   481,
+   231,   303,
+   226,   608,
+   300,   372,
+   210,   187,
+   306,   265,
+   328,   473,
+   382,   331,
+   371,   132,
+   139,    58,
+   365,    21,
+   250,   -82,
+   443,   218,
+   483,   110,
+   426,   415,
+   579,   222,
+   518,   333,
+   573,   448,
+   455,   529,
+   685,   329,
+   332,   580,
+   595,   593,
+   468,   645,
+   762,   517,
+   326,   709,
+   485,   793,
+   130,   684,
+   671,   737,
+   354,   876,
+    88,   806,
+   -65,   706,
+   -35,  1016,
+   266,  1123};
+
+
+/*------------------------------------------------*
+ * 2nd split:   isf2 to isf4
+ *------------------------------------------------*/
+
+ static Word16 dico2_isf_noise[SIZE_BK_NOISE2*3] = {
+
+  -824,  -884,  -949,
+  -805,  -456,  -418,
+  -442,  -438,  -541,
+  -217,  -578,  -793,
+  -168,  -444,  -582,
+  -287,  -492,  -274,
+  -552,  -297,  -300,
+  -163,  -333,  -358,
+  -370,  -232,  -232,
+  -175,  -358,  -159,
+  -381,   -21,  -357,
+  -184,  -159,  -162,
+   -53,  -191,  -280,
+    18,  -267,  -215,
+  -138,    61,  -283,
+    71,   -95,  -294,
+    13,  -156,  -546,
+     0,   -83,   -79,
+    44,    97,  -316,
+   178,   -52,  -213,
+   222,  -261,  -422,
+   237,  -118,   -44,
+   141,   145,  -132,
+   363,    81,  -287,
+   213,    65,    34,
+  -107,    94,    -5,
+    91,   -29,   126,
+  -355,    51,   -41,
+  -219,   -76,   145,
+   -63,   100,   244,
+  -719,    44,    27,
+  -572,  -124,   155,
+  -423,   133,   315,
+  -917,    71,   224,
+  -268,   318,   131,
+   -93,  -190,   420,
+   -97,   122,   491,
+   -79,   317,   355,
+   130,   100,   325,
+    86,  -293,   210,
+   133,   258,   161,
+   176,   -73,   465,
+   195,   300,   384,
+   348,    22,   221,
+   376,   183,   409,
+   377,   286,   202,
+   242,   213,   659,
+   257,   565,   248,
+   344,   408,   -76,
+   405,   440,   509,
+   612,   385,   379,
+   536,   607,   216,
+   -56,   582,   192,
+   100,   517,   567,
+  -365,   448,   445,
+   728,   347,    10,
+   505,   357,   759,
+   636,   582,   658,
+   335,   517,   852,
+   378,   809,   572,
+  -195,   878,   829,
+   529,   707,   987,
+   918,   726,   392,
+  1250,   997,  1063};
+
+/*------------------------------------------------*
+ * 3rd split:   isf5 to isf7
+ *------------------------------------------------*/
+
+ static Word16 dico3_isf_noise[SIZE_BK_NOISE3*3] = {
+
+  -805,  -838,  -774,
+  -522,  -627,  -828,
+  -477,  -486,  -603,
+  -295,  -481,  -634,
+  -366,  -384,  -393,
+  -186,  -414,  -396,
+  -237,  -394,  -106,
+  -252,  -202,  -275,
+   -61,  -177,  -442,
+   -84,  -198,  -199,
+  -179,  -125,   -31,
+   -72,   -47,  -163,
+  -298,  -220,   215,
+   -64,  -168,   251,
+  -133,   156,   -59,
+   -30,    -2,   127,
+    54,    66,   -61,
+  -233,    21,   251,
+   209,   -50,    32,
+    33,   194,   136,
+  -117,   -18,   475,
+   202,    46,   309,
+   256,   185,    53,
+    35,   200,   390,
+   200,   263,   242,
+  -216,   302,   294,
+   128,   358,     0,
+    19,   431,   287,
+   224,   447,   280,
+   367,   165,   213,
+   397,   314,   319,
+   383,   379,    75,
+   277,   325,   462,
+   394,   505,   334,
+   251,    98,  -213,
+   450,   153,   448,
+   565,   226,    76,
+   470,   383,   502,
+   635,   390,   278,
+   237,   135,   620,
+   342,   401,   649,
+   331,   551,   518,
+   130,   418,   592,
+   531,   306,   737,
+   729,   389,   580,
+   497,   557,   699,
+   296,   383,   874,
+   283,   624,   759,
+   126,   622,   476,
+   559,   595,   472,
+   382,   770,   616,
+   719,   613,   745,
+   540,   639,   928,
+   517,   826,   801,
+   684,   811,   604,
+   752,   786,   857,
+   933,   661,   350,
+   694,   450,  1061,
+   562,   911,  1051,
+   824,   813,  1104,
+   758,  1047,   882,
+  1140,   917,   889,
+  1039,  1246,  1426,
+  1483,  1666,  1876};
+
+/*------------------------------------------------*
+ * 4th split:   isf8 to isf11
+ *------------------------------------------------*/
+
+ static Word16 dico4_isf_noise[SIZE_BK_NOISE4*4] = {
+
+  -776,  -854,  -891,  -920,
+  -552,  -610,  -663,  -741,
+  -321,  -370,  -476,  -565,
+   274,  -160,  -456,   201,
+   265,    67,  -160,  -306,
+    -8,  -210,    79,   272,
+   163,   236,   307,   308,
+   578,   317,    64,   298,
+    -9,   197,   342,   620,
+   343,   232,   314,   622,
+   173,   149,   548,   527,
+   356,   370,   481,   376,
+   135,   444,   488,   556,
+   391,   471,   487,   653,
+   228,   424,   576,   835,
+   422,   372,   722,   682,
+   295,   673,   693,   635,
+   539,   596,   590,   449,
+   475,   618,   659,   818,
+   735,   517,   491,   673,
+   602,   346,   257,   877,
+   625,   635,   849,   720,
+   727,   818,   698,   595,
+   653,   481,   690,  1139,
+   814,   762,   704,   908,
+   507,   747,   898,   936,
+   848,   855,   924,   785,
+   646,  1037,   882,   795,
+   772,   845,  1024,  1151,
+  1133,   983,   818,   921,
+   940,  1068,  1252,  1302,
+  1588,  1767,  1718,  1513};
+
+/*------------------------------------------------*
+ * 5th split:   isf12 to isf15
+ *------------------------------------------------*/
+
+ static Word16 dico5_isf_noise[SIZE_BK_NOISE5*4] = {
+  -810,  -879,  -945,  -254,
+   248,   184,   671,   128,
+   288,   703,   918,    99,
+   658,   558,   662,   219,
+   552,   585,   910,   208,
+   559,   804,   759,   119,
+   606,   774,   921,  -139,
+   782,   761,   748,   208,
+   756,   708,   983,    56,
+   544,   864,  1010,   152,
+   737,   698,   987,   299,
+   771,   924,   879,   103,
+   536,   785,   961,   405,
+   667,   916,   801,   328,
+   738,   705,   773,   439,
+   823,   871,   992,   355,
+   640,  1004,  1052,   369,
+   724,   822,   949,   597,
+   415,   655,   729,   482,
+  1009,   896,   793,   363,
+   908,   803,   687,   -25,
+  1016,   838,  1011,   189,
+   947,  1112,   942,   222,
+   914,  1049,   981,   527,
+   956,   987,  1011,  -120,
+   781,  1049,  1121,    92,
+  1178,  1053,   884,    47,
+  1123,  1059,  1182,   118,
+   933,   972,  1277,   357,
+  1109,   918,  1101,   503,
+  1039,  1286,  1220,   317,
+  1351,  1207,  1010,   326};
+
--- /dev/null
+++ b/amr-wb/qpisf_2s.c
@@ -1,0 +1,554 @@
+/*-------------------------------------------------------------------*
+ *                         QPISF_2S.C                                *
+ *-------------------------------------------------------------------*
+ * Coding/Decoding of ISF parameters  with prediction.               *
+ *                                                                   *
+ * The ISF vector is quantized using two-stage VQ with split-by-2    *
+ * in 1st stage and split-by-5 (or 3)in the second stage.            *
+ *-------------------------------------------------------------------*/
+
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "cnst.h"
+#include "acelp.h"
+#include "count.h"
+
+#include "qpisf_2s.tab"                    /* Codebooks of isfs */
+
+#define MU         10923                   /* Prediction factor   (1.0/3.0) in Q15 */
+#define N_SURV_MAX 4                       /* 4 survivors max */
+#define ALPHA      29491                   /* 0. 9 in Q15     */
+#define ONE_ALPHA (32768-ALPHA)            /* (1.0 - ALPHA) in Q15 */
+
+/* local functions */
+
+static void VQ_stage1(
+     Word16 * x,                           /* input : ISF residual vector           */
+     Word16 * dico,                        /* input : quantization codebook         */
+     Word16 dim,                           /* input : dimention of vector           */
+     Word16 dico_size,                     /* input : size of quantization codebook */
+     Word16 * index,                       /* output: indices of survivors          */
+     Word16 surv                           /* input : number of survivor            */
+);
+
+/*-------------------------------------------------------------------*
+ * Function   Qpisf_2s_46B()                                         *
+ *            ~~~~~~~~~                                              *
+ * Quantization of isf parameters with prediction. (46 bits)         *
+ *                                                                   *
+ * The isf vector is quantized using two-stage VQ with split-by-2 in *
+ *  1st stage and split-by-5 in the second stage.                    *
+ *-------------------------------------------------------------------*/
+
+
+void Qpisf_2s_46b(
+     Word16 * isf1,                        /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* (o) Q15 : quantized ISF               (0..0.5) */
+     Word16 * past_isfq,                   /* (io)Q15 : past ISF quantizer                   */
+     Word16 * indice,                      /* (o)     : quantization indices                 */
+     Word16 nb_surv                        /* (i)     : number of survivor (1, 2, 3 or 4)    */
+)
+{
+    Word16 i, k, tmp_ind[5];
+    Word16 surv1[N_SURV_MAX];              /* indices of survivors from 1st stage */
+    Word32 temp, min_err, distance;
+    Word16 isf[ORDER];
+    Word16 isf_stage2[ORDER];
+
+
+    for (i = 0; i < ORDER; i++)
+    {
+        /* isf[i] = isf1[i] - mean_isf[i] - MU*past_isfq[i] */
+        isf[i] = sub(isf1[i], mean_isf[i]);move16();
+        isf[i] = sub(isf[i], mult(MU, past_isfq[i]));   move16();
+    }
+
+    VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
+
+    distance = MAX_32;                     move32();
+
+    for (k = 0; k < nb_surv; k++)
+    {
+        for (i = 0; i < 9; i++)
+        {
+            isf_stage2[i] = sub(isf[i], dico1_isf[i + surv1[k] * 9]);   move16();
+        }
+
+        tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf, 3, SIZE_BK21, &min_err);        move16();
+        temp = min_err;                    move32();
+        tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico22_isf, 3, SIZE_BK22, &min_err);        move16();
+        temp = L_add(temp, min_err);
+        tmp_ind[2] = Sub_VQ(&isf_stage2[6], dico23_isf, 3, SIZE_BK23, &min_err);        move16();
+        temp = L_add(temp, min_err);
+
+        test();
+        if (L_sub(temp, distance) < (Word32) 0)
+        {
+            distance = temp;               move32();
+            indice[0] = surv1[k];          move16();
+            for (i = 0; i < 3; i++)
+            {
+                indice[i + 2] = tmp_ind[i];move16();
+            }
+        }
+    }
+
+
+    VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
+
+    distance = MAX_32;                     move32();
+
+    for (k = 0; k < nb_surv; k++)
+    {
+        for (i = 0; i < 7; i++)
+        {
+            isf_stage2[i] = sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);       move16();
+        }
+
+        tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico24_isf, 3, SIZE_BK24, &min_err);        move16();
+        temp = min_err;                    move32();
+        tmp_ind[1] = Sub_VQ(&isf_stage2[3], dico25_isf, 4, SIZE_BK25, &min_err);        move16();
+        temp = L_add(temp, min_err);
+
+        test();
+        if (L_sub(temp, distance) < (Word32) 0)
+        {
+            distance = temp;               move32();
+            indice[1] = surv1[k];          move16();
+            for (i = 0; i < 2; i++)
+            {
+                indice[i + 5] = tmp_ind[i];move16();
+            }
+        }
+    }
+
+    Dpisf_2s_46b(indice, isf_q, past_isfq, isf_q, isf_q, 0, 0);
+
+    return;
+}
+
+/*-------------------------------------------------------------------*
+ * Function   Qpisf_2s_36B()                                         *
+ *            ~~~~~~~~~                                              *
+ * Quantization of isf parameters with prediction. (36 bits)         *
+ *                                                                   *
+ * The isf vector is quantized using two-stage VQ with split-by-2 in *
+ *  1st stage and split-by-3 in the second stage.                    *
+ *-------------------------------------------------------------------*/
+
+
+void Qpisf_2s_36b(
+     Word16 * isf1,                        /* (i) Q15 : ISF in the frequency domain (0..0.5) */
+     Word16 * isf_q,                       /* (o) Q15 : quantized ISF               (0..0.5) */
+     Word16 * past_isfq,                   /* (io)Q15 : past ISF quantizer                   */
+     Word16 * indice,                      /* (o)     : quantization indices                 */
+     Word16 nb_surv                        /* (i)     : number of survivor (1, 2, 3 or 4)    */
+)
+{
+    Word16 i, k, tmp_ind[5];
+    Word16 surv1[N_SURV_MAX];              /* indices of survivors from 1st stage */
+    Word32 temp, min_err, distance;
+    Word16 isf[ORDER];
+    Word16 isf_stage2[ORDER];
+
+    for (i = 0; i < ORDER; i++)
+    {
+        /* isf[i] = isf1[i] - mean_isf[i] - MU*past_isfq[i] */
+        isf[i] = sub(isf1[i], mean_isf[i]);move16();
+        isf[i] = sub(isf[i], mult(MU, past_isfq[i]));   move16();
+    }
+
+    VQ_stage1(&isf[0], dico1_isf, 9, SIZE_BK1, surv1, nb_surv);
+
+    distance = MAX_32;                     move32();
+
+    for (k = 0; k < nb_surv; k++)
+    {
+        for (i = 0; i < 9; i++)
+        {
+            isf_stage2[i] = sub(isf[i], dico1_isf[i + surv1[k] * 9]);   move16();
+        }
+
+        tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico21_isf_36b, 5, SIZE_BK21_36b, &min_err);        move16();
+        temp = min_err;                    move32();
+        tmp_ind[1] = Sub_VQ(&isf_stage2[5], dico22_isf_36b, 4, SIZE_BK22_36b, &min_err);        move16();
+        temp = L_add(temp, min_err);
+
+        test();
+        if (L_sub(temp, distance) < (Word32) 0)
+        {
+            distance = temp;               move32();
+            indice[0] = surv1[k];          move16();
+            for (i = 0; i < 2; i++)
+            {
+                indice[i + 2] = tmp_ind[i];move16();
+            }
+        }
+    }
+
+
+    VQ_stage1(&isf[9], dico2_isf, 7, SIZE_BK2, surv1, nb_surv);
+
+    distance = MAX_32;                     move32();
+
+    for (k = 0; k < nb_surv; k++)
+    {
+        for (i = 0; i < 7; i++)
+        {
+            isf_stage2[i] = sub(isf[9 + i], dico2_isf[i + surv1[k] * 7]);       move16();
+        }
+
+        tmp_ind[0] = Sub_VQ(&isf_stage2[0], dico23_isf_36b, 7, SIZE_BK23_36b, &min_err);        move16();
+        temp = min_err;                    move32();
+
+        test();
+        if (L_sub(temp, distance) < (Word32) 0)
+        {
+            distance = temp;               move32();
+            indice[1] = surv1[k];          move16();
+            indice[4] = tmp_ind[0];        move16();
+        }
+    }
+
+    Dpisf_2s_36b(indice, isf_q, past_isfq, isf_q, isf_q, 0, 0);
+
+    return;
+}
+
+/*-------------------------------------------------------------------*
+ * routine:   Disf_2s_46b()                                          *
+ *            ~~~~~~~~~                                              *
+ * Decoding of ISF parameters                                        *
+ *-------------------------------------------------------------------*/
+
+void Dpisf_2s_46b(
+     Word16 * indice,                      /* input:  quantization indices                       */
+     Word16 * isf_q,                       /* output: quantized ISF in frequency domain (0..0.5) */
+     Word16 * past_isfq,                   /* i/0   : past ISF quantizer                    */
+     Word16 * isfold,                      /* input : past quantized ISF                    */
+     Word16 * isf_buf,                     /* input : isf buffer                                                        */
+     Word16 bfi,                           /* input : Bad frame indicator                   */
+     Word16 enc_dec
+)
+{
+    Word16 ref_isf[M];
+    Word16 i, j, tmp;
+    Word32 L_tmp;
+
+    test();
+    if (bfi == 0)                          /* Good frame */
+    {
+        for (i = 0; i < 9; i++)
+        {
+            isf_q[i] = dico1_isf[indice[0] * 9 + i];    move16();
+        }
+        for (i = 0; i < 7; i++)
+        {
+            isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];        move16();
+        }
+
+        for (i = 0; i < 3; i++)
+        {
+            isf_q[i] = add(isf_q[i], dico21_isf[indice[2] * 3 + i]);    move16();
+        }
+        for (i = 0; i < 3; i++)
+        {
+            isf_q[i + 3] = add(isf_q[i + 3], dico22_isf[indice[3] * 3 + i]);    move16();
+        }
+        for (i = 0; i < 3; i++)
+        {
+            isf_q[i + 6] = add(isf_q[i + 6], dico23_isf[indice[4] * 3 + i]);    move16();
+        }
+        for (i = 0; i < 3; i++)
+        {
+            isf_q[i + 9] = add(isf_q[i + 9], dico24_isf[indice[5] * 3 + i]);    move16();
+        }
+        for (i = 0; i < 4; i++)
+        {
+            isf_q[i + 12] = add(isf_q[i + 12], dico25_isf[indice[6] * 4 + i]);  move16();
+        }
+
+        for (i = 0; i < ORDER; i++)
+        {
+            tmp = isf_q[i];                move16();
+            isf_q[i] = add(tmp, mean_isf[i]);   move16();
+            isf_q[i] = add(isf_q[i], mult(MU, past_isfq[i]));   move16();
+            past_isfq[i] = tmp;            move16();
+        }
+
+        test();
+        if (enc_dec)
+        {
+            for (i = 0; i < M; i++)
+            {
+                for (j = (L_MEANBUF - 1); j > 0; j--)
+                {
+                    isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];      move16();
+                }
+                isf_buf[i] = isf_q[i];     move16();
+            }
+        }
+    } else
+    {                                      /* bad frame */
+        for (i = 0; i < M; i++)
+        {
+            L_tmp = L_mult(mean_isf[i], 8192);
+            for (j = 0; j < L_MEANBUF; j++)
+            {
+                L_tmp = L_mac(L_tmp, isf_buf[j * M + i], 8192);
+            }
+            ref_isf[i] = round(L_tmp);     move16();
+        }
+
+        /* use the past ISFs slightly shifted towards their mean */
+        for (i = 0; i < ORDER; i++)
+        {
+            isf_q[i] = add(mult(ALPHA, isfold[i]), mult(ONE_ALPHA, ref_isf[i]));        move16();
+        }
+
+        /* estimate past quantized residual to be used in next frame */
+
+        for (i = 0; i < ORDER; i++)
+        {
+            tmp = add(ref_isf[i], mult(past_isfq[i], MU));      /* predicted ISF */
+            past_isfq[i] = sub(isf_q[i], tmp);  move16();
+            past_isfq[i] = shr(past_isfq[i], 1);        move16();  /* past_isfq[i] *= 0.5 */
+        }
+    }
+
+    Reorder_isf(isf_q, ISF_GAP, ORDER);
+
+    return;
+}
+
+/*-------------------------------------------------------------------*
+ * routine:   Disf_2s_36b()                                          *
+ *            ~~~~~~~~~                                              *
+ * Decoding of ISF parameters                                        *
+ *-------------------------------------------------------------------*/
+
+void Dpisf_2s_36b(
+     Word16 * indice,                      /* input:  quantization indices                       */
+     Word16 * isf_q,                       /* output: quantized ISF in frequency domain (0..0.5) */
+     Word16 * past_isfq,                   /* i/0   : past ISF quantizer                    */
+     Word16 * isfold,                      /* input : past quantized ISF                    */
+     Word16 * isf_buf,                     /* input : isf buffer                                                        */
+     Word16 bfi,                           /* input : Bad frame indicator                   */
+     Word16 enc_dec
+)
+{
+    Word16 ref_isf[M];
+    Word16 i, j, tmp;
+    Word32 L_tmp;
+
+    test();
+    if (bfi == 0)                          /* Good frame */
+    {
+        for (i = 0; i < 9; i++)
+        {
+            isf_q[i] = dico1_isf[indice[0] * 9 + i];    move16();
+        }
+        for (i = 0; i < 7; i++)
+        {
+            isf_q[i + 9] = dico2_isf[indice[1] * 7 + i];        move16();
+        }
+
+        for (i = 0; i < 5; i++)
+        {
+            isf_q[i] = add(isf_q[i], dico21_isf_36b[indice[2] * 5 + i]);        move16();
+        }
+        for (i = 0; i < 4; i++)
+        {
+            isf_q[i + 5] = add(isf_q[i + 5], dico22_isf_36b[indice[3] * 4 + i]);        move16();
+        }
+        for (i = 0; i < 7; i++)
+        {
+            isf_q[i + 9] = add(isf_q[i + 9], dico23_isf_36b[indice[4] * 7 + i]);        move16();
+        }
+
+        for (i = 0; i < ORDER; i++)
+        {
+            tmp = isf_q[i];
+            isf_q[i] = add(tmp, mean_isf[i]);   move16();
+            isf_q[i] = add(isf_q[i], mult(MU, past_isfq[i]));   move16();
+            past_isfq[i] = tmp;            move16();
+        }
+
+        test();
+        if (enc_dec)
+        {
+            for (i = 0; i < M; i++)
+            {
+                for (j = (L_MEANBUF - 1); j > 0; j--)
+                {
+                    isf_buf[j * M + i] = isf_buf[(j - 1) * M + i];      move16();
+                }
+                isf_buf[i] = isf_q[i];     move16();
+            }
+        }
+    } else
+    {                                      /* bad frame */
+        for (i = 0; i < M; i++)
+        {
+            L_tmp = L_mult(mean_isf[i], 8192);
+            for (j = 0; j < L_MEANBUF; j++)
+            {
+                L_tmp = L_mac(L_tmp, isf_buf[j * M + i], 8192);
+            }
+
+            ref_isf[i] = round(L_tmp);     move16();
+        }
+
+        /* use the past ISFs slightly shifted towards their mean */
+        for (i = 0; i < ORDER; i++)
+        {
+            isf_q[i] = add(mult(ALPHA, isfold[i]), mult(ONE_ALPHA, ref_isf[i]));        move16();
+        }
+
+        /* estimate past quantized residual to be used in next frame */
+
+        for (i = 0; i < ORDER; i++)
+        {
+            tmp = add(ref_isf[i], mult(past_isfq[i], MU));      /* predicted ISF */
+            past_isfq[i] = sub(isf_q[i], tmp);  move16();
+            past_isfq[i] = shr(past_isfq[i], 1);        move16();  /* past_isfq[i] *= 0.5 */
+        }
+    }
+
+    Reorder_isf(isf_q, ISF_GAP, ORDER);
+
+    return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * procedure  Reorder_isf()                                                 *
+ *            ~~~~~~~~~~~~~                                                 *
+ * To make sure that the  isfs are properly order and to keep a certain     *
+ * minimum distance between consecutive isfs.                               *
+ *--------------------------------------------------------------------------*
+ *    Argument         description                     in/out               *
+ *    ~~~~~~~~         ~~~~~~~~~~~                     ~~~~~~               *
+ *     isf[]           vector of isfs                    i/o                *
+ *     min_dist        minimum required distance         i                  *
+ *     n               LPC order                         i                  *
+ *--------------------------------------------------------------------------*/
+
+void Reorder_isf(
+     Word16 * isf,                         /* (i/o) Q15: ISF in the frequency domain (0..0.5) */
+     Word16 min_dist,                      /* (i) Q15  : minimum distance to keep             */
+     Word16 n                              /* (i)      : number of ISF                        */
+)
+{
+    Word16 i, isf_min;
+
+    isf_min = min_dist;                    move16();
+
+    for (i = 0; i < n - 1; i++)
+    {
+        test();
+        if (sub(isf[i], isf_min) < 0)
+        {
+            isf[i] = isf_min;              move16();
+        }
+        isf_min = add(isf[i], min_dist);
+    }
+
+    return;
+}
+
+
+Word16 Sub_VQ(                             /* output: return quantization index     */
+     Word16 * x,                           /* input : ISF residual vector           */
+     Word16 * dico,                        /* input : quantization codebook         */
+     Word16 dim,                           /* input : dimention of vector           */
+     Word16 dico_size,                     /* input : size of quantization codebook */
+     Word32 * distance                     /* output: error of quantization         */
+)
+{
+    Word16 i, j, index, temp, *p_dico;
+    Word32 dist_min, dist;
+
+    dist_min = MAX_32;                     move32();
+    p_dico = dico;                         move16();
+
+    index = 0;                             move16();
+    for (i = 0; i < dico_size; i++)
+    {
+        dist = 0;                          move32();
+        for (j = 0; j < dim; j++)
+        {
+            temp = sub(x[j], *p_dico++);
+            dist = L_mac(dist, temp, temp);
+        }
+
+        test();
+        if (L_sub(dist, dist_min) < (Word32) 0)
+        {
+            dist_min = dist;               move32();
+            index = i;                     move16();
+        }
+    }
+
+    *distance = dist_min;                  move32();
+
+    /* Reading the selected vector */
+
+    p_dico = &dico[index * dim];           move16();
+    for (j = 0; j < dim; j++)
+    {
+        x[j] = *p_dico++;                  move16();
+    }
+
+    return index;
+}
+
+
+static void VQ_stage1(
+     Word16 * x,                           /* input : ISF residual vector           */
+     Word16 * dico,                        /* input : quantization codebook         */
+     Word16 dim,                           /* input : dimention of vector           */
+     Word16 dico_size,                     /* input : size of quantization codebook */
+     Word16 * index,                       /* output: indices of survivors          */
+     Word16 surv                           /* input : number of survivor            */
+)
+{
+    Word16 i, j, k, l, temp, *p_dico;
+    Word32 dist_min[N_SURV_MAX], dist;
+
+    for (i = 0; i < surv; i++)
+    {
+        dist_min[i] = MAX_32;              move32();
+        index[i] = i;                      move16();
+    }
+    p_dico = dico;                         move16();
+
+    for (i = 0; i < dico_size; i++)
+    {
+        dist = 0;                          move32();
+        for (j = 0; j < dim; j++)
+        {
+            temp = sub(x[j], *p_dico++);
+            dist = L_mac(dist, temp, temp);
+        }
+
+        for (k = 0; k < surv; k++)
+        {
+            test();
+            if (L_sub(dist, dist_min[k]) < (Word32) 0)
+            {
+                for (l = sub(surv, 1); l > k; l--)
+                {
+                    dist_min[l] = dist_min[l - 1];      move32();
+                    index[l] = index[l - 1];    move16();
+                }
+                dist_min[k] = dist;        move32();
+                index[k] = i;              move16();
+                break;
+            }
+        }
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/qpisf_2s.tab
@@ -1,0 +1,1343 @@
+/*-------------------------------------------------------------------*
+ *                         qpisf_2s.h
+ *-------------------------------------------------------------------*
+ * Quantization tables for two-stage of ISFs (split by 2 in 1st stage)
+ * Version whith prediction MU = 0.25
+ *-------------------------------------------------------------------*/
+
+#define ORDER   16            /* order of linear prediction filter */
+#define ISF_GAP 128           /* 50 Hz */
+#define N_SURV  4
+
+#define SIZE_BK1  256
+#define SIZE_BK2  256
+#define SIZE_BK21 64
+#define SIZE_BK22 128
+#define SIZE_BK23 128
+#define SIZE_BK24 32
+#define SIZE_BK25 32
+
+#define SIZE_BK21_36b 128
+#define SIZE_BK22_36b 128
+#define SIZE_BK23_36b 64
+
+/* means of ISFs */
+static Word16 mean_isf[ORDER] = {
+
+   738,  1326,  2336,  3578,  4596,  5662,  6711,  7730,
+  8750,  9753, 10705, 11728, 12833, 13971, 15043,  4037};
+
+/* 46 bits */
+/*-------------------------------------------------------------------*
+ *  isf codebooks:  two-stage VQ with split-by-5 in 2nd stage        *
+ *                                                                   *
+ *  codebook   vector dimension    number of vectors                 *
+ *  ~~~~~~~~   ~~~~~~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~                 *
+ *     1_1            9                  256                         *
+ *     1_2            7                  256                         *
+ *     2_1            3                  64                          *
+ *     2_2            3                  128                         *
+ *     2_3            3                  128                         *
+ *     2_4            3                  32                          *
+ *     2_5            4                  32                          *
+ *-------------------------------------------------------------------*/
+
+/*------------------------------------------------*
+ * 1st stage codebook; 1st split:   isf0 to isf8
+ *------------------------------------------------*/
+
+static Word16 dico1_isf[SIZE_BK1*9] = {
+
+   579,  1081,  1035,   390,     3,  -263,  -198,   -82,    38,
+    18,   -68,   -12,   313,   761,   405,   249,   111,   -76,
+   740,  1263,  1292,  1006,   997,  1019,  1017,   976,   923,
+   -91,   827,   948,   648,   613,   535,   522,   490,   421,
+    41,   -44,  -281,  -472,   652,   534,   193,   135,   -90,
+    41,  -121,  -356,   -60,   663,   307,    61,   -48,  -344,
+   557,   946,  1049,   867,   846,   990,  1112,  1262,  1241,
+  -118,  -204,   328,   512,   870,   793,   610,   402,   186,
+   156,   293,    74,  -338,  -475,  -897,  -594,  -161,  -497,
+   226,   131,  -138,   307,   169,  -271,  -164,  -387,  -624,
+    62,   -32,   -61,  -252,  -541,  -828, -1027,  -523,  -662,
+   102,   -61,   141,   112,  -270,  -251,  -541,    25,  -150,
+     6,  -132,  -356,  -686,   -96,  -322,  -522,   -31,  -326,
+   -36,  -209,  -521,  -229,   307,  -132,    -5,   -99,  -384,
+    60,   -51,  -237,  -668,  -973,  -407,  -708,   -75,  -172,
+    26,  -138,  -266,   111,  -302,    43,  -278,  -356,  -359,
+   570,   822,   496,  -154,  -312,   -92,   137,   279,   371,
+  -146,   368,   409,    68,     6,    77,   167,   202,   162,
+   633,   898,   996,   756,   662,   683,   783,   909,   996,
+  -103,   294,   607,   415,   483,   462,   480,   431,   408,
+  -120,  -338,  -612,  -524,   584,   331,    92,   433,   276,
+  -178,  -293,  -154,   -41,   269,   100,    -9,   213,   160,
+   830,   736,   278,   820,  1254,   686,   712,  1039,   473,
+  -218,  -304,   463,   454,   397,   273,   202,   286,   273,
+  -232,     7,     6,  -388,  -472,  -427,  -378,  -167,  -100,
+  -294,  -183,   134,   -47,   101,   -88,   -84,  -117,    -3,
+    57,    17,  -202,  -634,  -989, -1119,  -533,   176,   -36,
+   120,   -28,    23,   111,  -319,   318,   -22,   -77,   266,
+  -271,  -464,  -434,  -658,  -640,  -385,  -385,   -99,   -69,
+  -198,  -259,  -266,   -44,   -39,  -139,  -137,   171,    66,
+     9,  -145,  -377,  -846, -1000,  -111,  -325,   342,   135,
+   -81,  -286,  -380,   192,   -57,   307,    76,   -24,  -140,
+   677,   702,   247,    56,   249,   141,  -105,  -236,   -99,
+    36,   -39,   -69,   348,   198,   -93,   322,    91,   -72,
+   503,   885,  1508,  1307,  1282,  1172,  1119,  1209,  1061,
+   416,   719,   989,  1227,  1001,  1052,   954,   741,  1044,
+  -127,  -376,  -657,   139,   623,   223,   501,   306,   220,
+  -113,  -384,  -796,   504,   438,    85,   213,   -83,  -194,
+   585,  1132,  1233,  1091,  1247,  1433,  1512,  1448,  1314,
+  -174,  -422,     7,  1155,  1089,  1182,  1003,   945,   806,
+     8,  -126,  -317,  -103,  -351,  -695,   -98,  -268,  -537,
+    33,  -103,  -290,   167,   -39,  -407,    44,  -208,  -375,
+   104,   -23,   -64,  -291,  -637,  -851, -1084,   -61,  -112,
+   -75,  -306,  -434,   218,  -148,  -354,  -680,  -133,  -216,
+  -121,  -377,  -718,   -97,  -130,  -361,  -156,  -379,  -599,
+   -56,  -254,  -586,   235,   157,  -214,    11,  -260,  -149,
+  -124,  -267,  -397,  -580,  -593,  -527,  -805,  -385,   346,
+  -193,  -440,  -708,  -351,  -141,  -255,  -499,  -147,  -185,
+   448,   660,   494,   208,   509,   461,   338,   291,   149,
+  -223,    88,   335,   159,   212,   191,   286,   308,   205,
+   -31,   469,   803,   659,   619,   658,   843,   987,  1113,
+  -171,  -242,   514,   362,   295,   524,   552,   694,   585,
+   -64,  -308,  -448,   -21,   284,   786,   446,   289,    92,
+  -218,  -390,    -7,   169,   206,   330,   352,   408,   358,
+   -36,   702,   959,   859,   861,  1115,  1269,  1357,  1305,
+  -133,  -341,   -65,   678,   417,   440,   486,   518,   780,
+    33,   -44,  -191,  -344,  -461,  -755,  -201,   217,   -31,
+  -353,  -547,   -44,   123,   -61,   -68,   -79,    29,    60,
+    73,   -57,  -406,  -766, -1243, -1203,   240,   400,   165,
+   -73,  -282,  -601,  -213,  -171,  -375,   332,    35,  -103,
+   -29,  -207,  -553,  -476,  -638,  -908,   172,   -22,  -135,
+  -192,  -239,  -164,  -103,  -111,   -47,   153,   125,   110,
+    -1,  -203,  -570, -1030, -1424,  -535,   155,     1,   147,
+  -333,  -653,  -865,  -197,  -158,   -21,   -44,    95,   108,
+   389,   588,   490,    33,  -237,  -524,  -628,  -136,  -260,
+    40,  -177,  -462,   453,   862,   380,   131,  -130,  -405,
+   842,  1678,  1841,  1549,  1474,  1256,  1082,   905,   742,
+   370,  1216,  1768,  1633,  1212,   636,    22,  -330,    71,
+   -76,  -281,  -741,  -742,   898,   619,   277,    71,  -222,
+   -32,  -265,  -556,   -25,   994,   682,   305,   126,  -165,
+    73,   738,   893,   968,   993,  1768,  2273,  1840,  1391,
+   -69,  -349,  -585,   234,  1158,   903,   626,   510,   251,
+    -1,   -99,  -272,  -210,  -603,  -351,  -540,  -811,  -383,
+   -16,  -230,  -504,   410,   149,  -205,  -343,  -651,  -639,
+   103,    -9,  -227,  -205,  -562,  -781, -1079, -1208,  -156,
+   143,    63,  -135,   -67,  -317,  -602,  -784, -1154,  -640,
+  -144,  -391,  -674,  -622,  -200,  -254,  -660,  -947,  -395,
+   -40,  -250,  -625,    27,   543,    94,  -131,  -386,  -673,
+  -123,  -371,  -757,  -451,  -564,  -614,  -415,  -711,   -35,
+  -116,  -309,  -593,  -268,   239,   -33,  -338,  -650,  -135,
+    94,   251,   554,    57,  -312,  -423,  -154,   -57,   235,
+  -268,   -71,   381,   114,   -44,   -87,   125,   173,   133,
+  1513,  1714,  1238,   534,   276,   315,   461,   459,   508,
+  -131,   -19,  1149,   670,   486,   356,   309,   369,   296,
+  -223,  -501,  -899,  -722,   -70,     6,   131,   310,   394,
+   -99,  -303,  -517,   249,    64,   -53,   135,   -11,   453,
+  -147,  -399,  -730,  -401,   817,   738,   802,   749,   575,
+  -154,  -435,  -739,   800,   593,   366,   529,   318,   326,
+  -224,    45,   -39,  -387,  -515,  -518,  -608,  -384,  -321,
+  -315,  -377,   143,  -101,  -113,  -377,  -177,  -144,   -12,
+   117,    40,  -239,  -651, -1051,  -581,  -737,  -990,  -328,
+    26,   -50,  -157,   -23,  -453,  -283,  -531,  -546,   192,
+  -252,  -501,  -743,  -589,  -627,  -499,  -328,  -118,   -72,
+  -324,  -494,  -244,  -306,  -144,  -177,  -262,  -135,   -78,
+   -36,  -234,  -519,  -961, -1290,  -314,  -479,  -371,   -45,
+   -95,  -292,  -535,    -8,  -300,   112,  -164,  -277,   198,
+   -99,  -128,   880,   836,   579,   351,    23,   -95,  -217,
+   -27,  -258,   124,  1011,   597,   425,   144,     7,   -73,
+   421,  1293,  1640,  1623,  1742,  1617,  1499,  1284,  1006,
+   -95,   752,  1680,  1569,  1618,  1436,  1200,   980,   712,
+   -69,  -300,  -683,  -435,  1132,   899,   504,   332,   109,
+   -74,  -323,  -637,   563,  1074,   608,   371,   105,   -49,
+   -78,   831,  1194,  1110,  1378,  1481,  1492,  1365,  1217,
+  -259,  -121,  1440,  1334,  1628,  1490,  1438,  1223,   933,
+   -82,  -306,  -613,  -222,  -378,  -675,  -545,  -671,  -845,
+    53,  -124,  -347,   422,    52,  -125,  -270,  -529,     9,
+    79,   -89,  -320,  -662,  -999, -1199, -1243,  -676,  -297,
+   -68,  -273,  -611,   137,  -146,  -397,  -627,  -845,  -220,
+  -112,  -346,  -797,  -826,   234,  -132,  -188,  -278,  -522,
+  -159,  -405,  -734,  -419,   293,    74,  -167,  -167,   184,
+  -153,  -437,  -833, -1080,  -336,  -472,  -561,  -340,  -253,
+  -169,  -423,  -820,  -904,  -131,   -19,  -346,  -604,    31,
+    33,   -31,   312,    62,  -148,    49,   -59,   564,   486,
+  -306,  -333,   194,   -44,    67,    72,   147,   205,   243,
+  -207,   -49,  1360,   983,   969,   991,  1014,  1110,   973,
+  -211,  -172,   883,   627,   711,   674,   705,   798,   746,
+   -88,  -325,  -763,  -974,   687,   908,   514,   382,   172,
+  -292,  -612,  -805,    63,   131,   270,   259,   352,   348,
+  -235,   -84,   955,   818,  1120,  1289,  1559,  1480,  1285,
+  -180,  -461,  -614,   657,   691,   745,   854,   783,   713,
+   -97,  -309,  -477,  -614,  -777,  -734,  -768,  -526,  -472,
+  -344,  -476,   -35,  -169,    49,   -77,  -150,  -240,  -141,
+   -52,  -268,  -639,  -919, -1278, -1113,  -342,  -333,  -151,
+   -68,  -242,  -585,   -73,  -209,  -478,  -159,  -429,   133,
+  -197,  -499, -1005, -1268,  -272,  -224,  -105,   -67,    17,
+  -363,  -618,  -414,  -116,   -62,    20,    10,   116,   108,
+  -195,  -475,  -906, -1260,  -891,  -441,  -277,  -142,   -28,
+  -226,  -519,  -950,  -700,  -275,  -266,  -116,  -105,    82,
+   404,   511,   520,   327,    17,  -194,  -333,  -536,  -586,
+  -114,  -130,   276,   237,   204,   342,   135,   -16,  -111,
+   670,  1208,  1168,   860,   742,   601,   528,   403,   309,
+   397,   621,   966,   752,   579,   398,   400,   329,   252,
+   191,   180,  -137,  -467,   272,   106,   -95,    17,  -192,
+   -80,  -290,  -626,   194,   598,   196,    21,  -281,    77,
+   510,   864,  1108,   807,   939,   902,   925,   717,   481,
+   137,   367,   534,   764,   670,   382,   296,   153,    84,
+   303,   497,   144,   -85,  -125,  -539,  -482,  -464,  -764,
+   233,   347,    68,  -147,   169,  -210,  -242,  -226,  -482,
+   307,   422,   154,  -175,  -386,  -722,  -724,  -904, -1015,
+   309,   308,   160,   -60,  -470,  -420,  -598,  -791,  -219,
+    68,   121,  -137,  -560,  -146,  -446,  -515,  -494,  -729,
+   130,    53,  -227,    46,   474,    32,  -161,  -192,  -490,
+   213,   164,   -71,  -465,  -876,  -161,  -456,  -587,   -48,
+   218,   117,    39,   177,  -194,   -88,  -226,  -418,    50,
+   210,   547,   569,   279,   121,   -44,   -50,    10,   -84,
+    58,   140,   182,    -5,   267,   117,   106,   211,   198,
+   539,   835,   913,   719,   617,   544,   591,   565,   642,
+   153,   559,   872,   460,   222,   108,   188,   180,   183,
+   158,   119,   284,  -153,  -271,   229,    87,   110,   -57,
+  -183,    82,   118,    21,    13,    40,   118,   191,   185,
+   162,   889,   654,   108,   -34,   244,   488,   561,   532,
+   163,    56,   609,   341,    50,   329,    68,   266,   218,
+   100,   206,    18,  -304,  -107,  -436,  -487,   -65,  -306,
+   -86,   154,   134,   -30,   -45,   -73,  -104,   -80,   -96,
+   245,   330,    10,  -440,  -849, -1082,    79,    40,  -265,
+   196,   372,   272,  -181,  -493,  -389,   275,    80,   -59,
+     2,   -12,  -246,  -505,  -100,  -436,    21,  -187,  -431,
+  -221,   -48,    36,  -271,  -186,  -147,  -109,    26,    71,
+   213,   140,    72,  -351,  -620,   -84,  -363,    69,    46,
+    91,   167,    -3,   -95,   -99,  -105,   -48,   114,   147,
+   259,   249,   172,   607,   406,    52,    59,  -189,  -320,
+   115,   -85,   -54,   574,   128,   226,   -59,  -253,   130,
+   -62,  1033,  1308,  1035,  1127,  1098,  1029,   961,   823,
+    39,   364,   757,   940,   728,   660,   659,   583,   770,
+  -115,  -338,  -760,  -471,   394,    37,   441,   178,     6,
+   -57,  -305,  -525,   796,   453,   188,    -4,  -114,   248,
+    71,   444,   797,   731,  1096,  1157,  1222,  1029,   811,
+   135,   359,   551,   425,   749,   815,   874,   704,   502,
+   132,   247,     0,  -206,  -449,  -750,  -258,  -514,  -633,
+   248,   249,    91,   121,  -195,  -499,   -90,  -282,  -435,
+    78,    20,  -277,  -623,  -983, -1224,  -415,  -458,  -639,
+   347,   509,   208,  -179,  -464,  -728,   -76,  -237,  -486,
+  -103,  -343,  -756,  -713,  -265,  -609,  -191,  -398,  -636,
+  -121,  -383,  -749,   567,   252,   -36,  -354,  -417,   -50,
+   204,   100,  -149,  -650, -1081,   -47,    -7,  -263,   111,
+   -46,  -180,  -267,  -324,  -562,  -394,  -692,   398,   292,
+   482,   670,   683,   624,   442,   165,   116,    36,  -149,
+   108,   247,   291,   247,   355,   122,   109,   224,   296,
+   -14,   945,   990,   801,   755,   815,   847,   913,   892,
+   292,   349,   725,   482,   388,   329,   429,   620,   667,
+   -34,   197,   213,  -127,    84,   494,   620,   575,   375,
+   126,   207,   172,   167,   362,   202,   296,   395,   455,
+    -6,   250,   539,   467,   636,   801,  1149,  1287,  1118,
+    27,   240,   369,   280,   440,   411,   634,   892,   953,
+   159,   170,   -58,  -395,  -797,  -690,    77,  -211,  -334,
+    -5,   -28,   -13,   -74,  -335,  -603,   300,    88,  -205,
+    82,   -33,  -364,  -698, -1203, -1153,   110,  -146,  -289,
+   113,     1,  -243,  -588,  -994,  -496,   414,   160,    42,
+   -56,  -247,  -440,  -693,  -996,  -479,    11,  -178,  -357,
+  -151,  -353,  -327,  -211,  -340,   141,    65,   425,   453,
+    34,  -169,  -455,  -932, -1215,   138,   499,   256,   324,
+    68,   139,   -15,  -547,  -478,    17,   306,   502,   481,
+   -32,  -134,   445,   129,  -143,  -244,  -503,  -507,  -599,
+    61,  -140,  -345,   496,   458,    -2,    20,  -227,  -514,
+   394,  1765,  1666,  1339,  1117,   806,   642,   479,   380,
+   215,   519,   920,  1053,  1090,   791,   528,   290,   155,
+   -54,  -233,  -647,  -602,   639,   294,    -2,  -167,  -442,
+   -78,  -315,  -791,  -113,   820,   403,   158,  -116,  -356,
+   529,  1851,  2003,  1228,   622,   -41,  -416,   344,   819,
+  -105,  -379,  -236,  1224,   893,   749,   568,   356,   214,
+   -17,  -199,  -144,    50,  -283,  -247,  -578,  -846, -1087,
+    69,   -11,  -381,  -206,   209,  -284,  -387,  -416,  -716,
+    39,    -5,  -145,  -374,  -682,  -909, -1074, -1169, -1066,
+   287,   226,    67,  -221,  -662,  -171,  -421,  -642,  -707,
+  -132,  -348,  -538,  -448,   -20,    -4,  -354,  -748,  -933,
+     4,   -75,  -289,  -598,   317,    52,  -208,  -297,  -559,
+   -88,  -264,  -358,  -589,  -631,  -248,  -523,  -822, -1071,
+    70,    -8,    54,  -314,  -515,    92,  -146,  -274,  -493,
+   199,    62,   391,   158,  -141,    71,  -219,  -203,  -207,
+   152,    40,   329,   162,   -29,    48,  -149,   108,   127,
+   635,  1058,   883,   492,   372,   312,   317,   274,   241,
+   267,   722,  1256,   882,   625,   248,     8,   -81,   -60,
+   -58,  -138,  -291,  -600,   -12,    -2,   -39,   147,   117,
+  -107,  -345,  -513,   459,    76,    92,  -272,   388,   262,
+   362,   516,   203,  -409,  -716,  -831,  -331,   185,   209,
+  -117,  -391,  -298,   671,   292,   538,   257,   166,   -38,
+  -102,  -319,  -194,  -283,  -573,  -262,  -579,  -219,  -444,
+  -235,    78,    11,  -168,  -101,  -229,  -263,  -321,  -123,
+    70,    50,  -170,  -599,  -996,  -588,  -263,  -516,  -455,
+   394,   363,   229,  -136,  -538,    21,  -183,  -348,  -201,
+  -124,  -368,  -640,  -879,  -847,  -209,  -409,  -494,  -515,
+  -127,  -341,  -541,  -425,  -510,   -10,  -252,  -473,  -291,
+    84,   -69,  -201,  -676,  -868,   103,  -311,  -132,  -320,
+     5,  -173,  -188,  -297,  -628,   197,   -57,     7,   -11,
+    49,  -160,    56,   558,   111,    33,  -311,  -440,  -463,
+    -1,  -246,  -307,   862,   453,   139,  -170,  -355,  -232,
+   279,   966,  1642,  1478,  1463,  1123,   795,   525,   339,
+  -197,   -38,  1702,  1331,  1252,   950,   692,   504,   426,
+  -108,  -344,  -861, -1172,   444,   354,    88,   -46,  -220,
+   -53,  -321,  -494,  1113,   744,   364,   198,   -34,   -75,
+   457,   955,  1177,  1214,  1427,  1457,  1345,   917,   539,
+   -69,   199,   897,  1140,  1343,  1183,   977,   742,   522,
+   122,    44,  -269,    27,  -155,  -562,  -307,  -590,  -773,
+   154,    42,  -160,   252,  -129,  -305,  -471,  -733,  -371,
+   135,   185,   -82,  -416,  -722,  -913,  -504,  -743,  -880,
+   149,   214,   -84,  -329,  -680,  -835,  -426,  -661,   -81,
+  -128,  -380,  -735,  -998,  -337,    17,  -182,  -467,  -697,
+   -84,  -290,  -510,  -592,    13,   440,   154,   -38,  -279,
+    70,   -61,  -246,  -727, -1047,   -80,  -381,  -535,  -704,
+   178,    -2,  -146,  -670,  -938,   482,   138,    63,    65,
+   -11,    15,   772,   443,   142,   -20,  -209,  -126,  -161,
+   -32,  -249,    95,   552,   124,    30,  -343,    82,   -86,
+   148,   751,  1515,  1105,   867,   606,   474,   448,   399,
+  -163,  -257,   899,  1097,   906,   751,   502,   390,   294,
+   -51,  -258,  -447,  -806,  -368,   763,   464,   364,   183,
+  -166,  -374,  -367,    87,    35,   399,   418,   856,   833,
+  -205,  -310,   588,   778,   785,  1065,  1118,  1245,  1157,
+  -173,  -312,   107,   345,   400,   790,   870,  1113,  1001,
+    -7,  -120,  -387,  -410,  -614,  -943,  -226,  -384,  -491,
+  -203,  -288,   -51,  -331,   -90,  -178,  -408,  -573,  -338,
+    56,   -29,  -273,  -627, -1041,  -798,  -247,  -467,   148,
+    66,    -2,  -205,  -205,  -575,  -349,   -57,  -352,   -58,
+   -45,  -225,  -471,  -924,  -497,    77,   -32,    44,  -135,
+  -277,  -491,  -497,  -502,  -424,  -202,  -137,    77,    96,
+    26,  -179,  -469, -1008, -1260,   262,   -35,  -132,  -259,
+   -66,  -232,  -447,  -533,  -789,  -191,  -100,  -267,   364};
+
+/*------------------------------------------------*
+ * 1st stage codebook; 2nd split:   isf9 to isf15
+ *------------------------------------------------*/
+
+static Word16 dico2_isf[SIZE_BK2*7] = {
+
+  1357,  1313,  1136,   784,   438,   181,   145,
+   636,   648,   667,   568,   442,   217,   362,
+   427,   440,   674,   524,   332,   117,  -417,
+   121,   295,   468,   465,   230,    44,  -221,
+  -147,  -240,   149,    80,   390,   278,   106,
+  -418,  -556,   552,   511,   235,   144,   -95,
+    43,   193,   274,   150,    67,    34,  -273,
+   -43,  -126,   171,   416,   282,    63,  -354,
+  -372,   -86,  -344,  -108,   -94,  -182,   -89,
+  -600,  -840,  -200,   465,   258,   -11,  -253,
+   -48,   329,    97,  -290,  -543,  -795,  -354,
+  -570,  -117,   187,    10,  -133,  -416,   -76,
+  -618,  -129,  -247,  -371,    45,   -76,   277,
+ -1022, -1079,   126,   474,   254,   127,    52,
+  -281,    76,  -167,  -361,  -283,  -551,  -283,
+  -119,   -52,    -1,   134,   -32,  -204,  -415,
+  1064,   827,   637,   684,   464,   209,    12,
+   482,   416,   449,   371,   335,   294,   194,
+   719,   576,   365,   135,   113,    91,  -199,
+   298,   176,   493,   366,   194,   163,    36,
+   -35,  -236,  -259,   -36,    -4,    99,   152,
+   -98,  -306,   -27,   228,    90,   111,   -86,
+    91,    13,  -211,  -258,  -106,    86,   -64,
+    73,   -35,   -57,   -31,   162,    35,  -192,
+  -109,  -335,  -629,   -66,   -61,  -128,   322,
+  -495,  -669,  -728,   193,    31,  -220,   122,
+   324,    95,   -89,   -91,  -409,  -710,  -154,
+     0,  -234,    92,    33,  -343,  -609,  -220,
+  -343,  -408,  -476,  -655,  -153,    82,   222,
+  -490,  -745,  -255,    49,   -48,   135,  -127,
+   119,   -67,  -328,  -390,  -272,  -545,   -56,
+   -57,  -130,   -10,    -7,  -164,   -47,   -22,
+   984,  1064,   961,   568,   210,   -27,    16,
+   811,   691,   754,   514,   224,   -35,   166,
+   662,   704,   618,   386,    57,  -211,  -257,
+   510,   359,   418,   393,    91,  -144,   -18,
+  -193,   -31,   -27,   223,    89,  -143,    24,
+  -112,   -98,   471,   319,   185,     3,   175,
+   252,   146,   -47,   272,    48,  -211,  -234,
+   146,    69,   203,   364,    68,   -52,    51,
+  -259,  -478,  -697,  -349,  -758,  -501,    63,
+  -501,  -769,  -289,    79,  -311,  -497,  -106,
+   251,    53,  -235,  -469,  -895,  -884,   145,
+  -416,  -551,   140,  -133,  -523,  -775,    44,
+  -326,  -423,  -713,  -497,   -86,  -431,    99,
+  -757,  -772,  -160,   -76,   -46,   -32,   379,
+    85,   -35,  -200,  -401,  -663, -1040,  -247,
+  -180,  -330,   -92,  -376,    27,  -183,  -110,
+  1279,  1086,   781,   502,   324,   164,   157,
+   682,   466,   449,   277,   146,    28,   409,
+   635,   472,   390,   107,  -232,  -538,  -139,
+   196,   396,   332,   213,   209,   -29,   -81,
+   150,   -95,  -312,    76,   -77,  -320,   -50,
+    46,     9,    47,   175,   139,    30,   384,
+   218,   206,   -24,  -250,   -96,  -276,  -183,
+    26,   119,    38,    14,    -4,  -133,   -52,
+  -477,  -614,  -987,  -715,  -631,  -813,   200,
+  -744, -1009, -1065,  -745,  -631,  -171,    18,
+  -137,  -251,  -483,  -613,  -980, -1203,    12,
+  -605,  -767,  -562,  -686, -1088,  -515,    58,
+  -202,  -428,  -782, -1072,   -96,  -234,  -179,
+  -480,  -709, -1070,  -897,  -131,   -92,   321,
+  -145,  -193,  -512,  -729,  -572,  -765,  -210,
+  -331,  -585,  -525,  -631,  -281,  -208,  -303,
+  1165,  1104,   939,   828,   716,   426,   155,
+     6,  -109,   820,   778,   415,   113,   -27,
+   381,   339,   314,   265,   121,    -9,  -474,
+  -373,    47,   584,   442,    99,  -231,  -113,
+  -496,   -38,  -285,   262,   305,   170,     4,
+  -587,  -556,    69,    66,   471,   354,    13,
+  -138,    70,   -18,   106,    67,   167,  -302,
+  -445,  -141,   185,   191,   151,    83,  -133,
+  -257,  -521,  -720,  -198,   134,   -46,  -182,
+  -819, -1168,  -777,   512,   359,    95,  -113,
+   137,    -2,   -74,  -138,  -401,  -114,  -371,
+  -242,  -466,   204,   223,   -31,  -212,  -192,
+  -532,  -637,  -466,  -686,   256,   277,  -139,
+ -1141, -1244,  -381,   -75,   -54,    14,    88,
+  -311,   115,  -143,  -499,  -343,   124,  -416,
+  -616,  -147,  -135,    43,    -4,   121,  -369,
+   835,   783,   641,   390,   355,   350,    64,
+    72,   194,   443,   467,   436,   219,   372,
+   464,   369,   192,     4,  -156,   -72,  -226,
+    57,   206,   303,   205,   188,   101,   265,
+   -40,  -205,  -488,  -184,   276,    64,   -26,
+  -217,  -433,  -297,   137,   328,   308,  -289,
+   378,    81,  -308,  -465,    57,   -37,   227,
+  -100,    24,   -36,  -151,   199,     8,   143,
+  -426,  -697, -1059,  -133,   388,   161,   321,
+  -644, -1023, -1271,    39,    66,  -123,    70,
+   372,   177,  -173,  -556,  -553,  -304,  -189,
+  -117,  -369,  -425,  -122,  -462,  -152,   -73,
+  -649,  -850, -1189,  -767,   497,   360,   222,
+  -798, -1139, -1455,  -190,   430,   234,   179,
+    42,   -94,  -405,  -692,    38,  -202,  -246,
+  -169,  -366,  -290,   -88,   -64,    32,  -292,
+  1010,   923,   938,   710,   465,   230,   342,
+   217,   300,  1054,   675,    68,  -458,  -179,
+    78,   453,   316,    18,  -237,  -496,  -243,
+   167,    21,   424,   215,   -91,  -303,  -170,
+  -290,   -81,   -70,   -67,    40,    54,   -59,
+  -353,  -427,   -90,    53,    94,     9,    54,
+   -28,   318,   283,    15,  -240,   -58,    79,
+   -75,  -121,   229,    35,    58,     6,  -133,
+  -351,  -514,  -744,  -834,  -705,  -137,   164,
+ -1124, -1388, -1055,  -230,   -73,    40,    36,
+  -163,  -233,  -532,  -785, -1170,  -697,    96,
+  -788,  -959,  -246,  -430,  -624,  -165,    -8,
+  -856,  -540,  -630,  -907,  -337,   -70,    76,
+  -937, -1042,  -659,  -733,  -208,   199,   -26,
+  -523,    78,   -98,  -501,  -869,  -890,   -81,
+  -624,  -703,   -45,  -348,   -25,    87,  -186,
+  1005,   823,   546,   249,    90,   -22,   207,
+   298,   397,   381,   319,   200,    62,   303,
+   473,   379,   133,  -247,  -632,  -441,    75,
+   284,   208,   391,   115,   -25,    44,    95,
+   -72,    79,   -95,   -63,  -129,  -293,   203,
+  -164,  -349,   115,   122,    69,    -1,   378,
+   348,   170,    99,    58,  -179,  -302,   188,
+  -190,    -2,   150,    23,   -51,   -11,   216,
+  -615,  -863, -1090, -1427,  -802,   -48,    -6,
+  -961, -1276, -1548,  -727,   -58,    56,   223,
+  -124,  -255,  -561,  -988, -1277,  -148,   -82,
+  -480,  -660,  -891, -1191, -1339,  -325,    20,
+  -621,  -917, -1296, -1350,   264,   289,    50,
+  -844, -1022, -1345, -1329,  -293,    46,   278,
+  -260,  -468,  -829, -1176,  -533,  -560,   -78,
+  -215,  -484,  -822, -1233,  -791,    15,  -138,
+  1301,  1317,  1262,  1048,   716,   357,   -64,
+   578,   824,   925,   802,   630,   362,   102,
+   470,   925,   767,   514,   327,   190,  -112,
+   225,   492,   495,   437,   598,   384,   -45,
+    43,    82,   -42,   175,   519,   342,   -64,
+  -304,  -154,   159,   576,   403,   221,   327,
+   214,   244,   122,   -62,   312,    92,  -160,
+   218,   208,   310,   268,   306,   323,  -199,
+  -285,  -269,   -79,  -124,  -143,  -153,   236,
+  -205,  -384,  -426,   344,    59,  -185,  -184,
+  -272,   247,   126,  -210,  -518,  -468,    78,
+   -99,  -120,   502,   160,  -280,  -557,   304,
+  -423,   -17,  -283,  -443,   215,   212,  -140,
+  -564,  -684,  -228,   510,   361,   130,   323,
+  -428,   335,    98,   -65,    36,  -215,  -246,
+  -362,    51,   364,   -16,  -234,   150,  -165,
+   914,   883,   751,   653,   676,   464,  -153,
+   631,   545,   535,   720,   596,   360,   -81,
+   783,   712,   512,   439,   341,   251,  -391,
+   497,   417,   249,   372,   295,   173,  -193,
+   128,  -110,  -385,    93,    39,   173,  -231,
+   216,   -59,  -253,   462,   389,   154,    69,
+   455,   270,    -4,  -337,   -49,   233,  -322,
+   307,   143,    53,   218,   128,   236,  -156,
+   -37,  -186,  -240,  -411,  -110,     9,   399,
+  -140,  -365,  -628,   258,   380,   214,   277,
+   131,   454,   177,  -285,  -520,   108,  -214,
+    77,  -141,   201,  -123,  -490,  -131,    60,
+   -14,  -194,  -521,  -741,   273,   362,   -33,
+  -362,  -566,  -287,  -228,   161,   237,   317,
+  -269,   195,   -75,  -375,  -204,    11,    77,
+  -128,  -264,  -156,  -223,  -475,   265,    27,
+  1238,  1147,   916,   689,   432,   210,  -280,
+   800,   664,   879,   726,   411,   160,  -164,
+   454,   686,   536,   275,   147,    46,   111,
+   303,   486,   512,   355,   241,   181,   -69,
+    79,    92,    29,   147,   233,    52,    17,
+  -171,   289,   131,   439,   271,     3,   -10,
+   413,   241,   144,   174,   155,    -2,    14,
+    58,   217,   247,   219,   149,   175,   -18,
+   228,    -8,  -240,  -206,  -513,  -191,   202,
+   -96,  -272,  -454,    33,  -300,  -575,    46,
+   -10,  -108,  -246,  -347,  -770,  -535,     9,
+  -326,  -430,   -61,  -321,  -704,  -299,   201,
+    -1,  -280,  -603,  -419,  -185,    18,   -36,
+  -516,  -522,  -379,  -291,  -181,   -97,    27,
+  -159,  -313,  -525,  -224,  -510,  -831,  -197,
+  -292,  -459,   -59,  -310,  -562,  -143,  -351,
+  1066,   912,   631,   389,   207,    86,  -224,
+   596,   512,   596,   505,   314,   122,   -48,
+   787,   861,   441,   -93,  -303,    33,  -190,
+   257,   469,   337,    51,    15,   298,   -93,
+   295,    73,  -119,    25,    36,    23,   108,
+   -28,    -3,   -32,   114,    21,   185,   107,
+   482,   305,    15,  -279,  -319,    52,    96,
+   226,    46,   115,    72,  -136,   133,  -125,
+    18,  -207,  -559,  -590,  -503,  -482,   321,
+  -571,  -789,  -951,  -172,  -441,  -538,   113,
+   181,    14,  -310,  -641, -1001,  -202,   159,
+  -136,  -393,  -433,  -513,  -911,  -144,   -22,
+    72,  -265,  -706,  -954,  -159,    53,   332,
+  -338,  -591,  -852,  -383,  -395,    56,    44,
+    43,  -158,  -464,  -897,  -631,  -157,  -294,
+  -161,  -128,  -328,  -573,  -483,  -125,    11,
+  1017,   906,  1051,  1005,   679,   341,  -102,
+   359,   334,  1567,  1314,   723,   105,    10,
+   -65,   726,   529,   301,   220,    43,  -273,
+  -510,   436,   719,   566,   358,   179,   114,
+  -560,   298,   133,  -120,   342,   225,    14,
+  -899,  -101,   217,   617,   400,   146,   -58,
+   -41,   352,    82,  -196,    39,   121,  -167,
+  -212,    59,   447,   284,   423,   250,  -169,
+  -371,  -484,  -596,    30,   -41,   249,    22,
+  -372,  -650,  -794,   477,   445,   216,   -79,
+  -352,   275,    17,  -443,  -929,    92,    19,
+  -699,  -696,   431,   264,   -49,  -310,   182,
+  -978,  -217,  -430,  -400,   101,   261,    72,
+  -929,  -889,  -357,   -13,   463,   378,   236,
+  -826,    56,    30,  -299,  -360,  -128,   -51,
+  -878,  -299,  -111,    75,    65,    36,     3,
+   817,   368,   -25,   354,   697,   591,  -173,
+   309,   212,   222,   751,   484,   140,   -56,
+   593,   379,    70,    -8,   258,   180,   110,
+   165,   -46,   255,   297,   219,   273,   105,
+   160,   -70,  -358,  -181,   379,   330,   319,
+  -238,  -369,  -198,   740,   580,   319,  -143,
+   201,   109,  -202,  -456,   328,   276,  -141,
+   203,   170,   111,    42,   207,   360,   188,
+  -345,  -399,  -513,  -233,   650,   422,    81,
+  -635,  -961, -1220,   463,   539,   204,   209,
+   202,   -25,  -194,  -498,  -787,   193,  -143,
+  -449,  -538,   195,  -106,  -331,    68,    62,
+  -228,  -477,  -840,  -576,   317,   128,   283,
+  -671,  -937,  -807,  -114,   391,   335,   -62,
+   246,     2,  -314,  -679,  -303,   180,   -88,
+  -107,  -272,    90,  -198,   -28,   290,  -112,
+   885,  1149,  1021,   712,   496,   281,   -83,
+   269,   492,   787,   643,   347,    70,   124,
+   336,   636,   499,    92,  -229,  -179,   191,
+    26,   402,   564,   340,   149,   -11,   135,
+  -440,   561,   470,   204,   -72,  -186,   140,
+  -720,    14,   355,   229,    68,  -133,   465,
+   110,   310,   103,    12,   106,    29,   158,
+  -178,   113,   161,   142,   121,   115,    27,
+  -651,  -414,  -645,  -152,  -164,   -13,  -429,
+  -639,  -944,  -681,  -104,   -81,    52,  -189,
+  -663,  -164,  -316,  -683,  -954,  -205,   -83,
+  -609,  -669,  -172,  -517,  -694,   283,   -80,
+  -646,  -152,  -383,  -678,  -246,   -40,  -143,
+  -747,  -796,  -745,  -390,   -98,    43,   275,
+  -599,  -199,  -398,  -433,  -436,  -538,    31,
+ -1107,  -568,  -376,  -265,  -126,   -21,     1,
+   847,   573,   308,   392,   305,   101,    55,
+   273,   293,   201,   267,   346,   201,   123,
+   727,   480,   226,     2,   -65,  -138,   164,
+   273,   208,   173,   292,    12,   253,   174,
+   340,   207,   180,    88,   116,    46,   475,
+  -460,  -166,   -30,    13,   110,   173,   396,
+   137,    88,    43,  -137,   -94,    34,   284,
+    96,   -14,   226,    40,    63,    70,   130,
+  -467,  -735, -1012, -1174,  -307,   305,   -67,
+  -612,  -920, -1146,  -567,    -8,    92,   -25,
+  -182,  -271,  -492,  -754,  -857,   287,   -75,
+  -494,  -787,  -689,  -683,  -709,   137,  -326,
+  -288,  -550,  -903, -1105,   334,   321,   -62,
+  -354,  -653,  -834,  -445,     1,   377,  -152,
+  -162,  -306,  -608,  -937,  -297,   247,  -192,
+  -234,  -477,  -244,  -488,  -266,   342,  -332};
+
+/*---------------------------------------------------*
+ * 2nd stage codebook; 1st split:   isf2_0 to isf2_2
+ *---------------------------------------------------*/
+
+
+static Word16 dico21_isf[SIZE_BK21*3] = {
+
+   329,   409,   249,
+   -33,   505,   160,
+   -29,   -14,   582,
+  -262,   127,   354,
+   145,   237,   175,
+  -152,   245,   122,
+    27,    42,   340,
+   -84,   -93,   311,
+   285,   222,  -156,
+    47,   -43,  -504,
+   234,   121,   385,
+   104,  -317,    45,
+   176,   195,     8,
+   104,   -59,   -94,
+   177,    53,   192,
+   -34,  -127,   152,
+   570,   277,   -34,
+   -67,  -329,  -639,
+  -157,  -272,   462,
+  -177,  -462,   198,
+   322,   179,   115,
+  -386,   171,    19,
+    19,   -12,   195,
+  -120,  -252,   201,
+   304,    36,  -336,
+  -128,  -221,  -380,
+   171,  -185,   296,
+  -242,  -312,    23,
+   198,    39,    16,
+    -3,  -177,  -111,
+   111,   -93,    76,
+   -92,  -223,     4,
+   177,   406,   -44,
+  -168,   380,  -149,
+    -4,   273,   331,
+  -420,   513,   277,
+    21,   247,    47,
+   -58,   131,    -2,
+    -3,   134,   180,
+  -145,    40,   175,
+   189,    74,  -145,
+   -27,   -45,  -325,
+   370,  -114,   -21,
+   -83,  -415,  -173,
+    77,    95,   -51,
+   -40,   -30,   -67,
+    71,    88,    86,
+   -35,   -98,    14,
+    69,   197,  -334,
+  -196,    79,  -231,
+  -348,  -137,   218,
+  -352,   -89,   -85,
+    47,   201,  -130,
+  -165,    37,   -15,
+   -43,     3,    86,
+  -161,  -108,    79,
+    83,    21,  -237,
+   -81,  -149,  -238,
+   150,  -186,  -251,
+  -186,  -249,  -162,
+   -19,    66,  -139,
+   -26,   -50,  -181,
+    24,    11,     0,
+  -130,  -105,   -98};
+
+
+
+/*---------------------------------------------------*
+ * 2nd stage codebook; 2nd split:   isf2_3 to isf2_5
+ *---------------------------------------------------*/
+
+
+static Word16 dico22_isf[SIZE_BK22*3] = {
+
+  -127,   310,    42,
+  -242,   197,     5,
+  -151,    84,   -17,
+  -214,   127,  -149,
+  -247,  -131,   159,
+  -268,  -267,   -95,
+  -217,     1,   -79,
+  -271,   -80,  -185,
+   -45,   436,   159,
+   165,   199,   391,
+   -33,    81,   187,
+   -66,   -42,   355,
+  -298,   -57,   343,
+  -108,  -537,   226,
+  -144,   -23,   193,
+   176,  -402,    87,
+    53,   296,    25,
+   -84,   253,  -104,
+   -58,   105,  -126,
+  -169,   174,  -314,
+   -48,    44,  -294,
+  -164,  -417,  -242,
+  -139,     3,  -194,
+  -155,  -207,  -211,
+   119,   322,   213,
+   333,    50,   380,
+   237,   247,    -2,
+   466,   -16,   201,
+   238,  -255,  -107,
+    67,  -440,  -149,
+   122,   -88,  -139,
+    88,  -247,   -73,
+   -41,   231,   167,
+   -62,   155,    16,
+   -65,    16,    77,
+   -68,    -2,   -63,
+  -151,  -300,   160,
+   -18,  -333,    54,
+   -56,   -94,     5,
+     2,  -190,    14,
+    92,   148,   209,
+   108,     9,   272,
+   108,    35,   110,
+   142,   -85,   145,
+    47,  -157,   279,
+     3,  -320,   246,
+    43,   -72,    68,
+    86,  -217,   135,
+    36,   140,    79,
+    56,   175,   -49,
+    26,    45,     3,
+    73,    55,  -101,
+   109,  -183,  -242,
+    -4,  -283,  -242,
+    48,   -68,   -48,
+    -6,  -153,  -122,
+   161,   196,    96,
+   232,    80,   190,
+   165,    97,    11,
+   258,   -31,    71,
+   267,   -77,   -91,
+   311,  -209,    87,
+   152,   -14,   -22,
+   150,  -149,     9,
+  -324,   557,   187,
+  -384,   307,    46,
+  -251,    27,    77,
+  -365,    77,   -52,
+  -482,   -84,   160,
+  -424,  -515,   -64,
+  -294,  -120,    -4,
+  -476,  -116,  -109,
+   -97,   318,   365,
+   106,   627,   445,
+  -190,   120,   287,
+  -146,    65,   619,
+  -427,   242,   363,
+  -361,  -371,   432,
+  -347,   102,   168,
+  -629,   195,   -14,
+   -65,   476,   -47,
+  -297,   320,  -168,
+   -55,   356,  -264,
+  -391,    82,  -286,
+   -51,   -31,  -556,
+  -178,  -399,  -586,
+  -205,   -49,  -360,
+  -343,  -238,  -337,
+   220,   457,    58,
+   561,   467,   259,
+   340,   270,  -168,
+   450,    77,  -280,
+    60,   167,  -413,
+   133,  -252,  -492,
+   216,   157,  -290,
+   282,     0,  -495,
+  -226,   293,   183,
+  -157,   135,   122,
+  -158,   -59,    39,
+  -133,  -118,   -97,
+  -332,  -309,   113,
+  -160,  -425,    -6,
+  -149,  -211,    24,
+   -80,  -277,   -90,
+   -11,   125,   338,
+   130,   -71,   465,
+     5,   -45,   184,
+   237,   -95,   253,
+  -139,  -197,   297,
+   -19,  -300,   511,
+   -63,  -152,   139,
+   250,  -289,   336,
+   124,   339,  -150,
+    34,   176,  -208,
+   171,   166,  -116,
+    94,    38,  -229,
+    75,   -65,  -339,
+   -78,  -205,  -385,
+     0,   -30,  -163,
+   -56,  -110,  -242,
+   321,   244,   194,
+   505,   238,    -1,
+   317,   116,    65,
+   309,    88,   -74,
+   452,   -51,   -50,
+   334,  -217,  -290,
+   211,    41,  -152,
+   238,   -55,  -260};
+
+
+/*---------------------------------------------------*
+ * 2nd stage codebook; 3rd split:   isf2_6 to isf2_8
+ *---------------------------------------------------*/
+
+
+static Word16 dico23_isf[SIZE_BK23*3] = {
+
+   -10,   151,   359,
+   136,   298,   223,
+   255,  -104,   290,
+   423,     6,   183,
+  -270,  -269,   -98,
+   -52,   -82,    13,
+   -82,  -274,   -97,
+    90,  -246,   -72,
+  -299,   -70,   421,
+   -88,   365,   430,
+   187,  -318,   381,
+   380,    37,   488,
+  -373,  -316,    79,
+  -308,  -101,     5,
+  -135,  -451,     8,
+    72,  -421,  -154,
+   180,   170,  -121,
+    62,   177,   -40,
+   326,    80,  -105,
+   248,   263,    -5,
+  -168,  -181,  -221,
+    -2,   -23,  -158,
+   -14,  -149,  -121,
+   119,   -91,  -147,
+   119,   332,  -153,
+    49,   303,    34,
+   442,   -55,   -69,
+   217,   454,    58,
+  -359,  -187,  -375,
+   -42,    50,  -274,
+    -8,  -267,  -249,
+    85,   -86,  -346,
+   -77,   -40,   345,
+    89,   134,   219,
+   156,   -80,   160,
+   108,    40,   116,
+  -158,  -206,    29,
+     5,   -32,   175,
+   -65,  -158,   146,
+    55,   -78,    73,
+  -114,  -222,   353,
+   -47,    81,   211,
+    49,  -151,   268,
+   105,     4,   302,
+  -263,  -132,   183,
+  -151,   -28,   201,
+  -177,  -307,   166,
+   101,  -221,   130,
+    74,    58,   -98,
+    32,    44,    13,
+   194,    30,  -142,
+   170,    96,     8,
+  -136,  -119,   -91,
+   -65,     8,   -55,
+     3,  -188,    12,
+    45,   -63,   -49,
+   149,   -21,   -19,
+    24,   144,    95,
+   254,   -22,    60,
+   161,   196,    96,
+  -158,   -61,    48,
+   -70,    33,    82,
+   -23,  -321,    58,
+   155,  -147,     5,
+  -364,   328,    77,
+   -21,   453,   173,
+  -108,    82,   630,
+   367,   263,   208,
+  -300,   -62,  -176,
+  -205,   143,  -158,
+  -169,  -410,  -264,
+   257,  -269,  -100,
+  -636,   289,    -2,
+  -292,   627,   173,
+  -382,  -363,   387,
+   248,   524,   447,
+  -521,  -111,  -107,
+  -395,   118,  -274,
+  -343,  -680,  -125,
+  -172,  -447,  -663,
+    75,   148,  -367,
+   -79,   263,   -94,
+   249,   148,  -286,
+   380,   271,  -162,
+  -142,    -4,  -186,
+   -57,   111,  -125,
+   -35,  -108,  -254,
+   100,    29,  -242,
+   -80,   303,  -264,
+   -78,   464,   -57,
+   248,   -22,  -494,
+   661,   662,    44,
+  -193,   -40,  -330,
+  -178,   145,  -337,
+   -90,  -199,  -400,
+   -40,   -23,  -498,
+  -192,   114,   315,
+   -41,   244,   190,
+    88,   -97,   485,
+   241,    80,   212,
+  -246,    40,    87,
+  -156,   147,   134,
+    -2,  -334,   239,
+   308,  -203,   110,
+  -459,   251,   422,
+  -218,   310,   228,
+   -86,  -346,   654,
+   184,   175,   425,
+  -481,   -63,   169,
+  -349,   117,   188,
+  -125,  -560,   310,
+   158,  -416,    94,
+    46,   171,  -192,
+   -63,   157,    14,
+   256,   -35,  -271,
+   322,   123,    53,
+  -214,     4,   -76,
+  -156,    86,   -18,
+   128,  -197,  -232,
+   265,   -90,   -98,
+  -308,   332,  -145,
+  -131,   308,    58,
+   509,    59,  -339,
+   562,   196,   -14,
+  -378,   100,   -47,
+  -234,   202,     1,
+   104,  -270,  -493,
+   319,  -210,  -325};
+
+
+/*---------------------------------------------------*
+ * 2nd stage codebook; 4th split:   isf2_9 to isf2_11
+ *---------------------------------------------------*/
+
+static Word16 dico24_isf[SIZE_BK24*3] = {
+
+   -79,   -89,    -4,
+  -171,    77,  -211,
+   160,  -193,    98,
+   120,  -103,   323,
+    32,   -22,  -129,
+    72,    78,  -268,
+   182,   -76,   -66,
+   309,    99,  -145,
+  -229,  -157,   -84,
+  -383,    98,   -71,
+   -90,  -352,    12,
+  -284,  -178,   178,
+   -65,  -125,  -166,
+   -87,  -175,  -351,
+    42,  -198,   -48,
+   154,  -140,  -243,
+   -77,    18,   108,
+   -39,   355,    91,
+    87,     8,   155,
+    -4,   158,   239,
+   128,    95,   -54,
+     7,   246,  -124,
+   258,    15,    89,
+   206,   216,    98,
+  -201,     9,    18,
+  -312,   233,   204,
+   -39,  -174,   155,
+  -144,    -9,   284,
+   -57,    70,   -69,
+  -157,   187,    18,
+    54,   -30,    23,
+    24,   135,    55};
+
+
+/*---------------------------------------------------*
+ * 2nd stage codebook; 5th split:   isf2_12 to isf2_15
+ *---------------------------------------------------*/
+
+static Word16 dico25_isf[SIZE_BK25*4] = {
+
+   169,   142,  -119,   115,
+   206,   -20,    94,   226,
+  -106,   313,   -21,    16,
+   -62,   161,    71,   255,
+   -89,   101,  -185,   125,
+    72,   -30,  -201,   344,
+  -258,    33,    -8,    81,
+  -104,  -154,    72,   296,
+   144,   -68,  -268,   -25,
+    81,   -78,   -87,   106,
+    22,   155,  -186,  -119,
+   -46,   -28,    27,    91,
+  -114,   -37,  -175,   -33,
+   -94,  -222,  -189,   122,
+  -132,  -119,  -191,  -270,
+  -172,  -173,    18,   -43,
+   279,   135,   -42,  -128,
+   187,   -86,   229,  -138,
+   159,   240,   140,    46,
+    69,    25,   227,    77,
+    21,   115,    13,     8,
+    68,  -248,   126,    81,
+  -150,   137,   207,    -9,
+  -154,  -133,   289,    67,
+   143,   -37,   -86,  -326,
+   180,   -32,    19,   -23,
+    26,   168,   116,  -233,
+   -32,   -26,   118,   -78,
+     3,    -8,   -45,  -115,
+    57,  -215,   -54,   -83,
+  -209,   112,   -22,  -167,
+   -91,  -151,   168,  -262};
+
+
+
+       /* 36 bit */
+/*-------------------------------------------------------------------*
+ *  isf codebooks:  two-stage VQ with split-by-3 in 2nd stage        *
+ *                1st stage is kept the same as the 46 bit quantizer *
+ *                                                                   *
+ *  codebook   vector dimension    number of vectors                 *
+ *  ~~~~~~~~   ~~~~~~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~                 *
+ *     1_1            9                  256                         *
+ *     1_2            7                  256                         *
+ *     2_1            5                  128                         *
+ *     2_2            4                  128                         *
+ *     2_3            7                  64                          *
+ *-------------------------------------------------------------------*/
+
+static Word16 dico21_isf_36b[SIZE_BK21_36b*5] = {
+
+   -52,   -96,   212,   315,   -73,
+    82,  -204,   363,   136,  -197,
+  -126,  -331,   183,   218,   143,
+   -49,   -41,   557,   230,    72,
+     2,   -73,   163,   377,   221,
+   133,   111,   278,   215,  -110,
+  -102,   -20,   284,   113,   273,
+    84,   319,   290,    18,    85,
+   -25,    -5,   125,   132,  -204,
+   -38,    -5,   286,    -9,  -356,
+  -140,  -256,    92,   117,  -189,
+  -144,   191,   313,    51,   -98,
+   167,   -10,    44,   247,    36,
+   381,   197,   238,    74,     6,
+    38,  -408,    29,    -3,   -85,
+    92,   266,   157,   -25,  -200,
+   161,  -121,    70,    84,  -140,
+   -16,   -86,   112,   -94,  -189,
+  -269,  -270,   351,   107,   -24,
+   -68,   -67,   492,  -103,  -155,
+   -53,  -131,    62,   122,    10,
+   135,    84,   283,   -55,  -120,
+   -12,  -219,   331,   -81,   167,
+   220,  -136,   147,  -172,   -42,
+   140,   -95,  -109,   -88,  -194,
+     0,    -2,    -4,   -33,  -381,
+   -66,  -217,   152,  -186,  -402,
+   244,   108,   156,  -140,  -395,
+   113,  -136,  -196,   110,   -24,
+   214,   118,    11,   -64,  -131,
+  -110,  -286,    -6,  -332,    16,
+    94,    97,    79,  -291,  -205,
+    -5,   -39,   -20,   252,   -96,
+    76,   174,   101,   163,    61,
+   -69,  -239,   -55,   399,     6,
+  -115,   319,   164,   275,   196,
+   -15,    36,   -47,   331,   121,
+   226,   209,   271,   325,   184,
+    13,   -80,  -218,   471,   353,
+   288,   378,    16,   -51,   251,
+   174,   116,    52,   149,  -279,
+   235,   276,    39,   120,   -48,
+     0,  -108,  -108,   241,  -339,
+   -93,   534,    45,    33,   -87,
+   194,   149,   -71,   405,   -44,
+   409,   370,    81,  -186,  -154,
+    25,  -102,  -448,   124,  -173,
+    22,   408,  -110,  -310,  -214,
+   -26,    23,   -83,   114,    14,
+  -110,   164,    52,   223,   -82,
+    37,   -25,  -263,   306,   -15,
+  -466,   415,   292,   165,   -18,
+    29,   -19,  -171,   155,   182,
+   179,   144,   -27,   231,   258,
+  -103,  -247,  -396,   238,   113,
+   375,  -154,  -109,    -4,   156,
+    98,    85,  -292,    -5,  -124,
+   116,   139,  -116,   -98,  -294,
+   -14,   -83,  -278,  -117,  -378,
+   106,    33,  -106,  -344,  -484,
+   119,    17,  -412,   138,   166,
+   384,   101,  -204,    88,  -156,
+  -121,  -284,  -300,    -1,  -166,
+   280,    33,  -152,  -313,   -81,
+   -37,    22,   229,   153,    37,
+   -60,   -83,   236,    -8,   -41,
+  -169,  -228,   126,   -20,   363,
+  -235,    17,   364,  -156,   156,
+   -25,   -30,    72,   144,   156,
+   153,   -26,   256,    97,   144,
+   -21,   -37,    48,   -65,   250,
+    63,    77,   273,  -128,   124,
+  -129,   -26,    40,     9,  -115,
+    -6,    82,    38,   -90,  -182,
+  -336,   -13,    28,   158,    91,
+   -30,   241,   137,  -170,   -17,
+   146,    14,   -11,    33,    61,
+   192,   197,    54,   -84,    85,
+    23,  -200,   -78,   -29,   140,
+   122,   237,   106,  -341,   136,
+   -57,  -142,   -85,   -16,   -74,
+   -59,   -90,    -8,  -187,   -20,
+  -211,  -267,   216,  -179,  -110,
+   -50,    -7,   220,  -267,   -70,
+   -57,   -42,   -17,   -15,    71,
+    32,    21,    63,  -137,    33,
+  -137,  -175,   104,   -68,    97,
+   -67,   -43,   133,  -301,   221,
+  -116,  -200,   -81,   -92,  -272,
+   -64,   -41,   -54,  -244,  -220,
+  -287,  -242,   -50,   -87,   -89,
+  -245,   236,   102,  -166,  -295,
+    66,    24,  -162,   -71,    95,
+    66,   136,   -90,  -220,   -36,
+   -98,  -161,  -222,  -188,    29,
+   -18,    18,   -19,  -415,     9,
+    49,    61,   100,    39,   -56,
+  -111,    82,   135,   -31,    52,
+   -90,  -153,   -93,   189,   182,
+  -214,   295,   119,   -74,   284,
+     2,   137,    37,    47,   182,
+    92,   117,   184,   -53,   373,
+   -21,   -14,   -35,   136,   391,
+   146,   129,  -164,   -28,   333,
+    92,    80,   -84,   100,  -134,
+    -8,   217,   -32,     3,   -47,
+  -151,   251,  -215,   142,    92,
+  -224,   310,  -172,  -275,    98,
+   159,   155,  -177,   112,    53,
+   205,    27,     8,  -240,   192,
+   169,   120,  -319,  -201,   106,
+    11,    36,   -86,  -237,   455,
+  -109,  -154,  -163,   174,   -55,
+   -38,    32,  -101,   -78,   -59,
+  -205,  -321,   -97,    69,    79,
+  -310,    44,    18,  -185,    34,
+  -115,   -20,  -148,   -39,   203,
+   -29,   154,   -30,  -158,   166,
+   -45,  -131,  -317,   -24,   363,
+  -165,  -205,  -112,  -222,   265,
+   -32,   -44,  -150,    54,  -193,
+    -6,   -38,  -255,  -169,  -115,
+  -266,    87,  -189,   -36,  -169,
+   -60,   -87,  -266,  -436,  -170,
+   -68,   -81,  -278,    24,    38,
+   -23,   -19,  -155,  -256,   141,
+   -61,  -226,  -565,  -175,    71,
+     9,   -29,  -237,  -515,   263};
+
+static Word16 dico22_isf_36b[SIZE_BK22_36b*4] = {
+
+  -298,    -6,    95,    31,
+  -213,   -87,  -122,   261,
+     4,   -49,   208,    14,
+  -129,  -110,    30,   118,
+  -214,   258,   110,  -235,
+   -41,   -18,  -126,   120,
+   103,    65,   127,   -37,
+   126,   -36,   -24,    25,
+  -138,   -67,  -278,  -186,
+  -164,  -194,  -201,    78,
+  -211,   -87,   -51,  -221,
+  -174,   -79,   -94,   -39,
+    23,    -6,  -157,  -240,
+    22,  -110,  -153,   -68,
+   148,    -5,    -2,  -149,
+    -1,  -135,   -39,  -179,
+    68,   360,  -117,   -15,
+   137,    47,  -278,   146,
+   136,   260,   135,    65,
+    61,   116,   -45,    97,
+   231,   379,    87,  -120,
+   338,   177,  -272,     3,
+   266,   156,    28,   -69,
+   260,    84,   -85,    86,
+  -266,   154,  -256,  -182,
+   -17,   -65,  -304,    -6,
+   -40,   175,  -151,  -180,
+   -27,    27,   -87,   -63,
+   121,   114,  -166,  -469,
+   159,   -66,  -323,  -231,
+   214,   152,  -141,  -212,
+   137,    36,  -184,   -51,
+  -282,  -237,    40,    10,
+   -48,  -235,   -37,   251,
+   -54,  -323,   136,    29,
+   -88,  -174,   213,   198,
+  -390,    99,   -63,  -375,
+   107,  -169,  -164,   424,
+    69,  -111,   141,  -167,
+    74,  -129,    65,   144,
+  -353,  -207,  -205,  -109,
+  -160,  -386,  -355,    98,
+  -176,  -493,   -20,  -143,
+  -252,  -432,    -2,   216,
+   -90,  -174,  -168,  -411,
+    13,  -284,  -229,  -160,
+   -87,  -279,    34,  -251,
+   -75,  -263,   -58,   -42,
+   420,    53,  -211,  -358,
+   384,   -35,  -374,   396,
+    68,  -228,   323,    -2,
+   167,  -307,   192,   194,
+   459,   329,    -5,  -332,
+   375,    79,    -7,   313,
+   282,  -124,   200,   -92,
+   271,  -162,   -70,   180,
+  -157,  -298,  -514,  -309,
+    58,  -163,  -546,    18,
+   124,  -364,   167,  -238,
+    83,  -411,  -117,    96,
+   140,  -112,  -388,  -624,
+   259,  -133,  -317,    41,
+   163,  -130,   -64,  -334,
+   226,  -165,  -124,  -110,
+  -466,   -61,     6,   229,
+  -153,   205,  -145,   242,
+  -159,    48,   195,   148,
+   -58,    28,    31,   279,
+  -303,   185,   279,    -4,
+   -61,   197,    59,    86,
+  -114,   123,   168,   -52,
+    35,    36,   100,   126,
+  -407,   102,   -77,   -40,
+  -338,    -1,  -342,   156,
+  -179,   105,   -34,   -97,
+  -185,    84,   -35,   108,
+  -133,   107,   -91,  -357,
+  -180,    54,  -229,    24,
+   -44,    47,    47,  -182,
+   -66,    13,    45,     4,
+  -339,   251,    64,   226,
+   -42,   101,  -350,   275,
+   -99,   398,   142,   121,
+   111,    12,  -102,   260,
+     0,   505,   260,   -94,
+   161,   285,   -96,   224,
+    -4,   206,   314,    33,
+   167,   139,    88,   204,
+  -235,   316,   -60,   -25,
+    -8,  -150,  -312,   201,
+   -36,   292,    61,  -104,
+   -40,   174,  -162,    42,
+   -21,   402,   -29,  -351,
+    21,   152,  -360,   -93,
+    57,   191,   212,  -196,
+    76,   158,   -21,   -69,
+  -328,  -185,   331,   119,
+   -53,   285,    56,   337,
+  -107,   -24,   405,    29,
+   -18,   137,   272,   277,
+  -255,    22,   173,  -191,
+   295,   322,   325,   302,
+    21,   -27,   332,  -178,
+   119,    13,   271,   129,
+  -455,  -180,   116,  -191,
+  -227,    62,  -148,   524,
+  -176,  -287,   282,  -157,
+  -243,    13,   199,   430,
+   -59,   -49,   115,  -365,
+    72,  -172,  -137,    93,
+  -138,  -126,   141,   -84,
+     5,  -124,    38,   -20,
+  -258,   311,   601,   213,
+    94,   130,   -61,   502,
+    -1,  -157,   485,   313,
+   146,   -74,   158,   345,
+   276,   135,   280,   -57,
+   490,   252,    99,    43,
+   267,   -74,   429,   105,
+   278,   -23,   119,    94,
+  -542,   488,   257,  -115,
+   -84,  -244,  -438,   478,
+  -113,  -545,   387,   101,
+   -95,  -306,   111,   498,
+    95,   166,    22,  -301,
+   420,   -15,   -58,   -78,
+   270,    29,   122,  -282,
+   160,  -240,    50,   -38};
+
+static Word16 dico23_isf_36b[SIZE_BK23_36b*7] = {
+
+    81,   -18,    68,   -27,  -122,  -280,    -4,
+    45,  -177,   209,   -30,  -136,   -74,   131,
+   -44,   101,   -75,   -88,   -48,  -137,   -54,
+  -245,   -28,    63,   -18,  -112,  -103,    58,
+   -79,    -6,   220,   -65,   114,   -35,   -50,
+   109,   -65,   143,  -114,   129,    76,   125,
+   166,    90,   -61,  -242,   186,   -74,   -43,
+   -46,   -92,    49,  -227,    24,  -155,    39,
+    67,    85,    99,   -42,    53,  -184,  -281,
+   142,  -122,     0,    21,  -142,   -15,   -17,
+   223,    92,   -21,   -48,   -82,   -14,  -167,
+    51,   -37,  -243,   -30,   -90,    18,   -56,
+    54,   105,    74,    86,    69,    13,  -101,
+   196,    72,   -89,    43,    65,    19,    39,
+   121,    34,   131,   -82,    25,   213,  -156,
+   101,  -102,  -136,   -21,    57,   214,    22,
+    36,  -124,   205,   204,    58,  -156,   -83,
+    83,  -117,   137,   137,    85,   116,    44,
+   -92,  -148,   -68,    11,  -102,  -197,  -220,
+   -76,  -185,   -58,   132,   -26,  -183,    85,
+    -7,   -31,    -2,    23,   205,  -151,    10,
+   -27,   -37,    -5,   -18,   292,   131,     1,
+   117,  -168,     9,   -93,    80,   -59,  -125,
+  -182,  -244,    98,   -24,   135,   -22,    94,
+   221,    97,   106,    42,    43,  -160,    83,
+    25,   -64,   -21,     6,    14,   -15,   154,
+   126,    15,  -140,   150,   -10,  -207,  -114,
+    79,   -63,  -211,   -70,   -28,  -217,   165,
+    46,    38,   -22,   281,   132,   -62,   109,
+   112,    54,  -112,   -93,   208,    27,   296,
+   115,    10,  -147,    41,   216,    42,  -276,
+    50,  -115,  -254,   167,   117,    -2,    61,
+    17,   144,    34,   -72,  -186,  -150,   272,
+   -29,   -66,   -89,   -95,  -149,   129,   251,
+   122,     0,   -50,  -234,   -91,    36,    26,
+  -105,  -102,   -88,  -121,  -236,    -7,   -11,
+  -204,   109,     5,  -191,   105,   -15,   163,
+   -80,    32,   -24,  -209,    41,   294,    70,
+  -106,   -94,  -204,  -118,   120,   -50,   -37,
+   -82,  -241,    46,  -131,   -29,   150,   -55,
+    33,   155,   120,   -89,    -8,     7,    62,
+   213,    82,    61,    18,  -161,   144,   152,
+    30,   131,    65,   -87,  -255,   -17,  -107,
+    -8,    85,   -64,    51,  -162,   223,   -53,
+  -134,   261,    69,   -56,   218,    72,  -111,
+     2,   155,  -113,   -87,    49,    85,   -28,
+  -163,    42,    -1,  -196,     7,    39,  -245,
+    14,  -137,   -79,    11,  -160,   202,  -293,
+   -94,    33,   208,   100,    56,   -44,   326,
+   -78,   -41,   232,    13,  -142,   227,    80,
+   -16,   -87,   201,    33,  -133,    15,  -183,
+   -58,  -192,   -47,   184,  -128,   133,    99,
+  -205,    11,  -155,    78,    52,    72,   141,
+  -246,    26,    99,   151,    59,   115,   -64,
+   -79,   -47,   -16,   -14,     6,    47,   -43,
+   -72,  -178,   -27,   162,   112,    43,  -174,
+  -175,   238,   186,    71,   -54,  -188,   -76,
+  -225,   233,    39,   -39,  -158,   122,    44,
+   -26,    43,    84,   130,   -93,   -51,    22,
+     3,    92,  -150,   136,  -182,   -57,    97,
+  -131,   179,   -78,    80,    91,  -165,    90,
+    -2,   148,    15,   130,    65,   175,   117,
+  -138,   114,  -137,   132,     3,   -10,  -186,
+   140,    -4,   -37,   254,   -62,    92,  -109};
+
+
--- /dev/null
+++ b/amr-wb/random.c
@@ -1,0 +1,19 @@
+/*-------------------------------------------------------------------*
+ *                         RANDOM.C                                  *
+ *-------------------------------------------------------------------*
+ * Signed 16 bits random generator.                                  *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+
+Word16 Random(Word16 * seed)
+{
+    /* static Word16 seed = 21845; */
+
+    *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L));   move16();
+
+    return (*seed);
+}
--- /dev/null
+++ b/amr-wb/residu.c
@@ -1,0 +1,35 @@
+/*-----------------------------------------------------------------------*
+ *                         RESIDU.C                                      *
+ *-----------------------------------------------------------------------*
+ * Compute the LPC residual by filtering the input speech through A(z)   *
+ *-----------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+
+void Residu(
+     Word16 a[],                           /* (i) Q12 : prediction coefficients                     */
+     Word16 m,                             /* (i)     : order of LP filter                          */
+     Word16 x[],                           /* (i)     : speech (values x[-m..-1] are needed         */
+     Word16 y[],                           /* (o) x2  : residual signal                             */
+     Word16 lg                             /* (i)     : size of filtering                           */
+)
+{
+    Word16 i, j;
+    Word32 s;
+
+    for (i = 0; i < lg; i++)
+    {
+        s = L_mult(x[i], a[0]);
+
+        for (j = 1; j <= m; j++)
+            s = L_mac(s, a[j], x[i - j]);
+
+        s = L_shl(s, 3 + 1);               /* saturation can occur here */
+        y[i] = round(s);                   move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/scale.c
@@ -1,0 +1,29 @@
+/*-------------------------------------------------------------------*
+ *                         SCALE.C                                   *
+ *-------------------------------------------------------------------*
+ * Scale signal to get maximum of dynamic.                           *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+
+void Scale_sig(
+     Word16 x[],                           /* (i/o) : signal to scale               */
+     Word16 lg,                            /* (i)   : size of x[]                   */
+     Word16 exp                            /* (i)   : exponent: x = round(x << exp) */
+)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    for (i = 0; i < lg; i++)
+    {
+        L_tmp = L_deposit_h(x[i]);
+        L_tmp = L_shl(L_tmp, exp);         /* saturation can occur here */
+        x[i] = round(L_tmp);               move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/syn_filt.c
@@ -1,0 +1,107 @@
+/*-------------------------------------------------------------------*
+ *                         SYN_FILT.C                                *
+ *-------------------------------------------------------------------*
+ * Do the synthesis filtering 1/A(z).                                *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+#include "cnst.h"
+
+
+void Syn_filt(
+     Word16 a[],                           /* (i) Q12 : a[m+1] prediction coefficients           */
+     Word16 m,                             /* (i)     : order of LP filter                       */
+     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.         */
+)
+{
+    Word16 i, j, y_buf[L_SUBFR16k + M16k], a0, s;
+    Word32 L_tmp;
+    Word16 *yy;
+
+    yy = &y_buf[0];                        move16();
+
+    /* copy initial filter states into synthesis buffer */
+    for (i = 0; i < m; i++)
+    {
+        *yy++ = mem[i];                    move16();
+    }
+
+    s = sub(norm_s(a[0]), 2);
+    a0 = shr(a[0], 1);                     /* input / 2 */
+
+    /* Do the filtering. */
+
+    for (i = 0; i < lg; i++)
+    {
+        L_tmp = L_mult(x[i], a0);
+
+        for (j = 1; j <= m; j++)
+            L_tmp = L_msu(L_tmp, a[j], yy[i - j]);
+
+        L_tmp = L_shl(L_tmp, add(3, s));
+
+        y[i] = yy[i] = round(L_tmp);       move16();move16();
+    }
+
+    /* Update memory if required */
+    test();
+    if (update)
+        for (i = 0; i < m; i++)
+        {
+            mem[i] = yy[lg - m + i];       move16();
+        }
+
+    return;
+}
+
+
+void Syn_filt_32(
+     Word16 a[],                           /* (i) Q12 : a[m+1] prediction coefficients */
+     Word16 m,                             /* (i)     : order of LP filter             */
+     Word16 exc[],                         /* (i) Qnew: excitation (exc[i] >> Qnew)    */
+     Word16 Qnew,                          /* (i)     : exc scaling = 0(min) to 8(max) */
+     Word16 sig_hi[],                      /* (o) /16 : synthesis high                 */
+     Word16 sig_lo[],                      /* (o) /16 : synthesis low                  */
+     Word16 lg                             /* (i)     : size of filtering              */
+)
+{
+    Word16 i, j, a0, s;
+    Word32 L_tmp;
+
+    s = sub(norm_s(a[0]), 2);
+
+    a0 = shr(a[0], add(4, Qnew));          /* input / 16 and >>Qnew */
+
+    /* Do the filtering. */
+
+    for (i = 0; i < lg; i++)
+    {
+        L_tmp = 0;                         move32();
+        for (j = 1; j <= m; j++)
+            L_tmp = L_msu(L_tmp, sig_lo[i - j], a[j]);
+
+        L_tmp = L_shr(L_tmp, 16 - 4);      /* -4 : sig_lo[i] << 4 */
+
+        L_tmp = L_mac(L_tmp, exc[i], a0);
+
+        for (j = 1; j <= m; j++)
+            L_tmp = L_msu(L_tmp, sig_hi[i - j], a[j]);
+
+        /* sig_hi = bit16 to bit31 of synthesis */
+        L_tmp = L_shl(L_tmp, add(3, s));           /* ai in Q12 */
+        sig_hi[i] = extract_h(L_tmp);      move16();
+
+        /* sig_lo = bit4 to bit15 of synthesis */
+        L_tmp = L_shr(L_tmp, 4);           /* 4 : sig_lo[i] >> 4 */
+        sig_lo[i] = extract_l(L_msu(L_tmp, sig_hi[i], 2048));   move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/typedef.h
@@ -1,0 +1,52 @@
+/*
+********************************************************************************
+*
+*      File             : typedef.c
+*      Purpose          : Basic types.
+*
+********************************************************************************
+*/
+
+
+#ifndef typedef_h
+#define typedef_h "$Id $"
+
+#undef ORIGINAL_TYPEDEF_H /* define to get "original" ETSI version
+                             of typedef.h                           */
+
+#ifdef ORIGINAL_TYPEDEF_H
+/*
+ * this is the original code from the ETSI file typedef.h
+ */
+   
+#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__)
+typedef signed char Word8;
+typedef short Word16;
+typedef long Word32;
+typedef int Flag;
+
+#elif defined(__sun)
+typedef signed char Word8;
+typedef short Word16;
+typedef long Word32;
+typedef int Flag;
+
+#elif defined(__unix__) || defined(__unix)
+typedef signed char Word8;
+typedef short Word16;
+typedef int Word32;
+typedef int Flag;
+
+#endif
+#else /* not original typedef.h */
+
+/*
+ * use (improved) type definition file typdefs.h and add a "Flag" type
+ */
+#include "typedefs.h"
+typedef int Flag;
+
+#endif
+
+#endif
+
--- /dev/null
+++ b/amr-wb/typedefs.h
@@ -1,0 +1,176 @@
+/*
+*
+*      File             : typedefs.h
+*      Description      : Definition of platform independent data
+*                         types and constants
+*
+*
+*      The following platform independent data types and corresponding
+*      preprocessor (#define) constants are defined:
+*
+*        defined type  meaning           corresponding constants
+*        ----------------------------------------------------------
+*        Char          character         (none)
+*        Bool          boolean           true, false
+*        Word8         8-bit signed      minWord8,   maxWord8
+*        UWord8        8-bit unsigned    minUWord8,  maxUWord8
+*        Word16        16-bit signed     minWord16,  maxWord16
+*        UWord16       16-bit unsigned   minUWord16, maxUWord16
+*        Word32        32-bit signed     minWord32,  maxWord32
+*        UWord32       32-bit unsigned   minUWord32, maxUWord32
+*        Float         floating point    minFloat,   maxFloat
+*
+*
+*      The following compile switches are #defined:
+*
+*        PLATFORM      string indicating platform progam is compiled on
+*                      possible values: "OSF", "PC", "SUN"
+*
+*        OSF           only defined if the current platform is an Alpha
+*        PC            only defined if the current platform is a PC
+*        SUN           only defined if the current platform is a Sun
+*        
+*        LSBFIRST      is defined if the byte order on this platform is
+*                      "least significant byte first" -> defined on DEC Alpha
+*                      and PC, undefined on Sun
+*
+********************************************************************************
+*/
+#ifndef typedefs_h
+#define typedefs_h "$Id $"
+
+/*
+********************************************************************************
+*                         INCLUDE FILES
+********************************************************************************
+*/
+#include <float.h>
+#include <limits.h>
+
+
+
+/*
+********************************************************************************
+*                         DEFINITION OF CONSTANTS 
+********************************************************************************
+*/
+/*
+ ********* define char type
+ */
+typedef char Char;
+
+/*
+ ********* define 8 bit signed/unsigned types & constants
+ */
+#if SCHAR_MAX == 127
+typedef signed char Word8;
+#define minWord8  SCHAR_MIN
+#define maxWord8  SCHAR_MAX
+
+typedef unsigned char UWord8;
+#define minUWord8 0
+#define maxUWord8 UCHAR_MAX
+#else
+#error cannot find 8-bit type
+#endif
+
+
+/*
+ ********* define 16 bit signed/unsigned types & constants
+ */
+#if INT_MAX == 32767
+typedef int Word16;
+#define minWord16     INT_MIN
+#define maxWord16     INT_MAX
+typedef unsigned int UWord16;
+#define minUWord16    0
+#define maxUWord16    UINT_MAX
+#elif SHRT_MAX == 32767
+typedef short Word16;
+#define minWord16     SHRT_MIN
+#define maxWord16     SHRT_MAX
+typedef unsigned short UWord16;
+#define minUWord16    0
+#define maxUWord16    USHRT_MAX
+#else
+#error cannot find 16-bit type
+#endif
+
+
+/*
+ ********* define 32 bit signed/unsigned types & constants
+ */
+#if INT_MAX == 2147483647
+typedef int Word32;
+#define minWord32     INT_MIN
+#define maxWord32     INT_MAX
+typedef unsigned int UWord32;
+#define minUWord32    0
+#define maxUWord32    UINT_MAX
+#elif LONG_MAX == 2147483647
+typedef long Word32;
+#define minWord32     LONG_MIN
+#define maxWord32     LONG_MAX
+typedef unsigned long UWord32;
+#define minUWord32    0
+#define maxUWord32    ULONG_MAX
+#else
+#error cannot find 32-bit type
+#endif
+
+/*
+ ********* define floating point type & constants
+ */
+/* use "#if 0" below if Float should be double;
+   use "#if 1" below if Float should be float
+ */
+#if 0
+typedef float Float;
+#define maxFloat      FLT_MAX
+#define minFloat      FLT_MIN
+#else
+typedef double Float;
+#define maxFloat      DBL_MAX
+#define minFloat      DBL_MIN
+#endif
+
+/*
+ ********* define complex type
+ */
+typedef struct {
+  Float r;  /* real      part */
+  Float i;  /* imaginary part */
+} CPX;
+
+/*
+ ********* define boolean type
+ */
+typedef int Bool;
+#define false 0
+#define true 1
+
+/*
+ ********* Check current platform
+ */
+#if defined(__MSDOS__)
+#define PC
+#define PLATFORM "PC"
+#define LSBFIRST
+#elif defined(__osf__)
+#define OSF
+#define PLATFORM "OSF"
+#define LSBFIRST
+#elif defined(__sun__) || defined(__sun)
+#define SUN
+#define PLATFORM "SUN"
+#undef LSBFIRST
+#elif defined(linux) && defined(i386)
+#define PC
+#define PLATFORM "PC"
+#define LSBFIRST
+#else
+#error "can't determine architecture; adapt typedefs.h to your platform"
+#endif
+
+#endif
+
--- /dev/null
+++ b/amr-wb/updt_tar.c
@@ -1,0 +1,30 @@
+/*-------------------------------------------------------------------*
+ *                         UPD_TAR.C                                 *
+ *-------------------------------------------------------------------*
+ * Update the target vector for codebook search.                     *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+void Updt_tar(
+     Word16 * x,                           /* (i) Q0  : old target (for pitch search)     */
+     Word16 * x2,                          /* (o) Q0  : new target (for codebook search)  */
+     Word16 * y,                           /* (i) Q0  : filtered adaptive codebook vector */
+     Word16 gain,                          /* (i) Q14 : adaptive codebook gain            */
+     Word16 L                              /* (i)     : subframe size                     */
+)
+{
+    Word16 i;
+    Word32 L_tmp;
+
+    for (i = 0; i < L; i++)
+    {
+        L_tmp = L_mult(x[i], 16384);
+        L_tmp = L_msu(L_tmp, y[i], gain);
+        x2[i] = extract_h(L_shl(L_tmp, 1));  move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/util.c
@@ -1,0 +1,54 @@
+/*-------------------------------------------------------------------*
+ *                         UTIL.C                                    *
+ *-------------------------------------------------------------------*
+ * Vector routines                                                   *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+
+/*-------------------------------------------------------------------*
+ * Function  Set zero()                                              *
+ *           ~~~~~~~~~~                                              *
+ * Set vector x[] to zero                                            *
+ *-------------------------------------------------------------------*/
+
+void Set_zero(
+     Word16 x[],                           /* (o)    : vector to clear     */
+     Word16 L                              /* (i)    : length of vector    */
+)
+{
+    Word16 i;
+
+    for (i = 0; i < L; i++)
+    {
+        x[i] = 0;                          move16();
+    }
+
+    return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function  Copy:                                                   *
+ *           ~~~~~                                                   *
+ * Copy vector x[] to y[]                                            *
+ *-------------------------------------------------------------------*/
+
+void Copy(
+     Word16 x[],                           /* (i)   : input vector   */
+     Word16 y[],                           /* (o)   : output vector  */
+     Word16 L                              /* (i)   : vector length  */
+)
+{
+    Word16 i;
+
+    for (i = 0; i < L; i++)
+    {
+        y[i] = x[i];                       move16();
+    }
+
+    return;
+}
--- /dev/null
+++ b/amr-wb/voicefac.c
@@ -1,0 +1,66 @@
+/*-------------------------------------------------------------------*
+ *                         VOICEFAC.C                                *
+ *-------------------------------------------------------------------*
+ * Find the voicing factor (1=voice to -1=unvoiced).                 *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "math_op.h"
+#include "count.h"
+
+Word16 voice_factor(                       /* (o) Q15   : factor (-1=unvoiced to 1=voiced) */
+     Word16 exc[],                         /* (i) Q_exc : pitch excitation                 */
+     Word16 Q_exc,                         /* (i)       : exc format                       */
+     Word16 gain_pit,                      /* (i) Q14   : gain of pitch                    */
+     Word16 code[],                        /* (i) Q9    : Fixed codebook excitation        */
+     Word16 gain_code,                     /* (i) Q0    : gain of code                     */
+     Word16 L_subfr                        /* (i)       : subframe length                  */
+)
+{
+    Word16 i, tmp, exp, ener1, exp1, ener2, exp2;
+    Word32 L_tmp;
+
+    ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1));
+    exp1 = sub(exp1, add(Q_exc, Q_exc));
+    L_tmp = L_mult(gain_pit, gain_pit);
+    exp = norm_l(L_tmp);
+    tmp = extract_h(L_shl(L_tmp, exp));
+    ener1 = mult(ener1, tmp);
+    exp1 = sub(sub(exp1, exp), 10);        /* 10 -> gain_pit Q14 to Q9 */
+
+    ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2));
+
+    exp = norm_s(gain_code);
+    tmp = shl(gain_code, exp);
+    tmp = mult(tmp, tmp);
+    ener2 = mult(ener2, tmp);
+    exp2 = sub(exp2, add(exp, exp));
+
+    i = sub(exp1, exp2);
+
+    test();
+    if (i >= 0)
+    {
+        ener1 = shr(ener1, 1);
+        ener2 = shr(ener2, add(i, 1));
+    } else
+    {
+        ener1 = shr(ener1, sub(1, i));
+        ener2 = shr(ener2, 1);
+    }
+
+    tmp = sub(ener1, ener2);
+    ener1 = add(add(ener1, ener2), 1);
+
+    test();
+    if (tmp >= 0)
+    {
+        tmp = div_s(tmp, ener1);
+    } else
+    {
+        tmp = negate(div_s(negate(tmp), ener1));
+    }
+
+    return (tmp);
+}
--- /dev/null
+++ b/amr-wb/wb_vad.c
@@ -1,0 +1,850 @@
+/*-------------------------------------------------------------------*
+ *                         WB_VAD.C                                  *
+ *-------------------------------------------------------------------*
+ * Voice Activity Detection.                                         *
+ *-------------------------------------------------------------------*/
+
+/******************************************************************************
+*                         INCLUDE FILES
+******************************************************************************/
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cnst.h"
+#include "wb_vad.h"
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+#include "math_op.h"
+#include "wb_vad_c.h"
+
+/******************************************************************************
+*                         PRIVATE PROGRAM CODE
+******************************************************************************/
+
+/******************************************************************************
+* log2
+*
+*  Calculate Log2 and scale the signal:
+*
+*    ilog2(Word32 in) = -1024*log10(in * 2^-31)/log10(2), where in = [1, 2^31-1]
+*
+*  input   output
+*  32768   16384
+*  1       31744
+*
+* When input is in the range of [1,2^16], max error is 0.0380%.
+*
+*
+*/
+
+Word16 ilog2(                              /* return: output value of the log2 */
+     Word16 mant                           /* i: value to be converted */
+)
+{
+    Word16 i, ex, ex2, res;
+    Word32 l_temp;
+
+    test();
+    if (mant <= 0)
+    {
+        mant = 1;                          move16();
+    }
+    ex = norm_s(mant);
+    mant = shl(mant, ex);
+
+    for (i = 0; i < 3; i++)
+        mant = mult(mant, mant);
+    l_temp = L_mult(mant, mant);
+
+    ex2 = norm_l(l_temp);
+    mant = extract_h(L_shl(l_temp, ex2));
+
+    res = shl(add(ex, 16), 10);
+    res = add(res, shl(ex2, 6));
+    res = sub(add(res, 127), shr(mant, 8));
+    return (res);
+}
+
+/******************************************************************************
+*
+*     Function     : filter5
+*     Purpose      : Fifth-order half-band lowpass/highpass filter pair with
+*                    decimation.
+*
+*/
+static void filter5(
+     Word16 * in0,                         /* i/o : input values; output low-pass part  */
+     Word16 * in1,                         /* i/o : input values; output high-pass part */
+     Word16 data[]                         /* i/o : filter memory                       */
+)
+{
+    Word16 temp0, temp1, temp2;
+
+    temp0 = sub(*in0, mult(COEFF5_1, data[0]));
+    temp1 = add(data[0], mult(COEFF5_1, temp0));
+    data[0] = temp0;                       move16();
+
+    temp0 = sub(*in1, mult(COEFF5_2, data[1]));
+    temp2 = add(data[1], mult(COEFF5_2, temp0));
+    data[1] = temp0;                       move16();
+
+    *in0 = extract_h(L_shl(L_add(temp1, temp2), 15));   move16();
+    *in1 = extract_h(L_shl(L_sub(temp1, temp2), 15));   move16();
+}
+
+/******************************************************************************
+*
+*     Function     : filter3
+*     Purpose      : Third-order half-band lowpass/highpass filter pair with
+*                    decimation.
+*
+*/
+static void filter3(
+     Word16 * in0,                         /* i/o : input values; output low-pass part  */
+     Word16 * in1,                         /* i/o : input values; output high-pass part */
+     Word16 * data                         /* i/o : filter memory                       */
+)
+{
+    Word16 temp1, temp2;
+
+    temp1 = sub(*in1, mult(COEFF3, *data));
+    temp2 = add(*data, mult(COEFF3, temp1));
+    *data = temp1;                         move16();
+
+    *in1 = extract_h(L_shl(L_sub(*in0, temp2), 15));    move16();
+    *in0 = extract_h(L_shl(L_add(*in0, temp2), 15));    move16();
+}
+
+/******************************************************************************
+*
+*     Function   : level_calculation
+*     Purpose    : Calculate signal level in a sub-band. Level is calculated
+*                  by summing absolute values of the input data.
+*
+*                  Signal level calculated from of the end of the frame
+*                  (data[count1 - count2]) is stored to (*sub_level)
+*                  and added to the level of the next frame.
+*
+*/
+static Word16 level_calculation(           /* return: signal level */
+     Word16 data[],                        /* i   : signal buffer                                    */
+     Word16 * sub_level,                   /* i   : level calculated at the end of the previous frame*/
+                                           /* o   : level of signal calculated from the last         */
+                                           /*       (count2 - count1) samples                        */
+     Word16 count1,                        /* i   : number of samples to be counted                  */
+     Word16 count2,                        /* i   : number of samples to be counted                  */
+     Word16 ind_m,                         /* i   : step size for the index of the data buffer       */
+     Word16 ind_a,                         /* i   : starting index of the data buffer                */
+     Word16 scale                          /* i   : scaling for the level calculation                */
+)
+{
+    Word32 l_temp1, l_temp2;
+    Word16 level, i;
+
+    l_temp1 = 0L;                          move32();
+    for (i = count1; i < count2; i++)
+    {
+        l_temp1 = L_mac(l_temp1, 1, abs_s(data[ind_m * i + ind_a]));
+    }
+
+    l_temp2 = L_add(l_temp1, L_shl(*sub_level, sub(16, scale)));
+    *sub_level = extract_h(L_shl(l_temp1, scale));      move16();
+
+    for (i = 0; i < count1; i++)
+    {
+        l_temp2 = L_mac(l_temp2, 1, abs_s(data[ind_m * i + ind_a]));
+    }
+    level = extract_h(L_shl(l_temp2, scale));
+
+    return level;
+}
+
+/******************************************************************************
+*
+*     Function     : filter_bank
+*     Purpose      : Divide input signal into bands and calculate level of
+*                    the signal in each band
+*
+*/
+static void filter_bank(
+     VadVars * st,                         /* i/o : State struct               */
+     Word16 in[],                          /* i   : input frame                */
+     Word16 level[]                        /* 0   : signal levels at each band */
+)
+{
+    Word16 i;
+    Word16 tmp_buf[FRAME_LEN];
+
+    /* shift input 1 bit down for safe scaling */
+    for (i = 0; i < FRAME_LEN; i++)
+    {
+        tmp_buf[i] = shr(in[i], 1);        move16();
+    }
+
+    /* run the filter bank */
+    for (i = 0; i < FRAME_LEN / 2; i++)
+    {
+        filter5(&tmp_buf[2 * i], &tmp_buf[2 * i + 1], st->a_data5[0]);
+    }
+    for (i = 0; i < FRAME_LEN / 4; i++)
+    {
+        filter5(&tmp_buf[4 * i], &tmp_buf[4 * i + 2], st->a_data5[1]);
+        filter5(&tmp_buf[4 * i + 1], &tmp_buf[4 * i + 3], st->a_data5[2]);
+    }
+    for (i = 0; i < FRAME_LEN / 8; i++)
+    {
+        filter5(&tmp_buf[8 * i], &tmp_buf[8 * i + 4], st->a_data5[3]);
+        filter5(&tmp_buf[8 * i + 2], &tmp_buf[8 * i + 6], st->a_data5[4]);
+        filter3(&tmp_buf[8 * i + 3], &tmp_buf[8 * i + 7], &st->a_data3[0]);
+    }
+    for (i = 0; i < FRAME_LEN / 16; i++)
+    {
+        filter3(&tmp_buf[16 * i + 0], &tmp_buf[16 * i + 8], &st->a_data3[1]);
+        filter3(&tmp_buf[16 * i + 4], &tmp_buf[16 * i + 12], &st->a_data3[2]);
+        filter3(&tmp_buf[16 * i + 6], &tmp_buf[16 * i + 14], &st->a_data3[3]);
+    }
+
+    for (i = 0; i < FRAME_LEN / 32; i++)
+    {
+        filter3(&tmp_buf[32 * i + 0], &tmp_buf[32 * i + 16], &st->a_data3[4]);
+        filter3(&tmp_buf[32 * i + 8], &tmp_buf[32 * i + 24], &st->a_data3[5]);
+    }
+
+    /* calculate levels in each frequency band */
+
+    /* 4800 - 6400 Hz */
+    level[11] = level_calculation(tmp_buf, &st->sub_level[11],
+        FRAME_LEN / 4 - 48, FRAME_LEN / 4, 4, 1, 14);   move16();
+    /* 4000 - 4800 Hz */
+    level[10] = level_calculation(tmp_buf, &st->sub_level[10],
+        FRAME_LEN / 8 - 24, FRAME_LEN / 8, 8, 7, 15);   move16();
+    /* 3200 - 4000 Hz */
+    level[9] = level_calculation(tmp_buf, &st->sub_level[9],
+        FRAME_LEN / 8 - 24, FRAME_LEN / 8, 8, 3, 15);   move16();
+    /* 2400 - 3200 Hz */
+    level[8] = level_calculation(tmp_buf, &st->sub_level[8],
+        FRAME_LEN / 8 - 24, FRAME_LEN / 8, 8, 2, 15);   move16();
+    /* 2000 - 2400 Hz */
+    level[7] = level_calculation(tmp_buf, &st->sub_level[7],
+        FRAME_LEN / 16 - 12, FRAME_LEN / 16, 16, 14, 16);       move16();
+    /* 1600 - 2000 Hz */
+    level[6] = level_calculation(tmp_buf, &st->sub_level[6],
+        FRAME_LEN / 16 - 12, FRAME_LEN / 16, 16, 6, 16);        move16();
+    /* 1200 - 1600 Hz */
+    level[5] = level_calculation(tmp_buf, &st->sub_level[5],
+        FRAME_LEN / 16 - 12, FRAME_LEN / 16, 16, 4, 16);        move16();
+    /* 800 - 1200 Hz */
+    level[4] = level_calculation(tmp_buf, &st->sub_level[4],
+        FRAME_LEN / 16 - 12, FRAME_LEN / 16, 16, 12, 16);       move16();
+    /* 600 - 800 Hz */
+    level[3] = level_calculation(tmp_buf, &st->sub_level[3],
+        FRAME_LEN / 32 - 6, FRAME_LEN / 32, 32, 8, 17); move16();
+    /* 400 - 600 Hz */
+    level[2] = level_calculation(tmp_buf, &st->sub_level[2],
+        FRAME_LEN / 32 - 6, FRAME_LEN / 32, 32, 24, 17);        move16();
+    /* 200 - 400 Hz */
+    level[1] = level_calculation(tmp_buf, &st->sub_level[1],
+        FRAME_LEN / 32 - 6, FRAME_LEN / 32, 32, 16, 17);        move16();
+    /* 0 - 200 Hz */
+    level[0] = level_calculation(tmp_buf, &st->sub_level[0],
+        FRAME_LEN / 32 - 6, FRAME_LEN / 32, 32, 0, 17); move16();
+}
+
+/******************************************************************************
+*
+*     Function   : update_cntrl
+*     Purpose    : Control update of the background noise estimate.
+*
+*/
+static void update_cntrl(
+     VadVars * st,                         /* i/o : State structure                    */
+     Word16 level[]                        /* i   : sub-band levels of the input frame */
+)
+{
+    Word16 i, temp, stat_rat, exp;
+    Word16 num, denom;
+    Word16 alpha;
+
+    /* if a tone has been detected for a while, initialize stat_count */
+    logic16();test();
+    if (sub((Word16) (st->tone_flag & 0x7c00), 0x7c00) == 0)
+    {
+        st->stat_count = STAT_COUNT;       move16();
+    } else
+    {
+        /* if 8 last vad-decisions have been "0", reinitialize stat_count */
+        logic16();test();
+        if ((st->vadreg & 0x7f80) == 0)
+        {
+            st->stat_count = STAT_COUNT;   move16();
+        } else
+        {
+            stat_rat = 0;                  move16();
+            for (i = 0; i < COMPLEN; i++)
+            {
+                test();
+                if (sub(level[i], st->ave_level[i]) > 0)
+                {
+                    num = level[i];        move16();
+                    denom = st->ave_level[i];   move16();
+                } else
+                {
+                    num = st->ave_level[i];move16();
+                    denom = level[i];      move16();
+                }
+                /* Limit nimimum value of num and denom to STAT_THR_LEVEL */
+                test();
+                if (sub(num, STAT_THR_LEVEL) < 0)
+                {
+                    num = STAT_THR_LEVEL;  move16();
+                }
+                test();
+                if (sub(denom, STAT_THR_LEVEL) < 0)
+                {
+                    denom = STAT_THR_LEVEL;move16();
+                }
+                exp = norm_s(denom);
+                denom = shl(denom, exp);
+
+                /* stat_rat = num/denom * 64 */
+                temp = div_s(shr(num, 1), denom);
+                stat_rat = add(stat_rat, shr(temp, sub(8, exp)));
+            }
+
+            /* compare stat_rat with a threshold and update stat_count */
+            test();
+            if (sub(stat_rat, STAT_THR) > 0)
+            {
+                st->stat_count = STAT_COUNT;    move16();
+            } else
+            {
+                logic16();test();
+                if ((st->vadreg & 0x4000) != 0)
+                {
+                    test();
+                    if (st->stat_count != 0)
+                    {
+                        st->stat_count = sub(st->stat_count, 1);        move16();
+                    }
+                }
+            }
+        }
+    }
+
+    /* Update average amplitude estimate for stationarity estimation */
+    alpha = ALPHA4;                        move16();
+    test();test();logic16();
+    if (sub(st->stat_count, STAT_COUNT) == 0)
+    {
+        alpha = 32767;                     move16();
+    } else if ((st->vadreg & 0x4000) == 0)
+    {
+        logic16();test();
+        alpha = ALPHA5;                    move16();
+    }
+    for (i = 0; i < COMPLEN; i++)
+    {
+        st->ave_level[i] = add(st->ave_level[i],
+            mult_r(alpha, sub(level[i], st->ave_level[i])));    move16();
+    }
+}
+
+/******************************************************************************
+*
+*     Function     : hangover_addition
+*     Purpose      : Add hangover after speech bursts
+*
+*/
+
+static Word16 hangover_addition(           /* return: VAD_flag indicating final VAD decision */
+     VadVars * st,                         /* i/o : State structure                     */
+     Word16 low_power,                     /* i   : flag power of the input frame    */
+     Word16 hang_len,                      /* i   : hangover length */
+     Word16 burst_len                      /* i   : minimum burst length for hangover addition */
+)
+{
+    /* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0"         */
+    test();
+    if (low_power != 0)
+    {
+        st->burst_count = 0;               move16();
+        st->hang_count = 0;                move16();
+        return 0;
+    }
+    /* update the counters (hang_count, burst_count) */
+    logic16();test();
+    if ((st->vadreg & 0x4000) != 0)
+    {
+        st->burst_count = add(st->burst_count, 1);      move16();
+        test();
+        if (sub(st->burst_count, burst_len) >= 0)
+        {
+            st->hang_count = hang_len;     move16();
+        }
+        return 1;
+    } else
+    {
+        st->burst_count = 0;               move16();
+        test();
+        if (st->hang_count > 0)
+        {
+            st->hang_count = sub(st->hang_count, 1);    move16();
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/******************************************************************************
+*
+*     Function   : noise_estimate_update
+*     Purpose    : Update of background noise estimate
+*
+*/
+
+static void noise_estimate_update(
+     VadVars * st,                         /* i/o : State structure                       */
+     Word16 level[]                        /* i   : sub-band levels of the input frame */
+)
+{
+    Word16 i, alpha_up, alpha_down, bckr_add;
+
+    /* Control update of bckr_est[] */
+    update_cntrl(st, level);
+
+    /* Reason for using bckr_add is to avoid problems caused by fixed-point dynamics when noise level and
+     * required change is very small. */
+    bckr_add = 2;                          move16();
+
+    /* Choose update speed */
+    logic16();test();
+    if ((0x7800 & st->vadreg) == 0)
+    {
+        alpha_up = ALPHA_UP1;              move16();
+        alpha_down = ALPHA_DOWN1;          move16();
+    } else
+    {
+        test();
+        if ((st->stat_count == 0))
+        {
+            alpha_up = ALPHA_UP2;          move16();
+            alpha_down = ALPHA_DOWN2;      move16();
+        } else
+        {
+            alpha_up = 0;                  move16();
+            alpha_down = ALPHA3;           move16();
+            bckr_add = 0;                  move16();
+        }
+    }
+
+    /* Update noise estimate (bckr_est) */
+    for (i = 0; i < COMPLEN; i++)
+    {
+        Word16 temp;
+
+        temp = sub(st->old_level[i], st->bckr_est[i]);
+
+        test();
+        if (temp < 0)
+        {                                  /* update downwards */
+            st->bckr_est[i] = add(-2, add(st->bckr_est[i],
+                    mult_r(alpha_down, temp))); move16();
+
+            /* limit minimum value of the noise estimate to NOISE_MIN */
+            test();
+            if (sub(st->bckr_est[i], NOISE_MIN) < 0)
+            {
+                st->bckr_est[i] = NOISE_MIN;    move16();
+            }
+        } else
+        {                                  /* update upwards */
+            st->bckr_est[i] = add(bckr_add, add(st->bckr_est[i],
+                    mult_r(alpha_up, temp)));   move16();
+
+            /* limit maximum value of the noise estimate to NOISE_MAX */
+            test();
+            if (sub(st->bckr_est[i], NOISE_MAX) > 0)
+            {
+                st->bckr_est[i] = NOISE_MAX;    move16();
+            }
+        }
+    }
+
+    /* Update signal levels of the previous frame (old_level) */
+    for (i = 0; i < COMPLEN; i++)
+    {
+        st->old_level[i] = level[i];       move16();
+    }
+}
+
+/******************************************************************************
+*
+*     Function     : vad_decision
+*     Purpose      : Calculates VAD_flag
+*
+*/
+
+static Word16 vad_decision(                /* return value : VAD_flag */
+     VadVars * st,                         /* i/o : State structure                       */
+     Word16 level[COMPLEN],                /* i   : sub-band levels of the input frame */
+     Word32 pow_sum                        /* i   : power of the input frame           */
+)
+{
+    Word16 i;
+    Word32 L_snr_sum;
+    Word32 L_temp;
+    Word16 vad_thr, temp, noise_level;
+    Word16 low_power_flag;
+    Word16 hang_len, burst_len;
+    Word16 ilog2_speech_level, ilog2_noise_level;
+    Word16 temp2;
+
+    /* Calculate squared sum of the input levels (level) divided by the background noise components
+     * (bckr_est). */
+    L_snr_sum = 0;                         move32();
+    for (i = 0; i < COMPLEN; i++)
+    {
+        Word16 exp;
+
+        exp = norm_s(st->bckr_est[i]);
+        temp = shl(st->bckr_est[i], exp);
+        temp = div_s(shr(level[i], 1), temp);
+        temp = shl(temp, sub(exp, UNIRSHFT - 1));
+        L_snr_sum = L_mac(L_snr_sum, temp, temp);
+    }
+
+    /* Calculate average level of estimated background noise */
+    L_temp = 0;                            move32();
+    for (i = 1; i < COMPLEN; i++)          /* ignore lowest band */
+    {
+        L_temp = L_add(L_temp, st->bckr_est[i]);
+    }
+
+    noise_level = extract_h(L_shl(L_temp, 12));
+    /* if SNR is lower than a threshold (MIN_SPEECH_SNR), and increase speech_level */
+    temp = shl(mult(noise_level, MIN_SPEECH_SNR), 3);
+
+    test();
+    if (sub(st->speech_level, temp) < 0)
+    {
+        st->speech_level = temp;           move16();
+    }
+    ilog2_noise_level = ilog2(noise_level);
+
+    /* If SNR is very poor, speech_level is probably corrupted by noise level. This is correctred by
+     * subtracting MIN_SPEECH_SNR*noise_level from speech level */
+    ilog2_speech_level = ilog2(sub(st->speech_level, temp));
+
+    temp = add(mult(NO_SLOPE, sub(ilog2_noise_level, NO_P1)), THR_HIGH);
+
+    temp2 = add(SP_CH_MIN, mult(SP_SLOPE, sub(ilog2_speech_level, SP_P1)));
+    test();
+    if (sub(temp2, SP_CH_MIN) < 0)
+    {
+        temp2 = SP_CH_MIN;                 move16();
+    }
+    test();
+    if (sub(temp2, SP_CH_MAX) > 0)
+    {
+        temp2 = SP_CH_MAX;                 move16();
+    }
+    vad_thr = add(temp, temp2);
+
+    test();
+    if (sub(vad_thr, THR_MIN) < 0)
+    {
+        vad_thr = THR_MIN;                 move16();
+    }
+    /* Shift VAD decision register */
+    st->vadreg = shr(st->vadreg, 1);       move16();
+
+    /* Make intermediate VAD decision */
+    test();
+    if (L_sub(L_snr_sum, L_mult(vad_thr, 512 * COMPLEN)) > 0)
+    {
+        st->vadreg = (Word16) (st->vadreg | 0x4000);    logic16();move16();
+    }
+    /* check if the input power (pow_sum) is lower than a threshold" */
+    test();
+    if (L_sub(pow_sum, VAD_POW_LOW) < 0)
+    {
+        low_power_flag = 1;                move16();
+    } else
+    {
+        low_power_flag = 0;                move16();
+    }
+    /* Update background noise estimates */
+    noise_estimate_update(st, level);
+
+    /* Calculate values for hang_len and burst_len based on vad_thr */
+    hang_len = add(mult(HANG_SLOPE, sub(vad_thr, HANG_P1)), HANG_HIGH);
+    test();
+    if (sub(hang_len, HANG_LOW) < 0)
+    {
+        hang_len = HANG_LOW;               move16();
+    };
+
+    burst_len = add(mult(BURST_SLOPE, sub(vad_thr, BURST_P1)), BURST_HIGH);
+
+    return (hangover_addition(st, low_power_flag, hang_len, burst_len));
+}
+
+/******************************************************************************
+*
+*     Estimate_Speech()
+*     Purpose      : Estimate speech level
+*
+* Maximum signal level is searched and stored to the variable sp_max.
+* The speech frames must locate within SP_EST_COUNT number of frames.
+* Thus, noisy frames having occasional VAD = "1" decisions will not
+* affect to the estimated speech_level.
+*
+*/
+static void Estimate_Speech(
+     VadVars * st,                         /* i/o : State structure    */
+     Word16 in_level                       /* level of the input frame */
+)
+{
+    Word16 alpha;
+
+    /* if the required activity count cannot be achieved, reset counters */
+    test();
+    /* if (SP_ACTIVITY_COUNT  > SP_EST_COUNT - st->sp_est_cnt + st->sp_max_cnt) */
+    if (sub(sub(st->sp_est_cnt, st->sp_max_cnt), SP_EST_COUNT - SP_ACTIVITY_COUNT) > 0)
+    {
+        st->sp_est_cnt = 0;                move16();
+        st->sp_max = 0;                    move16();
+        st->sp_max_cnt = 0;                move16();
+    }
+    st->sp_est_cnt = add(st->sp_est_cnt, 1);    move16();
+
+    logic16();test();test();test();
+    if (((st->vadreg & 0x4000) || (sub(in_level, st->speech_level) > 0))
+        && (sub(in_level, MIN_SPEECH_LEVEL1) > 0))
+    {
+        /* update sp_max */
+        test();
+        if (sub(in_level, st->sp_max) > 0)
+        {
+            st->sp_max = in_level;         move16();
+        }
+        st->sp_max_cnt = add(st->sp_max_cnt, 1);        move16();
+        test();
+        if (sub(st->sp_max_cnt, SP_ACTIVITY_COUNT) >= 0)
+        {
+            Word16 tmp;
+
+            /* update speech estimate */
+            tmp = shr(st->sp_max, 1);      /* scale to get "average" speech level */
+
+            /* select update speed */
+            test();
+            if (sub(tmp, st->speech_level) > 0)
+            {
+                alpha = ALPHA_SP_UP;       move16();
+            } else
+            {
+                alpha = ALPHA_SP_DOWN;     move16();
+            }
+            test();
+            if (sub(tmp, MIN_SPEECH_LEVEL2) > 0)
+            {
+                st->speech_level = add(st->speech_level,
+                    mult_r(alpha, sub(tmp, st->speech_level))); move16();
+            }
+            /* clear all counters used for speech estimation */
+            st->sp_max = 0;                move16();
+            st->sp_max_cnt = 0;            move16();
+            st->sp_est_cnt = 0;            move16();
+        }
+    }
+}
+
+/******************************************************************************
+*                         PUBLIC PROGRAM CODE
+******************************************************************************/
+
+/******************************************************************************
+*
+*  Function:   wb_vad_init
+*  Purpose:    Allocates state memory and initializes state memory
+*
+*/
+
+Word16 wb_vad_init(                        /* return: non-zero with error, zero for ok. */
+     VadVars ** state                      /* i/o : State structure    */
+)
+{
+    VadVars *s;
+
+    if (state == (VadVars **) NULL)
+    {
+        fprintf(stderr, "vad_init: invalid parameter\n");
+        return -1;
+    }
+    *state = NULL;
+
+    /* allocate memory */
+    if ((s = (VadVars *) malloc(sizeof(VadVars))) == NULL)
+    {
+        fprintf(stderr, "vad_init: can not malloc state structure\n");
+        return -1;
+    }
+    wb_vad_reset(s);
+
+    *state = s;
+
+    return 0;
+}
+
+/******************************************************************************
+*
+*  Function:   wb_vad_reset
+*  Purpose:    Initializes state memory
+*
+*/
+Word16 wb_vad_reset(                       /* return: non-zero with error, zero for ok. */
+     VadVars * state                       /* i/o : State structure    */
+)
+{
+    Word16 i, j;
+
+    if (state == (VadVars *) NULL)
+    {
+        fprintf(stderr, "vad_reset: invalid parameter\n");
+        return -1;
+    }
+    state->tone_flag = 0;
+    state->vadreg = 0;
+    state->hang_count = 0;
+    state->burst_count = 0;
+    state->hang_count = 0;
+
+    /* initialize memory used by the filter bank */
+    for (i = 0; i < F_5TH_CNT; i++)
+    {
+        for (j = 0; j < 2; j++)
+        {
+            state->a_data5[i][j] = 0;
+        }
+    }
+
+    for (i = 0; i < F_3TH_CNT; i++)
+    {
+        state->a_data3[i] = 0;
+    }
+
+    /* initialize the rest of the memory */
+    for (i = 0; i < COMPLEN; i++)
+    {
+        state->bckr_est[i] = NOISE_INIT;
+        state->old_level[i] = NOISE_INIT;
+        state->ave_level[i] = NOISE_INIT;
+        state->sub_level[i] = 0;
+    }
+
+    state->sp_est_cnt = 0;
+    state->sp_max = 0;
+    state->sp_max_cnt = 0;
+    state->speech_level = SPEECH_LEVEL_INIT;
+    state->prev_pow_sum = 0;
+    return 0;
+}
+
+/******************************************************************************
+*
+*  Function:   wb_vad_exit
+*  Purpose:    The memory used for state memory is freed
+*
+*/
+void wb_vad_exit(
+     VadVars ** state                      /* i/o : State structure    */
+)
+{
+    if (state == NULL || *state == NULL)
+        return;
+
+    /* deallocate memory */
+    free(*state);
+    *state = NULL;
+    return;
+}
+
+/******************************************************************************
+*
+*     Function     : wb_vad_tone_detection
+*     Purpose      : Search maximum pitch gain from a frame. Set tone flag if
+*                    pitch gain is high. This is used to detect
+*                    signaling tones and other signals with high pitch gain.
+*
+*/
+void wb_vad_tone_detection(
+     VadVars * st,                         /* i/o : State struct            */
+     Word16 p_gain                         /* pitch gain      */
+)
+{
+    /* update tone flag */
+    st->tone_flag = shr(st->tone_flag, 1); move16();
+
+    /* if (pitch_gain > TONE_THR) set tone flag */
+    test();
+    if (sub(p_gain, TONE_THR) > 0)
+    {
+        st->tone_flag = (Word16) (st->tone_flag | 0x4000);      logic16();move16();
+    }
+}
+
+/******************************************************************************
+*
+*     Function     : wb_vad
+*     Purpose      : Main program for Voice Activity Detection (VAD) for AMR
+*
+*/
+Word16 wb_vad(                             /* Return value : VAD Decision, 1 = speech, 0 = noise */
+     VadVars * st,                         /* i/o : State structure                 */
+     Word16 in_buf[]                       /* i   : samples of the input frame   */
+)
+{
+    Word16 level[COMPLEN];
+    Word16 i;
+    Word16 VAD_flag, temp;
+    Word32 L_temp, pow_sum;
+
+    /* Calculate power of the input frame. */
+    L_temp = 0L;                           move32();
+    for (i = 0; i < FRAME_LEN; i++)
+    {
+        L_temp = L_mac(L_temp, in_buf[i], in_buf[i]);
+    }
+
+    /* pow_sum = power of current frame and previous frame */
+    pow_sum = L_add(L_temp, st->prev_pow_sum);  move32();
+
+    /* save power of current frame for next call */
+    st->prev_pow_sum = L_temp;             move32();
+
+    /* If input power is very low, clear tone flag */
+    test();
+    if (L_sub(pow_sum, POW_TONE_THR) < 0)
+    {
+        st->tone_flag = (Word16) (st->tone_flag & 0x1fff);      logic16();move16();
+    }
+    /* Run the filter bank and calculate signal levels at each band */
+    filter_bank(st, in_buf, level);
+
+    /* compute VAD decision */
+    VAD_flag = vad_decision(st, level, pow_sum);
+
+    /* Calculate input level */
+    L_temp = 0;                            move32();
+    for (i = 1; i < COMPLEN; i++)          /* ignore lowest band */
+    {
+        L_temp = L_add(L_temp, level[i]);
+    }
+
+    temp = extract_h(L_shl(L_temp, 12));
+
+    Estimate_Speech(st, temp);             /* Estimate speech level */
+    return (VAD_flag);
+}
--- /dev/null
+++ b/amr-wb/wb_vad.h
@@ -1,0 +1,58 @@
+/*-------------------------------------------------------------------*
+ *                         WB_VAD.H                                  *
+ *-------------------------------------------------------------------*
+ * Functions and static memory for Voice Activity Detection.         *
+ *-------------------------------------------------------------------*/
+
+#ifndef wb_vad_h
+#define wb_vad_h
+
+/******************************************************************************
+ *                         INCLUDE FILES
+ ******************************************************************************/
+#include "typedef.h"
+#include "wb_vad_c.h"
+
+/******************************************************************************
+ *                         DEFINITION OF DATA TYPES
+ ******************************************************************************/
+
+typedef struct
+{
+    Word16 bckr_est[COMPLEN];              /* background noise estimate                */
+    Word16 ave_level[COMPLEN];             /* averaged input components for stationary */
+                                           /* estimation                               */
+    Word16 old_level[COMPLEN];             /* input levels of the previous frame       */
+    Word16 sub_level[COMPLEN];             /* input levels calculated at the end of a frame (lookahead)  */
+    Word16 a_data5[F_5TH_CNT][2];          /* memory for the filter bank               */
+    Word16 a_data3[F_3TH_CNT];             /* memory for the filter bank               */
+
+    Word16 burst_count;                    /* counts length of a speech burst          */
+    Word16 hang_count;                     /* hangover counter                         */
+    Word16 stat_count;                     /* stationary counter                       */
+
+    /* Note that each of the following two variables holds 15 flags. Each flag reserves 1 bit of the
+     * variable. The newest flag is in the bit 15 (assuming that LSB is bit 1 and MSB is bit 16). */
+    Word16 vadreg;                         /* flags for intermediate VAD decisions     */
+    Word16 tone_flag;                      /* tone detection flags                     */
+
+    Word16 sp_est_cnt;                     /* counter for speech level estimation      */
+    Word16 sp_max;                         /* maximum level                            */
+    Word16 sp_max_cnt;                     /* counts frames that contains speech       */
+    Word16 speech_level;                   /* estimated speech level                   */
+    Word32 prev_pow_sum;                   /* power of previous frame                  */
+
+} VadVars;
+
+/********************************************************************************
+ *
+ * DECLARATION OF PROTOTYPES
+ ********************************************************************************/
+
+Word16 wb_vad_init(VadVars ** st);
+Word16 wb_vad_reset(VadVars * st);
+void wb_vad_exit(VadVars ** st);
+void wb_vad_tone_detection(VadVars * st, Word16 p_gain);
+Word16 wb_vad(VadVars * st, Word16 in_buf[]);
+
+#endif
--- /dev/null
+++ b/amr-wb/wb_vad_c.h
@@ -1,0 +1,89 @@
+/*-------------------------------------------------------------------*
+ *                         WB_VAD_C.H                                *
+ *-------------------------------------------------------------------*
+ * Constants for Voice Activity Detection.                           *
+ *-------------------------------------------------------------------*/
+
+#ifndef wb_vad_c_h
+#define wb_vad_c_h
+
+#define FRAME_LEN 256                      /* Length (samples) of the input frame          */
+#define COMPLEN 12                         /* Number of sub-bands used by VAD              */
+
+#define UNIRSHFT 7                         /* = log2(MAX_16/UNITY), UNITY = 256      */
+#define SCALE 128                          /* (UNITY*UNITY)/512 */
+
+#define TONE_THR (Word16)(0.65*MAX_16)     /* Threshold for tone detection   */
+
+/* constants for speech level estimation */
+#define SP_EST_COUNT 80
+#define SP_ACTIVITY_COUNT 25
+#define ALPHA_SP_UP (Word16)((1.0 - 0.85)*MAX_16)
+#define ALPHA_SP_DOWN (Word16)((1.0 - 0.85)*MAX_16)
+
+#define NOM_LEVEL 2050                     /* about -26 dBov Q15 */
+#define SPEECH_LEVEL_INIT NOM_LEVEL        /* initial speech level */
+#define MIN_SPEECH_LEVEL1  (Word16)(NOM_LEVEL * 0.063)  /* NOM_LEVEL -24 dB */
+#define MIN_SPEECH_LEVEL2  (Word16)(NOM_LEVEL * 0.2)    /* NOM_LEVEL -14 dB */
+#define MIN_SPEECH_SNR 4096                /* 0 dB, lowest SNR estimation, Q12 */
+
+/* Time constants for background spectrum update */
+#define ALPHA_UP1   (Word16)((1.0 - 0.95)*MAX_16)       /* Normal update, upwards:   */
+#define ALPHA_DOWN1 (Word16)((1.0 - 0.936)*MAX_16)      /* Normal update, downwards  */
+#define ALPHA_UP2   (Word16)((1.0 - 0.985)*MAX_16)      /* Forced update, upwards    */
+#define ALPHA_DOWN2 (Word16)((1.0 - 0.943)*MAX_16)      /* Forced update, downwards  */
+#define ALPHA3      (Word16)((1.0 - 0.95)*MAX_16)       /* Update downwards          */
+#define ALPHA4      (Word16)((1.0 - 0.9)*MAX_16)        /* For stationary estimation */
+#define ALPHA5      (Word16)((1.0 - 0.5)*MAX_16)        /* For stationary estimation */
+
+/* Constants for VAD threshold */
+#define THR_MIN  (Word16)(1.6*SCALE)       /* Minimum threshold               */
+#define THR_HIGH (Word16)(6*SCALE)         /* Highest threshold               */
+#define THR_LOW (Word16)(1.7*SCALE)        /* Lowest threshold               */
+#define NO_P1 31744                        /* ilog2(1), Noise level for highest threshold */
+#define NO_P2 19786                        /* ilog2(0.1*MAX_16), Noise level for lowest threshold */
+#define NO_SLOPE (Word16)(MAX_16*(float)(THR_LOW-THR_HIGH)/(float)(NO_P2-NO_P1))
+
+#define SP_CH_MIN (Word16)(-0.75*SCALE)
+#define SP_CH_MAX (Word16)(0.75*SCALE)
+#define SP_P1 22527                        /* ilog2(NOM_LEVEL/4) */
+#define SP_P2 17832                        /* ilog2(NOM_LEVEL*4) */
+#define SP_SLOPE (Word16)(MAX_16*(float)(SP_CH_MAX-SP_CH_MIN)/(float)(SP_P2-SP_P1))
+
+/* Constants for hangover length */
+#define HANG_HIGH  12                      /* longest hangover               */
+#define HANG_LOW  2                        /* shortest hangover               */
+#define HANG_P1 THR_LOW                    /* threshold for longest hangover */
+#define HANG_P2 (Word16)(4*SCALE)          /* threshold for shortest hangover */
+#define HANG_SLOPE (Word16)(MAX_16*(float)(HANG_LOW-HANG_HIGH)/(float)(HANG_P2-HANG_P1))
+
+/* Constants for burst length */
+#define BURST_HIGH 8                       /* longest burst length         */
+#define BURST_LOW 3                        /* shortest burst length        */
+#define BURST_P1 THR_HIGH                  /* threshold for longest burst */
+#define BURST_P2 THR_LOW                   /* threshold for shortest burst */
+#define BURST_SLOPE (Word16)(MAX_16*(float)(BURST_LOW-BURST_HIGH)/(float)(BURST_P2-BURST_P1))
+
+/* Parameters for background spectrum recovery function */
+#define STAT_COUNT 20                      /* threshold of stationary detection counter         */
+
+#define STAT_THR_LEVEL 184                 /* Threshold level for stationarity detection        */
+#define STAT_THR 1000                      /* Threshold for stationarity detection              */
+
+/* Limits for background noise estimate */
+#define NOISE_MIN 40                       /* minimum */
+#define NOISE_MAX 20000                    /* maximum */
+#define NOISE_INIT 150                     /* initial */
+
+/* Thresholds for signal power (now calculated on 2 frames) */
+#define VAD_POW_LOW (Word32)30000L         /* If input power is lower than this, VAD is set to 0 */
+#define POW_TONE_THR (Word32)686080L       /* If input power is lower,tone detection flag is ignored */
+
+/* Constants for the filter bank */
+#define COEFF3   13363                     /* coefficient for the 3rd order filter     */
+#define COEFF5_1 21955                     /* 1st coefficient the for 5th order filter */
+#define COEFF5_2 6390                      /* 2nd coefficient the for 5th order filter */
+#define F_5TH_CNT 5                        /* number of 5th order filters */
+#define F_3TH_CNT 6                        /* number of 3th order filters */
+
+#endif
--- /dev/null
+++ b/amr-wb/weight_a.c
@@ -1,0 +1,31 @@
+/*-------------------------------------------------------------------*
+ *                         WB_VAD.C                                  *
+ *-------------------------------------------------------------------*
+ * Weighting of LPC coefficients.                                    *
+ *   ap[i]  =  a[i] * (gamma ** i)                                   *
+ *-------------------------------------------------------------------*/
+
+#include "typedef.h"
+#include "basic_op.h"
+#include "count.h"
+
+void Weight_a(
+     Word16 a[],                           /* (i) Q12 : a[m+1]  LPC coefficients             */
+     Word16 ap[],                          /* (o) Q12 : Spectral expanded LPC coefficients   */
+     Word16 gamma,                         /* (i) Q15 : Spectral expansion factor.           */
+     Word16 m                              /* (i)     : LPC order.                           */
+)
+{
+    Word16 i, fac;
+
+    ap[0] = a[0];                          move16();
+    fac = gamma;                           move16();
+    for (i = 1; i < m; i++)
+    {
+        ap[i] = round(L_mult(a[i], fac));  move16();
+        fac = round(L_mult(fac, gamma));
+    }
+    ap[m] = round(L_mult(a[m], fac));      move16();
+
+    return;
+}
--- a/configure.ac
+++ b/configure.ac
@@ -180,7 +180,8 @@
 
 dnl Generate output files.
 AX_CREATE_STDINT_H(src/ststdint.h)
-AC_CONFIG_FILES(Makefile src/Makefile src/libgsm/Makefile src/libst-config)
+AC_CONFIG_FILES(Makefile src/Makefile src/libgsm/Makefile
+		amr-wb/Makefile src/libst-config)
 AC_OUTPUT
 
 if test "$found_libgsm" = "yes"; then
--- a/sox.1
+++ b/sox.1
@@ -777,6 +777,17 @@
 the highest quality format your ALSA system can handle.  Example:
 .B sox infile \-t alsa default
 .TP
+\&\fB.amr\-wb\fR
+Adaptive Multi Rate\*mWideband speech codec; a lossy format used in 3rd
+generation mobile telephony and defined in 3GPP TS 26.173.
+.SP
+AMR-WB audio has a fixed sampling rate of 16 kHz and supports encoding
+to the following bit-rates (as selected by the
+.B -C
+option): 0 = 6\*d6 kbit/s, 1 = 8\*d85 kbit/s, 2 = 12\*d65 kbit/s, 3 =
+14\*d25 kbit/s, 4 = 15\*d85 kbit/s 5 = 18\*d25 kbit/s, 6 = 19\*d85
+kbit/s, 7 = 23\*d05 kbit/s, 8 = 23\*d85 kbit/s
+.TP
 \&\fB.au\fR, \fB.snd\fR \fB(also with \-t sndfile)\fR
 Sun Microsystems AU files.
 There are many types of AU file;
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,7 @@
 	  g723_40.c g72x.c g72x.h gsm.c hcom.c ima_rw.c ima_rw.h \
 	  maud.c mp3.c nulfile.c prc.c raw.c sf.c sfircam.h skelform.c smp.c \
 	  sndfile.c sndrtool.c sphere.c tx16w.c voc.c vorbis.c vox.c wav.c \
-	  wav.h wve.c xa.c
+	  wav.h wve.c xa.c amr-wb.c
 
 effects = band.h biquad.c biquad.h biquads.c chorus.c compand.c \
 	  compandt.c compandt.h dcshift.c\
@@ -33,7 +33,7 @@
 libst_la_LIBADD = @LIBGSM_LIBADD@
 
 sox_SOURCES = sox.c
-sox_LDADD = libst.la
+sox_LDADD = libst.la ../amr-wb/libamrwb.la
 
 EXTRA_DIST = tests.sh testall.sh tests.bat testall.bat monkey.au monkey.wav
 
--- /dev/null
+++ b/src/amr-wb.c
@@ -1,0 +1,211 @@
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library.  If not, write to the Free Software Foundation,
+ * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
+ */
+
+/* File format: AMR-WB   (c) 2007 robs@users.sourceforge.net */
+
+#include "st_i.h"
+#include "../amr-wb/amr-wb.h"
+#include <string.h>
+#include <math.h>
+
+static char const magic[] = "#!AMR-WB\n";
+
+typedef struct amr_wb
+{
+  RX_State * rx_state;
+  TX_State * tx_state;
+  void * state;
+  Word16 coding_mode;
+  Word16 mode_previous;
+  st_bool reset;
+  st_bool reset_previous;
+  Word16 pcm[L_FRAME16k];
+  st_size_t pcm_index;
+} * amr_wb_t;
+
+assert_static(sizeof(struct amr_wb) <= ST_MAX_FILE_PRIVSIZE,
+              /* else */ amr_wb_PRIVSIZE_too_big);
+
+#define ENCODING 2 /* 0..2 */
+
+static st_size_t decode_1_frame(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+  Word16 nb_bits, i;
+  Word16 mode, frame_type, frame_length;
+  Word16 prms[NB_BITS_MAX];
+
+  nb_bits = Read_serial(ft->fp, prms, &frame_type, &mode, this->rx_state, ENCODING);
+  if (nb_bits == 0)
+    return L_FRAME16k;
+
+  if (frame_type == RX_NO_DATA || frame_type == RX_SPEECH_LOST) {
+    mode = this->mode_previous;
+    this->reset = st_false;
+  } else {
+    this->mode_previous = mode;
+
+    if (this->reset_previous)
+      this->reset = decoder_homing_frame_test_first(prms, mode);
+  }
+  if (this->reset && this->reset_previous)
+    for (i = 0; i < L_FRAME16k; i++)
+      this->pcm[i] = EHF_MASK;
+  else
+    decoder(mode, prms, this->pcm, &frame_length, this->state, frame_type);
+  if (!this->reset_previous)
+    this->reset = decoder_homing_frame_test(prms, mode);
+  if (this->reset)
+    Reset_decoder(this->state, 1);
+  this->reset_previous = this->reset;
+  return 0;
+}
+
+static void encode_1_frame(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+  st_size_t i;
+  Word16 nb_bits;
+  Word16 prms[NB_BITS_MAX];
+  Word16 reset = encoder_homing_frame_test(this->pcm);
+  Word16 mode = this->coding_mode;
+
+  for (i = 0; i < L_FRAME16k; ++i)
+    this->pcm[i] = this->pcm[i] & ~3;
+  coder(&mode, this->pcm, prms, &nb_bits, this->state, 1);
+  Write_serial(ft->fp, prms, mode, this->coding_mode, this->tx_state, ENCODING);
+  if (reset)
+    Reset_encoder(this->state, 1);
+}
+
+static void set_format(ft_t ft)
+{
+  ft->signal.rate = 16000;
+  ft->signal.size = ST_SIZE_16BIT;
+  ft->signal.encoding = ST_ENCODING_AMR_WB;
+  ft->signal.channels = 1;
+}
+
+static int startread(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+
+  this->reset_previous = st_true;
+  this->pcm_index = L_FRAME16k;
+
+  Init_decoder(&this->state);
+  Init_read_serial(&this->rx_state);
+
+  if (ENCODING == 2) {
+    char buffer[sizeof(magic)];
+
+    fread(buffer, sizeof(char), sizeof(buffer) - 1, ft->fp);
+    buffer[sizeof(buffer) - 1] = 0;
+    if (strcmp(buffer, magic)) {
+      st_fail("Invalid magic number");
+      return ST_EOF;
+    }
+  }
+  set_format(ft);
+  return ST_SUCCESS;
+}
+
+static st_size_t read(ft_t ft, st_sample_t * buf, st_size_t len)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+  st_size_t done;
+
+  for (done = 0; done < len; done++) {
+    if (this->pcm_index >= L_FRAME16k)
+      this->pcm_index = decode_1_frame(ft);
+    if (this->pcm_index >= L_FRAME16k)
+      break;
+    *buf++ = ST_SIGNED_WORD_TO_SAMPLE(0xfffc & this->pcm[this->pcm_index++], ft->clips);
+  }
+  return done;
+}
+
+static int stopread(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+  Close_decoder(this->state);
+  Close_read_serial(this->rx_state);
+  return ST_SUCCESS;
+}
+
+static int startwrite(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+
+  if (ft->signal.compression != HUGE_VAL) {
+    this->coding_mode = ft->signal.compression;
+    if (this->coding_mode != ft->signal.compression || this->coding_mode > 8) {
+      st_fail_errno(ft, ST_EINVAL, "compression level must be a whole number from 0 to 8");
+      return ST_EOF;
+    }
+  }
+  else this->coding_mode = 0;
+
+  set_format(ft);
+  Init_coder(&this->state);
+  Init_write_serial(&this->tx_state);
+  if (ENCODING == 2)
+    st_writes(ft, magic);
+  this->pcm_index = 0;
+  return ST_SUCCESS;
+}
+
+static st_size_t write(ft_t ft, const st_sample_t * buf, st_size_t len)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+  st_size_t done;
+
+  for (done = 0; done < len; ++done) {
+    this->pcm[this->pcm_index++] = (Word16) (ST_SAMPLE_TO_SIGNED_WORD(*buf++, ft->clips));
+    if (this->pcm_index == L_FRAME16k) {
+      this->pcm_index = 0;
+      encode_1_frame(ft);
+    }
+  }
+  return done;
+}
+
+static int stopwrite(ft_t ft)
+{
+  amr_wb_t this = (amr_wb_t) ft->priv;
+
+  if (this->pcm_index) {
+    do {
+      this->pcm[this->pcm_index++] = 0;
+    } while (this->pcm_index < L_FRAME16k);
+    encode_1_frame(ft);
+  }
+  Close_coder(this->state);
+  Close_write_serial(this->tx_state);
+  return ST_SUCCESS;
+}
+
+st_format_t const * st_amr_wb_format_fn(void)
+{
+  static char const * names[] = {"amr-wb", NULL};
+  static st_format_t driver = {
+    names, NULL, 0,
+    startread, read, stopread,
+    startwrite, write, stopwrite,
+    st_format_nothing_seek
+  };
+  return &driver;
+}
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -21,6 +21,7 @@
 #ifdef HAVE_ALSA
   st_alsa_format_fn,
 #endif
+  st_amr_wb_format_fn,
   st_au_format_fn,
   st_auto_format_fn,
   st_avr_format_fn,
--- a/src/misc.c
+++ b/src/misc.c
@@ -72,6 +72,7 @@
         "MPEG audio (layer I, II or III)",
         "Vorbis",
         "FLAC",
+        "AMR-WB",
 };
 
 assert_static(array_length(st_encodings_str) == ST_ENCODINGS,
--- a/src/st.h
+++ b/src/st.h
@@ -179,6 +179,7 @@
   ST_ENCODING_MP3       , /* MP3 compression */
   ST_ENCODING_VORBIS    , /* Vorbis compression */
   ST_ENCODING_FLAC      , /* FLAC compression */
+  ST_ENCODING_AMR_WB    , /* AMR-WB compression */
 
   ST_ENCODINGS            /* End of list marker */
 } st_encoding_t;
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -207,6 +207,7 @@
 #ifdef HAVE_ALSA
 extern const st_format_t *st_alsa_format_fn(void);
 #endif
+extern const st_format_t *st_amr_wb_format_fn(void);
 extern const st_format_t *st_au_format_fn(void);
 extern const st_format_t *st_auto_format_fn(void);
 extern const st_format_t *st_avr_format_fn(void);