2
|
1
|
|
2
|
|
3 /******************************************************************
|
|
4
|
|
5 iLBC Speech Coder ANSI-C Source Code
|
|
6
|
|
7 createCB.c
|
|
8
|
|
9 Copyright (C) The Internet Society (2004).
|
|
10 All Rights Reserved.
|
|
11
|
|
12 ******************************************************************/
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18 #include "iLBC_define.h"
|
|
19 #include "constants.h"
|
|
20 #include <string.h>
|
|
21 #include <math.h>
|
|
22
|
|
23 /*----------------------------------------------------------------*
|
|
24 * Construct an additional codebook vector by filtering the
|
|
25 * initial codebook buffer. This vector is then used to expand
|
|
26 * the codebook with an additional section.
|
|
27 *---------------------------------------------------------------*/
|
|
28
|
|
29 void filteredCBvecs(float *cbvectors, /* (o) Codebook vectors for the
|
|
30 higher section */
|
|
31 float *mem, /* (i) Buffer to create codebook
|
|
32 vector from */
|
|
33 int lMem /* (i) Length of buffer */
|
|
34 )
|
|
35 {
|
|
36 int j, k;
|
|
37 float *pp, *pp1;
|
|
38 float tempbuff2[CB_MEML + CB_FILTERLEN];
|
|
39 float *pos;
|
|
40
|
|
41 memset(tempbuff2, 0, (CB_HALFFILTERLEN - 1) * sizeof(float));
|
|
42 memcpy(&tempbuff2[CB_HALFFILTERLEN - 1], mem, lMem * sizeof(float));
|
|
43 memset(&tempbuff2[lMem + CB_HALFFILTERLEN - 1], 0,
|
|
44 (CB_HALFFILTERLEN + 1) * sizeof(float));
|
|
45
|
|
46 /* Create codebook vector for higher section by filtering */
|
|
47
|
|
48 /* do filtering */
|
|
49 pos = cbvectors;
|
|
50 memset(pos, 0, lMem * sizeof(float));
|
|
51 for (k = 0; k < lMem; k++) {
|
|
52 pp = &tempbuff2[k];
|
|
53 pp1 = &cbfiltersTbl[CB_FILTERLEN - 1];
|
|
54 for (j = 0; j < CB_FILTERLEN; j++) {
|
|
55 (*pos) += (*pp++) * (*pp1--);
|
|
56 }
|
|
57 pos++;
|
|
58 }
|
|
59 }
|
|
60
|
|
61 /*----------------------------------------------------------------*
|
|
62 * Search the augmented part of the codebook to find the best
|
|
63 * measure.
|
|
64 *----------------------------------------------------------------*/
|
|
65
|
|
66
|
|
67
|
|
68
|
|
69
|
|
70
|
|
71 void searchAugmentedCB(int low, /* (i) Start index for the search */
|
|
72 int high, /* (i) End index for the search */
|
|
73 int stage, /* (i) Current stage */
|
|
74 int startIndex, /* (i) Codebook index for the first
|
|
75 aug vector */
|
|
76 float *target, /* (i) Target vector for encoding */
|
|
77 float *buffer, /* (i) Pointer to the end of the buffer for
|
|
78 augmented codebook construction */
|
|
79 float *max_measure, /* (i/o) Currently maximum measure */
|
|
80 int *best_index, /* (o) Currently the best index */
|
|
81 float *gain, /* (o) Currently the best gain */
|
|
82 float *energy, /* (o) Energy of augmented codebook
|
|
83 vectors */
|
|
84 float *invenergy /* (o) Inv energy of augmented codebook
|
|
85 vectors */
|
|
86 )
|
|
87 {
|
|
88 int icount, ilow, j, tmpIndex;
|
|
89 float *pp, *ppo, *ppi, *ppe, crossDot, alfa;
|
|
90 float weighted, measure, nrjRecursive;
|
|
91 float ftmp;
|
|
92
|
|
93 /* Compute the energy for the first (low-5)
|
|
94 noninterpolated samples */
|
|
95 nrjRecursive = (float) 0.0;
|
|
96 pp = buffer - low + 1;
|
|
97 for (j = 0; j < (low - 5); j++) {
|
|
98 nrjRecursive += ((*pp) * (*pp));
|
|
99 pp++;
|
|
100 }
|
|
101 ppe = buffer - low;
|
|
102
|
|
103
|
|
104 for (icount = low; icount <= high; icount++) {
|
|
105
|
|
106 /* Index of the codebook vector used for retrieving
|
|
107 energy values */
|
|
108 tmpIndex = startIndex + icount - 20;
|
|
109
|
|
110 ilow = icount - 4;
|
|
111
|
|
112 /* Update the energy recursively to save complexity */
|
|
113 nrjRecursive = nrjRecursive + (*ppe) * (*ppe);
|
|
114 ppe--;
|
|
115 energy[tmpIndex] = nrjRecursive;
|
|
116
|
|
117 /* Compute cross dot product for the first (low-5)
|
|
118 samples */
|
|
119
|
|
120
|
|
121
|
|
122
|
|
123
|
|
124 crossDot = (float) 0.0;
|
|
125 pp = buffer - icount;
|
|
126 for (j = 0; j < ilow; j++) {
|
|
127 crossDot += target[j] * (*pp++);
|
|
128 }
|
|
129
|
|
130 /* interpolation */
|
|
131 alfa = (float) 0.2;
|
|
132 ppo = buffer - 4;
|
|
133 ppi = buffer - icount - 4;
|
|
134 for (j = ilow; j < icount; j++) {
|
|
135 weighted = ((float) 1.0 - alfa) * (*ppo) + alfa * (*ppi);
|
|
136 ppo++;
|
|
137 ppi++;
|
|
138 energy[tmpIndex] += weighted * weighted;
|
|
139 crossDot += target[j] * weighted;
|
|
140 alfa += (float) 0.2;
|
|
141 }
|
|
142
|
|
143 /* Compute energy and cross dot product for the
|
|
144 remaining samples */
|
|
145 pp = buffer - icount;
|
|
146 for (j = icount; j < SUBL; j++) {
|
|
147 energy[tmpIndex] += (*pp) * (*pp);
|
|
148 crossDot += target[j] * (*pp++);
|
|
149 }
|
|
150
|
|
151 if (energy[tmpIndex] > 0.0) {
|
|
152 invenergy[tmpIndex] = (float) 1.0 / (energy[tmpIndex] + EPS);
|
|
153 } else {
|
|
154 invenergy[tmpIndex] = (float) 0.0;
|
|
155 }
|
|
156
|
|
157 if (stage == 0) {
|
|
158 measure = (float) -10000000.0;
|
|
159
|
|
160 if (crossDot > 0.0) {
|
|
161 measure = crossDot * crossDot * invenergy[tmpIndex];
|
|
162 }
|
|
163 } else {
|
|
164 measure = crossDot * crossDot * invenergy[tmpIndex];
|
|
165 }
|
|
166
|
|
167 /* check if measure is better */
|
|
168 ftmp = crossDot * invenergy[tmpIndex];
|
|
169
|
|
170 if ((measure > *max_measure) && (fabs(ftmp) < CB_MAXGAIN)) {
|
|
171
|
|
172
|
|
173
|
|
174
|
|
175
|
|
176 *best_index = tmpIndex;
|
|
177 *max_measure = measure;
|
|
178 *gain = ftmp;
|
|
179 }
|
|
180 }
|
|
181 }
|
|
182
|
|
183
|
|
184 /*----------------------------------------------------------------*
|
|
185 * Recreate a specific codebook vector from the augmented part.
|
|
186 *
|
|
187 *----------------------------------------------------------------*/
|
|
188
|
|
189 void createAugmentedVec(int index, /* (i) Index for the augmented vector
|
|
190 to be created */
|
|
191 float *buffer, /* (i) Pointer to the end of the buffer for
|
|
192 augmented codebook construction */
|
|
193 float *cbVec /* (o) The construced codebook vector */
|
|
194 )
|
|
195 {
|
|
196 int ilow, j;
|
|
197 float *pp, *ppo, *ppi, alfa, alfa1, weighted;
|
|
198
|
|
199 ilow = index - 5;
|
|
200
|
|
201 /* copy the first noninterpolated part */
|
|
202
|
|
203 pp = buffer - index;
|
|
204 memcpy(cbVec, pp, sizeof(float) * index);
|
|
205
|
|
206 /* interpolation */
|
|
207
|
|
208 alfa1 = (float) 0.2;
|
|
209 alfa = 0.0;
|
|
210 ppo = buffer - 5;
|
|
211 ppi = buffer - index - 5;
|
|
212 for (j = ilow; j < index; j++) {
|
|
213 weighted = ((float) 1.0 - alfa) * (*ppo) + alfa * (*ppi);
|
|
214 ppo++;
|
|
215 ppi++;
|
|
216 cbVec[j] = weighted;
|
|
217 alfa += alfa1;
|
|
218 }
|
|
219
|
|
220 /* copy the second noninterpolated part */
|
|
221
|
|
222 pp = buffer - index;
|
|
223 memcpy(cbVec + index, pp, sizeof(float) * (SUBL - index));
|
|
224
|
|
225
|
|
226
|
|
227
|
|
228
|
|
229 }
|