Windows2003-3790/enduser/netmeeting/av/codecs/lh/decoder.c
2020-09-30 16:53:55 +02:00

1081 lines
31 KiB
C
Raw Permalink Blame History

/*#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<EFBFBD>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<EFBFBD>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 <20> 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 <20> 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;
}