
   /******************************************************************

       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));
    }
  }
}
