/*#define __TEST
#ifdef __TEST
#include <stdio.h>
FILE *d_codage;
FILE *d_test;
#endif*/

/*
 *   Project:		Direct Subband 16000 bps coder
 *   Workfile:		sb_encod.c
 *   Author:		Alfred Wiesen
 *   Created:		30 August 1995
 *   Last update:	4 September 1995
 *   DLL Version:	1.00
 *   Revision:          Single DLL for coder and decoder.
 *   Comment:
 *
 *	(C) Copyright 1993-95 Lernout & Hauspie Speech Products N.V. (TM)
 *	All rights reserved. Company confidential.
 */


// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Included files
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
#include <math.h>
#include <windows.h>
#include <windowsx.h>

//#define USE_CRT_RAND 1

#ifdef USE_CRT_RAND
#include <stdlib.h>	// for rand() function
#endif

#include "fv_x8.h"
#include "data.h"
#include "bib_32.h"

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Function prototypes
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
//------------------------------------------------------------------------
void InitializeDecoderInstanceData(PVOID p, DWORD dwMaxBitRate);
void interpolation_I(short low_input[],short coef[],short low_part_mem[],short order);
void bruit_I(PD16008DATA p, short vec[],short max, short deb ,short fin);
#if 0
// PhilF: The following is never called!!!
void dec_0a16_I2(short z1, short z2, short vec[], short maxv, short V1[], short V2[],long *code);
#endif
void dec_sous_bandes(PD16008DATA p,short *out,short *codes_max, long *codes_sb, short *indic_br/*, short *code_max_br*/);
#if 0
// PhilF: The following is not defined anywhere!!!
void decodeframe(short codes_max[],long codes_sb[],short d_indic_sp[],char stream[]);
#endif

#ifdef CELP4800
void demux(PD4808DATA p);
void decode_ai(PD4808DATA p);
void dec_ltp(PD4808DATA p,short no),dec_dic(PD4808DATA p);
void post_synt(PD4808DATA p),post_filt(PD4808DATA p,short no);
#endif

/*void iConvert64To8(short *in, short *out, short N, short *mem);
void iConvert8To64(short *in, short *out, short N, short *mem);
void filt_in(short *mem, short *Vin, short *Vout, short lfen);
//void PassHigh(short *vin,short *vout,short *mem,short nech);
void BandPass(short *,short *,short *,short);*/

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Global variables for decoder
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

/*#define MAXDECODINGHANDLES 10

// Instance data structure
PD16008DATA pDecoderData;
D16008DATA DecoderData[MAXDECODINGHANDLES];
short brol[300];
short DecodingHandles[MAXDECODINGHANDLES];*/

// ROM tables :
//extern long coef_outfil[];
extern short coef_I[];	// QMF filter coefficients
extern short V3_I[];
extern short V4_I[];
extern short V5_I[];
extern short V6_I[];
extern short V7_I[];
extern short V8_I[];
extern short V9_I[];
extern short d_max_level[];  // Quantified maximum sample level
extern long coeffs[];
extern short quantif[];
extern long Mask[];
extern short tabcos[];
extern short LSP_Q[];
extern short TAB_DI[];
extern short GV[];
extern short BV[];
extern long coef_i[];
extern short NBB[],BITDD[];
extern short LSP0ROM[];
//extern short bytes[];
//extern short bits[];

// RAM variables
/*extern char d_stream[];
extern short synth_speech[];
extern short d_DATA_I[];                  // Intermediate vector = input and output of QMF
extern short d_codes_max[];
extern long d_codes_sb[];
extern short d_indic_sp[];
extern short d_num_bandes;
//extern float d_vect6[256], d_vect8[256];*/

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Function implementation
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
void InitializeDecoderInstanceData(PVOID p, DWORD dwMaxBitRate)
// Instance data initializations
{
  short i;

#ifdef CELP4800
  if (dwMaxBitRate == 4800)
    {
    ((PD4808DATA)p)->dwMaxBitRate = dwMaxBitRate;

    for (i=0;i<10;i++)
      ((PD4808DATA)p)->LSP0[i]=LSP0ROM[i];
    }
  else
#endif
    {
    ((PD16008DATA)p)->dwMaxBitRate = dwMaxBitRate;
    ((PD16008DATA)p)->lRand = 1L;

    ((PD16008DATA)p)->quantif[0] = 9;
    ((PD16008DATA)p)->quantif[1] = 9;
    ((PD16008DATA)p)->quantif[4] = 5;
    ((PD16008DATA)p)->quantif[5] = 5;
    ((PD16008DATA)p)->quantif[6] = 5;
    ((PD16008DATA)p)->quantif[7] = 5;
    ((PD16008DATA)p)->quantif[8] = 5;
    ((PD16008DATA)p)->quantif[9] = 5;
    ((PD16008DATA)p)->bits[0] = 52;
    ((PD16008DATA)p)->bits[2] = 38;
    ((PD16008DATA)p)->bits[3] = 38;
    ((PD16008DATA)p)->bits[4] = 38;
    if (dwMaxBitRate == 16000)
      {
      ((PD16008DATA)p)->quantif[2] = 7;
      ((PD16008DATA)p)->quantif[3] = 7;
      ((PD16008DATA)p)->bits[1] = 46;
      }
    else
      {
      ((PD16008DATA)p)->quantif[2] = 9;
      ((PD16008DATA)p)->quantif[3] = 9;
      ((PD16008DATA)p)->quantif[10] = 5;
      ((PD16008DATA)p)->quantif[11] = 5;
      ((PD16008DATA)p)->bits[1] = 52;
      ((PD16008DATA)p)->bits[5] = 38;
      }
    }
   return;
}

