/****************************************************************** | |
iLBC Speech Coder ANSI-C Source Code | |
getCBvec.c | |
Copyright (C) The Internet Society (2004). | |
All Rights Reserved. | |
******************************************************************/ | |
#include "iLBC_define.h" | |
#include "constants.h" | |
#include <string.h> | |
/*----------------------------------------------------------------* | |
* Construct codebook vector for given index. | |
*---------------------------------------------------------------*/ | |
void getCBvec( | |
float *cbvec, /* (o) Constructed codebook vector */ | |
float *mem, /* (i) Codebook buffer */ | |
int index, /* (i) Codebook index */ | |
int lMem, /* (i) Length of codebook buffer */ | |
int cbveclen/* (i) Codebook vector length */ | |
){ | |
int j, k, n, memInd, sFilt; | |
float tmpbuf[CB_MEML]; | |
int base_size; | |
int ilow, ihigh; | |
float alfa, alfa1; | |
/* Determine size of codebook sections */ | |
base_size=lMem-cbveclen+1; | |
if (cbveclen==SUBL) { | |
base_size+=cbveclen/2; | |
} | |
/* No filter -> First codebook section */ | |
if (index<lMem-cbveclen+1) { | |
/* first non-interpolated vectors */ | |
k=index+cbveclen; | |
/* get vector */ | |
memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float)); | |
} else if (index < base_size) { | |
k=2*(index-(lMem-cbveclen+1))+cbveclen; | |
ihigh=k/2; | |
ilow=ihigh-5; | |
/* Copy first noninterpolated part */ | |
memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float)); | |
/* interpolation */ | |
alfa1=(float)0.2; | |
alfa=0.0; | |
for (j=ilow; j<ihigh; j++) { | |
cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+ | |
alfa*mem[lMem-k+j]; | |
alfa+=alfa1; | |
} | |
/* Copy second noninterpolated part */ | |
memcpy(cbvec+ihigh, mem+lMem-k+ihigh, | |
(cbveclen-ihigh)*sizeof(float)); | |
} | |
/* Higher codebook section based on filtering */ | |
else { | |
/* first non-interpolated vectors */ | |
if (index-base_size<lMem-cbveclen+1) { | |
float tempbuff2[CB_MEML+CB_FILTERLEN+1]; | |
float *pos; | |
float *pp, *pp1; | |
memset(tempbuff2, 0, | |
CB_HALFFILTERLEN*sizeof(float)); | |
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, | |
lMem*sizeof(float)); | |
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, | |
(CB_HALFFILTERLEN+1)*sizeof(float)); | |
k=index-base_size+cbveclen; | |
sFilt=lMem-k; | |
memInd=sFilt+1-CB_HALFFILTERLEN; | |
/* do filtering */ | |
pos=cbvec; | |
memset(pos, 0, cbveclen*sizeof(float)); | |
for (n=0; n<cbveclen; n++) { | |
pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; | |
pp1=&cbfiltersTbl[CB_FILTERLEN-1]; | |
for (j=0; j<CB_FILTERLEN; j++) { | |
(*pos)+=(*pp++)*(*pp1--); | |
} | |
pos++; | |
} | |
} | |
/* interpolated vectors */ | |
else { | |
float tempbuff2[CB_MEML+CB_FILTERLEN+1]; | |
float *pos; | |
float *pp, *pp1; | |
int i; | |
memset(tempbuff2, 0, | |
CB_HALFFILTERLEN*sizeof(float)); | |
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, | |
lMem*sizeof(float)); | |
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, | |
(CB_HALFFILTERLEN+1)*sizeof(float)); | |
k=2*(index-base_size- | |
(lMem-cbveclen+1))+cbveclen; | |
sFilt=lMem-k; | |
memInd=sFilt+1-CB_HALFFILTERLEN; | |
/* do filtering */ | |
pos=&tmpbuf[sFilt]; | |
memset(pos, 0, k*sizeof(float)); | |
for (i=0; i<k; i++) { | |
pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN]; | |
pp1=&cbfiltersTbl[CB_FILTERLEN-1]; | |
for (j=0; j<CB_FILTERLEN; j++) { | |
(*pos)+=(*pp++)*(*pp1--); | |
} | |
pos++; | |
} | |
ihigh=k/2; | |
ilow=ihigh-5; | |
/* Copy first noninterpolated part */ | |
memcpy(cbvec, tmpbuf+lMem-k/2, | |
ilow*sizeof(float)); | |
/* interpolation */ | |
alfa1=(float)0.2; | |
alfa=0.0; | |
for (j=ilow; j<ihigh; j++) { | |
cbvec[j]=((float)1.0-alfa)* | |
tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j]; | |
alfa+=alfa1; | |
} | |
/* Copy second noninterpolated part */ | |
memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh, | |
(cbveclen-ihigh)*sizeof(float)); | |
} | |
} | |
} | |