Coverage Report

Created: 2026-03-22 06:50

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