/* * iLBC - a library for the iLBC codec * * getCBvec.c - The iLBC low bit rate speech codec. * * Adapted by Steve Underwood from the reference * iLBC code supplied in RFC3951. * * Original code Copyright (C) The Internet Society (2004). * All changes to produce this version Copyright (C) 2008 by Steve Underwood * All Rights Reserved. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Id: getCBvec.c,v 1.2 2008/03/06 12:27:38 steveu Exp $ */ /*! \file */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "ilbc.h" #include "constants.h" #include "getCBvec.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; int k; int n; int memInd; int sFilt; float tmpbuf[CB_MEML]; int base_size; int ilow; int ihigh; float alfa; float 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 = 0.2f; alfa = 0.0f; for (j = ilow; j < ihigh; j++) { cbvec[j] = (1.0f - 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 { if (index - base_size < lMem - cbveclen + 1) { float tempbuff2[CB_MEML + CB_FILTERLEN + 1]; float *pos; const float *pp; const float *pp1; /* Non-interpolated vectors */ 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++; } } else { float tempbuff2[CB_MEML + CB_FILTERLEN + 1]; float *pos; const float *pp; const float *pp1; int i; /* Interpolated vectors */ 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 = 0.2f; alfa = 0.0f; for (j = ilow; j < ihigh; j++) { cbvec[j] = (1.0f - 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)); } } }