diff options
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/quant_lsp.c')
-rw-r--r-- | lib/rbcodec/codecs/libspeex/quant_lsp.c | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/quant_lsp.c b/lib/rbcodec/codecs/libspeex/quant_lsp.c new file mode 100644 index 0000000000..9b9104c842 --- /dev/null +++ b/lib/rbcodec/codecs/libspeex/quant_lsp.c | |||
@@ -0,0 +1,391 @@ | |||
1 | /* Copyright (C) 2002 Jean-Marc Valin | ||
2 | File: quant_lsp.c | ||
3 | LSP vector quantization | ||
4 | |||
5 | Redistribution and use in source and binary forms, with or without | ||
6 | modification, are permitted provided that the following conditions | ||
7 | are met: | ||
8 | |||
9 | - Redistributions of source code must retain the above copyright | ||
10 | notice, this list of conditions and the following disclaimer. | ||
11 | |||
12 | - Redistributions in binary form must reproduce the above copyright | ||
13 | notice, this list of conditions and the following disclaimer in the | ||
14 | documentation and/or other materials provided with the distribution. | ||
15 | |||
16 | - Neither the name of the Xiph.org Foundation nor the names of its | ||
17 | contributors may be used to endorse or promote products derived from | ||
18 | this software without specific prior written permission. | ||
19 | |||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
24 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
25 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifdef HAVE_CONFIG_H | ||
34 | #include "config-speex.h" | ||
35 | #endif | ||
36 | |||
37 | #include "quant_lsp.h" | ||
38 | #include "os_support.h" | ||
39 | #include <math.h> | ||
40 | #ifndef M_PI | ||
41 | #define M_PI 3.14159265358979323846 | ||
42 | #endif | ||
43 | |||
44 | #include "arch.h" | ||
45 | |||
46 | #ifdef BFIN_ASM | ||
47 | #include "quant_lsp_bfin.h" | ||
48 | #endif | ||
49 | |||
50 | #ifdef FIXED_POINT | ||
51 | |||
52 | #define LSP_LINEAR(i) (SHL16(i+1,11)) | ||
53 | #define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144)) | ||
54 | #define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5)) | ||
55 | #define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4)) | ||
56 | #define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3)) | ||
57 | #define LSP_PI 25736 | ||
58 | |||
59 | #else | ||
60 | |||
61 | #define LSP_LINEAR(i) (.25*(i)+.25) | ||
62 | #define LSP_LINEAR_HIGH(i) (.3125*(i)+.75) | ||
63 | #define LSP_SCALE 256. | ||
64 | #define LSP_DIV_256(x) (0.0039062*(x)) | ||
65 | #define LSP_DIV_512(x) (0.0019531*(x)) | ||
66 | #define LSP_DIV_1024(x) (0.00097656*(x)) | ||
67 | #define LSP_PI M_PI | ||
68 | |||
69 | #endif | ||
70 | |||
71 | #ifndef SPEEX_DISABLE_ENCODER | ||
72 | static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order) | ||
73 | { | ||
74 | int i; | ||
75 | spx_word16_t tmp1, tmp2; | ||
76 | for (i=0;i<order;i++) | ||
77 | { | ||
78 | if (i==0) | ||
79 | tmp1 = qlsp[i]; | ||
80 | else | ||
81 | tmp1 = qlsp[i]-qlsp[i-1]; | ||
82 | if (i==order-1) | ||
83 | tmp2 = LSP_PI-qlsp[i]; | ||
84 | else | ||
85 | tmp2 = qlsp[i+1]-qlsp[i]; | ||
86 | if (tmp2<tmp1) | ||
87 | tmp1 = tmp2; | ||
88 | #ifdef FIXED_POINT | ||
89 | quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1)); | ||
90 | #else | ||
91 | quant_weight[i] = 10/(.04+tmp1); | ||
92 | #endif | ||
93 | } | ||
94 | |||
95 | } | ||
96 | |||
97 | /* Note: x is modified*/ | ||
98 | #ifndef OVERRIDE_LSP_QUANT | ||
99 | static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim) | ||
100 | { | ||
101 | int i,j; | ||
102 | spx_word32_t dist; | ||
103 | spx_word16_t tmp; | ||
104 | spx_word32_t best_dist=VERY_LARGE32; | ||
105 | int best_id=0; | ||
106 | const signed char *ptr=cdbk; | ||
107 | for (i=0;i<nbVec;i++) | ||
108 | { | ||
109 | dist=0; | ||
110 | for (j=0;j<nbDim;j++) | ||
111 | { | ||
112 | tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5)); | ||
113 | dist=MAC16_16(dist,tmp,tmp); | ||
114 | } | ||
115 | if (dist<best_dist) | ||
116 | { | ||
117 | best_dist=dist; | ||
118 | best_id=i; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | for (j=0;j<nbDim;j++) | ||
123 | x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); | ||
124 | |||
125 | return best_id; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | /* Note: x is modified*/ | ||
130 | #ifndef OVERRIDE_LSP_WEIGHT_QUANT | ||
131 | static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim) | ||
132 | { | ||
133 | int i,j; | ||
134 | spx_word32_t dist; | ||
135 | spx_word16_t tmp; | ||
136 | spx_word32_t best_dist=VERY_LARGE32; | ||
137 | int best_id=0; | ||
138 | const signed char *ptr=cdbk; | ||
139 | for (i=0;i<nbVec;i++) | ||
140 | { | ||
141 | dist=0; | ||
142 | for (j=0;j<nbDim;j++) | ||
143 | { | ||
144 | tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5)); | ||
145 | dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp)); | ||
146 | } | ||
147 | if (dist<best_dist) | ||
148 | { | ||
149 | best_dist=dist; | ||
150 | best_id=i; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | for (j=0;j<nbDim;j++) | ||
155 | x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5)); | ||
156 | return best_id; | ||
157 | } | ||
158 | #endif | ||
159 | |||
160 | void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) | ||
161 | { | ||
162 | int i; | ||
163 | int id; | ||
164 | spx_word16_t quant_weight[10]; | ||
165 | |||
166 | for (i=0;i<order;i++) | ||
167 | qlsp[i]=lsp[i]; | ||
168 | |||
169 | compute_quant_weights(qlsp, quant_weight, order); | ||
170 | |||
171 | for (i=0;i<order;i++) | ||
172 | qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i)); | ||
173 | |||
174 | #ifndef FIXED_POINT | ||
175 | for (i=0;i<order;i++) | ||
176 | qlsp[i] = LSP_SCALE*qlsp[i]; | ||
177 | #endif | ||
178 | id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); | ||
179 | speex_bits_pack(bits, id, 6); | ||
180 | |||
181 | for (i=0;i<order;i++) | ||
182 | qlsp[i]*=2; | ||
183 | |||
184 | id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); | ||
185 | speex_bits_pack(bits, id, 6); | ||
186 | |||
187 | for (i=0;i<5;i++) | ||
188 | qlsp[i]*=2; | ||
189 | |||
190 | id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5); | ||
191 | speex_bits_pack(bits, id, 6); | ||
192 | |||
193 | id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); | ||
194 | speex_bits_pack(bits, id, 6); | ||
195 | |||
196 | for (i=5;i<10;i++) | ||
197 | qlsp[i]*=2; | ||
198 | |||
199 | id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5); | ||
200 | speex_bits_pack(bits, id, 6); | ||
201 | |||
202 | #ifdef FIXED_POINT | ||
203 | for (i=0;i<order;i++) | ||
204 | qlsp[i]=PSHR16(qlsp[i],2); | ||
205 | #else | ||
206 | for (i=0;i<order;i++) | ||
207 | qlsp[i]=qlsp[i] * .00097656; | ||
208 | #endif | ||
209 | |||
210 | for (i=0;i<order;i++) | ||
211 | qlsp[i]=lsp[i]-qlsp[i]; | ||
212 | } | ||
213 | #endif /* SPEEX_DISABLE_ENCODER */ | ||
214 | |||
215 | void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits) | ||
216 | { | ||
217 | int i, id; | ||
218 | for (i=0;i<order;i++) | ||
219 | lsp[i]=LSP_LINEAR(i); | ||
220 | |||
221 | |||
222 | id=speex_bits_unpack_unsigned(bits, 6); | ||
223 | for (i=0;i<10;i++) | ||
224 | lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i])); | ||
225 | |||
226 | id=speex_bits_unpack_unsigned(bits, 6); | ||
227 | for (i=0;i<5;i++) | ||
228 | lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i])); | ||
229 | |||
230 | id=speex_bits_unpack_unsigned(bits, 6); | ||
231 | for (i=0;i<5;i++) | ||
232 | lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i])); | ||
233 | |||
234 | id=speex_bits_unpack_unsigned(bits, 6); | ||
235 | for (i=0;i<5;i++) | ||
236 | lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i])); | ||
237 | |||
238 | id=speex_bits_unpack_unsigned(bits, 6); | ||
239 | for (i=0;i<5;i++) | ||
240 | lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i])); | ||
241 | } | ||
242 | |||
243 | |||
244 | #ifndef SPEEX_DISABLE_ENCODER | ||
245 | void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) | ||
246 | { | ||
247 | int i; | ||
248 | int id; | ||
249 | spx_word16_t quant_weight[10]; | ||
250 | |||
251 | for (i=0;i<order;i++) | ||
252 | qlsp[i]=lsp[i]; | ||
253 | |||
254 | compute_quant_weights(qlsp, quant_weight, order); | ||
255 | |||
256 | for (i=0;i<order;i++) | ||
257 | qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i)); | ||
258 | #ifndef FIXED_POINT | ||
259 | for (i=0;i<order;i++) | ||
260 | qlsp[i]=qlsp[i]*LSP_SCALE; | ||
261 | #endif | ||
262 | id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order); | ||
263 | speex_bits_pack(bits, id, 6); | ||
264 | |||
265 | for (i=0;i<order;i++) | ||
266 | qlsp[i]*=2; | ||
267 | |||
268 | id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5); | ||
269 | speex_bits_pack(bits, id, 6); | ||
270 | |||
271 | id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5); | ||
272 | speex_bits_pack(bits, id, 6); | ||
273 | |||
274 | #ifdef FIXED_POINT | ||
275 | for (i=0;i<order;i++) | ||
276 | qlsp[i] = PSHR16(qlsp[i],1); | ||
277 | #else | ||
278 | for (i=0;i<order;i++) | ||
279 | qlsp[i] = qlsp[i]*0.0019531; | ||
280 | #endif | ||
281 | |||
282 | for (i=0;i<order;i++) | ||
283 | qlsp[i]=lsp[i]-qlsp[i]; | ||
284 | } | ||
285 | #endif /* SPEEX_DISABLE_ENCODER */ | ||
286 | |||
287 | void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits) | ||
288 | { | ||
289 | int i, id; | ||
290 | for (i=0;i<order;i++) | ||
291 | lsp[i]=LSP_LINEAR(i); | ||
292 | |||
293 | |||
294 | id=speex_bits_unpack_unsigned(bits, 6); | ||
295 | for (i=0;i<10;i++) | ||
296 | lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]); | ||
297 | |||
298 | id=speex_bits_unpack_unsigned(bits, 6); | ||
299 | for (i=0;i<5;i++) | ||
300 | lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]); | ||
301 | |||
302 | id=speex_bits_unpack_unsigned(bits, 6); | ||
303 | for (i=0;i<5;i++) | ||
304 | lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]); | ||
305 | |||
306 | } | ||
307 | |||
308 | |||
309 | #ifdef DISABLE_WIDEBAND | ||
310 | void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) | ||
311 | { | ||
312 | speex_fatal("Wideband and Ultra-wideband are disabled"); | ||
313 | } | ||
314 | void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) | ||
315 | { | ||
316 | speex_fatal("Wideband and Ultra-wideband are disabled"); | ||
317 | } | ||
318 | #else | ||
319 | extern const signed char high_lsp_cdbk[]; | ||
320 | extern const signed char high_lsp_cdbk2[]; | ||
321 | |||
322 | |||
323 | #ifndef SPEEX_DISABLE_ENCODER | ||
324 | void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits) | ||
325 | { | ||
326 | int i; | ||
327 | int id; | ||
328 | spx_word16_t quant_weight[10]; | ||
329 | |||
330 | for (i=0;i<order;i++) | ||
331 | qlsp[i]=lsp[i]; | ||
332 | |||
333 | compute_quant_weights(qlsp, quant_weight, order); | ||
334 | |||
335 | /* quant_weight[0] = 10/(qlsp[1]-qlsp[0]); | ||
336 | quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]); | ||
337 | for (i=1;i<order-1;i++) | ||
338 | { | ||
339 | tmp1 = 10/(qlsp[i]-qlsp[i-1]); | ||
340 | tmp2 = 10/(qlsp[i+1]-qlsp[i]); | ||
341 | quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2; | ||
342 | }*/ | ||
343 | |||
344 | for (i=0;i<order;i++) | ||
345 | qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i)); | ||
346 | #ifndef FIXED_POINT | ||
347 | for (i=0;i<order;i++) | ||
348 | qlsp[i] = qlsp[i]*LSP_SCALE; | ||
349 | #endif | ||
350 | id = lsp_quant(qlsp, high_lsp_cdbk, 64, order); | ||
351 | speex_bits_pack(bits, id, 6); | ||
352 | |||
353 | for (i=0;i<order;i++) | ||
354 | qlsp[i]*=2; | ||
355 | |||
356 | id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order); | ||
357 | speex_bits_pack(bits, id, 6); | ||
358 | |||
359 | #ifdef FIXED_POINT | ||
360 | for (i=0;i<order;i++) | ||
361 | qlsp[i] = PSHR16(qlsp[i],1); | ||
362 | #else | ||
363 | for (i=0;i<order;i++) | ||
364 | qlsp[i] = qlsp[i]*0.0019531; | ||
365 | #endif | ||
366 | |||
367 | for (i=0;i<order;i++) | ||
368 | qlsp[i]=lsp[i]-qlsp[i]; | ||
369 | } | ||
370 | #endif /* SPEEX_DISABLE_ENCODER */ | ||
371 | |||
372 | void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits) | ||
373 | { | ||
374 | |||
375 | int i, id; | ||
376 | for (i=0;i<order;i++) | ||
377 | lsp[i]=LSP_LINEAR_HIGH(i); | ||
378 | |||
379 | |||
380 | id=speex_bits_unpack_unsigned(bits, 6); | ||
381 | for (i=0;i<order;i++) | ||
382 | lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]); | ||
383 | |||
384 | |||
385 | id=speex_bits_unpack_unsigned(bits, 6); | ||
386 | for (i=0;i<order;i++) | ||
387 | lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]); | ||
388 | } | ||
389 | |||
390 | #endif | ||
391 | |||