/*====================================================================*/
/*         MPEG-4 Audio (ISO/IEC 14496-3) Copyright Header            */
/*====================================================================*/
/*
This software module was originally developed by Rakesh Taori and Andy
Gerrits (Philips Research Laboratories, Eindhoven, The Netherlands) in
the course of development of the MPEG-4 Audio (ISO/IEC 14496-3). This
software module is an implementation of a part of one or more MPEG-4
Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio
(ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC
14496-3) free license to this software module or modifications thereof
for use in hardware or software products claiming conformance to the
MPEG-4 Audio (ISO/IEC 14496-3). Those intending to use this software
module in hardware or software products are advised that its use may
infringe existing patents. The original developer of this software
module and his/her company, the subsequent editors and their
companies, and ISO/IEC have no liability for use of this software
module or modifications thereof in an implementation. Copyright is not
released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming products.
CN1 retains full right to use the code for his/her own purpose, assign
or donate the code to a third party and to inhibit third parties from
using the code for non MPEG-4 Audio (ISO/IEC 14496-3) conforming
products.  This copyright notice must be included in all copies or
derivative works. Copyright 1996.
*/
/*====================================================================*/
/*======================================================================*/
/*                                                                      */
/*      SOURCE_FILE:    CELP_ENCODER.C                                  */
/*                                                                      */
/*======================================================================*/
    
/*======================================================================*/
/*      I N C L U D E S                                                 */
/*======================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "phi_cons.h"     /* Philips Defined Constants                  */
#include "lpc_common.h"   /* Common LPC core Defined Constants          */
#include "phi_prep.h"     /* Prototypes for Preprocessing Modules       */
#include "phi_lpc.h"      /* Prototypes for LPC Modules                 */
#include "phi_axit.h"     /* Prototypes for Excitation Analysis Module  */
#include "celp_bitstream_mux.h"     /* Prototypes for Bitstream Mux     */
#include "phi_apre.h"     /* Prototypes for Excitation Analysis Module  */
#include "phi_fbit.h"     /* Frame bit allocation table                 */
#include "celp_encoder.h" /* Prototypes for Coder Routines              */
#include "pan_celp_const.h"/* Constants for PAN Routines                */
#include "celp_proto_enc.h"/* Prototypes for CELP Routines              */
#include "nec_abs_const.h" /* Constants for NEC Routines                */
#include "nec_abs_proto.h" /* Prototypes for NEC Routines               */
#include "phi_nec_lpc.h"   /* Prototypes for NEC Routines               */

int CELPencDebugLevel = 0;	/* HP 971120 */

/*======================================================================*/
/*    L O C A L     F U N C T I O N     D E C L A R A T I O N           */
/*======================================================================*/
void nec_lpf_down( float xin[], float xout[], int len );

/*======================================================================*/
/*    L O C A L     D A T A     D E C L A R A T I O N                   */
/*======================================================================*/
/*======================================================================*/
/*    WideBand Data Declaration                                         */
/*======================================================================*/
static float *PHI_sp_pp_buf;
static float PHI_af;
static long  PHI_BUFFER;

static float *Downsampled_signal;

static float **SquaredHammingWindow;       /* For Haming Window         */
static float **HammingWindow;              /* For Haming Window         */
static float *PHI_GammaArrayBE;            /* For Bandwidth Expansion   */
static float *PAN_GammaArrayBE;            /* For Bandwidth Expansion   */

static float PHI_prev_x = (float)0.0;      /* Previous x value          */
static float PHI_prev_y = (float)0.0;      /* previous y value          */

static float NEC_prev_x = (float)0.0;      /* Previous x value          */
static float NEC_prev_y = (float)0.0;      /* previous y value          */


/*======================================================================*/
/*    NarrowBand Data declaration                                       */
/*======================================================================*/
static float *nb_pp_sp_buffer;        /* input signal buffer */
static float *bws_sp_buffer;          /* input signal buffer */
static float *prev_Qlsp_coefficients; /* previous quantized LSP coeff. */
static float *buf_Qlsp_coefficients_bws; /* current quantized LSP coeff. */
static float *prev_Qlsp_coefficients_bws;/* previous quantized LSP coeff. */
static long prev_adaptive_pitch_lag;  /* previous adapt. pitch lag */

static float gamma_num;    /* fixed or variable? */
static float gamma_den;	  /* fixed or variable? */

static long num_indices, buffer_size;
static long num_enhstages;

static long buffer_size_bws;
static long frame_size_nb, frame_size_bws;
static long n_subframes_bws;
static long sbfrm_size_bws;
static long lpc_order_bws;
static long n_lpc_analysis_bws;
static long num_lpc_indices_bws;
static long *window_sizes_bws;
static long *window_offsets_bws;

/* ---------------------------------------------------------------------*/ 
/*Frame Related Information                                             */
/* ---------------------------------------------------------------------*/
static unsigned long frame_ctr = 0;    /* Frame Counter                 */
static unsigned long lpc_sent_frames=0;/* Frames where LPc is sent      */

