231 lines
6.6 KiB
C
231 lines
6.6 KiB
C
|
|
|
|
/******************************************************************
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|