//------------------------------------------------------------------------
void interpolation_I(short low_input[],short coef[],short low_part_mem[],short order)
// Purpose : from subbands stored in low_input[], create the corresponding signal
// Remark  : The reconstruct signal is stored at *(input+N_SB*L_RES)
{
   short *output;
   short *high_input;
   short *buffer,*sa_vec;
   short lng,j,i;

   buffer = low_part_mem;
   for (i = 7-N_SB; i<7; i++)
	{
	lng = 1<<i;
	high_input=low_input+lng;
	output=low_input+L_RES;
	sa_vec=output;
	for (j = L_RES >> (i+1); j>0; j--)
		{
		low_part_mem=buffer;

		QMInverse(low_input,high_input,coef,output,low_part_mem,lng);

		output += 2*lng; low_input += lng; high_input += lng;

		if (j&1) high_input += 2*lng;
		else low_input += 2*lng;

		buffer += 2*order;
		}
	low_input=sa_vec;
	}
}

//------------------------------------------------------------------------
void bruit_I(PD16008DATA p, short vec[],short max, short deb ,short fin)
// rand() generates integers from 1 to RAND_MAX (32767)
{
   short i;

   for (i=deb;i<fin;i++)
     {
#ifdef USE_CRT_RAND
     *vec++ =  (short)(((long)max*(long)(rand()-16384))>>15);
#else
    // We provide our own rand() function in order
    // to go away from libcmt, msvcrt...
    p->lRand = p->lRand * 214013L + 2531011L;
     *vec++ =  (short)(((long)max*(long)((long)((p->lRand >> 16) & 0x7fff)-16384))>>15);
#endif
}    }

/*void bruit_I(int vec[],int max, int deb ,int fin)
{
   int i;
   for (i=deb;i<fin;i++) *vec++ = (int)(((long)max*(long)(rand()-16384))>>15);
}*/

//------------------------------------------------------------------------
// PhilF: The following is never called!!!
#if 0
void dec_0a16_I2(short z1, short z2, short vec[], short maxv, short V1[], short V2[],long *code)

// Decodes two long codes to retreive the z level quantified subband

{
//   short vect1[16];
   short i,x;
   long result;
//   long lp1,lp2;

   result=*(code+1);
   for (i=15;i>=8;i--)	// Decodes the 8 last samples of the subband
     {
     if (i==2*(short)(i/2))
       {
       x=result%z1;
       result-=x;
       result/=z1;
       *(vec+i)=(short)(((long)V1[x]*(long)maxv)>>13);
       }
     else
       {
       x=result%z2;
       result-=x;
       result/=z2;
       *(vec+i)=(short)(((long)V2[x]*(long)maxv)>>13);
       }
     }

   result=*(code);
   for (i=7;i>=0;i--)	// Decodes the 8 first samples of the subband
     {
     if (i==2*(short)(i/2))
       {
       x=result%z1;
       result-=x;
       result/=z1;
       *(vec+i)=(short)(((long)V1[x]*(long)maxv)>>13);
       }
     else
       {
       x=result%z2;
       result-=x;
       result/=z2;
       *(vec+i)=(short)(((long)V2[x]*(long)maxv)>>13);
       }
     }
}
#endif

void dec_0a16_I3(short z1, short z2, short vec[], short maxv, long *code)

// Decodes two long codes to retreive the z level quantified subband