/*======================================================================*/
/* Function definition: celp_coder                                      */
/*======================================================================*/
void celp_coder
(
float     **InputSignal,           /* In: Multichannel Speech           */
BITSTREAM * p_bitstream,           /* Out: Bitstream                    */
long        sampling_frequency,    /* In:  Sampling Frequency           */
long        bit_rate,              /* In:  Bit rate                     */
long        SampleRateMode,
long        QuantizationMode,      /* In: Type of Quantization  	    */
long        FineRateControl,	   /* In: Fine Rate Control switch      */
long        LosslessCodingMode,    /* In: Lossless Coding Mode  	    */   
long        WB_Configuration,      /* In: Wideband configuration 	    */
long        Wideband_VQ,		   /* In: Wideband VQ mode			    */
long        NB_Configuration,      /* In: Narrowband configuration      */
long        NumEnhLayers,  	       /* In: Number of Enhancement Layers  */
long        BandwidthScalabilityMode, /* In: bandwidth switch           */
long        BWS_Configuration,     /* In: BWS_configuration 		    */
long        PreProcessingSW,       /* In: PreProcessingSW	    */
long        frame_size,            /* In:  Frame size                   */
long        n_subframes,           /* In:  Number of subframes          */
long        sbfrm_size,            /* In:  Subframe size                */
long        lpc_order,             /* In:  Order of LPC                 */
long        num_lpc_indices,       /* In:  Number of LPC indices        */
long        num_shape_cbks,        /* In:  Number of Shape Codebooks    */
long        num_gain_cbks,         /* In:  Number of Gain Codebooks     */
long        n_lpc_analysis,        /* In:  Number of LPCs per frame     */
long        window_offsets[],      /* In:  Offset for LPC-frame v.window*/
long        window_sizes[],        /* In:  LPC Analysis Window size     */
long        max_n_lag_candidates,  /* In:  Maximum search candidates    */
float       min_pitch_frequency,   /* IN:  Min Pitch Frequency          */
float       max_pitch_frequency,   /* IN:  Max Pitch Frequency          */
long        org_frame_bit_allocation[]/* In: Frame BIt alolocation      */
)
{    
    /*==================================================================*/
    /*      L O C A L   D A T A   D E F I N I T I O N S                 */
    /*==================================================================*/
    float af_next =(float)0.0;    /* First-order fit lpc parameter      */
    float *sp_buf_ptr = InputSignal[0];    /* Speech Buffer             */
    float *int_ap;                         /* Interpolated LPC coeffs   */
    float *ap;                             /* LPC Parameters            */
    float *ds_ap;                            
    long *ds_window_offsets;                            
    long *ds_window_sizes;                            
    long  *shape_indices;                  /* Lags for Codebooks        */
    long  *gain_indices;                   /* Gains for Codebooks       */
    long  *codes;                          /* LPC codes                 */
    long  interpolation_flag  = 0;         /* Interpolation flag        */
	long LPC_Present = 1;                   
    long  signal_mode  = 0;                /* Signal mode               */
    long  sbfrm_ctr = 0;                   /* Subframe counter          */
    long  dum       = 0;
    int   k;
    float *Downsampled_frame;
    long rms_index;
    float open_loop_gain;

    float *int_ap_bws;                     /* Interpolated LPC coeffs   */
    float *ap_bws;                         /* LPC Parameters            */
    long  *shape_indices_bws;              /* Lags for Codebooks        */
    long  *gain_indices_bws;               /* Gains for Codebooks       */
    long  *codes_bws;                      /* LPC codes                 */
    long  *bws_nb_acb_index;               /* ACB codes                 */

    long dummy = 0;

    if ( BandwidthScalabilityMode == OFF) {
    /* -----------------------------------------------------------------*/
    /* Segmentation for wideband speech                                 */
    /* -----------------------------------------------------------------*/
    for ( k = 0; k < (int)(PHI_BUFFER-frame_size); k++)
    {
         PHI_sp_pp_buf[k] = PHI_sp_pp_buf[k + (int)(frame_size)];
    }
    /* -----------------------------------------------------------------*/
    /* Preprocessing (In our case it is just a DC notch)                */
    /* -----------------------------------------------------------------*/
    if (PreProcessingSW == ON) {
      celp_preprocessing(sp_buf_ptr, &PHI_sp_pp_buf[PHI_BUFFER-frame_size], &PHI_prev_x, &PHI_prev_y, frame_size, sampling_frequency);
    } else {
      for ( k = 0; k < frame_size; k++)
	PHI_sp_pp_buf[PHI_BUFFER-frame_size+k] = sp_buf_ptr[k];
    }
    } else {
      for ( k = 0; k < (int)(PHI_BUFFER-frame_size_nb); k++) {
	PHI_sp_pp_buf[k] = PHI_sp_pp_buf[k + (int)(frame_size_nb)];
      }
      for ( k = 0; k < (int)(buffer_size_bws-frame_size_bws); k++) {
	bws_sp_buffer[k] = bws_sp_buffer[k + (int)(frame_size_bws)];
      }
      if (PreProcessingSW == ON) {
	celp_preprocessing(sp_buf_ptr, &bws_sp_buffer[buffer_size_bws-frame_size_bws], &PHI_prev_x, &PHI_prev_y, frame_size_bws, sampling_frequency);
      } else {
	for ( k = 0; k < frame_size_bws; k++)
	  bws_sp_buffer[buffer_size_bws-frame_size_bws+k] = sp_buf_ptr[k];
      }

      nec_lpf_down( &bws_sp_buffer[buffer_size_bws-frame_size_bws],
		    &PHI_sp_pp_buf[buffer_size-frame_size_nb], frame_size_bws );
    }

    /* -----------------------------------------------------------------*/
    /* Segmentation for downsampled speech                              */
    /* -----------------------------------------------------------------*/
    if ((SampleRateMode == fs16kHz) && (QuantizationMode == VectorQuantizer) && (Wideband_VQ == Scalable_VQ))
	{
    	for ( k = 0; k < (int)(PHI_BUFFER-frame_size)/2; k++)
    	{
        	 Downsampled_signal[k] = Downsampled_signal[k + (int)(frame_size/2)];
    	}
    	/* -----------------------------------------------------------------*/
    	/*  Allocate memory for downsampling frame                          */
    	/* -----------------------------------------------------------------*/
    	if
    	(
    	(( Downsampled_frame = (float *)malloc((unsigned int)(frame_size/2) * sizeof(float))) == NULL )
    	)
    	{
        	fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
        	exit(1);
    	}

    	/* -----------------------------------------------------------------*/
    	/* Segmentation for downsampled speech                              */
    	/* -----------------------------------------------------------------*/
    	nec_lpf_down(sp_buf_ptr, Downsampled_frame, (int)frame_size);

    	/* -----------------------------------------------------------------*/
    	/* Preprocessing (In our case it is just a DC notch)                */
    	/* -----------------------------------------------------------------*/
    	celp_preprocessing(Downsampled_frame, &Downsampled_signal[(PHI_BUFFER-frame_size)/2], &NEC_prev_x, &NEC_prev_y, frame_size/2, sampling_frequency/2);

    	/* -----------------------------------------------------------------*/
    	/* Free allocated downsampled frame                                 */
    	/* -----------------------------------------------------------------*/
    	free(Downsampled_frame);
    }

	if (SampleRateMode == fs16kHz)
	{
    	/* -----------------------------------------------------------------*/
    	/* To synchronise the decoded output with the original signal       */
    	/* This helps to make measurements such as SNR                      */
    	/* -----------------------------------------------------------------*/
    	if (frame_ctr < 2)
    	{
        	frame_ctr++;
        	if (p_bitstream != NULL)
        	{
            	p_bitstream->valid_bits = 0;
            	p_bitstream->buffer_length = 0;
        	}

        	return;
    	}
    }
    else
	{
		if (p_bitstream->p_bitstream_buffer_start == NULL) return;
	}
	
    /* -----------------------------------------------------------------*/
    /* Create Arrays for frame processing                               */
    /* -----------------------------------------------------------------*/
    if
    (
    (( int_ap = (float *)malloc((unsigned int)(n_subframes * lpc_order) * sizeof(float))) == NULL )||
    (( ap     = (float *)malloc((unsigned int)(n_lpc_analysis * lpc_order) * sizeof(float))) == NULL )||
    (( shape_indices = (long *)malloc((unsigned int)((num_enhstages+1)*num_shape_cbks * n_subframes) * sizeof(long))) == NULL )||
    (( gain_indices = (long *)malloc((unsigned int)((num_enhstages+1)*num_gain_cbks * n_subframes) * sizeof(long))) == NULL )||
    (( ds_ap = (float *)malloc((unsigned int)(n_lpc_analysis * lpc_order) * sizeof(float))) == NULL )||
    (( ds_window_offsets = (long *)malloc((unsigned int)(n_lpc_analysis) * sizeof(long))) == NULL )||
    (( ds_window_sizes = (long *)malloc((unsigned int)(n_lpc_analysis) * sizeof(long))) == NULL )||
    (( codes = (long *)malloc((unsigned int)num_lpc_indices * sizeof(long))) == NULL )
	)
    {
        fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
        exit(1);
    }
    if ( BandwidthScalabilityMode == ON) {
    if
    (
    (( int_ap_bws = (float *)malloc((unsigned int)(n_subframes_bws * lpc_order_bws) * sizeof(float))) == NULL )||
    (( ap_bws     = (float *)malloc((unsigned int)(n_lpc_analysis_bws * lpc_order_bws) * sizeof(float))) == NULL )||
    (( shape_indices_bws = (long *)malloc((unsigned int)(num_shape_cbks * n_subframes_bws) * sizeof(long))) == NULL )||
    (( gain_indices_bws = (long *)malloc((unsigned int)(num_gain_cbks * n_subframes_bws) * sizeof(long))) == NULL )||
    (( codes_bws = (long *)malloc((unsigned int)num_lpc_indices_bws * sizeof(long))) == NULL ) ||
    (( bws_nb_acb_index = (long *)malloc((unsigned int)n_subframes_bws * sizeof(long))) == NULL )
	)
    {
        fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
        exit(1);
    }
    }    

    /* -----------------------------------------------------------------*/
    /* LPC Analysis - I  (down sampled parameter computation)           */
    /* -----------------------------------------------------------------*/
    if ((SampleRateMode == fs16kHz) && (QuantizationMode == VectorQuantizer) && (Wideband_VQ == Scalable_VQ))
    {
        long kk;
        float dmy_af;
        
        for (kk=0; kk < n_lpc_analysis; kk++)
        {
        	ds_window_offsets[kk] = window_offsets[kk]/2;
        	ds_window_sizes[kk]   = window_sizes[kk]/2;
        }
        
    	celp_lpc_analysis(Downsampled_signal, ds_ap, &dmy_af, frame_size/2, ds_window_offsets,
    	ds_window_sizes, HammingWindow, PAN_GammaArrayBE, lpc_order/2, n_lpc_analysis); 
    }

    /* -----------------------------------------------------------------*/
    /* LPC Analysis - II  (parameter computation)                       */
    /* -----------------------------------------------------------------*/
	if (SampleRateMode == fs16kHz)
	{
    	celp_lpc_analysis(PHI_sp_pp_buf, ap, &af_next, frame_size, window_offsets,
    	window_sizes, SquaredHammingWindow, PHI_GammaArrayBE, lpc_order, n_lpc_analysis); 
    }
    else
	{
	  celp_lpc_analysis(PHI_sp_pp_buf, ap, &af_next, frame_size_nb,
			    window_offsets, window_sizes, HammingWindow,
			    PAN_GammaArrayBE, lpc_order, n_lpc_analysis); 

	  if ( BandwidthScalabilityMode == ON) {
	    float dmy_af_bws;
	    celp_lpc_analysis_bws(bws_sp_buffer, ap_bws, &dmy_af_bws,
				  frame_size_bws, window_offsets_bws,
				  window_sizes_bws, lpc_order_bws,
				  n_lpc_analysis_bws); 
	  }
	}
	
    /* -----------------------------------------------------------------*/
    /* LPC Analysis - III (parameter quantization)                      */
    /* -----------------------------------------------------------------*/
    if (QuantizationMode == VectorQuantizer)     
	{
		if (FineRateControl == ON)
		{
    		VQ_celp_lpc_quantizer(ap, ds_ap, int_ap, codes, lpc_order, num_lpc_indices, n_lpc_analysis, n_subframes,
    		&interpolation_flag, &LPC_Present, Wideband_VQ);
	    }
		else
		{
		    /* LPC quantization & interpolation */
    		nb_abs_lpc_quantizer(ap, int_ap, codes, lpc_order,
				     num_lpc_indices, n_lpc_analysis, 
				     n_subframes, &interpolation_flag,
				     signal_mode, org_frame_bit_allocation, 
				     dummy, prev_Qlsp_coefficients);
		if ( BandwidthScalabilityMode == ON) {
		for ( k = 0; k < lpc_order; k++ ) {
		  buf_Qlsp_coefficients_bws[k] = PAN_PI * prev_Qlsp_coefficients[k];
		}
    		bws_lpc_quantizer(ap_bws, int_ap_bws, codes_bws,
				  lpc_order, lpc_order_bws,
				  num_lpc_indices_bws, n_lpc_analysis_bws, 
				  n_subframes_bws,buf_Qlsp_coefficients_bws,
				  prev_Qlsp_coefficients_bws,
				  &org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+(num_enhstages+1)*n_subframes*(num_shape_cbks+num_gain_cbks)]);
		}
		}
	}
    else
	{
    	SQ_celp_lpc_quantizer(ap, int_ap, codes, lpc_order, num_lpc_indices, n_lpc_analysis, n_subframes,
    	&interpolation_flag, &LPC_Present);
    }

    /* -----------------------------------------------------------------*/
    /* Also weight the first-order-fit lpc parameter                    */
    /* -----------------------------------------------------------------*/
    PHI_af *= (float)GAMMA_WF;

    if (SampleRateMode == fs16kHz)
      {
    /* -----------------------------------------------------------------*/
    /* Begin Processing on a subframe basis                             */
    /* -----------------------------------------------------------------*/
    for (sbfrm_ctr = 0; sbfrm_ctr < n_subframes; sbfrm_ctr++)
    {
        long  m = sbfrm_ctr * lpc_order;
        float *sptr;
        long  *lag_cands;
        float *cbk_sig;
        float *a_parw;
        float *residue;
        float *dummy1;
        long  dum1 = 0;
    	float *Wnum_coeff;    
    	float *Wden_coeff;
        
    	/* -------------------------------------------------------------*/
    	/* Create Arrays for subframe processing                        */
    	/* -------------------------------------------------------------*/
    	if
    	(
    	(( lag_cands = (long  *)malloc((unsigned int)max_n_lag_candidates * sizeof(long))) == NULL )||
    	(( residue   = (float *)malloc((unsigned int)sbfrm_size * sizeof(float))) == NULL )||
    	(( cbk_sig   = (float *)malloc((unsigned int)sbfrm_size * sizeof(float))) == NULL )||
    	(( a_parw    = (float *)malloc((unsigned int)lpc_order * sizeof(float))) == NULL )||
        (( Wden_coeff=(float *)calloc(lpc_order*n_subframes, sizeof(float)))==NULL)    ||
        (( Wnum_coeff=(float *)calloc(lpc_order*n_subframes, sizeof(float)))==NULL)    ||
		(( dummy1    = (float *)malloc((unsigned int)lpc_order * sizeof(float))) == NULL )
    	)
    	{
        	fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
        	exit(1);
    	}

        	/* -------------------------------------------------------------*/
        	/* LPC inverse-filtering                                        */
        	/* -------------------------------------------------------------*/
        	sptr = PHI_sp_pp_buf + PHI_BUFFER - (3 * frame_size) + (sbfrm_ctr * sbfrm_size);
        	celp_lpc_analysis_filter(sptr, residue, &int_ap[m], lpc_order, sbfrm_size);


        	/* -------------------------------------------------------------*/
        	/* Weighting filter parameter generation                        */
        	/* -------------------------------------------------------------*/
        	celp_weighting_module(&int_ap[m], lpc_order, dummy1, a_parw, (float)GAMMA_WF, (float)GAMMA_WF);

        	/* -------------------------------------------------------------*/
        	/* Excitation Analysis                                          */
        	/* -------------------------------------------------------------*/
        	celp_excitation_analysis
        	(
        	sp_buf_ptr, residue, a_parw, lpc_order, dummy1, dummy1, PHI_af, 
        	lag_cands, max_n_lag_candidates, frame_size, sbfrm_size, n_subframes, signal_mode,
        	org_frame_bit_allocation,
        	&(shape_indices[sbfrm_ctr * num_shape_cbks]), 
        	&(gain_indices[sbfrm_ctr * num_gain_cbks]),
        	num_shape_cbks, num_gain_cbks, &dum1, cbk_sig
        	);
		
    	/* -------------------------------------------------------------*/
    	/* Free   Arrays for subframe processing                        */
    	/* -------------------------------------------------------------*/
    	free ( lag_cands );
    	free ( residue );
    	free ( cbk_sig );
    	free ( a_parw );
    	free ( dummy1 );
		free(Wnum_coeff);
		free(Wden_coeff);
    }
    }
		
    if (SampleRateMode == fs8kHz) {
      long NQlpc_cnt;
      float *sptr;
      float *wn_ap;
      float *wd_ap;
      float *dec_sig;
      float *bws_mp_sig;

      float *dmy_res;	/* HP 971112 */
      long  *dmy_cands;

      if(
	 (( dec_sig   = (float *)malloc((unsigned int)sbfrm_size * sizeof(float))) == NULL )||
	 (( bws_mp_sig   = (float *)malloc((unsigned int)frame_size_nb * sizeof(float))) == NULL )||
	 (( wn_ap=(float *)calloc(lpc_order*n_subframes, sizeof(float)))==NULL)    ||
	 (( wd_ap=(float *)calloc(lpc_order*n_subframes, sizeof(float)))==NULL)
	 ) {
	fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
	exit(1);
      }

      for ( sbfrm_ctr = 0; sbfrm_ctr < n_subframes; sbfrm_ctr++ ) {
	NQlpc_cnt = n_lpc_analysis*sbfrm_ctr/n_subframes;
	celp_weighting_module (ap+lpc_order*NQlpc_cnt,
			       lpc_order, &wn_ap[lpc_order*sbfrm_ctr],
			       &wd_ap[lpc_order*sbfrm_ctr],
			       gamma_num, gamma_den);
      }

      for ( sbfrm_ctr = 0; sbfrm_ctr < n_subframes; sbfrm_ctr++ ) {
	if ((FineRateControl == ON) || (QuantizationMode == ScalarQuantizer))
	{	  
	sptr = PHI_sp_pp_buf + (sbfrm_ctr * sbfrm_size);
    }
    else
	{
	sptr = PHI_sp_pp_buf + NEC_PAN_NLB + (sbfrm_ctr * sbfrm_size);
	}
	nb_abs_excitation_analysis(sptr, dmy_res, int_ap, lpc_order, 
				   wn_ap, wd_ap, PHI_af, 
				   dmy_cands, max_n_lag_candidates,
				   frame_size_nb, sbfrm_size, 
				   n_subframes, &signal_mode,
				   org_frame_bit_allocation, 
				   shape_indices, gain_indices, 
				   num_shape_cbks, num_gain_cbks, 
				   &rms_index, dec_sig, num_enhstages,
				   bws_mp_sig+sbfrm_size*sbfrm_ctr);
      }

      if ( BandwidthScalabilityMode == ON) {
	float *wn_ap_bws;
	float *wd_ap_bws;
	float *dec_sig_bws;

	if(
	   (( dec_sig_bws   = (float *)malloc((unsigned int)sbfrm_size_bws * sizeof(float))) == NULL )||
	   (( wn_ap_bws=(float *)calloc(lpc_order_bws*n_subframes_bws, sizeof(float)))==NULL)    ||
	   (( wd_ap_bws=(float *)calloc(lpc_order_bws*n_subframes_bws, sizeof(float)))==NULL)
	   ) {
	  fprintf(stderr, "MALLOC FAILURE in abs_coder  \n");
	  exit(1);
	}
	for ( sbfrm_ctr = 0; sbfrm_ctr < n_subframes_bws; sbfrm_ctr++ ) {
	  NQlpc_cnt = n_lpc_analysis_bws*sbfrm_ctr/n_subframes_bws;
	  celp_weighting_module (ap_bws+lpc_order_bws*NQlpc_cnt,
				 lpc_order_bws,
				 &wn_ap_bws[lpc_order_bws*sbfrm_ctr],
				 &wd_ap_bws[lpc_order_bws*sbfrm_ctr],
				 NEC_GAM_MA, NEC_GAM_AR);
	}

	for ( sbfrm_ctr = 0; sbfrm_ctr < n_subframes_bws; sbfrm_ctr++ ) {
	  bws_nb_acb_index[sbfrm_ctr] = shape_indices[sbfrm_ctr*n_subframes/n_subframes_bws*num_shape_cbks];
	}

	for ( sbfrm_ctr = 0; sbfrm_ctr < n_subframes_bws; sbfrm_ctr++ ) {
	  sptr = bws_sp_buffer + NEC_FRQ16_NLB + (sbfrm_ctr * sbfrm_size_bws);

	  bws_excitation_analysis(sptr, int_ap_bws, lpc_order_bws, 
				  wn_ap_bws, wd_ap_bws,
				  frame_size_bws, sbfrm_size_bws, 
				  n_subframes_bws, signal_mode,
				  &org_frame_bit_allocation[num_indices-n_subframes_bws*(num_shape_cbks+num_gain_cbks)],
				  shape_indices_bws, gain_indices_bws, 
				  num_shape_cbks, num_gain_cbks, 
				  dec_sig_bws,
				  bws_mp_sig+sbfrm_size*n_subframes/n_subframes_bws*sbfrm_ctr,
				  bws_nb_acb_index, rms_index);
	}

	free ( wn_ap_bws );
	free ( wd_ap_bws );
	free ( dec_sig_bws );
      }

      free ( wn_ap );
      free ( wd_ap );
      free ( dec_sig );
      free ( bws_mp_sig );
    }

    /*==================================================================*/
    /* CELP Lpc Mux                                                     */
    /*==================================================================*/
	if (QuantizationMode == ScalarQuantizer)
	{
	    /* -------------------------------------------------------------*/
		/* Scalar Quantization Mode                                     */
	    /* -------------------------------------------------------------*/
		/* Step I: Write interpolation_flag and LPC_present flag        */
	    /* -------------------------------------------------------------*/
		PutBit(p_bitstream, interpolation_flag, 1);
		PutBit(p_bitstream, LPC_Present, 1);
		
	    /* -------------------------------------------------------------*/
		/* Step II: If LPC is present                                   */
	    /* -------------------------------------------------------------*/
		if (LPC_Present == YES)
		{
		    /* ---------------------------------------------------------*/
			/* Check whether lossless coding mode is on                 */
		    /* ---------------------------------------------------------*/
		    if (LosslessCodingMode == ON)
			{
			    Write_LosslessCoded_LPC(p_bitstream, num_lpc_indices, codes);
			}
			else
			{
			    if (SampleRateMode == fs16kHz)
				{
				    Write_WidebandPacked_LPC(p_bitstream, num_lpc_indices, codes);
				}
				else if (SampleRateMode == fs8kHz)
				{
				    Write_NarrowbandPacked_LPC(p_bitstream, codes);
				}
			}
		}		
	}
	else
	{
	  /* -------------------------------------------------------------*/
	  /* Vector Quantization Mode                                     */
	  /* -------------------------------------------------------------*/
	  if (FineRateControl == ON)
	    {
	      /* ---------------------------------------------------------*/
	      /* Step I: Read interpolation_flag and LPC_present flag     */
	      /* ---------------------------------------------------------*/
	      PutBit(p_bitstream, interpolation_flag, 1);
	      PutBit(p_bitstream, LPC_Present, 1);
			
	      /* ---------------------------------------------------------*/
	      /* Step II: If LPC is present                               */
	      /* ---------------------------------------------------------*/
	      if (LPC_Present == YES)
		{
		  if (SampleRateMode == fs16kHz)
		    {
		      if (Wideband_VQ == Optimized_VQ)
			{
			  /*---------------------------------------------*/
			  /* Use the Optimised Wideband Vector Quantiser */
			  /*---------------------------------------------*/
			  Write_Wideband_LSP(p_bitstream, codes);
			}
		      else
			{
			  /*---------------------------------------------*/
			  /* Use the Bandscalable Vector Quantiser       */
			  /*---------------------------------------------*/
			  Write_NarrowBand_LSP(p_bitstream, codes);
			  Write_BandScalable_LSP(p_bitstream, codes+5);
			}
		    }
		  else if (SampleRateMode == fs8kHz)
		    {
		      Write_NarrowBand_LSP(p_bitstream, codes); 
		      /*--------------------------------------------------*/
		      /* If BandwidthScalabilityMode is On                */
		      /*--------------------------------------------------*/
		      if (BandwidthScalabilityMode == ON)
			{
			  Write_BandScalable_LSP(p_bitstream, codes_bws);
			}
		    }
		}
	    }
	  else
	    {
	      if (SampleRateMode == fs16kHz)
		{
		  if (Wideband_VQ == Optimized_VQ)
		    {
		      /*-------------------------------------------------*/
		      /* Use the Optimised Wideband Vector Quantiser     */
		      /*-------------------------------------------------*/
		      Write_Wideband_LSP(p_bitstream, codes);
		    }
		  else
		    {
		      /*-------------------------------------------------*/
		      /* Use the Bandscalable Vector Quantiser           */
		      /*-------------------------------------------------*/
		      Write_NarrowBand_LSP(p_bitstream, codes);
		      Write_BandScalable_LSP(p_bitstream, codes+5);
		    }
		}
	      else if (SampleRateMode == fs8kHz)
		{
		  Write_NarrowBand_LSP(p_bitstream, codes); 
		  /*------------------------------------------------------*/
		  /* If BandwidthScalabilityMode is On                    */
		  /*------------------------------------------------------*/
		  if (BandwidthScalabilityMode == ON)
		    {
		      Write_BandScalable_LSP(p_bitstream, codes_bws);
		    }
		}
	    }
	}

	/*==================================================================*/
	/* CELP Excitation decoding                                         */
    /*==================================================================*/
	if (SampleRateMode == fs16kHz)
	{
		long subframe;
		
	    /*--------------------------------------------------------------*/
		/* Regular Pulse Excitation                                     */ 
		/*--------------------------------------------------------------*/
		for(subframe = 0; subframe < n_subframes; subframe++)
		{
	        /* ---------------------------------------------------------*/
		    /*Read the Adaptive Codebook Lag                            */
	        /* ---------------------------------------------------------*/
		    PutBit(p_bitstream, shape_indices[subframe * num_shape_cbks], 8);
			
	        /* ---------------------------------------------------------*/
		    /*Read the Fixed Codebook Index (function of bit-rate)      */
	        /* ---------------------------------------------------------*/
			if (WB_Configuration > 2)
			{
		        PutBit(p_bitstream, shape_indices[subframe * num_shape_cbks + 1], 12);
			}
			else
			{
		        PutBit(p_bitstream, shape_indices[subframe * num_shape_cbks + 1], 11);
			}
			
	        /* ---------------------------------------------------------*/
		    /*Read the Adaptive Codebook Gain                           */
	        /* ---------------------------------------------------------*/
		    PutBit(p_bitstream, gain_indices[subframe * num_gain_cbks], 6);
			
	        /* ---------------------------------------------------------*/
		    /*Read the Fixed Codebook Gain (function of subframe)       */
			/*Later subframes are encoded differentially w.r.t previous */
	        /* ---------------------------------------------------------*/
			if (subframe == 0)
			{
		        PutBit(p_bitstream, gain_indices[subframe * num_gain_cbks + 1], 5);
			}
			else
			{
		        PutBit(p_bitstream, gain_indices[subframe * num_gain_cbks + 1], 3);
			}
			
		}
	}
	else if (SampleRateMode == fs8kHz)
	{
	  /*--------------------------------------------------------------*/
	  /* Multi-Pulse Excitation                                       */ 
	  /*--------------------------------------------------------------*/
	  long i, j;
	  long mp_pos_bits, mp_sgn_bits;
	  long enh_pos_bits, enh_sgn_bits;
	  long bws_pos_bits, bws_sgn_bits;

	  mp_pos_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+1];
	  mp_sgn_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+2];
	  enh_pos_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+n_subframes*(num_shape_cbks+num_gain_cbks)+1];
	  enh_sgn_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+n_subframes*(num_shape_cbks+num_gain_cbks)+2];
	  bws_pos_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+(num_enhstages+1)*n_subframes*(num_shape_cbks+num_gain_cbks)+NEC_NUM_LPC_INDICES_FRQ16+1];
	  bws_sgn_bits = org_frame_bit_allocation[PAN_NUM_LPC_INDICES+NEC_NUM_OTHER_INDICES+(num_enhstages+1)*n_subframes*(num_shape_cbks+num_gain_cbks)+NEC_NUM_LPC_INDICES_FRQ16+2];

	  PutBit(p_bitstream, signal_mode, NEC_BIT_MODE);
	  PutBit(p_bitstream, rms_index, NEC_BIT_RMS);
	  for ( i = 0; i < n_subframes; i++ ) {
	    PutBit(p_bitstream,
		   shape_indices[i*num_shape_cbks+0], NEC_BIT_ACB);
	    PutBit(p_bitstream,
		   shape_indices[i*num_shape_cbks+1], mp_pos_bits);
	    PutBit(p_bitstream,
		   shape_indices[i*num_shape_cbks+2], mp_sgn_bits);
	    PutBit(p_bitstream,
		   gain_indices[i*num_gain_cbks+0], NEC_BIT_GAIN);
	    for ( j = 1; j <= num_enhstages; j++ ) {
	      PutBit(p_bitstream,
		     shape_indices[(j*n_subframes+i)*num_shape_cbks+1],
		     enh_pos_bits);
	      PutBit(p_bitstream,
		     shape_indices[(j*n_subframes+i)*num_shape_cbks+2],
		     enh_sgn_bits);
	      PutBit(p_bitstream,
		     gain_indices[(j*n_subframes+i)*num_gain_cbks+0],
		     NEC_BIT_ENH_GAIN);
	    }
	  }
	  if ( BandwidthScalabilityMode == ON ) {
	    for ( i = 0; i < n_subframes_bws; i++ ) {
	      PutBit(p_bitstream,
		     shape_indices_bws[i*num_shape_cbks+0],
		     NEC_BIT_ACB_FRQ16);
	      PutBit(p_bitstream,
		     shape_indices_bws[i*num_shape_cbks+1], bws_pos_bits);
	      PutBit(p_bitstream,
		     shape_indices_bws[i*num_shape_cbks+2], bws_sgn_bits);
	      PutBit(p_bitstream,
		     gain_indices_bws[i*num_gain_cbks+0],
		     NEC_BIT_GAIN_FRQ16);
	    }
	  }
	}
		
    /* -----------------------------------------------------------------*/
    /* Next becomes currrent af                                         */
    /* -----------------------------------------------------------------*/
    PHI_af  = af_next;
    
    /* -----------------------------------------------------------------*/
    /* Free Arrays that were malloced for Frame processing              */
    /* -----------------------------------------------------------------*/
    free ( int_ap );
    free ( ap );
    free ( shape_indices );
    free ( gain_indices );
    free ( codes );
    free ( ds_ap  );
    free ( ds_window_offsets );
    free ( ds_window_sizes );

    if (SampleRateMode == fs8kHz) {
      if ( BandwidthScalabilityMode == ON) {
	free ( int_ap_bws );
	free ( ap_bws );
	free ( shape_indices_bws );
	free ( gain_indices_bws );
	free ( codes_bws );
	free ( bws_nb_acb_index );
      }
    }
    /* -----------------------------------------------------------------*/
    /* Frame Counter                                                    */
    /* -----------------------------------------------------------------*/
    if (!interpolation_flag)
    {
        lpc_sent_frames++;
    }
    frame_ctr++;
    if ((frame_ctr % 10) == 0)
    {
      if (CELPencDebugLevel) {	/* HP 971120 */
        fprintf(stderr, "Frame Counter: %ld \r", frame_ctr);
      }
    }
}
/*======================================================================*/
/*   Function Definition:celp_initialisation_encoder                    */
/*======================================================================*/
void celp_initialisation_encoder
(
BITSTREAM  * const p_bitstream,  /* In/Out: Bitstream                   */
long	 bit_rate,  	         /* In: bit rate                        */
long	 sampling_frequency,     /* In: sampling frequency              */
long     SampleRateMode,	     /* In: SampleRate Mode 		*/
long     QuantizationMode,       /* In: Type of Quantization		*/
long     FineRateControl,	     /* In: Fine Rate Control switch	 */
long     LosslessCodingMode,     /* In: Lossless Coding Mode	*/
long     *WB_Configuration,      /* In: Wideband configuration 	*/
long     Wideband_VQ,		     /* Out: Wideband VQ mode			*/
long     *NB_Configuration,      /* Out: Narrowband configuration   */
long     NumEnhLayers,  	     /* In: Number of Enhancement Layers*/
long     BandwidthScalabilityMode, /* In: bandwidth switch   */
long     *BWS_Configuration,     /* Out: BWS_configuration 		*/
long     BWS_nb_bitrate,  	     /* In: narrowband bitrate for BWS */
long	 *frame_size,	         /* Out: frame size                     */
long	 *n_subframes,           /* Out: number of  subframes           */
long	 *sbfrm_size,	         /* Out: subframe size                  */ 
long	 *lpc_order,	         /* Out: LP analysis order              */
long	 *num_lpc_indices,       /* Out: number of LPC indices          */
long	 *num_shape_cbks,	     /* Out: number of Shape Codebooks      */
long	 *num_gain_cbks,	     /* Out: number of Gain Codebooks       */ 
long	 *n_lpc_analysis,	     /* Out: number of LP analysis per frame*/
long	 **window_offsets,       /* Out: window offset for each LP ana  */
long	 **window_sizes,         /* Out: window size for each LP ana    */
long	 *n_lag_candidates,      /* Out: number of pitch candidates     */
float	 *min_pitch_frequency,   /* Out: minimum pitch frequency        */
float	 *max_pitch_frequency,   /* Out: maximum pitch frequency        */
long	 **org_frame_bit_allocation/* Out: bit num. for each index      */
)
{
	
	if (SampleRateMode == fs16kHz)
	{
    	int k;
		long BIT_RATE_1;
		long BIT_RATE_2;
		long BIT_RATE_3;
		long BIT_RATE_4;
		long BIT_RATE_5;
		long BIT_RATE_6;
		long BIT_RATE_7;
		long BIT_RATE_8;
		
    	if (QuantizationMode == VectorQuantizer) 
		{
			BIT_RATE_1 = 13267;
			BIT_RATE_2 = 15067;
			BIT_RATE_3 = 15067;
			BIT_RATE_4 = 17000;
			BIT_RATE_5 = 17533;
			BIT_RATE_6 = 19333;
			BIT_RATE_7 = 21400;
			BIT_RATE_8 = 23200;
		}
		else
		{
			BIT_RATE_1 = 13667;
			BIT_RATE_2 = 15867;
			BIT_RATE_3 = 15867;
			BIT_RATE_4 = 18200;
			BIT_RATE_5 = 18200;
			BIT_RATE_6 = 20133;
			BIT_RATE_7 = 21800;
			BIT_RATE_8 = 24000;
		}


    	/* -----------------------------------------------------------------*/
    	/*Check if the sampling rate mode is set correctly                  */
    	/* -----------------------------------------------------------------*/ 
		if (FineRateControl == OFF)
		{
    		/* -----------------------------------------------------------------*/
    		/*Check if a bit rate is a set of allowed bit rates                 */
    		/* -----------------------------------------------------------------*/ 
    		if (bit_rate == BIT_RATE_1)
    		{
		    		*WB_Configuration = 0;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   6;        
    		}
    		else
    		if (bit_rate == BIT_RATE_2)
    		{
		    		*WB_Configuration = 1;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   6;        
    		}
    		else
    		if (bit_rate == BIT_RATE_4)
    		{
		    		*WB_Configuration = 2;
            		*frame_size  = TEN_MS;
            		*n_subframes =   4;
    		}
    		else
    		if (bit_rate == BIT_RATE_6)
    		{
		    		*WB_Configuration = 3;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   8;
    		}
    		else
    		if (bit_rate == BIT_RATE_7)
    		{
		    		*WB_Configuration = 4;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   10;
    		}
    		else
    		if (bit_rate == BIT_RATE_8)
    		{
		    		*WB_Configuration = 5;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   10;
    		}
    		else
    		{
        		fprintf(stderr, "ERROR: Bit Rate not in the set of supported bit rates \n");
        		fprintf(stderr, "Supported bit rates: %d, %d, %d, %d, %d and %d\n", 
            		 BIT_RATE_1, BIT_RATE_2, BIT_RATE_4, 
            		 BIT_RATE_6, BIT_RATE_7, BIT_RATE_8);
        		exit(1); 
    		}

		}
		else
		{
    		/* -----------------------------------------------------------------*/
    		/*Check if a bit rate is a set of allowed bit rates                 */
    		/* -----------------------------------------------------------------*/ 
    		if ((bit_rate <= BIT_RATE_2) && (bit_rate >= BIT_RATE_1))
    		{
		    		*WB_Configuration = 0;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   6;        
    		}
    		else
    		if ((bit_rate <= BIT_RATE_4) && (bit_rate > BIT_RATE_3))
    		{
		    		*WB_Configuration = 2;
            		*frame_size  = TEN_MS;
            		*n_subframes =   4;
    		}
    		else
    		if ((bit_rate <= BIT_RATE_6) && (bit_rate > BIT_RATE_5))
    		{
		    		*WB_Configuration = 3;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   8;
    		}
    		else
    		if ((bit_rate <= BIT_RATE_8) && (bit_rate > BIT_RATE_7))
    		{
		    		*WB_Configuration = 5;
            		*frame_size  = FIFTEEN_MS;
            		*n_subframes =   10;
    		}
    		else
    		{
        		fprintf(stderr, "ERROR: Bit Rate not in the set of supported bit rates \n");
        		fprintf(stderr, "Supported bit rates: %d-%d, %d-%d, %d-%d and %d-%d\n", 
            		 BIT_RATE_1, BIT_RATE_2, BIT_RATE_3, BIT_RATE_4, BIT_RATE_5,
            		 BIT_RATE_6, BIT_RATE_7, BIT_RATE_8);
        		exit(1); 
    		}
		}

    	*sbfrm_size          = (*frame_size)/(*n_subframes);
		*lpc_order           = ORDER_LPC;	 
    	if (QuantizationMode == VectorQuantizer)  /* VQ */  
		{ 
        	*num_lpc_indices     = 11;
	    	if (LosslessCodingMode == ON)
			{
	        	fprintf(stderr, "Lossless coding is only possible with Scalar Quantization\n");
				exit(0);
			}
			
		}
    	else /* SQ */
		{
	    	if (LosslessCodingMode == ON)
			{
	        	*num_lpc_indices     = 20;   
			}
			else
			{
	        	*num_lpc_indices     = N_INDICES;   
			}
		}

		*n_lpc_analysis      = 1;	 
    	*n_lag_candidates    = MAX_N_LAG_CANDIDATES;            
		*min_pitch_frequency = (float)1.0/(float)Lmax;              
		*max_pitch_frequency = (float)1.0/(float)Lmin;             
    	PHI_BUFFER           = ((3 * (*frame_size)) + (*sbfrm_size)/2);
		*num_shape_cbks      = 2;	 
		*num_gain_cbks       = 2;	 

    	/* -----------------------------------------------------------------*/
    	/* Malloc  parameters  and set them                                 */
    	/* -----------------------------------------------------------------*/
    	if
    	(
    	(( *window_offsets = (long *)malloc((unsigned int)(*n_lpc_analysis) * sizeof(long))) == NULL )||
    	(( PHI_sp_pp_buf = (float *)malloc((unsigned int)PHI_BUFFER *  sizeof(float))) == NULL )||
    	(( Downsampled_signal = (float *)malloc((unsigned int)(PHI_BUFFER/2) *  sizeof(float))) == NULL )||
    	(( *window_sizes   = (long *)malloc((unsigned int)(*n_lpc_analysis) * sizeof(long))) == NULL )
    	)
    	{
			printf("MALLOC FAILURE in Routine abs_initialisation_encoder \n");
			exit(1);
    	} 
    	if (*WB_Configuration == 2)
    	{
        	(*window_sizes)[0]   = TWENTY_MS;     
    	}
    	else
    	{
        	(*window_sizes)[0]   = TWENTY_MS + FIVE_MS;     
    	}
		(*window_offsets)[0] = 2 * (*frame_size) - (*window_sizes)[0]/2;

    	/* -----------------------------------------------------------------*/
    	/* Initilialising data                                              */
    	/* -----------------------------------------------------------------*/ 
    	for(k = 0; k < (int)PHI_BUFFER; k++)
    	{
    	   PHI_sp_pp_buf[k] = (float)0.0;
    	}

    	/* -----------------------------------------------------------------*/
    	/* Call various init routines to allocate memory                    */
    	/* -----------------------------------------------------------------*/ 
    	PHI_allocate_energy_table(*sbfrm_size, ACBK_SIZE, Sa);

    	PHI_init_excitation_analysis(Lmax, *lpc_order, *sbfrm_size, *WB_Configuration);

    	*org_frame_bit_allocation = PHI_init_bit_allocation(*WB_Configuration, 
				QuantizationMode, LosslessCodingMode, *num_lpc_indices,
                                            	   *n_subframes, *num_shape_cbks, *num_gain_cbks); 

    	PHI_InitLpcAnalysisEncoder(*window_sizes, *n_lpc_analysis, *lpc_order, *lpc_order/2, (float)GAMMA_BE, bit_rate, 
    	  sampling_frequency,*frame_size, *num_lpc_indices, *n_subframes, *num_shape_cbks, *num_gain_cbks,  
    	  *org_frame_bit_allocation, num_indices, QuantizationMode);

    	/* -----------------------------------------------------------------*/
    	/* Initialise windows for wideband LPC analysis                     */
    	/* -----------------------------------------------------------------*/ 
		{			       
        	int     x;
    		float   *pin;
    		float   *pout;

    		long i;

    		if((SquaredHammingWindow=(float **)calloc((unsigned int)*n_lpc_analysis, sizeof(float *)))==NULL)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}

    		for(i=0;i<*n_lpc_analysis;i++) 
    		{
        		if((SquaredHammingWindow[i]=(float *)calloc((unsigned int)(*window_sizes)[i], sizeof(float)))==NULL)
            	{
		    		printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
		    		exit(1);
        		}

    			/* -------------------------------------------------------------*/       
    			/* Generate Hamming Window For Lpc                              */
    			/* -------------------------------------------------------------*/ 
        		pout = SquaredHammingWindow[i];   	
        		for(x=0; x < (int)(*window_sizes)[i];x++)
        		{
            		*pout++ = (float)(0.540000 - 0.460000 * cos(6.283185307 * ((double)x-(double)0.00000)/(double)((*window_sizes)[i])));
        		}

        		for(x = 0; x < (int)(*window_sizes)[i]; x++)
        		{
            		SquaredHammingWindow[i][x] *= SquaredHammingWindow[i][x];
        		}

    		}

    		/* -----------------------------------------------------------------*/       
    		/* Generate Gamma Array for Bandwidth Expansion                     */
    		/* -----------------------------------------------------------------*/       
    		if
    		(
    		(( PHI_GammaArrayBE = (float *)malloc((unsigned int)(*lpc_order) * sizeof(float))) == NULL )
    		)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}
    		pin     = PHI_GammaArrayBE;
    		pout    = PHI_GammaArrayBE;
    		*pout++ = (float)GAMMA_BE;
    		for(x=1; x < (int)*lpc_order; x++)
    		{
        		*pout++ = (float)GAMMA_BE * *pin++;
    		}
		}	

    	/* -----------------------------------------------------------------*/
    	/* Initialise windows for narrowband LPC analysis                   */
    	/* -----------------------------------------------------------------*/ 
		{			       
        	int     x;
    		float   *pin;
    		float   *pout;

    		long i;

    		if((HammingWindow=(float **)calloc((unsigned int)*n_lpc_analysis, sizeof(float *)))==NULL)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}

    		for(i=0;i<*n_lpc_analysis;i++) 
    		{
        		if((HammingWindow[i]=(float *)calloc((unsigned int)(((*window_sizes)[i])/2), sizeof(float)))==NULL)
            	{
		    		printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
		    		exit(1);
        		}

    			/* -------------------------------------------------------------*/       
    			/* Generate Hamming Window For Lpc                              */
    			/* -------------------------------------------------------------*/ 
        		pout = HammingWindow[i];   	
        		for(x=0; x < (int)(((*window_sizes)[i])/2);x++)
        		{
            		*pout++ = (float)(0.540000 - 0.460000 * cos(6.283185307 * ((double)x-(double)0.00000)/(double)((((*window_sizes)[i])/2))));
        		}
    		}

    		/* -----------------------------------------------------------------*/       
    		/* Generate Gamma Array for Bandwidth Expansion                     */
    		/* -----------------------------------------------------------------*/       
    		if
    		(
    		(( PAN_GammaArrayBE = (float *)malloc((unsigned int)(*lpc_order/2) * sizeof(float))) == NULL )
    		)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}
    		pin     = PAN_GammaArrayBE;
    		pout    = PAN_GammaArrayBE;
    		*pout++ = (float)PAN_GAMMA_BE;
    		for(x=1; x < (int)*lpc_order/2; x++)
    		{
        		*pout++ = (float)PAN_GAMMA_BE * *pin++;
    		}
		}	
	
	}
	
	if (SampleRateMode == fs8kHz)
	{
    	int i, j;
    	long	target_mp_bits, mp_pos_bits, mp_sgn_bits;
	long    enh_pos_bits, enh_sgn_bits;
	long    bws_pos_bits, bws_sgn_bits;
    	long	ctr, calc_bit_rate;
    	long	CoreBitRate;
    	long	num_bits_lpc_int;
    	int     high_bound_found = 0;
		long BITRATE1;
		long BITRATE2;
		long BITRATE3;
		long BITRATE4;
		long BITRATE5;
		long BITRATE6;

        if (QuantizationMode == VectorQuantizer)
		{
			BITRATE1=3850;
			BITRATE2=4900;
			BITRATE3=5700;
			BITRATE4=7700;
			BITRATE5=11000;
			BITRATE6=12200;
		}
		else
		{
			BITRATE1=4325;  /* 3850 + 475 */
			BITRATE2=5533; /* 4900 + 633 */
			BITRATE3=6650;  /* 5700 + 950 */
			BITRATE4=8650;  /* 7700 + 950 */
			BITRATE5=12900; /* 11000 + 1900 */
			BITRATE6=14100; /* 12200 + 1900 */
		}
	
    	num_enhstages = NumEnhLayers;
	if (BandwidthScalabilityMode==ON) {
	  CoreBitRate = BWS_nb_bitrate - NEC_ENH_BITRATE * num_enhstages;
	} else {
	  CoreBitRate = bit_rate - NEC_ENH_BITRATE * num_enhstages;
	}

	*lpc_order = NEC_LPC_ORDER;
	*num_shape_cbks = NEC_NUM_SHAPE_CBKS;
	*num_gain_cbks = NEC_NUM_GAIN_CBKS;
	if (QuantizationMode == ScalarQuantizer) {
	  *num_lpc_indices = 4;
	} else {
	  *num_lpc_indices = PAN_NUM_LPC_INDICES;
	}
	*n_lag_candidates = PAN_N_PCAN_INT;
	*min_pitch_frequency = sampling_frequency/(float)NEC_PITCH_MAX;
	*max_pitch_frequency = sampling_frequency/(float)NEC_PITCH_MIN;

	if ((QuantizationMode == ScalarQuantizer)){
	  num_bits_lpc_int = 2 + 39;
	} else {
	  if (FineRateControl == ON) {
	    num_bits_lpc_int = 2;
	  } else {
	    num_bits_lpc_int = 0;
	  }
	}

	while (!high_bound_found) {
	  if ( CoreBitRate >= BITRATE1 && CoreBitRate < BITRATE2 ) {
	    frame_size_nb = NEC_FRAME40MS;
	    *n_subframes = NEC_NSF4;
	  }
	  if ( CoreBitRate >= BITRATE2 && CoreBitRate < BITRATE3 ) {
	    frame_size_nb = NEC_FRAME30MS;
	    *n_subframes = NEC_NSF3;
	  }
	  if ( CoreBitRate >= BITRATE3 && CoreBitRate < BITRATE4 ) {
	    frame_size_nb = NEC_FRAME20MS;
	    *n_subframes = NEC_NSF2;
	  }
	  if ( CoreBitRate >= BITRATE4 && CoreBitRate < BITRATE5 ) {
	    frame_size_nb = NEC_FRAME20MS;
	    *n_subframes = NEC_NSF4;
	  }
	  if ( CoreBitRate >= BITRATE5 && CoreBitRate <= BITRATE6 ) {
	    frame_size_nb = NEC_FRAME10MS;
	    *n_subframes = NEC_NSF2;
	  }
	  if ( CoreBitRate < BITRATE1 || CoreBitRate > BITRATE6 ) {
	    printf("Error: Specified BitRate %d is not supported.\n",
		   CoreBitRate);
	    exit(1); 
	  }

	  *sbfrm_size = (frame_size_nb)/(*n_subframes);
	  *n_lpc_analysis = (frame_size_nb)/NEC_LEN_LPC_ANALYSIS;

	  num_indices = NEC_NUM_OTHER_INDICES + PAN_NUM_LPC_INDICES
	    + (num_enhstages + 1) * (*n_subframes) *
	      (NEC_NUM_SHAPE_CBKS+NEC_NUM_GAIN_CBKS);

	  if (QuantizationMode == ScalarQuantizer)
	  {
		  target_mp_bits=(long)(((float)(frame_size_nb)*CoreBitRate/8000
					 - (num_bits_lpc_int+NEC_BIT_MODE
				    	+ NEC_BIT_RMS))
					/(*n_subframes)
					- (NEC_BIT_ACB + NEC_BIT_GAIN));

		  nec_mp_config((*sbfrm_size),target_mp_bits,
				&mp_pos_bits,&mp_sgn_bits);

		  calc_bit_rate=(long)(((num_bits_lpc_int+NEC_BIT_MODE
					 + NEC_BIT_RMS)
					+(NEC_BIT_ACB+mp_pos_bits+mp_sgn_bits
					  +NEC_BIT_GAIN)*(*n_subframes))
			    	   *8000/(frame_size_nb));
		  
	  }
	  else
	  {
		  target_mp_bits=(long)(((float)(frame_size_nb)*CoreBitRate/8000
					 - (num_bits_lpc_int+NEC_BIT_MODE
				    	+PAN_BIT_LSP22_0
    				    	+PAN_BIT_LSP22_1+PAN_BIT_LSP22_2
     				    	+PAN_BIT_LSP22_3+PAN_BIT_LSP22_4
				    	+NEC_BIT_RMS))
					/(*n_subframes)
					- (NEC_BIT_ACB + NEC_BIT_GAIN));

		  nec_mp_config((*sbfrm_size),target_mp_bits,
				&mp_pos_bits,&mp_sgn_bits);

		  calc_bit_rate=(long)(((num_bits_lpc_int+NEC_BIT_MODE
					 +PAN_BIT_LSP22_0
					 +PAN_BIT_LSP22_1+PAN_BIT_LSP22_2
					 +PAN_BIT_LSP22_3+PAN_BIT_LSP22_4+NEC_BIT_RMS)
					+(NEC_BIT_ACB+mp_pos_bits+mp_sgn_bits
					  +NEC_BIT_GAIN)*(*n_subframes))
			    	   *8000/(frame_size_nb));
      }
	  
	  if ( CoreBitRate != calc_bit_rate ) {
	    if (FineRateControl == OFF) {
	      printf("Error: Specified BitRate %d is not supported.\n",
		     bit_rate);
	      printf("\t Please set BitRate at %d\n",
		     calc_bit_rate+num_enhstages*NEC_ENH_BITRATE);
	      exit(1); 
	    } else {
	      CoreBitRate += 25;
	    }
	  } else {
	    high_bound_found = 1;
	    if ( CoreBitRate >= BITRATE1 && CoreBitRate < BITRATE2 ) {
	      *NB_Configuration = mp_sgn_bits-3;
	    }
	    if ( CoreBitRate >= BITRATE2 && CoreBitRate < BITRATE3 ) {
	      *NB_Configuration = (mp_sgn_bits-5)+3;
	    }
	    if ( CoreBitRate >= BITRATE3 && CoreBitRate < BITRATE4 ) {
	      *NB_Configuration = (mp_sgn_bits-6)+6;
	    }
	    if ( CoreBitRate >= BITRATE4 && CoreBitRate < BITRATE5 ) {
	      *NB_Configuration = (mp_sgn_bits-4)+13;
	    }
	    if ( CoreBitRate >= BITRATE5 && CoreBitRate <= BITRATE6 ) {
	      *NB_Configuration = (mp_sgn_bits-8)+22;
	    }
	  }
    	}

	if (BandwidthScalabilityMode==ON) {
	  frame_size_bws = frame_size_nb * 2;
	  n_subframes_bws = frame_size_bws/80;
	  sbfrm_size_bws = frame_size_bws / n_subframes_bws;
	  lpc_order_bws = NEC_LPC_ORDER_FRQ16;
	  n_lpc_analysis_bws = frame_size_bws / NEC_LEN_LPC_ANALYSIS;

	  target_mp_bits=(long)(((float)(frame_size_bws)*
				 (bit_rate-BWS_nb_bitrate)
				 /16000 - NEC_BIT_LSP1620)
				/n_subframes_bws - (NEC_BIT_ACB_FRQ16
						    + NEC_BIT_GAIN_FRQ16));
	  nec_mp_config(sbfrm_size_bws,target_mp_bits,
			&bws_pos_bits,&bws_sgn_bits);
    
	  calc_bit_rate=(long)((NEC_BIT_LSP1620
				+(NEC_BIT_ACB_FRQ16 + bws_pos_bits
				  +bws_sgn_bits + NEC_BIT_GAIN_FRQ16)
				*n_subframes_bws)*16000/(frame_size_bws));

	  if ( (bit_rate-BWS_nb_bitrate) != calc_bit_rate ) {
	    printf("Error: Specified BitRate %d is not supported.\n",bit_rate);
	    exit(1); 
	  }
	  if ( bws_sgn_bits < 6 || bws_sgn_bits > 9 ) {
	    printf("Error: Specified BitRate %d is not supported.\n",bit_rate);
	    exit(1);
	  } else {
	    *BWS_Configuration = (bws_sgn_bits-6)/2;
	  }

	  *frame_size = frame_size_bws;
	  num_lpc_indices_bws = NEC_NUM_LPC_INDICES_FRQ16 ;
	  num_indices += NEC_NUM_LPC_INDICES_FRQ16 
	               + n_subframes_bws * (NEC_NUM_SHAPE_CBKS
					    +NEC_NUM_GAIN_CBKS);
	} else {
	  *frame_size = frame_size_nb;
	}

    	if((*window_sizes=(long *)calloc(*n_lpc_analysis, 
				    	 sizeof(long)))==NULL) {
    	   printf("\n memory allocation error in initialization_encoder\n");
    	   exit(1);
    	}
    	if((*window_offsets=(long *)calloc(*n_lpc_analysis, 
				    	   sizeof(long)))==NULL) {
    	   printf("\n memory allocation error in initialization_encoder\n");
    	   exit(2);
    	}

        if ((FineRateControl == ON) || (QuantizationMode == ScalarQuantizer)) {
	  for(i=0;i<(*n_lpc_analysis);i++) {
	    *(*window_sizes+i) = NEC_PAN_NLB+NEC_LEN_LPC_ANALYSIS+NEC_PAN_NLA;
	    *(*window_offsets+i) = i*NEC_LEN_LPC_ANALYSIS + ((*frame_size) - NEC_PAN_NLB);
	  }
	} else {
	  for(i=0;i<(*n_lpc_analysis);i++) {
	    *(*window_sizes+i) = NEC_PAN_NLB+NEC_LEN_LPC_ANALYSIS+NEC_PAN_NLA;
	    *(*window_offsets+i) = i*NEC_LEN_LPC_ANALYSIS;
	  }
	}

    	if((*org_frame_bit_allocation=(long *)calloc(num_indices, 
						     sizeof(long)))==NULL) {
    	   printf("\n memory allocation error in initialization_encoder\n");
    	   exit(3);
    	}

    	ctr = 0;
    	*(*org_frame_bit_allocation+(ctr++)) =  PAN_BIT_LSP22_0;
    	*(*org_frame_bit_allocation+(ctr++)) =  PAN_BIT_LSP22_1;
    	*(*org_frame_bit_allocation+(ctr++)) =  PAN_BIT_LSP22_2;
    	*(*org_frame_bit_allocation+(ctr++)) =  PAN_BIT_LSP22_3;
    	*(*org_frame_bit_allocation+(ctr++)) =  PAN_BIT_LSP22_4;
    	*(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_MODE;
    	*(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_RMS;
    	for ( i = 0; i < *n_subframes; i++ ) {
	  *(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_ACB;
	  *(*org_frame_bit_allocation+(ctr++)) =  mp_pos_bits;
	  *(*org_frame_bit_allocation+(ctr++)) =  mp_sgn_bits;
	  *(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_GAIN;
    	}

	if ( *sbfrm_size == (NEC_FRAME20MS/NEC_NSF4) ) {
	  enh_pos_bits = NEC_BIT_ENH_POS40_2;
	  enh_sgn_bits = NEC_BIT_ENH_SGN40_2;
	} else {
	  enh_pos_bits = NEC_BIT_ENH_POS80_4;
	  enh_sgn_bits = NEC_BIT_ENH_SGN80_4;
	}
    	for ( i = 0; i < num_enhstages; i++ ) {
	  for ( j = 0; j < *n_subframes; j++ ) {
	    *(*org_frame_bit_allocation+(ctr++)) =  0;
	    *(*org_frame_bit_allocation+(ctr++)) =  enh_pos_bits;
	    *(*org_frame_bit_allocation+(ctr++)) =  enh_sgn_bits;
	    *(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_ENH_GAIN;
	  }
    	}

	if (BandwidthScalabilityMode==ON) {
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_0;
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_1;
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_2;
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_3; 
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_4; 
	  *(*org_frame_bit_allocation+(ctr++)) = NEC_BIT_LSP1620_5;
	  for ( i = 0; i < n_subframes_bws; i++ ) {
	    *(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_ACB_FRQ16;
	    *(*org_frame_bit_allocation+(ctr++)) =  bws_pos_bits;
	    *(*org_frame_bit_allocation+(ctr++)) =  bws_sgn_bits;
	    *(*org_frame_bit_allocation+(ctr++)) =  NEC_BIT_GAIN_FRQ16;
	  }
	}

        if ((FineRateControl == ON) || (QuantizationMode == ScalarQuantizer)) {
	  PHI_BUFFER = buffer_size = NEC_PAN_NLB+frame_size_nb+NEC_PAN_NLA + (frame_size_nb-NEC_PAN_NLB); 
	  /* AG: one frame delay for interpolation */ 
	} else {
	  PHI_BUFFER = buffer_size = NEC_PAN_NLB+frame_size_nb+NEC_PAN_NLA;
	}

    	/* momory allocation to static parameters */
    	if((PHI_sp_pp_buf=(float *)calloc(buffer_size, sizeof(float)))==NULL) {
	  printf("\n memory allocation error in initialization_encoder\n");
	  exit(4);
    	}
    	for(i=0;i<buffer_size;i++) *(PHI_sp_pp_buf+i) = 0.;

    	if((prev_Qlsp_coefficients=(float *)calloc(*lpc_order,
						   sizeof(float)))==NULL) {
	  printf("\n memory allocation error in initialization_encoder\n");
	  exit(5);
    	}

    	for(i=0;i<(*lpc_order);i++) 
	  *(prev_Qlsp_coefficients+i) = (i+1)/(float)((*lpc_order)+1);

    	gamma_num=PAN_GAM_MA;
    	gamma_den=PAN_GAM_AR;

	/* momory allocation to static parameters */
	if (BandwidthScalabilityMode==ON) {
	  if((window_sizes_bws=(long *)calloc(n_lpc_analysis_bws,
					      sizeof(long)))==NULL) {
	    printf("\n memory allocation error in initialization_encoder\n");
	    exit(1);
	  }
	  if((window_offsets_bws=(long *)calloc(n_lpc_analysis_bws,
						sizeof(long)))==NULL) {
	    printf("\n memory allocation error in initialization_encoder\n");
	    exit(2);
	  }

	  for(i=0;i<n_lpc_analysis_bws;i++) {
	    *(window_sizes_bws+i) = NEC_FRQ16_NLB+NEC_LEN_LPC_ANALYSIS
	                          + NEC_FRQ16_NLA;
	    *(window_offsets_bws+i) = i*NEC_LEN_LPC_ANALYSIS;
	  }

	  buffer_size_bws = NEC_FRQ16_NLB+(frame_size_bws)
	                  + NEC_FRQ16_NLA+NEC_LPF_DELAY;
	  if((bws_sp_buffer=(float *)calloc(buffer_size_bws,
					    sizeof(float)))==NULL) {
	    printf("\n memory allocation error in initialization_encoder\n");
	    exit(4);
	  }
	  for(i=0;i<buffer_size_bws;i++) *(bws_sp_buffer+i) = 0.;

	  if((buf_Qlsp_coefficients_bws=(float *)calloc(*lpc_order,
						      sizeof(float)))==NULL) {
	    printf("\n memory allocation error in initialization_encoder\n");
	    exit(5);
	  }

	  if((prev_Qlsp_coefficients_bws=(float *)calloc(lpc_order_bws,
						       sizeof(float)))==NULL) {
	    printf("\n memory allocation error in initialization_encoder\n");
	    exit(5);
	  }
	  for(i=0;i<(lpc_order_bws);i++) 
	    *(prev_Qlsp_coefficients_bws+i) = PAN_PI * (i+1)
	                                    / (float)(lpc_order_bws+1);
	}

	/* submodules for initialization */
	if ((QuantizationMode == VectorQuantizer) && (FineRateControl == OFF)) {
	  PAN_InitLpcAnalysisEncoder(*window_sizes,*n_lpc_analysis,*lpc_order, 
				     PAN_GAMMA_BE, bit_rate);
	  if (BandwidthScalabilityMode == ON) {
	    NEC_InitLpcAnalysisEncoder(window_sizes_bws,n_lpc_analysis_bws,
				       lpc_order_bws, NEC_GAMMA_BE, bit_rate);
	  }
	} else {
	  PHI_InitLpcAnalysisEncoder(*window_sizes, *n_lpc_analysis, *lpc_order, *lpc_order, (float)PAN_GAMMA_BE, bit_rate, 
    		  sampling_frequency,*frame_size, *num_lpc_indices, *n_subframes, *num_shape_cbks, *num_gain_cbks,  
    		  *org_frame_bit_allocation, num_indices, QuantizationMode);
		}
    	/* -----------------------------------------------------------------*/
    	/* Initialise windows for narrowband LPC analysis                   */
    	/* -----------------------------------------------------------------*/ 
		{			       
        	int     x;
    		float   *pin;
    		float   *pout;

    		long i;

    		if((HammingWindow=(float **)calloc((unsigned int)*n_lpc_analysis, sizeof(float *)))==NULL)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}

    		for(i=0;i<*n_lpc_analysis;i++) 
    		{
        		if((HammingWindow[i]=(float *)calloc((unsigned int)(((*window_sizes)[i])), sizeof(float)))==NULL)
            	{
		    		printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
		    		exit(1);
        		}

    			/* -------------------------------------------------------------*/       
    			/* Generate Hamming Window For Lpc                              */
    			/* -------------------------------------------------------------*/ 
        		pout = HammingWindow[i];   	
        		for(x=0; x < (int)(((*window_sizes)[i]));x++)
        		{
            		*pout++ = (float)(0.540000 - 0.460000 * cos(6.283185307 * ((double)x-(double)0.00000)/(double)((((*window_sizes)[i])/2))));
        		}
    		}

    		/* -----------------------------------------------------------------*/       
    		/* Generate Gamma Array for Bandwidth Expansion                     */
    		/* -----------------------------------------------------------------*/       
    		if
    		(
    		(( PAN_GammaArrayBE = (float *)malloc((unsigned int)(*lpc_order) * sizeof(float))) == NULL )
    		)
    		{
				printf("MALLOC FAILURE in Routine celp_initialisation_encoder \n");
				exit(1);
    		}
    		pin     = PAN_GammaArrayBE;
    		pout    = PAN_GammaArrayBE;
    		*pout++ = (float)PAN_GAMMA_BE;
    		for(x=1; x < (int)*lpc_order; x++)
    		{
        		*pout++ = (float)PAN_GAMMA_BE * *pin++;
    		}
		}	
		
	    if (LosslessCodingMode == ON)
		{
	        *num_lpc_indices     = 10;   
		}
	}

    /* -----------------------------------------------------------------*/       
    /* Write bitstream header                                           */
    /* -----------------------------------------------------------------*/
    write_celp_bitstream_header(p_bitstream, SampleRateMode, QuantizationMode,
			FineRateControl, LosslessCodingMode, *WB_Configuration, Wideband_VQ, *NB_Configuration, 
			NumEnhLayers, BandwidthScalabilityMode, *BWS_Configuration);

} 

/*======================================================================*/
/*   Function Definition: celp_close_encoder                            */
/*======================================================================*/
/* Modified 14/11/96 */
void celp_close_encoder
(
	long SampleRateMode,
	long BandwidthScalabilityMode,
    long sbfrm_size,              /* In: subframe size                  */
    long frame_bit_allocation[],  /* In: bit num. for each index        */
    long window_offsets[],        /* In: window offset for each LP ana  */
    long window_sizes[],          /* In: window size for each LP ana    */
    long n_lpc_analysis           /* In: number of LP analysis/frame    */
)
{
    long i;

	
    PHI_FreeLpcAnalysisEncoder(n_lpc_analysis);
    
	if (SampleRateMode == fs16kHz)
	{
		PHI_close_excitation_analysis();
    	PHI_free_energy_table(sbfrm_size, ACBK_SIZE);
    	PHI_free_bit_allocation(frame_bit_allocation);

    	free(window_offsets);
    	free(window_sizes);

    	for(i=0;i<n_lpc_analysis;i++) 
    	{
        	free(SquaredHammingWindow[i]);
        	free(HammingWindow[i]);
    	}
    	free(SquaredHammingWindow);
    	free(HammingWindow);

    	free(PHI_GammaArrayBE);
    	free(PAN_GammaArrayBE);
    	/* -----------------------------------------------------------------*/
    	/* Print Total Frames Processed                                     */
    	/* -----------------------------------------------------------------*/
    	frame_ctr -= 2; 
	if (CELPencDebugLevel) {	/* HP 971120 */
	  fprintf(stderr,"\n");
	  fprintf(stderr,"Total Frames:  %d \n", frame_ctr);
	  fprintf(stderr,"LPC Frames:    %d \n", lpc_sent_frames);
	  fprintf(stderr,"LPC sent:      %5.2f %%\n", (float)lpc_sent_frames/(float)frame_ctr * (float)100.0);
	}
    }
    
	if (SampleRateMode == fs8kHz)
	{
	if (CELPencDebugLevel) {	/* HP 971120 */
	  fprintf(stderr,"Total Frames:  %d \n", frame_ctr);
	  fprintf(stderr,"LPC Frames:    %d \n", lpc_sent_frames);
	  fprintf(stderr,"LPC sent:      %5.2f %%\n", (float)lpc_sent_frames/(float)frame_ctr * (float)100.0);
	}

    	free(window_offsets);
    	free(window_sizes);

    	for(i=0;i<n_lpc_analysis;i++) 
    	{
        	free(HammingWindow[i]);
    	}
    	free(HammingWindow);
    	free(PAN_GammaArrayBE);
    	free(frame_bit_allocation);
    	free(PHI_sp_pp_buf);
    	free(prev_Qlsp_coefficients);
	if (BandwidthScalabilityMode == ON) {
	  free(window_offsets_bws);
	  free(window_sizes_bws);
	  free(bws_sp_buffer);
	  free(buf_Qlsp_coefficients_bws);
	  free(prev_Qlsp_coefficients_bws);
	  NEC_FreeLpcAnalysisEncoder(n_lpc_analysis_bws);
	}
	}
    
}

/*======================================================================*/
/*      H I S T O R Y                                                   */
/*======================================================================*/
/* 27-08-96 R. Taori  Initial Version                                   */
/* 18-09-96 R. Taori  Brought in line with MPEG-4 Interface             */
/* 26-09-96 R. Taori  & A. Gerrits                                      */
/* 09-09-97 A. Gerrits  Introduction of NEC VQ                          */

