/src/pjsip/third_party/ilbc/createCB.c
Line | Count | Source |
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( |
30 | | float *cbvectors, /* (o) Codebook vectors for the |
31 | | higher section */ |
32 | | float *mem, /* (i) Buffer to create codebook |
33 | | vector from */ |
34 | | int lMem /* (i) Length of buffer */ |
35 | 1.07k | ){ |
36 | 1.07k | int j, k; |
37 | 1.07k | float *pp, *pp1; |
38 | 1.07k | float tempbuff2[CB_MEML+CB_FILTERLEN]; |
39 | 1.07k | float *pos; |
40 | | |
41 | 1.07k | memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float)); |
42 | 1.07k | memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float)); |
43 | 1.07k | memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0, |
44 | 1.07k | (CB_HALFFILTERLEN+1)*sizeof(float)); |
45 | | |
46 | | /* Create codebook vector for higher section by filtering */ |
47 | | |
48 | | /* do filtering */ |
49 | 1.07k | pos=cbvectors; |
50 | 1.07k | memset(pos, 0, lMem*sizeof(float)); |
51 | 145k | for (k=0; k<lMem; k++) { |
52 | 144k | pp=&tempbuff2[k]; |
53 | 144k | pp1=&cbfiltersTbl[CB_FILTERLEN-1]; |
54 | 1.30M | for (j=0;j<CB_FILTERLEN;j++) { |
55 | 1.15M | (*pos)+=(*pp++)*(*pp1--); |
56 | 1.15M | } |
57 | 144k | pos++; |
58 | 144k | } |
59 | 1.07k | } |
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( |
72 | | int low, /* (i) Start index for the search */ |
73 | | int high, /* (i) End index for the search */ |
74 | | int stage, /* (i) Current stage */ |
75 | | int startIndex, /* (i) Codebook index for the first |
76 | | aug vector */ |
77 | | float *target, /* (i) Target vector for encoding */ |
78 | | float *buffer, /* (i) Pointer to the end of the buffer for |
79 | | augmented codebook construction */ |
80 | | float *max_measure, /* (i/o) Currently maximum measure */ |
81 | | int *best_index,/* (o) Currently the best index */ |
82 | | float *gain, /* (o) Currently the best gain */ |
83 | | float *energy, /* (o) Energy of augmented codebook |
84 | | vectors */ |
85 | | float *invenergy/* (o) Inv energy of augmented codebook |
86 | | vectors */ |
87 | 3.65k | ) { |
88 | 3.65k | int icount, ilow, j, tmpIndex; |
89 | 3.65k | float *pp, *ppo, *ppi, *ppe, crossDot, alfa; |
90 | 3.65k | float weighted, measure, nrjRecursive; |
91 | 3.65k | float ftmp; |
92 | | |
93 | | /* Compute the energy for the first (low-5) |
94 | | noninterpolated samples */ |
95 | 3.65k | nrjRecursive = (float) 0.0; |
96 | 3.65k | pp = buffer - low + 1; |
97 | 62.6k | for (j=0; j<(low-5); j++) { |
98 | 58.9k | nrjRecursive += ( (*pp)*(*pp) ); |
99 | 58.9k | pp++; |
100 | 58.9k | } |
101 | 3.65k | ppe = buffer - low; |
102 | | |
103 | | |
104 | 72.4k | for (icount=low; icount<=high; icount++) { |
105 | | |
106 | | /* Index of the codebook vector used for retrieving |
107 | | energy values */ |
108 | 68.8k | tmpIndex = startIndex+icount-20; |
109 | | |
110 | 68.8k | ilow = icount-4; |
111 | | |
112 | | /* Update the energy recursively to save complexity */ |
113 | 68.8k | nrjRecursive = nrjRecursive + (*ppe)*(*ppe); |
114 | 68.8k | ppe--; |
115 | 68.8k | energy[tmpIndex] = nrjRecursive; |
116 | | |
117 | | /* Compute cross dot product for the first (low-5) |
118 | | samples */ |
119 | | |
120 | | |
121 | | |
122 | | |
123 | | |
124 | 68.8k | crossDot = (float) 0.0; |
125 | 68.8k | pp = buffer-icount; |
126 | 1.84M | for (j=0; j<ilow; j++) { |
127 | 1.77M | crossDot += target[j]*(*pp++); |
128 | 1.77M | } |
129 | | |
130 | | /* interpolation */ |
131 | 68.8k | alfa = (float) 0.2; |
132 | 68.8k | ppo = buffer-4; |
133 | 68.8k | ppi = buffer-icount-4; |
134 | 344k | for (j=ilow; j<icount; j++) { |
135 | 275k | weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); |
136 | 275k | ppo++; |
137 | 275k | ppi++; |
138 | 275k | energy[tmpIndex] += weighted*weighted; |
139 | 275k | crossDot += target[j]*weighted; |
140 | 275k | alfa += (float)0.2; |
141 | 275k | } |
142 | | |
143 | | /* Compute energy and cross dot product for the |
144 | | remaining samples */ |
145 | 68.8k | pp = buffer - icount; |
146 | 775k | for (j=icount; j<SUBL; j++) { |
147 | 706k | energy[tmpIndex] += (*pp)*(*pp); |
148 | 706k | crossDot += target[j]*(*pp++); |
149 | 706k | } |
150 | | |
151 | 68.8k | if (energy[tmpIndex]>0.0) { |
152 | 68.7k | invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); |
153 | 68.7k | } else { |
154 | 81 | invenergy[tmpIndex] = (float) 0.0; |
155 | 81 | } |
156 | | |
157 | 68.8k | if (stage==0) { |
158 | 22.0k | measure = (float)-10000000.0; |
159 | | |
160 | 22.0k | if (crossDot > 0.0) { |
161 | 10.0k | measure = crossDot*crossDot*invenergy[tmpIndex]; |
162 | 10.0k | } |
163 | 22.0k | } |
164 | 46.7k | else { |
165 | 46.7k | measure = crossDot*crossDot*invenergy[tmpIndex]; |
166 | 46.7k | } |
167 | | |
168 | | /* check if measure is better */ |
169 | 68.8k | ftmp = crossDot*invenergy[tmpIndex]; |
170 | | |
171 | 68.8k | if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { |
172 | | |
173 | | |
174 | | |
175 | | |
176 | | |
177 | 1.42k | *best_index = tmpIndex; |
178 | 1.42k | *max_measure = measure; |
179 | 1.42k | *gain = ftmp; |
180 | 1.42k | } |
181 | 68.8k | } |
182 | 3.65k | } |
183 | | |
184 | | |
185 | | /*----------------------------------------------------------------* |
186 | | * Recreate a specific codebook vector from the augmented part. |
187 | | * |
188 | | *----------------------------------------------------------------*/ |
189 | | |
190 | | void createAugmentedVec( |
191 | | int index, /* (i) Index for the augmented vector |
192 | | to be created */ |
193 | | float *buffer, /* (i) Pointer to the end of the buffer for |
194 | | augmented codebook construction */ |
195 | | float *cbVec/* (o) The construced codebook vector */ |
196 | 649 | ) { |
197 | 649 | int ilow, j; |
198 | 649 | float *pp, *ppo, *ppi, alfa, alfa1, weighted; |
199 | | |
200 | 649 | ilow = index-5; |
201 | | |
202 | | /* copy the first noninterpolated part */ |
203 | | |
204 | 649 | pp = buffer-index; |
205 | 649 | memcpy(cbVec,pp,sizeof(float)*index); |
206 | | |
207 | | /* interpolation */ |
208 | | |
209 | 649 | alfa1 = (float)0.2; |
210 | 649 | alfa = 0.0; |
211 | 649 | ppo = buffer-5; |
212 | 649 | ppi = buffer-index-5; |
213 | 3.89k | for (j=ilow; j<index; j++) { |
214 | 3.24k | weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); |
215 | 3.24k | ppo++; |
216 | 3.24k | ppi++; |
217 | 3.24k | cbVec[j] = weighted; |
218 | 3.24k | alfa += alfa1; |
219 | 3.24k | } |
220 | | |
221 | | /* copy the second noninterpolated part */ |
222 | | |
223 | 649 | pp = buffer - index; |
224 | 649 | memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index)); |
225 | | |
226 | | |
227 | | |
228 | | |
229 | | |
230 | 649 | } |
231 | | |