{
//   short vect1[16];
   short i,x;
   long result;
   short *V1,*V2;
//   long lp1,lp2;

   switch (z1)
   {
      case 3: V1=V3_I; break;
      case 4: V1=V4_I; break;
      case 5: V1=V5_I; break;
      case 6: V1=V6_I; break;
      case 7: V1=V7_I; break;
      case 8: V1=V8_I; break;
      case 9: V1=V9_I; break;
   }
   switch (z2)
   {
      case 3: V2=V3_I; break;
      case 4: V2=V4_I; break;
      case 5: V2=V5_I; break;
      case 6: V2=V6_I; break;
      case 7: V2=V7_I; break;
      case 8: V2=V8_I; break;
      case 9: V2=V9_I; break;
   }

  result=*(code+1);
  if (z1 && z2)
  {
   for (i=15;i>=8;i--)	// Decodes the 8 last samples of the subband
     {
     if (i==2*(short)(i/2))
       {
       x=result%z1;
       result-=x;
       result/=z1;
       *(vec+i)=(short)(((long)V1[x]*(long)maxv)>>13);
       }
     else
       {
       x=result%z2;
       result-=x;
       result/=z2;
       *(vec+i)=(short)(((long)V2[x]*(long)maxv)>>13);
       }
     }

   result=*(code);
   for (i=7;i>=0;i--)	// Decodes the 8 first samples of the subband
     {
     if (i==2*(short)(i/2))
       {
       x=result%z1;
       result-=x;
       result/=z1;
       *(vec+i)=(short)(((long)V1[x]*(long)maxv)>>13);
       }
     else
       {
       x=result%z2;
       result-=x;
       result/=z2;
       *(vec+i)=(short)(((long)V2[x]*(long)maxv)>>13);
       }
     }
  }
}

//------------------------------------------------------------------------

void dec_sous_bandes(PD16008DATA p,short *out,short *codes_max, long *codes_sb, short *d_indic_sp)

// Decodes the 8 subbands

{
   short max[8]={0,0,0,0,0,0,0,0};
   short max_loc[8]={0,0,0,0,0,0,0,0};
   short order[8]={0,0,0,0,0,0,0,0};
   short maximum,max_num;
   short i,j,nbsb_sp,ord;

  #ifdef MAX_SB_ABSOLU
   short sb_count;
  #endif


   for (i=0;i<8;i++)	// Decodes the maximums
     {
     max_loc[i]=2*d_max_level[codes_max[i]];
     }
   nbsb_sp=0;
   j=0;
   for (i=0;i<8;i++)
     {
     if (d_indic_sp[i]==1)
       {
       max[i]=max_loc[j];
       nbsb_sp++;
       j++;
       }
     }

  if (p->dwMaxBitRate == 16000)
    {
   j=0;

  #ifdef MAX_SB_ABSOLU
   sb_count=nbsb_sp;
   if (sb_count>=MAX_SB_ABSOLU) return;
  #endif

   for (i=0;i<8;i++)
   {
     if (d_indic_sp[i]==0)
     {
       max[i]=max_loc[nbsb_sp+j];
       j++;
      #ifdef MAX_SB_ABSOLU
       sb_count++;
       quant_0a16_I3(SILENCE_QUANT_LEVEL_16000,SILENCE_QUANT_LEVEL_16000,in+i*16,max[i],codes_sb+2*sb_count);
       if (sb_count>=MAX_SB_ABSOLU) break;
      #endif
     }
   }
    }

   ord=8;
   for (i=0;i<8;i++)	// Calculates the order of the subbands
     {                  // 1 is higher energy than 2 than 3,..
     maximum=32767;
     for (j=7;j>=0;j--)
       {
       if ((order[j]==0)&&(max[j]<maximum))
	 {
	 max_num=j; maximum=max[j];
	 }
       }
     order[max_num]=ord;
     ord--;
     }


  if (p->dwMaxBitRate == 16000)
    {
   // On g�n�re les sous-bandes
   for (i=7;i>=nbsb_sp;i--)
     {
     j=0;
     while (order[j]!=i+1) j++;
     dec_0a16_I3(SILENCE_QUANT_LEVEL_16000,SILENCE_QUANT_LEVEL_16000,out+j*16,max[j],codes_sb+2*i);
     }
    }
   else
    {
   // On g�n�re du bruit
   if (nbsb_sp==0) maximum=20; // qd on ne doit generer que du bruit
   else
     {
     maximum=32767;
     for (i=0;i<nbsb_sp;i++) if (max_loc[i]<maximum) maximum=max_loc[i];
     maximum>>=2;   // le 64eme du plus petit max transmis
     }

   //en fait il faudrait diminuer le bruit avec l'ordre

   for (i=0;i<8;i++)              // Replaces the less energetic subbands
     {			          // with white noise
     if (d_indic_sp[i]==0)
       {
       maximum/=order[i];
       bruit_I(p,out+i*16,maximum,0,16);
       }
     }
   }

   for (i=nbsb_sp-1;i>=0;i--)
     {
     j=0;
     while (order[j]!=i+1) j++;
     dec_0a16_I3(p->quantif[2*i],p->quantif[2*i+1],out+j*16,max[j],codes_sb+2*i);
     }

}

