aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/codecs/ilbc/createCB.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/codecs/ilbc/createCB.c')
-rw-r--r--trunk/codecs/ilbc/createCB.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/trunk/codecs/ilbc/createCB.c b/trunk/codecs/ilbc/createCB.c
new file mode 100644
index 000000000..a7efd9380
--- /dev/null
+++ b/trunk/codecs/ilbc/createCB.c
@@ -0,0 +1,216 @@
+
+
+
+/******************************************************************
+
+ iLBC Speech Coder ANSI-C Source Code
+
+ createCB.c
+
+ Copyright (C) The Internet Society (2004).
+ All Rights Reserved.
+
+******************************************************************/
+
+#include "iLBC_define.h"
+#include "createCB.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));
+}
+
+