2
/******************************************************************
4
iLBC Speech Coder ANSI-C Source Code
8
Copyright (C) The Internet Society (2004).
11
******************************************************************/
16
#include "iLBC_define.h"
17
#include "gainquant.h"
20
#include "constants.h"
22
/*----------------------------------------------------------------*
23
* Search routine for codebook encoding and gain quantization.
24
*---------------------------------------------------------------*/
27
iLBC_Enc_Inst_t *iLBCenc_inst,
28
/* (i) the encoder state structure */
29
int *index, /* (o) Codebook indices */
30
int *gain_index,/* (o) Gain quantization indices */
36
float *intarget,/* (i) Target vector for encoding */
37
float *mem, /* (i) Buffer for codebook construction */
38
int lMem, /* (i) Length of buffer */
39
int lTarget, /* (i) Length of vector */
40
int nStages, /* (i) Number of codebook stages */
41
float *weightDenum, /* (i) weighting filter coefficients */
42
float *weightState, /* (i) weighting filter state */
43
int block /* (i) the sub-block number */
45
int i, j, icount, stage, best_index, range, counter;
46
float max_measure, gain, measure, crossDot, ftmp;
47
float gains[CB_NSTAGES];
49
int base_index, sInd, eInd, base_size;
50
int sIndAug=0, eIndAug=0;
51
float buf[CB_MEML+SUBL+2*LPC_FILTERORDER];
52
float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];
53
float *pp, *ppi=0, *ppo=0, *ppe=0;
54
float cbvectors[CB_MEML];
55
float tene, cene, cvec[SUBL];
58
memset(cvec,0,SUBL*sizeof(float));
60
/* Determine size of codebook sections */
62
base_size=lMem-lTarget+1;
65
base_size=lMem-lTarget+1+lTarget/2;
68
/* setup buffer for weighting */
70
memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER);
71
memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float));
72
memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));
76
AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,
77
lMem+lTarget, LPC_FILTERORDER);
79
/* Construct the codebook and target needed */
81
memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
89
for (i=0; i<lTarget; i++) {
90
tene+=target[i]*target[i];
93
/* Prepare search over one more codebook section. This section
94
is created by filtering the original buffer with a filter. */
96
filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
98
/* The Main Loop over stages */
100
for (stage=0; stage<nStages; stage++) {
102
range = search_rangeTbl[block][stage];
104
/* initialize search measure */
106
max_measure = (float)-10000000.0;
110
/* Compute cross dot product between the target
114
pp=buf+LPC_FILTERORDER+lMem-lTarget;
115
for (j=0; j<lTarget; j++) {
116
crossDot += target[j]*(*pp++);
121
/* Calculate energy in the first block of
122
'lTarget' samples. */
124
ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;
125
ppo = buf+LPC_FILTERORDER+lMem-1;
128
pp=buf+LPC_FILTERORDER+lMem-lTarget;
129
for (j=0; j<lTarget; j++) {
135
invenergy[0] = (float) 1.0 / (*ppe + EPS);
137
invenergy[0] = (float) 0.0;
146
measure=(float)-10000000.0;
148
if (crossDot > 0.0) {
149
measure = crossDot*crossDot*invenergy[0];
153
measure = crossDot*crossDot*invenergy[0];
156
/* check if measure is better */
157
ftmp = crossDot*invenergy[0];
159
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
161
max_measure = measure;
165
/* loop over the main first codebook section,
168
for (icount=1; icount<range; icount++) {
170
/* calculate measure */
173
pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
175
for (j=0; j<lTarget; j++) {
176
crossDot += target[j]*(*pp++);
180
*ppe++ = energy[icount-1] + (*ppi)*(*ppi) -
185
if (energy[icount]>0.0) {
187
(float)1.0/(energy[icount]+EPS);
189
invenergy[icount] = (float) 0.0;
196
measure=(float)-10000000.0;
198
if (crossDot > 0.0) {
199
measure = crossDot*crossDot*invenergy[icount];
203
measure = crossDot*crossDot*invenergy[icount];
206
/* check if measure is better */
207
ftmp = crossDot*invenergy[icount];
209
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
211
max_measure = measure;
216
/* Loop over augmented part in the first codebook
217
* section, full search.
218
* The vectors are interpolated.
223
/* Search for best possible cb vector and
224
compute the CB-vectors' energy. */
225
searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
226
target, buf+LPC_FILTERORDER+lMem,
227
&max_measure, &best_index, &gain, energy,
231
/* set search range for following codebook sections */
233
base_index=best_index;
235
/* unrestricted search */
237
# if CB_RESRANGE == -1
238
//if (CB_RESRANGE == -1) {
247
/* restricted search around best index from first
251
/* Initialize search indices */
254
sInd=base_index-CB_RESRANGE/2;
255
eInd=sInd+CB_RESRANGE;
265
} else if ( base_index < (base_size-20) ) {
268
sInd -= (eInd-range);
271
} else { /* base_index >= (base_size-20) */
273
if (sInd < (base_size-20)) {
277
eIndAug = 19 + CB_RESRANGE;
284
sIndAug = 20 + sInd - (base_size-20);
287
eInd = CB_RESRANGE - (eIndAug-sIndAug+1);
291
} else { /* lTarget = 22 or 23 */
304
sInd -= (eInd - range);
310
# endif /* CB_RESRANGE == -1 */
313
/* search of higher codebook section */
315
/* index search range */
322
ppe = energy+base_size;
325
pp=cbvectors+lMem-lTarget;
326
for (j=0; j<lTarget; j++) {
331
ppi = cbvectors + lMem - 1 - lTarget;
332
ppo = cbvectors + lMem - 1;
334
for (j=0; j<(range-1); j++) {
335
*(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);
342
/* loop over search range */
344
for (icount=sInd; icount<eInd; icount++) {
346
/* calculate measure */
349
pp=cbvectors + lMem - (counter++) - lTarget;
351
for (j=0;j<lTarget;j++) {
357
crossDot += target[j]*(*pp++);
360
if (energy[icount]>0.0) {
361
invenergy[icount] =(float)1.0/(energy[icount]+EPS);
363
invenergy[icount] =(float)0.0;
368
measure=(float)-10000000.0;
370
if (crossDot > 0.0) {
371
measure = crossDot*crossDot*
376
measure = crossDot*crossDot*invenergy[icount];
379
/* check if measure is better */
380
ftmp = crossDot*invenergy[icount];
382
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
384
max_measure = measure;
389
/* Search the augmented CB inside the limited range. */
391
if ((lTarget==SUBL)&&(sIndAug!=0)) {
392
searchAugmentedCB(sIndAug, eIndAug, stage,
393
2*base_size-20, target, cbvectors+lMem,
394
&max_measure, &best_index, &gain, energy,
398
/* record best index */
400
index[stage] = best_index;
402
/* gain quantization */
415
if (gain>CB_MAXGAIN) {
416
gain = (float)CB_MAXGAIN;
418
gain = gainquant(gain, 1.0, 32, &gain_index[stage]);
422
gain = gainquant(gain, (float)fabs(gains[stage-1]),
423
16, &gain_index[stage]);
425
gain = gainquant(gain, (float)fabs(gains[stage-1]),
426
8, &gain_index[stage]);
430
/* Extract the best (according to measure)
433
if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
435
if (index[stage]<base_size) {
436
pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];
438
pp=cbvectors+lMem-lTarget-
439
index[stage]+base_size;
443
if (index[stage]<base_size) {
444
if (index[stage]<(base_size-20)) {
445
pp=buf+LPC_FILTERORDER+lMem-
446
lTarget-index[stage];
448
createAugmentedVec(index[stage]-base_size+40,
449
buf+LPC_FILTERORDER+lMem,aug_vec);
453
int filterno, position;
455
filterno=index[stage]/base_size;
456
position=index[stage]-filterno*base_size;
464
if (position<(base_size-20)) {
465
pp=cbvectors+filterno*lMem-lTarget-
466
index[stage]+filterno*base_size;
469
index[stage]-(filterno+1)*base_size+40,
470
cbvectors+filterno*lMem,aug_vec);
476
/* Subtract the best codebook vector, according
477
to measure, from the target vector */
479
for (j=0;j<lTarget;j++) {
480
cvec[j] += gain*(*pp);
481
target[j] -= gain*(*pp++);
484
/* record quantized gain */
488
}/* end of Main Loop. for (stage=0;... */
490
/* Gain adjustment for energy matching */
492
for (i=0; i<lTarget; i++) {
493
cene+=cvec[i]*cvec[i];
497
for (i=gain_index[0]; i<32; i++) {
498
ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
500
if ((ftmp<(tene*gains[0]*gains[0])) &&
501
(gain_sq5Tbl[j]<(2.0*gains[0]))) {