//------------------------------------------------------------------------
short Demultiplexing(
	char *Stream,
	long *Codes,
	short *CodeSizes,
	short NumCodes,
	short StreamSize)
{
   short B,P;	// B=bits � coder, P=bits disponibles
   short i,j;

   #ifdef __CHECK_FORMAT
   long TotalBytes=0;

   for (i=0;i<NumCodes;i++) TotalBytes+=CodeSizes[i];
   if (TotalBytes>StreamSize*8) return 1;
   #endif

   i=0;
   j=0;
   B=CodeSizes[i];	// bits � coder
   P=8;			// 1 octet libre au d�part
   Codes[i]=0;
   while (i<NumCodes)
   {
      if (P>B)
      {
	 Codes[i]|=(Stream[j]>>(P-B))&Mask[B];
	 P-=B;
	 i++;
	 if (i<NumCodes)
	 {
	    B=CodeSizes[i];
	    Codes[i]=0;
	 }
      }
      else if (P<B)
      {
	 Codes[i]|=(Stream[j]&Mask[P])<<(B-P);
	 B-=P;
	 P=8;
	 j++;
      }
      else
      {
	 Codes[i]|=Stream[j]&Mask[P];
	 i++;
	 j++;
	 P=8;
	 if (i<NumCodes)
	 {
	    B=CodeSizes[i];
	    Codes[i]=0;
	 }
      }
   }
   return 0;
}

// ------------------------------------------------------------------------
#ifdef CELP4800
void decode_ai(PD4808DATA p)
{
   short_to_short(p->code,p->LSP,10);
   p->LSP[10]=32767;
   dec_lsp(p->LSP,LSP_Q,NBB,BITDD,TAB_DI);

   short_to_short(p->LSP,p->A3,10);
   teta_to_cos(tabcos,p->A3,10);
   lsp_to_ai(p->A3,p->TLSP,10);

   interpol(p->LSP0,p->LSP,p->A1,NETAGES);
   teta_to_cos(tabcos,p->A1,10);
   lsp_to_ai(p->A1,p->TLSP,10);

   interpol(p->LSP,p->LSP0,p->A2,NETAGES);
   teta_to_cos(tabcos,p->A2,10);
   lsp_to_ai(p->A2,p->TLSP,10);

   short_to_short(p->LSP,p->LSP0,NETAGES);
}

// ------------------------------------------------------------------------
void dec_ltp(PD4808DATA p,short no)
{
   short k;

   switch (no)
   {
   case 0:
      break;
   case 1:
      short_to_short(p->A2,p->A1,11);
      break;
   case 2:
      short_to_short(p->A3,p->A1,11);
      break;
   }


   p->PITCH=p->code[10+p->depl];
   k=p->code[11+p->depl];
   if (k<10) p->GLTP = BV[k+1]; /* les BV sont multiplies par 16384 */
   else p->GLTP = -BV[k-9];

   if (p->PITCH<p->SOULONG)
   {
      short_to_short(p->EE+lngEE-p->PITCH,p->E,p->PITCH);
      short_to_short(p->E,p->E+p->PITCH,(short)(p->SOULONG-p->PITCH));
      mult_fact(p->E,p->E,p->GLTP,p->SOULONG);
   }
   else
   {
      mult_fact(p->EE+lngEE-p->PITCH,p->E,p->GLTP,p->SOULONG);
   }
}

// ------------------------------------------------------------------------
void dec_dic(PD4808DATA p)
{
   short i,esp_opt,j,position,npopt,phas_opt,cod;
   short c[10];
   short Gopt;

   cod=p->code[13+p->depl];
   if (cod<16) Gopt=GV[cod+1];
   else Gopt=-GV[cod-15];

   cod=p->code[12+p->depl];

   if (cod<54) { position=cod; esp_opt=p->PITCH; }
   else
   {
      if (cod<64)
      {
	 position=cod-54;
	 if (p->PITCH<p->SOULONG) esp_opt=p->SOULONG+5;
	 else if (p->PITCH/2<p->SOULONG) esp_opt=p->PITCH/2;
	    else esp_opt=p->PITCH/3;
      }
      else
      {
	 if (cod<128)
	 {
	    npopt=7;
	    phas_opt=3;
	    esp_opt=8;
	    i=cod-64;
	    c[0]=1;
	    decode_dic(c,i,npopt);
	 }
	 else
	 {
	    npopt=8;
	    phas_opt=0;
	    esp_opt=7;
	    i=cod-128;
	    c[0]=1;
	    decode_dic(c,i,npopt);
	 }
      }
   }

   if (cod<64)
   {
      i=0;
      do
      {
	 p->E[position+i] += Gopt;
	 i += esp_opt;
      }
      while ((position+i)<p->SOULONG);
   }
   else
      for (j=0;j<npopt;j++)
	 p->E[esp_opt*j+phas_opt] += c[j]*Gopt;

   short_to_short(p->EE+p->SOULONG,p->EE,(short)(lngEE - p->SOULONG));
   short_to_short(p->E,p->EE+lngEE-p->SOULONG,p->SOULONG);
}

