   
   /******************************************************************
   
       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 codebbok 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));
           }
       }
   }
   
   
