Asterisk - The Open Source Telephony Project  18.5.0
iCBSearch.c
Go to the documentation of this file.
1 
2  /******************************************************************
3 
4  iLBC Speech Coder ANSI-C Source Code
5 
6  iCBSearch.c
7 
8  Copyright (C) The Internet Society (2004).
9  All Rights Reserved.
10 
11  ******************************************************************/
12 
13  #include <math.h>
14  #include <string.h>
15 
16  #include "iLBC_define.h"
17  #include "gainquant.h"
18  #include "createCB.h"
19  #include "filter.h"
20  #include "constants.h"
21 
22  /*----------------------------------------------------------------*
23  * Search routine for codebook encoding and gain quantization.
24  *---------------------------------------------------------------*/
25 
26  void iCBSearch(
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 */
31 
32 
33 
34 
35 
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 */
44  ){
45  int i, j, icount, stage, best_index, range, counter;
46  float max_measure, gain, measure, crossDot, ftmp;
47  float gains[CB_NSTAGES];
48  float target[SUBL];
49  int base_index, sInd, eInd, base_size;
50  int sIndAug=0, eIndAug=0;
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];
56  float aug_vec[SUBL];
57 
58  memset(cvec,0,SUBL*sizeof(float));
59 
60  /* Determine size of codebook sections */
61 
62  base_size=lMem-lTarget+1;
63 
64  if (lTarget==SUBL) {
65  base_size=lMem-lTarget+1+lTarget/2;
66  }
67 
68  /* setup buffer for weighting */
69 
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));
73 
74  /* weighting */
75 
76  AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,
77  lMem+lTarget, LPC_FILTERORDER);
78 
79  /* Construct the codebook and target needed */
80 
81  memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
82 
83  tene=0.0;
84 
85 
86 
87 
88 
89  for (i=0; i<lTarget; i++) {
90  tene+=target[i]*target[i];
91  }
92 
93  /* Prepare search over one more codebook section. This section
94  is created by filtering the original buffer with a filter. */
95 
96  filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
97 
98  /* The Main Loop over stages */
99 
100  for (stage=0; stage<nStages; stage++) {
101 
102  range = search_rangeTbl[block][stage];
103 
104  /* initialize search measure */
105 
106  max_measure = (float)-10000000.0;
107  gain = (float)0.0;
108  best_index = 0;
109 
110  /* Compute cross dot product between the target
111  and the CB memory */
112 
113  crossDot=0.0;
114  pp=buf+LPC_FILTERORDER+lMem-lTarget;
115  for (j=0; j<lTarget; j++) {
116  crossDot += target[j]*(*pp++);
117  }
118 
119  if (stage==0) {
120 
121  /* Calculate energy in the first block of
122  'lTarget' samples. */
123  ppe = energy;
124  ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;
125  ppo = buf+LPC_FILTERORDER+lMem-1;
126 
127  *ppe=0.0;
128  pp=buf+LPC_FILTERORDER+lMem-lTarget;
129  for (j=0; j<lTarget; j++, pp++) {
130  *ppe+=(*pp)*(*pp);
131  }
132 
133  if (*ppe>0.0) {
134  invenergy[0] = (float) 1.0 / (*ppe + EPS);
135  } else {
136  invenergy[0] = (float) 0.0;
137 
138 
139 
140 
141 
142  }
143  ppe++;
144 
145  measure=(float)-10000000.0;
146 
147  if (crossDot > 0.0) {
148  measure = crossDot*crossDot*invenergy[0];
149  }
150  }
151  else {
152  measure = crossDot*crossDot*invenergy[0];
153  }
154 
155  /* check if measure is better */
156  ftmp = crossDot*invenergy[0];
157 
158  if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
159  best_index = 0;
160  max_measure = measure;
161  gain = ftmp;
162  }
163 
164  /* loop over the main first codebook section,
165  full search */
166 
167  for (icount=1; icount<range; icount++) {
168 
169  /* calculate measure */
170 
171  crossDot=0.0;
172  pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
173 
174  for (j=0; j<lTarget; j++) {
175  crossDot += target[j]*(*pp++);
176  }
177 
178  if (stage==0) {
179  *ppe++ = energy[icount-1] + (*ppi)*(*ppi) -
180  (*ppo)*(*ppo);
181  ppo--;
182  ppi--;
183 
184  if (energy[icount]>0.0) {
185  invenergy[icount] =
186  (float)1.0/(energy[icount]+EPS);
187  } else {
188  invenergy[icount] = (float) 0.0;
189  }
190 
191 
192 
193 
194 
195  measure=(float)-10000000.0;
196 
197  if (crossDot > 0.0) {
198  measure = crossDot*crossDot*invenergy[icount];
199  }
200  }
201  else {
202  measure = crossDot*crossDot*invenergy[icount];
203  }
204 
205  /* check if measure is better */
206  ftmp = crossDot*invenergy[icount];
207 
208  if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
209  best_index = icount;
210  max_measure = measure;
211  gain = ftmp;
212  }
213  }
214 
215  /* Loop over augmented part in the first codebook
216  * section, full search.
217  * The vectors are interpolated.
218  */
219 
220  if (lTarget==SUBL) {
221 
222  /* Search for best possible cb vector and
223  compute the CB-vectors' energy. */
224  searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
225  target, buf+LPC_FILTERORDER+lMem,
226  &max_measure, &best_index, &gain, energy,
227  invenergy);
228  }
229 
230  /* set search range for following codebook sections */
231 
232  base_index=best_index;
233 
234  /* unrestricted search */
235 
236  if (CB_RESRANGE == -1) {
237  sInd=0;
238  eInd=range-1;
239  sIndAug=20;
240  eIndAug=39;
241  }
242 
243 
244 
245 
246 
247 
248  /* restricted search around best index from first
249  codebook section */
250 
251  else {
252  /* Initialize search indices */
253  sIndAug=0;
254  eIndAug=0;
255  sInd=base_index-CB_RESRANGE/2;
256  eInd=sInd+CB_RESRANGE;
257 
258  if (lTarget==SUBL) {
259 
260  if (sInd<0) {
261 
262  sIndAug = 40 + sInd;
263  eIndAug = 39;
264  sInd=0;
265 
266  } else if ( base_index < (base_size-20) ) {
267 
268  if (eInd > range) {
269  sInd -= (eInd-range);
270  eInd = range;
271  }
272  } else { /* base_index >= (base_size-20) */
273 
274  if (sInd < (base_size-20)) {
275  sIndAug = 20;
276  sInd = 0;
277  eInd = 0;
278  eIndAug = 19 + CB_RESRANGE;
279 
280  if(eIndAug > 39) {
281  eInd = eIndAug-39;
282  eIndAug = 39;
283  }
284  } else {
285  sIndAug = 20 + sInd - (base_size-20);
286  eIndAug = 39;
287  sInd = 0;
288  eInd = CB_RESRANGE - (eIndAug-sIndAug+1);
289  }
290  }
291 
292  } else { /* lTarget = 22 or 23 */
293 
294  if (sInd < 0) {
295  eInd -= sInd;
296 
297 
298 
299 
300 
301  sInd = 0;
302  }
303 
304  if(eInd > range) {
305  sInd -= (eInd - range);
306  eInd = range;
307  }
308  }
309  }
310 
311  /* search of higher codebook section */
312 
313  /* index search range */
314  counter = sInd;
315  sInd += base_size;
316  eInd += base_size;
317 
318 
319  if (stage==0) {
320  ppe = energy+base_size;
321  *ppe=0.0;
322 
323  pp=cbvectors+lMem-lTarget;
324  for (j=0; j<lTarget; j++, pp++) {
325  *ppe+=(*pp)*(*pp);
326  }
327 
328  ppi = cbvectors + lMem - 1 - lTarget;
329  ppo = cbvectors + lMem - 1;
330 
331  for (j=0; j<(range-1); j++) {
332  *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);
333  ppo--;
334  ppi--;
335  ppe++;
336  }
337  }
338 
339  /* loop over search range */
340 
341  for (icount=sInd; icount<eInd; icount++) {
342 
343  /* calculate measure */
344 
345  crossDot=0.0;
346  pp=cbvectors + lMem - (counter++) - lTarget;
347 
348  for (j=0;j<lTarget;j++) {
349 
350 
351 
352 
353 
354  crossDot += target[j]*(*pp++);
355  }
356 
357  if (energy[icount]>0.0) {
358  invenergy[icount] =(float)1.0/(energy[icount]+EPS);
359  } else {
360  invenergy[icount] =(float)0.0;
361  }
362 
363  if (stage==0) {
364 
365  measure=(float)-10000000.0;
366 
367  if (crossDot > 0.0) {
368  measure = crossDot*crossDot*
369  invenergy[icount];
370  }
371  }
372  else {
373  measure = crossDot*crossDot*invenergy[icount];
374  }
375 
376  /* check if measure is better */
377  ftmp = crossDot*invenergy[icount];
378 
379  if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
380  best_index = icount;
381  max_measure = measure;
382  gain = ftmp;
383  }
384  }
385 
386  /* Search the augmented CB inside the limited range. */
387 
388  if ((lTarget==SUBL)&&(sIndAug!=0)) {
389  searchAugmentedCB(sIndAug, eIndAug, stage,
390  2*base_size-20, target, cbvectors+lMem,
391  &max_measure, &best_index, &gain, energy,
392  invenergy);
393  }
394 
395  /* record best index */
396 
397  index[stage] = best_index;
398 
399  /* gain quantization */
400 
401  if (stage==0){
402 
403 
404 
405 
406 
407 
408  if (gain<0.0){
409  gain = 0.0;
410  }
411 
412  if (gain>CB_MAXGAIN) {
413  gain = (float)CB_MAXGAIN;
414  }
415  gain = gainquant(gain, 1.0, 32, &gain_index[stage]);
416  }
417  else {
418  if (stage==1) {
419  gain = gainquant(gain, (float)fabs(gains[stage-1]),
420  16, &gain_index[stage]);
421  } else {
422  gain = gainquant(gain, (float)fabs(gains[stage-1]),
423  8, &gain_index[stage]);
424  }
425  }
426 
427  /* Extract the best (according to measure)
428  codebook vector */
429 
430  if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
431 
432  if (index[stage]<base_size) {
433  pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];
434  } else {
435  pp=cbvectors+lMem-lTarget-
436  index[stage]+base_size;
437  }
438  } else {
439 
440  if (index[stage]<base_size) {
441  if (index[stage]<(base_size-20)) {
442  pp=buf+LPC_FILTERORDER+lMem-
443  lTarget-index[stage];
444  } else {
445  createAugmentedVec(index[stage]-base_size+40,
446  buf+LPC_FILTERORDER+lMem,aug_vec);
447  pp=aug_vec;
448  }
449  } else {
450  int filterno, position;
451 
452  filterno=index[stage]/base_size;
453  position=index[stage]-filterno*base_size;
454 
455 
456 
457 
458 
459 
460 
461  if (position<(base_size-20)) {
462  pp=cbvectors+filterno*lMem-lTarget-
463  index[stage]+filterno*base_size;
464  } else {
466  index[stage]-(filterno+1)*base_size+40,
467  cbvectors+filterno*lMem,aug_vec);
468  pp=aug_vec;
469  }
470  }
471  }
472 
473  /* Subtract the best codebook vector, according
474  to measure, from the target vector */
475 
476  for (j=0;j<lTarget;j++) {
477  cvec[j] += gain*(*pp);
478  target[j] -= gain*(*pp++);
479  }
480 
481  /* record quantized gain */
482 
483  gains[stage]=gain;
484 
485  }/* end of Main Loop. for (stage=0;... */
486 
487  /* Gain adjustment for energy matching */
488  cene=0.0;
489  for (i=0; i<lTarget; i++) {
490  cene+=cvec[i]*cvec[i];
491  }
492  j=gain_index[0];
493 
494  for (i=gain_index[0]; i<32; i++) {
495  ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
496 
497  if ((ftmp<(tene*gains[0]*gains[0])) &&
498  (gain_sq5Tbl[j]<(2.0*gains[0]))) {
499  j=i;
500  }
501  }
502  gain_index[0]=j;
503  }
#define CB_RESRANGE
Definition: iLBC_define.h:61
#define CB_MEML
Definition: iLBC_define.h:58
#define EPS
Definition: iLBC_define.h:111
#define CB_NSTAGES
Definition: iLBC_define.h:56
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define STATE_LEN
Definition: iLBC_define.h:34
int search_rangeTbl[5][CB_NSTAGES]
Definition: constants.c:135
void iCBSearch(iLBC_Enc_Inst_t *iLBCenc_inst, int *index, int *gain_index, float *intarget, float *mem, int lMem, int lTarget, int nStages, float *weightDenum, float *weightState, int block)
Definition: iCBSearch.c:26
#define CB_EXPAND
Definition: iLBC_define.h:57
void AllPoleFilter(float *InOut, float *Coef, int lengthInOut, int orderCoef)
Definition: filter.c:19
#define CB_MAXGAIN
Definition: iLBC_define.h:62
#define SUBL
Definition: iLBC_define.h:33
void createAugmentedVec(int index, float *buffer, float *cbVec)
Definition: createCB.c:190
#define LPC_FILTERORDER
Definition: iLBC_define.h:40
float gain_sq5Tbl[32]
Definition: constants.c:168
void filteredCBvecs(float *cbvectors, float *mem, int lMem)
Definition: createCB.c:29
void searchAugmentedCB(int low, int high, int stage, int startIndex, float *target, float *buffer, float *max_measure, int *best_index, float *gain, float *energy, float *invenergy)
Definition: createCB.c:71
float gainquant(float in, float maxIn, int cblen, int *index)
Definition: gainquant.c:27