This patch includes the iLBC source code for distribution with Asterisk. Clarification regarding the iLBC source code was provided by Google, and the appropriate licenses have been included in the codecs/ilbc folder. Review: https://reviewboard.asterisk.org/r/1675 Review: https://reviewboard.asterisk.org/r/1649 (closes issue: ASTERISK-18943) Reporter: Leif Madsen Tested by: Matt Jordan ........ Merged revisions 351450 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 351451 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@351452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
232 lines
6.6 KiB
C
232 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));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|