Mercurial > hg > audiostuff
view intercom/ilbc/createCB.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/****************************************************************** iLBC Speech Coder ANSI-C Source Code createCB.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include "iLBC_define.h" #include "constants.h" #include <string.h> #include <math.h> /*----------------------------------------------------------------* * Construct an additional codebook vector by filtering the * initial codebook buffer. This vector is then used to expand * the codebook with an additional section. *---------------------------------------------------------------*/ void filteredCBvecs(float *cbvectors, /* (o) Codebook vectors for the higher section */ float *mem, /* (i) Buffer to create codebook vector from */ int lMem /* (i) Length of buffer */ ) { int j, k; float *pp, *pp1; float tempbuff2[CB_MEML + CB_FILTERLEN]; float *pos; memset(tempbuff2, 0, (CB_HALFFILTERLEN - 1) * sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN - 1], mem, lMem * sizeof(float)); memset(&tempbuff2[lMem + CB_HALFFILTERLEN - 1], 0, (CB_HALFFILTERLEN + 1) * sizeof(float)); /* Create codebook vector for higher section by filtering */ /* do filtering */ pos = cbvectors; memset(pos, 0, lMem * sizeof(float)); for (k = 0; k < lMem; k++) { pp = &tempbuff2[k]; pp1 = &cbfiltersTbl[CB_FILTERLEN - 1]; for (j = 0; j < CB_FILTERLEN; j++) { (*pos) += (*pp++) * (*pp1--); } pos++; } } /*----------------------------------------------------------------* * Search the augmented part of the codebook to find the best * measure. *----------------------------------------------------------------*/ void searchAugmentedCB(int low, /* (i) Start index for the search */ int high, /* (i) End index for the search */ int stage, /* (i) Current stage */ int startIndex, /* (i) Codebook index for the first aug vector */ float *target, /* (i) Target vector for encoding */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *max_measure, /* (i/o) Currently maximum measure */ int *best_index, /* (o) Currently the best index */ float *gain, /* (o) Currently the best gain */ float *energy, /* (o) Energy of augmented codebook vectors */ float *invenergy /* (o) Inv energy of augmented codebook vectors */ ) { int icount, ilow, j, tmpIndex; float *pp, *ppo, *ppi, *ppe, crossDot, alfa; float weighted, measure, nrjRecursive; float ftmp; /* Compute the energy for the first (low-5) noninterpolated samples */ nrjRecursive = (float) 0.0; pp = buffer - low + 1; for (j = 0; j < (low - 5); j++) { nrjRecursive += ((*pp) * (*pp)); pp++; } ppe = buffer - low; for (icount = low; icount <= high; icount++) { /* Index of the codebook vector used for retrieving energy values */ tmpIndex = startIndex + icount - 20; ilow = icount - 4; /* Update the energy recursively to save complexity */ nrjRecursive = nrjRecursive + (*ppe) * (*ppe); ppe--; energy[tmpIndex] = nrjRecursive; /* Compute cross dot product for the first (low-5) samples */ crossDot = (float) 0.0; pp = buffer - icount; for (j = 0; j < ilow; j++) { crossDot += target[j] * (*pp++); } /* interpolation */ alfa = (float) 0.2; ppo = buffer - 4; ppi = buffer - icount - 4; for (j = ilow; j < icount; j++) { weighted = ((float) 1.0 - alfa) * (*ppo) + alfa * (*ppi); ppo++; ppi++; energy[tmpIndex] += weighted * weighted; crossDot += target[j] * weighted; alfa += (float) 0.2; } /* Compute energy and cross dot product for the remaining samples */ pp = buffer - icount; for (j = icount; j < SUBL; j++) { energy[tmpIndex] += (*pp) * (*pp); crossDot += target[j] * (*pp++); } if (energy[tmpIndex] > 0.0) { invenergy[tmpIndex] = (float) 1.0 / (energy[tmpIndex] + EPS); } else { invenergy[tmpIndex] = (float) 0.0; } if (stage == 0) { measure = (float) -10000000.0; if (crossDot > 0.0) { measure = crossDot * crossDot * invenergy[tmpIndex]; } } else { measure = crossDot * crossDot * invenergy[tmpIndex]; } /* check if measure is better */ ftmp = crossDot * invenergy[tmpIndex]; if ((measure > *max_measure) && (fabs(ftmp) < CB_MAXGAIN)) { *best_index = tmpIndex; *max_measure = measure; *gain = ftmp; } } } /*----------------------------------------------------------------* * Recreate a specific codebook vector from the augmented part. * *----------------------------------------------------------------*/ void createAugmentedVec(int index, /* (i) Index for the augmented vector to be created */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *cbVec /* (o) The construced codebook vector */ ) { int ilow, j; float *pp, *ppo, *ppi, alfa, alfa1, weighted; ilow = index - 5; /* copy the first noninterpolated part */ pp = buffer - index; memcpy(cbVec, pp, sizeof(float) * index); /* interpolation */ alfa1 = (float) 0.2; alfa = 0.0; ppo = buffer - 5; ppi = buffer - index - 5; for (j = ilow; j < index; j++) { weighted = ((float) 1.0 - alfa) * (*ppo) + alfa * (*ppi); ppo++; ppi++; cbVec[j] = weighted; alfa += alfa1; } /* copy the second noninterpolated part */ pp = buffer - index; memcpy(cbVec + index, pp, sizeof(float) * (SUBL - index)); }