Remove unused tests from configure.ac
[speexdsp.git] / tmv / quant_lsp_tm.h
1 /* Copyright (C) 2007 Hong Zhiqian */\r
2 /**\r
3    @file quant_lsp_tm.h\r
4    @author Hong Zhiqian\r
5    @brief Various compatibility routines for Speex (TriMedia version)\r
6 */\r
7 /*\r
8    Redistribution and use in source and binary forms, with or without\r
9    modification, are permitted provided that the following conditions\r
10    are met:\r
11    \r
12    - Redistributions of source code must retain the above copyright\r
13    notice, this list of conditions and the following disclaimer.\r
14    \r
15    - Redistributions in binary form must reproduce the above copyright\r
16    notice, this list of conditions and the following disclaimer in the\r
17    documentation and/or other materials provided with the distribution.\r
18    \r
19    - Neither the name of the Xiph.org Foundation nor the names of its\r
20    contributors may be used to endorse or promote products derived from\r
21    this software without specific prior written permission.\r
22    \r
23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
24    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
26    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\r
27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
28    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
29    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
30    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
31    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
32    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
33    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
34 */\r
35 #include <ops/custom_defs.h>\r
36 #include "profile_tm.h"\r
37 \r
38 #ifdef FIXED_POINT\r
39 \r
40 #define OVERRIDE_COMPUTE_QUANT_WEIGHTS\r
41 static void compute_quant_weights(Int16 *qlsp, Int16 *qw, int order)\r
42 {\r
43         int             qlspi, qlspii;\r
44         int             w1, w2;\r
45         int             i;\r
46 \r
47         TMDEBUG_ALIGNMEM(qlsp);\r
48         TMDEBUG_ALIGNMEM(qw);\r
49 \r
50         COMPUTEQUANTWEIGHTS_START();\r
51 \r
52         --order;\r
53 \r
54         qlspi   = (int)qlsp[0]; \r
55         qlspii  = (int)qlsp[1];\r
56         w1              = qlspi;        \r
57         w2              = qlspii - qlspi;\r
58 \r
59         qw[0]   = 81920 / (300 + imin(w1,w2));\r
60 \r
61         for ( i=1 ; i<order ; ++i )\r
62         {       qlspi   = qlspii;\r
63                 qlspii  = qlsp[i+1];\r
64 \r
65                 w1 = w2;\r
66                 w2 = qlspii - qlspi;\r
67 \r
68                 qw[i] = 81920 / (300 + imin(w1,w2));\r
69         }\r
70 \r
71         w1 = LSP_PI - qlspii;\r
72         qw[i] = 81920 / (300 + imin(w1,w2));\r
73 \r
74         COMPUTEQUANTWEIGHTS_STOP();\r
75 }\r
76 \r
77 \r
78 \r
79 #define OVERRIDE_LSP_QUANT\r
80 static int lsp_quant(Int16 *x, const signed char *cdbk, int nbVec, int nbDim)\r
81 {\r
82         register int best_dist=VERY_LARGE32;\r
83         register int best_id=0;\r
84         register int i, j;\r
85         register int dt0, dt1, dt2, dt3;\r
86         register int cb0, cb1, cb2, cb3, xx;\r
87         register int ptr_inc = nbDim * 3;\r
88         register int five = 5;\r
89     const signed char *ptr;\r
90 \r
91         TMDEBUG_ALIGNMEM(x);\r
92 \r
93         LSPQUANT_START();\r
94 \r
95         for ( i=0, ptr=cdbk ; i<nbVec ; i+=4, ptr += ptr_inc )\r
96         {       dt3 = dt2 = dt1 = dt0 = 0;\r
97 \r
98                 for ( j=0 ; j <nbDim ; j += 2 )\r
99                 {\r
100                         xx        =  ld32x(x,j>>1);\r
101                         cb0       =  pack16lsb((int)ptr[1], (int)ptr[0]);\r
102                         cb0       =  dualasl(cb0,five);\r
103                         cb0       =  dspidualsub(xx,cb0);\r
104                         dt0       += ifir16(cb0,cb0);\r
105 \r
106                         cb1       =      pack16lsb((int)ptr[nbDim+1], (int)ptr[nbDim]);\r
107                         cb1       =  dualasl(cb1,five);\r
108                         cb1   =  dspidualsub(xx,cb1);\r
109                         dt1   += ifir16(cb1, cb1);\r
110 \r
111                         cb2       =      pack16lsb((int)ptr[nbDim*2+1], (int)ptr[nbDim*2]);\r
112                         cb2       =  dualasl(cb2,five);\r
113                         cb2       =  dspidualsub(xx,cb2);\r
114                         dt2   += ifir16(cb2, cb2);\r
115 \r
116                         cb3       =      pack16lsb((int)ptr[nbDim*3+1], (int)ptr[nbDim*3]);\r
117                         cb3       =  dualasl(cb3,five);\r
118                         cb3       =  dspidualsub(xx,cb3);\r
119                         dt3   += ifir16(cb3, cb3);\r
120 \r
121                         ptr += 2;\r
122                 }\r
123 \r
124                 if ( dt0<best_dist )\r
125                 {       best_dist       =       dt0;\r
126                         best_id         =       i;\r
127                 }\r
128 \r
129                 if ( dt1<best_dist )\r
130                 {       best_dist       =       dt1;\r
131                         best_id         =       i+1;\r
132                 }\r
133                 \r
134                 if ( dt2<best_dist )\r
135                 {       best_dist       =       dt2;\r
136                         best_id         =       i+2;\r
137                 }\r
138 \r
139                 if ( dt3<best_dist )\r
140                 {       best_dist       =       dt3;\r
141                         best_id         =       i+3;\r
142                 }\r
143         }\r
144 \r
145         for ( j=0,ptr=cdbk+best_id*nbDim ; j<nbDim ; j+=2 )\r
146         {       xx        =  ld32x(x,j>>1);\r
147                 cb0       =  pack16lsb((int)ptr[j+1], (int)ptr[j]);\r
148                 cb0       =  dualasl(cb0,five);\r
149                 dt0       =  dspidualsub(xx,cb0);\r
150                 st32d(j<<1, x, dt0);\r
151         }\r
152 \r
153         LSPQUANT_STOP();\r
154         return best_id;\r
155 }\r
156 \r
157 \r
158 #define OVERRIDE_LSP_WEIGHT_QUANT\r
159 static int lsp_weight_quant(Int16 *x, Int16 *weight, const signed char *cdbk, int nbVec, int nbDim)\r
160 {\r
161         register int best_dist=VERY_LARGE32;\r
162         register int best_id=0;\r
163         register int i, j;\r
164         register int dt1, dt2, dt3, dt4;\r
165         register int cb1, cb2, cb3, cb4, wt, xx;\r
166         register int ptr_inc = nbDim * 3;\r
167         const signed char *ptr;\r
168 \r
169         LSPWEIGHTQUANT_START();\r
170 \r
171         for ( i=0, ptr=cdbk ; i<nbVec ; i+=4, ptr += ptr_inc )\r
172         {       dt4 = dt3 = dt2 = dt1 = 0;\r
173                         \r
174                 for ( j=0 ; j<nbDim ; ++j )\r
175                 {       wt        =  weight[j];\r
176                         xx        =  x[j];\r
177 \r
178                         cb1       =  xx - (ptr[0]               << 5);\r
179                         cb2       =  xx - (ptr[nbDim]   << 5);\r
180                         cb3       =  xx - (ptr[nbDim*2] << 5);\r
181                         cb4       =  xx - (ptr[nbDim*3] << 5);\r
182 \r
183                         ++ptr;\r
184 \r
185                         cb1       *= cb1;\r
186                         cb2       *= cb2;\r
187                         cb3       *= cb3;\r
188                         cb4       *= cb4;\r
189 \r
190                         dt1 += (wt * (cb1 >> 15)) + ((wt * (cb1 & 0x7fff)) >> 15);\r
191                         dt2 += (wt * (cb2 >> 15)) + ((wt * (cb2 & 0x7fff)) >> 15);\r
192                         dt3 += (wt * (cb3 >> 15)) + ((wt * (cb3 & 0x7fff)) >> 15);\r
193                         dt4 += (wt * (cb4 >> 15)) + ((wt * (cb4 & 0x7fff)) >> 15);\r
194 \r
195                 }\r
196 \r
197                 if ( dt1<best_dist )\r
198                 {       best_dist       =       dt1;\r
199                         best_id         =       i;\r
200                 }\r
201 \r
202                 if ( dt2<best_dist )\r
203                 {       best_dist       =       dt2;\r
204                         best_id         =       i+1;\r
205                 }\r
206                 \r
207                 if ( dt3<best_dist )\r
208                 {       best_dist       =       dt3;\r
209                         best_id         =       i+2;\r
210                 }\r
211 \r
212                 if ( dt4<best_dist )\r
213                 {       best_dist       =       dt4;\r
214                         best_id         =       i+3;\r
215                 }\r
216         }\r
217 \r
218         for ( j=0 ; j<nbDim ; ++j )\r
219         {       x[j] = x[j] - ((Int16)cdbk[best_id*nbDim+j] << 5);\r
220         }\r
221 \r
222         LSPWEIGHTQUANT_STOP();\r
223 \r
224         return best_id;\r
225 }\r
226 \r
227 #if 0\r
228 // TODO: unroll loops\r
229 #define OVERRIDE_LSP_QUANT_NB\r
230 void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\r
231 {\r
232    int i;\r
233    int id;\r
234    spx_word16_t quant_weight[10];\r
235    \r
236    for (i=0;i<order;i++)\r
237       qlsp[i]=lsp[i];\r
238 \r
239    compute_quant_weights(qlsp, quant_weight, order);\r
240 \r
241    for (i=0;i<order;i++)\r
242       qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));\r
243 \r
244 #ifndef FIXED_POINT\r
245    for (i=0;i<order;i++)\r
246       qlsp[i] = LSP_SCALE*qlsp[i];\r
247 #endif\r
248    id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);\r
249    speex_bits_pack(bits, id, 6);\r
250 \r
251    for (i=0;i<order;i++)\r
252       qlsp[i]*=2;\r
253  \r
254    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);\r
255    speex_bits_pack(bits, id, 6);\r
256 \r
257    for (i=0;i<5;i++)\r
258       qlsp[i]*=2;\r
259 \r
260    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);\r
261    speex_bits_pack(bits, id, 6);\r
262 \r
263    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);\r
264    speex_bits_pack(bits, id, 6);\r
265 \r
266    for (i=5;i<10;i++)\r
267       qlsp[i]*=2;\r
268 \r
269    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);\r
270    speex_bits_pack(bits, id, 6);\r
271 \r
272 #ifdef FIXED_POINT\r
273    for (i=0;i<order;i++)\r
274       qlsp[i]=PSHR16(qlsp[i],2);\r
275 #else\r
276    for (i=0;i<order;i++)\r
277       qlsp[i]=qlsp[i] * .00097656;\r
278 #endif\r
279 \r
280    for (i=0;i<order;i++)\r
281       qlsp[i]=lsp[i]-qlsp[i];\r
282 }\r
283 \r
284 \r
285 #define OVERRIDE_LSP_UNQUANT_NB\r
286 void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)\r
287 {\r
288    int i, id;\r
289    for (i=0;i<order;i++)\r
290       lsp[i]=LSP_LINEAR(i);\r
291 \r
292    id=speex_bits_unpack_unsigned(bits, 6);\r
293    for (i=0;i<10;i++)\r
294       lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));\r
295 \r
296    id=speex_bits_unpack_unsigned(bits, 6);\r
297    for (i=0;i<5;i++)\r
298       lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));\r
299 \r
300    id=speex_bits_unpack_unsigned(bits, 6);\r
301    for (i=0;i<5;i++)\r
302       lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));\r
303 \r
304    id=speex_bits_unpack_unsigned(bits, 6);\r
305    for (i=0;i<5;i++)\r
306       lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));\r
307    \r
308    id=speex_bits_unpack_unsigned(bits, 6);\r
309    for (i=0;i<5;i++)\r
310       lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));\r
311 }\r
312 \r
313 #define OVERRIDE_LSP_QUANT_LBR\r
314 void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\r
315 {\r
316    int i;\r
317    int id;\r
318    spx_word16_t quant_weight[10];\r
319 \r
320    for (i=0;i<order;i++)\r
321       qlsp[i]=lsp[i];\r
322 \r
323    compute_quant_weights(qlsp, quant_weight, order);\r
324 \r
325    for (i=0;i<order;i++)\r
326       qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));\r
327 #ifndef FIXED_POINT\r
328    for (i=0;i<order;i++)\r
329       qlsp[i]=qlsp[i]*LSP_SCALE;\r
330 #endif\r
331    id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);\r
332    speex_bits_pack(bits, id, 6);\r
333    \r
334    for (i=0;i<order;i++)\r
335       qlsp[i]*=2;\r
336    \r
337    id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);\r
338    speex_bits_pack(bits, id, 6);\r
339 \r
340    id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);\r
341    speex_bits_pack(bits, id, 6);\r
342 \r
343 #ifdef FIXED_POINT\r
344    for (i=0;i<order;i++)\r
345       qlsp[i] = PSHR16(qlsp[i],1);\r
346 #else\r
347    for (i=0;i<order;i++)\r
348       qlsp[i] = qlsp[i]*0.0019531;\r
349 #endif\r
350 \r
351    for (i=0;i<order;i++)\r
352       qlsp[i]=lsp[i]-qlsp[i];\r
353 }\r
354 \r
355 #define OVERRIDE_LSP_UNQUANT_LBR\r
356 void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)\r
357 {\r
358    int i, id;\r
359    for (i=0;i<order;i++)\r
360       lsp[i]=LSP_LINEAR(i);\r
361 \r
362 \r
363    id=speex_bits_unpack_unsigned(bits, 6);\r
364    for (i=0;i<10;i++)\r
365       lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);\r
366 \r
367    id=speex_bits_unpack_unsigned(bits, 6);\r
368    for (i=0;i<5;i++)\r
369       lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);\r
370 \r
371    id=speex_bits_unpack_unsigned(bits, 6);\r
372    for (i=0;i<5;i++)\r
373       lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);\r
374    \r
375 }\r
376 \r
377 extern const signed char high_lsp_cdbk[];\r
378 extern const signed char high_lsp_cdbk2[];\r
379 \r
380 #define OVERRIDE_LSP_UNQUANT_HIGH\r
381 void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)\r
382 {\r
383 \r
384    int i, id;\r
385    for (i=0;i<order;i++)\r
386       lsp[i]=LSP_LINEAR_HIGH(i);\r
387 \r
388 \r
389    id=speex_bits_unpack_unsigned(bits, 6);\r
390    for (i=0;i<order;i++)\r
391       lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);\r
392 \r
393 \r
394    id=speex_bits_unpack_unsigned(bits, 6);\r
395    for (i=0;i<order;i++)\r
396       lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);\r
397 }\r
398 \r
399 #define OVERRIDE_LSP_QUANT_HIGH\r
400 void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)\r
401 {\r
402    int i;\r
403    int id;\r
404    spx_word16_t quant_weight[10];\r
405 \r
406    for (i=0;i<order;i++)\r
407       qlsp[i]=lsp[i];\r
408 \r
409    compute_quant_weights(qlsp, quant_weight, order);\r
410 \r
411    /*   quant_weight[0] = 10/(qlsp[1]-qlsp[0]);\r
412    quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);\r
413    for (i=1;i<order-1;i++)\r
414    {\r
415       tmp1 = 10/(qlsp[i]-qlsp[i-1]);\r
416       tmp2 = 10/(qlsp[i+1]-qlsp[i]);\r
417       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;\r
418       }*/\r
419 \r
420    for (i=0;i<order;i++)\r
421       qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));\r
422 #ifndef FIXED_POINT\r
423    for (i=0;i<order;i++)\r
424       qlsp[i] = qlsp[i]*LSP_SCALE;\r
425 #endif\r
426    id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);\r
427    speex_bits_pack(bits, id, 6);\r
428 \r
429    for (i=0;i<order;i++)\r
430       qlsp[i]*=2;\r
431 \r
432    id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);\r
433    speex_bits_pack(bits, id, 6);\r
434 \r
435 #ifdef FIXED_POINT\r
436    for (i=0;i<order;i++)\r
437       qlsp[i] = PSHR16(qlsp[i],1);\r
438 #else\r
439    for (i=0;i<order;i++)\r
440       qlsp[i] = qlsp[i]*0.0019531;\r
441 #endif\r
442 \r
443    for (i=0;i<order;i++)\r
444       qlsp[i]=lsp[i]-qlsp[i];\r
445 }\r
446 #endif\r
447 \r
448 #endif\r