// ------------------------------------------------------------------------
void post_synt(PD4808DATA p)
{
   short GPREF;

   if (abs(p->GLTP)<8192) GPREF = (long)p->GLTP*(long)35/100;
   if (p->GLTP>=8192)  GPREF=2867;
   if (p->GLTP<=-8192) GPREF=-2867;

   if (p->PITCH>=p->SOULONG) mult_f_acc(p->EEE+lngEE-p->PITCH,p->E,GPREF,p->SOULONG);
   else
   {
      mult_f_acc(p->EEE+lngEE-p->PITCH,p->E,GPREF,p->PITCH);
      mult_f_acc(p->E,p->E+p->PITCH,GPREF,(short)(p->SOULONG-p->PITCH));
   }

   short_to_short(p->EEE+p->SOULONG,p->EEE,(short)(lngEE-p->SOULONG));
   short_to_short(p->E,p->EEE+lngEE-p->SOULONG,p->SOULONG);

   synthese(p->MSYNTH,p->A1,p->E,p->E,p->SOULONG,NETAGES);
}

// ------------------------------------------------------------------------
void post_filt(PD4808DATA p,short no)
{
   short i0;

   switch (no)
   {
   case 0: i0=0;
	   break;
   case 1: i0=SOUDECAL1;
	   break;
   case 2: i0=SOUDECAL1+SOUDECAL;
	   break;
   }
   filt_iir(p->memfil,coef_i,p->E,p->ss+i0,p->SOULONG,4);
}

// ------------------------------------------------------------------------
void demux(PD4808DATA p)
// Purpose : deconcatenate the input stream
// Input parameter  :
//          input_stream[]  :  input stream
//  Output parameter :
//          code[]   :  separate parameter code
//
//  Comments: The LTP or Adaptive codebook is also called PITCH.
//
//  Stream format :
//  input_stream[0] = LSP[0] | LSP[1] | LSP[2] | (Binary gain 2)
//  input_stream[1] = LSP[3] | (Binary gain 3) | (Binary codebook 1)
//  input_stream[2] = LSP[4] | LSP[5] | LSP[6] | LSP[7] | LSP[8] | LSP[9]
//  input_stream[3] = (LTP codebook 1) | (LTP gain 1) | (Binary gain 1)
//  input_stream[4] = (LTP codebook 2) | (LTP gain 2) | (Binary codebook 2)
//  input_stream[5] = (LTP codebook 3) | (LTP gain 3) | (Binary codebook 3)
//
//  Bit allocation : Codebook or gain "i" is the codebook for subframe "i".
//  code[0] = LSP(0) : 3bits     code[10] = LTP codebook 1    : 7bits
//  code[1] = LSP(1) : 4bits     code[11] = LTP gain 1        : 4bits
//  code[2] = LSP(2) : 4bits     code[12] = Binary codebook 1 : 8bits
//  code[3] = LSP(3) : 3bits     code[13] = Binary gain 1     : 5bits
//  code[4] = LSP(4) : 4bits     code[14] = LTP codebook 2    : 4bits
//  code[5] = LSP(5) : 3bits     code[15] = LTP gain 2        : 4bits
//  code[6] = LSP(6) : 3bits     code[16] = Binary codebook 2 : 8bits
//  code[7] = LSP(7) : 2bits     code[17] = Binary gain 2     : 5bits
//  code[8] = LSP(8) : 3bits     code[18] = LTP codebook 3    : 4bits
//  code[9] = LSP(9) : 1bits     code[19] = LTP gain 3        : 4bits
//                               code[20] = Binary codebook 3 : 8bits
//                               code[21] = Binary gain 3     : 5bits
//
{
   p->code[0] = (p->frame[0]>>13) & 0x0007;
   p->code[1] = (p->frame[0]>>9) & 0x000f;
   p->code[2] = (p->frame[0]>>5) & 0x000f;
   p->code[17] = p->frame[0] & 0x001f;

   p->code[3] = (p->frame[1]>>13) & 0x0007;
   p->code[21] = (p->frame[1]>>8) & 0x001f;
   p->code[12] = p->frame[1] & 0x00ff;

   p->code[4] = (p->frame[2]>>12) & 0x000f;
   p->code[5] = (p->frame[2]>>9) & 0x0007;
   p->code[6] = (p->frame[2]>>6) & 0x0007;
   p->code[7] = (p->frame[2]>>4) & 0x0003;
   p->code[8] = (p->frame[2]>>1) & 0x0007;
   p->code[9] = p->frame[2] & 0x0001;

   p->code[10] = (p->frame[3]>>9) & 0x007f;
   p->code[11] = (p->frame[3]>>5) & 0x000f;
   p->code[13] = p->frame[3] & 0x001f;

   p->code[14] = (p->frame[4]>>12) & 0x000f;
   p->code[15] = (p->frame[4]>>8) & 0x000f;
   p->code[16] = p->frame[4] & 0x00ff;

   p->code[18] = (p->frame[5]>>12) & 0x000f;
   p->code[19] = (p->frame[5]>>8) & 0x000f;
   p->code[20] = p->frame[5] & 0x00ff;

   p->code[10] += LIM_P1;
   p->code[14] = p->code[14]+p->code[10]-7;
   p->code[18] = p->code[18]+p->code[14]-7;

}
#endif

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// DLL entry points
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
LH_PREFIX HANDLE LH_SUFFIX MSLHSB_Open_Decoder(DWORD dwMaxBitRate)
{
   PVOID pDecoderData;
   /*short i,flag=0;

   // Test if there are free handles
   for (i=0;i<MAXDECODINGHANDLES;i++)
      if (DecodingHandles[i]==0) {DecodingHandles[i]=1; flag=1; break;}
   if (flag==0) return 0;
   pDecoderData=&DecoderData[i];*/

  // Check the input bit rate param.
  if (
#ifdef CELP4800
	  (dwMaxBitRate != 4800) && 
#endif
	  (dwMaxBitRate != 8000) && 
	  (dwMaxBitRate != 12000) && 
	  (dwMaxBitRate != 16000))
      return (HANDLE)0;

   // pDecoderData=(PVOID)GlobalAllocPtr(GMEM_MOVEABLE, dwMaxBitRate == 4800 ? sizeof(D4808DATA) : sizeof(D16008DATA));
#ifdef CELP4800
   pDecoderData=(PVOID)GlobalAllocPtr(GHND, dwMaxBitRate == 4800 ? sizeof(D4808DATA) : sizeof(D16008DATA));
#else
   pDecoderData=(PVOID)GlobalAllocPtr(GHND, sizeof(D16008DATA));
#endif
   if (pDecoderData==NULL)
      return (HANDLE)0;

   InitializeDecoderInstanceData(pDecoderData, dwMaxBitRate);

   #ifdef __TEST
   d_codage=(FILE*)fopen("codage.dat","rb");
   d_test=(FILE*)fopen("codes_dec.dat","wt");
   #endif

   return((HANDLE)pDecoderData);
}

