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.h"
35 #endif
36
37 #include "quant_lsp.h"
38 #include <math.h>
39 #ifndef M_PI
40 #define M_PI 3.14159265358979323846
41 #endif
42
43
44 #include "misc.h"
45
46 #ifdef FIXED_POINT
47
48 #define LSP_LINEAR(i) (SHL16(i+1,11))
49 #define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144))
50 #define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5))
51 #define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4))
52 #define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3))
53 #define LSP_PI 25736
54
55 #else
56
57 #define LSP_LINEAR(i) (.25*(i)+.25)
58 #define LSP_LINEAR_HIGH(i) (.3125*(i)+.75)
59 #define LSP_SCALE 256.
60 #define LSP_DIV_256(x) (0.0039062*(x))
61 #define LSP_DIV_512(x) (0.0019531*(x))
62 #define LSP_DIV_1024(x) (0.00097656*(x))
63 #define LSP_PI M_PI
64
65 #endif
66
compute_quant_weights(spx_lsp_t * qlsp,spx_word16_t * quant_weight,int order)67 static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)
68 {
69 int i;
70 spx_word16_t tmp1, tmp2;
71 for (i=0;i<order;i++)
72 {
73 if (i==0)
74 tmp1 = qlsp[i];
75 else
76 tmp1 = qlsp[i]-qlsp[i-1];
77 if (i==order-1)
78 tmp2 = LSP_PI-qlsp[i];
79 else
80 tmp2 = qlsp[i+1]-qlsp[i];
81 if (tmp2<tmp1)
82 tmp1 = tmp2;
83 #ifdef FIXED_POINT
84 quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1));
85 #else
86 quant_weight[i] = 10/(.04+tmp1);
87 #endif
88 }
89
90 }
91
92 /* Note: x is modified*/
lsp_quant(spx_word16_t * x,const signed char * cdbk,int nbVec,int nbDim)93 static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim)
94 {
95 int i,j;
96 spx_word32_t dist;
97 spx_word16_t tmp;
98 spx_word32_t best_dist=0;
99 int best_id=0;
100 const signed char *ptr=cdbk;
101 for (i=0;i<nbVec;i++)
102 {
103 dist=0;
104 for (j=0;j<nbDim;j++)
105 {
106 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
107 dist=MAC16_16(dist,tmp,tmp);
108 }
109 if (dist<best_dist || i==0)
110 {
111 best_dist=dist;
112 best_id=i;
113 }
114 }
115
116 for (j=0;j<nbDim;j++)
117 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
118
119 return best_id;
120 }
121
122 /* Note: x is modified*/
lsp_weight_quant(spx_word16_t * x,spx_word16_t * weight,const signed char * cdbk,int nbVec,int nbDim)123 static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim)
124 {
125 int i,j;
126 spx_word32_t dist;
127 spx_word16_t tmp;
128 spx_word32_t best_dist=0;
129 int best_id=0;
130 const signed char *ptr=cdbk;
131 for (i=0;i<nbVec;i++)
132 {
133 dist=0;
134 for (j=0;j<nbDim;j++)
135 {
136 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
137 dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));
138 }
139 if (dist<best_dist || i==0)
140 {
141 best_dist=dist;
142 best_id=i;
143 }
144 }
145
146 for (j=0;j<nbDim;j++)
147 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
148 return best_id;
149 }
150
151
lsp_quant_nb(spx_lsp_t * lsp,spx_lsp_t * qlsp,int order,SpeexBits * bits)152 void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
153 {
154 int i;
155 int id;
156 spx_word16_t quant_weight[10];
157
158 for (i=0;i<order;i++)
159 qlsp[i]=lsp[i];
160
161 compute_quant_weights(qlsp, quant_weight, order);
162
163 for (i=0;i<order;i++)
164 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
165
166 #ifndef FIXED_POINT
167 for (i=0;i<order;i++)
168 qlsp[i] = LSP_SCALE*qlsp[i];
169 #endif
170 id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
171 speex_bits_pack(bits, id, 6);
172
173 for (i=0;i<order;i++)
174 qlsp[i]*=2;
175
176 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
177 speex_bits_pack(bits, id, 6);
178
179 for (i=0;i<5;i++)
180 qlsp[i]*=2;
181
182 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
183 speex_bits_pack(bits, id, 6);
184
185 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
186 speex_bits_pack(bits, id, 6);
187
188 for (i=5;i<10;i++)
189 qlsp[i]*=2;
190
191 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
192 speex_bits_pack(bits, id, 6);
193
194 #ifdef FIXED_POINT
195 for (i=0;i<order;i++)
196 qlsp[i]=PSHR16(qlsp[i],2);
197 #else
198 for (i=0;i<order;i++)
199 qlsp[i]=qlsp[i] * .00097656;
200 #endif
201
202 for (i=0;i<order;i++)
203 qlsp[i]=lsp[i]-qlsp[i];
204 }
205
lsp_unquant_nb(spx_lsp_t * lsp,int order,SpeexBits * bits)206 void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
207 {
208 int i, id;
209 for (i=0;i<order;i++)
210 lsp[i]=LSP_LINEAR(i);
211
212
213 id=speex_bits_unpack_unsigned(bits, 6);
214 for (i=0;i<10;i++)
215 lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));
216
217 id=speex_bits_unpack_unsigned(bits, 6);
218 for (i=0;i<5;i++)
219 lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));
220
221 id=speex_bits_unpack_unsigned(bits, 6);
222 for (i=0;i<5;i++)
223 lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));
224
225 id=speex_bits_unpack_unsigned(bits, 6);
226 for (i=0;i<5;i++)
227 lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));
228
229 id=speex_bits_unpack_unsigned(bits, 6);
230 for (i=0;i<5;i++)
231 lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));
232 }
233
234
lsp_quant_lbr(spx_lsp_t * lsp,spx_lsp_t * qlsp,int order,SpeexBits * bits)235 void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
236 {
237 int i;
238 int id;
239 spx_word16_t quant_weight[10];
240
241 for (i=0;i<order;i++)
242 qlsp[i]=lsp[i];
243
244 compute_quant_weights(qlsp, quant_weight, order);
245
246 for (i=0;i<order;i++)
247 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
248 #ifndef FIXED_POINT
249 for (i=0;i<order;i++)
250 qlsp[i]=qlsp[i]*LSP_SCALE;
251 #endif
252 id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
253 speex_bits_pack(bits, id, 6);
254
255 for (i=0;i<order;i++)
256 qlsp[i]*=2;
257
258 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
259 speex_bits_pack(bits, id, 6);
260
261 id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
262 speex_bits_pack(bits, id, 6);
263
264 #ifdef FIXED_POINT
265 for (i=0;i<order;i++)
266 qlsp[i] = PSHR16(qlsp[i],1);
267 #else
268 for (i=0;i<order;i++)
269 qlsp[i] = qlsp[i]*0.0019531;
270 #endif
271
272 for (i=0;i<order;i++)
273 qlsp[i]=lsp[i]-qlsp[i];
274 }
275
lsp_unquant_lbr(spx_lsp_t * lsp,int order,SpeexBits * bits)276 void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
277 {
278 int i, id;
279 for (i=0;i<order;i++)
280 lsp[i]=LSP_LINEAR(i);
281
282
283 id=speex_bits_unpack_unsigned(bits, 6);
284 for (i=0;i<10;i++)
285 lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);
286
287 id=speex_bits_unpack_unsigned(bits, 6);
288 for (i=0;i<5;i++)
289 lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);
290
291 id=speex_bits_unpack_unsigned(bits, 6);
292 for (i=0;i<5;i++)
293 lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);
294
295 }
296
297
298 #ifdef DISABLE_WIDEBAND
lsp_quant_high(spx_lsp_t * lsp,spx_lsp_t * qlsp,int order,SpeexBits * bits)299 void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
300 {
301 speex_error("Wideband and Ultra-wideband are disabled");
302 }
lsp_unquant_high(spx_lsp_t * lsp,int order,SpeexBits * bits)303 void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
304 {
305 speex_error("Wideband and Ultra-wideband are disabled");
306 }
307 #else
308 extern const signed char high_lsp_cdbk[];
309 extern const signed char high_lsp_cdbk2[];
310
311
lsp_quant_high(spx_lsp_t * lsp,spx_lsp_t * qlsp,int order,SpeexBits * bits)312 void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
313 {
314 int i;
315 int id;
316 spx_word16_t quant_weight[10];
317
318 for (i=0;i<order;i++)
319 qlsp[i]=lsp[i];
320
321 compute_quant_weights(qlsp, quant_weight, order);
322
323 /* quant_weight[0] = 10/(qlsp[1]-qlsp[0]);
324 quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);
325 for (i=1;i<order-1;i++)
326 {
327 tmp1 = 10/(qlsp[i]-qlsp[i-1]);
328 tmp2 = 10/(qlsp[i+1]-qlsp[i]);
329 quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
330 }*/
331
332 for (i=0;i<order;i++)
333 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));
334 #ifndef FIXED_POINT
335 for (i=0;i<order;i++)
336 qlsp[i] = qlsp[i]*LSP_SCALE;
337 #endif
338 id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
339 speex_bits_pack(bits, id, 6);
340
341 for (i=0;i<order;i++)
342 qlsp[i]*=2;
343
344 id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
345 speex_bits_pack(bits, id, 6);
346
347 #ifdef FIXED_POINT
348 for (i=0;i<order;i++)
349 qlsp[i] = PSHR16(qlsp[i],1);
350 #else
351 for (i=0;i<order;i++)
352 qlsp[i] = qlsp[i]*0.0019531;
353 #endif
354
355 for (i=0;i<order;i++)
356 qlsp[i]=lsp[i]-qlsp[i];
357 }
358
lsp_unquant_high(spx_lsp_t * lsp,int order,SpeexBits * bits)359 void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
360 {
361
362 int i, id;
363 for (i=0;i<order;i++)
364 lsp[i]=LSP_LINEAR_HIGH(i);
365
366
367 id=speex_bits_unpack_unsigned(bits, 6);
368 for (i=0;i<order;i++)
369 lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);
370
371
372 id=speex_bits_unpack_unsigned(bits, 6);
373 for (i=0;i<order;i++)
374 lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);
375 }
376
377 #endif
378
379
380 #ifdef EPIC_48K
381
382 extern const signed char cdbk_lsp_vlbr[5120];
383 extern const signed char cdbk_lsp2_vlbr[160];
384
lsp_quant_48k(spx_lsp_t * lsp,spx_lsp_t * qlsp,int order,SpeexBits * bits)385 void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
386 {
387 int i;
388 int id;
389 spx_word16_t quant_weight[10];
390
391 for (i=0;i<order;i++)
392 qlsp[i]=lsp[i];
393
394 compute_quant_weights(qlsp, quant_weight, order);
395
396 for (i=0;i<order;i++)
397 qlsp[i]=SUB16(qlsp[i],LSP_SCALING*(.25*i+.3125));
398 #ifndef FIXED_POINT
399 for (i=0;i<order;i++)
400 qlsp[i] = qlsp[i]*LSP_SCALE;
401 #endif
402
403 id = lsp_quant(qlsp, cdbk_lsp_vlbr, 512, order);
404 speex_bits_pack(bits, id, 9);
405
406 for (i=0;i<order;i++)
407 qlsp[i]*=4;
408
409 id = lsp_weight_quant(qlsp, quant_weight, cdbk_lsp2_vlbr, 16, 10);
410 speex_bits_pack(bits, id, 4);
411
412 #ifdef FIXED_POINT
413 for (i=0;i<order;i++)
414 qlsp[i]=PSHR(qlsp[i],2);
415 #else
416 for (i=0;i<order;i++)
417 qlsp[i]=qlsp[i]*0.00097655;
418 #endif
419
420 for (i=0;i<order;i++)
421 qlsp[i]=lsp[i]-qlsp[i];
422 }
423
lsp_unquant_48k(spx_lsp_t * lsp,int order,SpeexBits * bits)424 void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits)
425 {
426 int i, id;
427 for (i=0;i<order;i++)
428 lsp[i]=LSP_SCALING*(.25*i+.3125);
429
430
431 id=speex_bits_unpack_unsigned(bits, 9);
432 for (i=0;i<10;i++)
433 lsp[i] += LSP_SCALING*0.0039062*cdbk_lsp_vlbr[id*10+i];
434
435 id=speex_bits_unpack_unsigned(bits, 4);
436 for (i=0;i<10;i++)
437 lsp[i] += LSP_SCALING*0.00097655*cdbk_lsp2_vlbr[id*10+i];
438
439 }
440
441 #endif
442