comparison intercom/ilbc/iCBSearch.c @ 2:13be24d74cd2

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

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.