Do not produce additional space after 'to the picture above'
[kugel-rb.git] / apps / codecs / libspeex / quant_lsp.c
blob9b9104c842aadc10d510c4f59716fc8088c01f6a
1 /* Copyright (C) 2002 Jean-Marc Valin
2 File: quant_lsp.c
3 LSP vector quantization
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
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.
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.
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.
33 #ifdef HAVE_CONFIG_H
34 #include "config-speex.h"
35 #endif
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
44 #include "arch.h"
46 #ifdef BFIN_ASM
47 #include "quant_lsp_bfin.h"
48 #endif
50 #ifdef FIXED_POINT
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
59 #else
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
69 #endif
71 #ifndef SPEEX_DISABLE_ENCODER
72 static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)
74 int i;
75 spx_word16_t tmp1, tmp2;
76 for (i=0;i<order;i++)
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
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)
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++)
109 dist=0;
110 for (j=0;j<nbDim;j++)
112 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
113 dist=MAC16_16(dist,tmp,tmp);
115 if (dist<best_dist)
117 best_dist=dist;
118 best_id=i;
122 for (j=0;j<nbDim;j++)
123 x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
125 return best_id;
127 #endif
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)
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++)
141 dist=0;
142 for (j=0;j<nbDim;j++)
144 tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
145 dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));
147 if (dist<best_dist)
149 best_dist=dist;
150 best_id=i;
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;
158 #endif
160 void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
162 int i;
163 int id;
164 spx_word16_t quant_weight[10];
166 for (i=0;i<order;i++)
167 qlsp[i]=lsp[i];
169 compute_quant_weights(qlsp, quant_weight, order);
171 for (i=0;i<order;i++)
172 qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
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);
181 for (i=0;i<order;i++)
182 qlsp[i]*=2;
184 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
185 speex_bits_pack(bits, id, 6);
187 for (i=0;i<5;i++)
188 qlsp[i]*=2;
190 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
191 speex_bits_pack(bits, id, 6);
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);
196 for (i=5;i<10;i++)
197 qlsp[i]*=2;
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);
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
210 for (i=0;i<order;i++)
211 qlsp[i]=lsp[i]-qlsp[i];
213 #endif /* SPEEX_DISABLE_ENCODER */
215 void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
217 int i, id;
218 for (i=0;i<order;i++)
219 lsp[i]=LSP_LINEAR(i);
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]));
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]));
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]));
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]));
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]));
244 #ifndef SPEEX_DISABLE_ENCODER
245 void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
247 int i;
248 int id;
249 spx_word16_t quant_weight[10];
251 for (i=0;i<order;i++)
252 qlsp[i]=lsp[i];
254 compute_quant_weights(qlsp, quant_weight, order);
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);
265 for (i=0;i<order;i++)
266 qlsp[i]*=2;
268 id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
269 speex_bits_pack(bits, id, 6);
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);
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
282 for (i=0;i<order;i++)
283 qlsp[i]=lsp[i]-qlsp[i];
285 #endif /* SPEEX_DISABLE_ENCODER */
287 void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
289 int i, id;
290 for (i=0;i<order;i++)
291 lsp[i]=LSP_LINEAR(i);
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]);
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]);
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]);
309 #ifdef DISABLE_WIDEBAND
310 void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
312 speex_fatal("Wideband and Ultra-wideband are disabled");
314 void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
316 speex_fatal("Wideband and Ultra-wideband are disabled");
318 #else
319 extern const signed char high_lsp_cdbk[];
320 extern const signed char high_lsp_cdbk2[];
323 #ifndef SPEEX_DISABLE_ENCODER
324 void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
326 int i;
327 int id;
328 spx_word16_t quant_weight[10];
330 for (i=0;i<order;i++)
331 qlsp[i]=lsp[i];
333 compute_quant_weights(qlsp, quant_weight, order);
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++)
339 tmp1 = 10/(qlsp[i]-qlsp[i-1]);
340 tmp2 = 10/(qlsp[i+1]-qlsp[i]);
341 quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
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);
353 for (i=0;i<order;i++)
354 qlsp[i]*=2;
356 id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
357 speex_bits_pack(bits, id, 6);
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
367 for (i=0;i<order;i++)
368 qlsp[i]=lsp[i]-qlsp[i];
370 #endif /* SPEEX_DISABLE_ENCODER */
372 void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
375 int i, id;
376 for (i=0;i<order;i++)
377 lsp[i]=LSP_LINEAR_HIGH(i);
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]);
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]);
390 #endif