// ------------------------------------------------------------------------
LH_PREFIX LH_ERRCODE LH_SUFFIX MSLHSB_Decode(
   HANDLE hAccess,
   LPBYTE lpSrcBuf,
   LPWORD lpSrcBufSize,
   LPBYTE lpDstBuf,
   LPWORD lpDstBufSize)
{
    short i,iOutputSize,flag=0;
    char  *input;
    char  *int_ptr;
    unsigned short  *ptr1;
    unsigned short  *ptr3;
    long interm;

    short codesizes[24];
    long codes[24];
    short numcodes,temp;
    short bits_count;

	PVOID pDecoderData;

    if ((!hAccess) || (!lpSrcBuf) || (!lpDstBuf))
      return LH_EBADARG;

    /*// First check that the handle provided as argument is correct
    for (i=0;i<MAXDECODINGHANDLES;i++)
       if ((DecodingHandles[i]==1)&&(hAccess==(HANDLE)&DecoderData[i])) {flag=1; break;}
    if (flag==0) return LH_BADHANDLE;*/

    pDecoderData=(PVOID)hAccess;

  // Check the input bit rate param.
  if (
#ifdef CELP4800
	  (((PD4808DATA)pDecoderData)->dwMaxBitRate != 4800) && 
#endif
	  (((PD16008DATA)pDecoderData)->dwMaxBitRate != 8000) && 
	  (((PD16008DATA)pDecoderData)->dwMaxBitRate != 12000) && 
	  (((PD16008DATA)pDecoderData)->dwMaxBitRate != 16000))
    return (LH_ERRCODE)LH_EBADARG;

#ifdef CELP4800
  if ((((PD4808DATA)pDecoderData)->dwMaxBitRate == 4800))
    {
    // then check the buffer sizes passed as argument.
    if ((*lpDstBufSize<2*NECHDECAL)||(*lpSrcBufSize<12))
      return (LH_ERRCODE)LH_EBADARG;
    *lpDstBufSize=2*NECHDECAL;
    *lpSrcBufSize=12;

    ptr1 = (unsigned short *)lpSrcBuf;
    ptr3 = (unsigned short *)&(((PD4808DATA)pDecoderData)->frame);

    for (i=6 ; i>0 ; i--) *ptr3++ = *ptr1++;

    demux(((PD4808DATA)pDecoderData));

    decode_ai(((PD4808DATA)pDecoderData));

    for (i=0;i<3;i++)
	     {
	     if (i==0) ((PD4808DATA)pDecoderData)->SOULONG=SOUDECAL1;
	     else ((PD4808DATA)pDecoderData)->SOULONG=SOUDECAL;
	     ((PD4808DATA)pDecoderData)->depl=4*i;
	     dec_ltp((PD4808DATA)pDecoderData,i);
	     dec_dic((PD4808DATA)pDecoderData);
	     post_synt((PD4808DATA)pDecoderData);
	     post_filt((PD4808DATA)pDecoderData,i);
	     }

    ptr3 = (unsigned short *)&(((PD4808DATA)pDecoderData)->ss);
    ptr1 = (unsigned short *)lpDstBuf;

    for (i =160; i>0;i--) *ptr1++ = *ptr3++;
    }
  else
#endif
    {
    // then check the buffer sizes passed as argument.
    switch (((PD16008DATA)pDecoderData)->dwMaxBitRate)
      {
      case 8000:
        if ((*lpSrcBufSize<1)||(*lpDstBufSize<2*160))
           return (LH_ERRCODE)LH_EBADARG;
        *lpDstBufSize=2*160;
        break;
      case 12000:
      case 16000:
        if ((*lpSrcBufSize<1)||(*lpDstBufSize<2*128))
           return (LH_ERRCODE)LH_EBADARG;
        *lpDstBufSize=2*128;
        break;
      }
    input = (char  *)lpSrcBuf;
    int_ptr=(char  *)(((PD16008DATA)pDecoderData)->d_stream);

    /*for (i=0;i<26;i++)
       *int_ptr++=*input++;*/

    *int_ptr++=*input++;	// read d_stream[0]

    for (i=0;i<8;i++)
       ((PD16008DATA)pDecoderData)->d_indic_sp[i]=(short)((((PD16008DATA)pDecoderData)->d_stream[0]>>i)&0x01);

    ((PD16008DATA)pDecoderData)->d_num_bandes=0;
    for (i=0;i<8;i++)
      if (((PD16008DATA)pDecoderData)->d_indic_sp[i]==1)
	     ((PD16008DATA)pDecoderData)->d_num_bandes++;


    bits_count=8;
    for (i=0;i<((PD16008DATA)pDecoderData)->d_num_bandes;i++)
       bits_count+=5+((PD16008DATA)pDecoderData)->bits[i];

  if (((PD16008DATA)pDecoderData)->dwMaxBitRate == 16000)
    {
    #ifdef MAX_SB_ABSOLU
    for (i=((PD16008DATA)pDecoderData)->d_num_bandes;i<MAX_SB_ABSOLU;i++)
    #else
    for (i=((PD16008DATA)pDecoderData)->d_num_bandes;i<8;i++)
    #endif
       bits_count+=5+SILENCE_CODING_BIT_16000;
    }         

    //temp=bytes[d_num_bandes]; //9
#if 0
    temp=(short)((float)bits_count/8.0+0.99);
#else
    // We want to go away of libcmt, msvcrt... and
    // floating point is not really essential here...
    if (bits_count)
      temp=(short)((bits_count-1)/8+1);
    else
      temp=0;
#endif

    if (*lpSrcBufSize<temp)
       return (LH_ERRCODE)LH_EBADARG;

    if ((((PD16008DATA)pDecoderData)->dwMaxBitRate == 16000) || ((((PD16008DATA)pDecoderData)->dwMaxBitRate == 8000) && (((PD16008DATA)pDecoderData)->d_num_bandes)) || ((((PD16008DATA)pDecoderData)->dwMaxBitRate == 12000) && (((PD16008DATA)pDecoderData)->d_num_bandes)))
    {
       for (i=0;i<temp-1;i++)		// read 8 last bytes
	  *int_ptr++=*input++;

       numcodes=0;
       for (i=0;i<24;i++) codesizes[i]=0;
       for (i=0;i<((PD16008DATA)pDecoderData)->d_num_bandes;i++)
       {
	  codesizes[i]=5;
	  codesizes[((PD16008DATA)pDecoderData)->d_num_bandes+2*i]=((PD16008DATA)pDecoderData)->bits[i]/2;
	  codesizes[((PD16008DATA)pDecoderData)->d_num_bandes+2*i+1]=((PD16008DATA)pDecoderData)->bits[i]/2;
	  numcodes+=3;
       }
  if (((PD16008DATA)pDecoderData)->dwMaxBitRate == 16000)
    {
       for (i=((PD16008DATA)pDecoderData)->d_num_bandes;i<8;i++)
       {
	  codesizes[2*((PD16008DATA)pDecoderData)->d_num_bandes+i]=5;
	  codesizes[8+2*i]=SILENCE_CODING_BIT_16000/2;
	  codesizes[8+2*i+1]=SILENCE_CODING_BIT_16000/2;
	  numcodes+=3;
       }
    }

       if (Demultiplexing(((PD16008DATA)pDecoderData)->d_stream+1,codes,codesizes,numcodes,(short)(temp-1)))
	  return (LH_ERRCODE)LH_BADHANDLE;

       for (i=0;i<((PD16008DATA)pDecoderData)->d_num_bandes;i++)
       {
	  ((PD16008DATA)pDecoderData)->d_codes_max[i]=(short)codes[i];
	  ((PD16008DATA)pDecoderData)->d_codes_sb[2*i]=codes[((PD16008DATA)pDecoderData)->d_num_bandes+2*i];
	  ((PD16008DATA)pDecoderData)->d_codes_sb[2*i+1]=codes[((PD16008DATA)pDecoderData)->d_num_bandes+2*i+1];
       }
    if (((PD16008DATA)pDecoderData)->dwMaxBitRate == 16000)
      {
      #ifdef MAX_SB_ABSOLU
       for (i=((PD16008DATA)pDecoderData)->d_num_bandes;i<MAX_SB_ABSOLU;i++)
      #else
       for (i=((PD16008DATA)pDecoderData)->d_num_bandes;i<8;i++)
      #endif
       {
	  ((PD16008DATA)pDecoderData)->d_codes_max[i]=(short)codes[2*((PD16008DATA)pDecoderData)->d_num_bandes+i];
	  ((PD16008DATA)pDecoderData)->d_codes_sb[2*i]=codes[8+2*i];
	  ((PD16008DATA)pDecoderData)->d_codes_sb[2*i+1]=codes[8+2*i+1];
       }
       }
    }
    *lpSrcBufSize=temp;

    dec_sous_bandes(((PD16008DATA)pDecoderData),((PD16008DATA)pDecoderData)->d_DATA_I,((PD16008DATA)pDecoderData)->d_codes_max,((PD16008DATA)pDecoderData)->d_codes_sb,((PD16008DATA)pDecoderData)->d_indic_sp);
    interpolation_I(((PD16008DATA)pDecoderData)->d_DATA_I,coef_I,((PD16008DATA)pDecoderData)->QMF_MEM_SYNT_I,Fil_Lenght);

    for (i=0;i<128;i++) ((PD16008DATA)pDecoderData)->d_DATA_I[3*L_RES+i]*=8; //TEST 16; // Because input divided before coding

    switch (((PD16008DATA)pDecoderData)->dwMaxBitRate)
      {
      case 8000:
        iOutputSize = 160;
#ifdef _X86_
        iConvert64To8(((PD16008DATA)pDecoderData)->d_DATA_I+3*L_RES, ((PD16008DATA)pDecoderData)->synth_speech, 128, ((PD16008DATA)pDecoderData)->imem2);
        PassLow8(((PD16008DATA)pDecoderData)->synth_speech, ((PD16008DATA)pDecoderData)->synth_speech,((PD16008DATA)pDecoderData)->out_mem2,160);
#else
        SampleRate6400To8000(((PD16008DATA)pDecoderData)->d_DATA_I+3*L_RES,
                             ((PD16008DATA)pDecoderData)->synth_speech,
                             128,
                             ((PD16008DATA)pDecoderData)->imem2,
                             &((PD16008DATA)pDecoderData)->uiDelayPosition,
                             &((PD16008DATA)pDecoderData)->iInputStreamTime,
                             &((PD16008DATA)pDecoderData)->iOutputStreamTime );
#endif
        break;
      case 12000:
      case 16000:
        iOutputSize = 128;
        for (i=0;i<128;i++)
          ((PD16008DATA)pDecoderData)->synth_speech[i]=((PD16008DATA)pDecoderData)->d_DATA_I[3*L_RES+i];
        break;
      }

    for (i=0;i<iOutputSize;i++)
    {
       interm=((long)((PD16008DATA)pDecoderData)->synth_speech[i] * 2L);//VERS 4 + ( ((long)(rand()-16384))>>8 ) ;
       if (interm>32700L) interm=32700L;
       if (interm<-32700L) interm=-32700L;
       ((PD16008DATA)pDecoderData)->synth_speech[i] = (short)interm ;
    }

    ptr3 = (unsigned short  *)&(((PD16008DATA)pDecoderData)->synth_speech);
    ptr1 = (unsigned short  *)lpDstBuf;

    for (i =0;i<iOutputSize;i++) ptr1[i] = ptr3[i];
    }
    return (LH_SUCCESS);
}

// ------------------------------------------------------------------------
LH_PREFIX LH_ERRCODE LH_SUFFIX MSLHSB_Close_Decoder(HANDLE hAccess)
{
   PVOID pDecoderData;

   /*short i,flag=0;

   // Check if right handle
   for (i=0;i<MAXDECODINGHANDLES;i++)
      if ((DecodingHandles[i]==1)&&(hAccess==(HANDLE)&DecoderData[i])) {flag=1; break;}
   if (flag==0) return LH_BADHANDLE;
   // Free handle
   DecodingHandles[i]=0;*/

  if (!hAccess)
    return LH_EBADARG;

   pDecoderData=(PVOID)hAccess;

   GlobalFreePtr(pDecoderData);

   #ifdef __TEST
   fclose(d_codage);
   fclose(d_test);
   #endif

   return LH_SUCCESS;
}