summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspeex/quant_lsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/quant_lsp.c')
-rw-r--r--lib/rbcodec/codecs/libspeex/quant_lsp.c391
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
72static 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
99static 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
131static 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
160void 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
215void 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
245void 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
287void 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
310void 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}
314void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
315{
316 speex_fatal("Wideband and Ultra-wideband are disabled");
317}
318#else
319extern const signed char high_lsp_cdbk[];
320extern const signed char high_lsp_cdbk2[];
321
322
323#ifndef SPEEX_DISABLE_ENCODER
324void 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
372void 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