1 /*
2 	synth.c: The functions for synthesizing samples, at the end of decoding.
crypto_verify(const unsigned char * x,const unsigned char * y)3 
4 	copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
5 	see COPYING and AUTHORS files in distribution or http://mpg123.org
6 	initially written by Michael Hipp, heavily dissected and rearranged by Thomas Orgis
7 */
8 
9 #include "mpg123lib_intern.h"
10 #ifdef OPT_GENERIC_DITHER
11 #define FORCE_ACCURATE
12 #endif
13 #include "sample.h"
14 #include "debug.h"
15 
16 /*
17 	Part 1: All synth functions that produce signed short.
18 	That is:
19 		- synth_1to1 with cpu-specific variants (synth_1to1_i386, synth_1to1_i586 ...)
20 		- synth_1to1_mono and synth_1to1_m2s; which use fr->synths.plain[r_1to1][f_16].
21 	Nearly every decoder variant has it's own synth_1to1, while the mono conversion is shared.
22 */
23 
24 #define SAMPLE_T short
25 #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
26 
27 /* Part 1a: All straight 1to1 decoding functions */
28 #define BLOCK 0x40 /* One decoding block is 64 samples. */
29 
30 #define SYNTH_NAME synth_1to1
31 #include "synth.h"
32 #undef SYNTH_NAME
33 
34 /* Mono-related synths; they wrap over _some_ synth_1to1. */
35 #define SYNTH_NAME       fr->synths.plain[r_1to1][f_16]
36 #define MONO_NAME        synth_1to1_mono
37 #define MONO2STEREO_NAME synth_1to1_m2s
38 #include "synth_mono.h"
39 #undef SYNTH_NAME
40 #undef MONO_NAME
41 #undef MONO2STEREO_NAME
42 
43 /* Now we have possibly some special synth_1to1 ...
44    ... they produce signed short; the mono functions defined above work on the special synths, too. */
45 
46 #ifdef OPT_GENERIC_DITHER
47 #define SYNTH_NAME synth_1to1_dither
48 /* We need the accurate sample writing... */
49 #undef WRITE_SAMPLE
50 #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip)
51 
52 #define USE_DITHER
53 #include "synth.h"
54 #undef USE_DITHER
55 #undef SYNTH_NAME
56 
57 #undef WRITE_SAMPLE
58 #define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
59 
60 #endif
61 
62 #ifdef OPT_X86
63 /* The i386-specific C code, here as short variant, later 8bit and float. */
64 #define NO_AUTOINCREMENT
65 #define SYNTH_NAME synth_1to1_i386
66 #include "synth.h"
67 #undef SYNTH_NAME
68 /* i386 uses the normal mono functions. */
69 #undef NO_AUTOINCREMENT
70 #endif
71 
72 #undef BLOCK /* Following functions are so special that they don't need this. */
73 
74 #ifdef OPT_I586
75 /* This is defined in assembler. */
76 int synth_1to1_i586_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
77 /* This is just a hull to use the mpg123 handle. */
78 int synth_1to1_i586(real *bandPtr, int channel, mpg123_handle *fr, int final)
79 {
80 	int ret;
81 #ifndef NO_EQUALIZER
82 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
83 #endif
84 	ret = synth_1to1_i586_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
85 	if(final) fr->buffer.fill += 128;
86 	return ret;
87 }
88 #endif
89 
90 #ifdef OPT_I586_DITHER
91 /* This is defined in assembler. */
92 int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin, float *dithernoise);
93 /* This is just a hull to use the mpg123 handle. */
94 int synth_1to1_i586_dither(real *bandPtr, int channel, mpg123_handle *fr, int final)
95 {
96 	int ret;
97 	int bo_dither[2]; /* Temporary workaround? Could expand the asm code. */
98 #ifndef NO_EQUALIZER
99 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
100 #endif
101 	/* Applying this hack, to change the asm only bit by bit (adding dithernoise pointer). */
102 	bo_dither[0] = fr->bo;
103 	bo_dither[1] = fr->ditherindex;
104 	ret = synth_1to1_i586_asm_dither(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, bo_dither, fr->decwin, fr->dithernoise);
105 	fr->bo          = bo_dither[0];
106 	fr->ditherindex = bo_dither[1];
107 
108 	if(final) fr->buffer.fill += 128;
109 	return ret;
110 }
111 #endif
112 
113 #if defined(OPT_3DNOW) || defined(OPT_3DNOW_VINTAGE)
114 /* Those are defined in assembler. */
115 void do_equalizer_3dnow(real *bandPtr,int channel, real equalizer[2][32]);
116 int synth_1to1_3dnow_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
117 /* This is just a hull to use the mpg123 handle. */
118 int synth_1to1_3dnow(real *bandPtr, int channel, mpg123_handle *fr, int final)
119 {
120 	int ret;
121 #ifndef NO_EQUALIZER
122 	if(fr->have_eq_settings) do_equalizer_3dnow(bandPtr,channel,fr->equalizer);
123 #endif
124 	/* this is in asm, can be dither or not */
125 	/* uh, is this return from pointer correct? */
126 	ret = (int) synth_1to1_3dnow_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
127 	if(final) fr->buffer.fill += 128;
128 	return ret;
129 }
130 #endif
131 
132 #ifdef OPT_MMX
133 /* This is defined in assembler. */
134 int synth_1to1_MMX(real *bandPtr, int channel, short *out, short *buffs, int *bo, float *decwins);
135 /* This is just a hull to use the mpg123 handle. */
136 int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
137 {
138 #ifndef NO_EQUALIZER
139 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
140 #endif
141 	/* in asm */
142 	synth_1to1_MMX(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
143 	if(final) fr->buffer.fill += 128;
144 	return 0;
145 }
146 #endif
147 
148 #if defined(OPT_SSE) || defined(OPT_SSE_VINTAGE)
149 #ifdef ACCURATE_ROUNDING
150 /* This is defined in assembler. */
151 int synth_1to1_sse_accurate_asm(real *window, real *b0, short *samples, int bo1);
152 int synth_1to1_s_sse_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
153 void dct64_real_sse(real *out0, real *out1, real *samples);
154 /* This is just a hull to use the mpg123 handle. */
155 int synth_1to1_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)
156 {
157 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
158 	real *b0, **buf;
159 	int clip;
160 	int bo1;
161 #ifndef NO_EQUALIZER
162 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
163 #endif
164 	if(!channel)
165 	{
166 		fr->bo--;
167 		fr->bo &= 0xf;
168 		buf = fr->real_buffs[0];
169 	}
170 	else
171 	{
172 		samples++;
173 		buf = fr->real_buffs[1];
174 	}
175 
176 	if(fr->bo & 0x1)
177 	{
178 		b0 = buf[0];
179 		bo1 = fr->bo;
180 		dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
181 	}
182 	else
183 	{
184 		b0 = buf[1];
185 		bo1 = fr->bo+1;
186 		dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
187 	}
188 
189 	clip = synth_1to1_sse_accurate_asm(fr->decwin, b0, samples, bo1);
190 
191 	if(final) fr->buffer.fill += 128;
192 
193 	return clip;
194 }
195 
196 int synth_1to1_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
197 {
198 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
199 
200 	real *b0l, *b0r, **bufl, **bufr;
201 	int bo1;
202 	int clip;
203 #ifndef NO_EQUALIZER
204 	if(fr->have_eq_settings)
205 	{
206 		do_equalizer(bandPtr_l,0,fr->equalizer);
207 		do_equalizer(bandPtr_r,1,fr->equalizer);
208 	}
209 #endif
210 	fr->bo--;
211 	fr->bo &= 0xf;
212 	bufl = fr->real_buffs[0];
213 	bufr = fr->real_buffs[1];
214 
215 	if(fr->bo & 0x1)
216 	{
217 		b0l = bufl[0];
218 		b0r = bufr[0];
219 		bo1 = fr->bo;
220 		dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
221 		dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
222 	}
223 	else
224 	{
225 		b0l = bufl[1];
226 		b0r = bufr[1];
227 		bo1 = fr->bo+1;
228 		dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
229 		dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
230 	}
231 
232 	clip = synth_1to1_s_sse_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
233 
234 	fr->buffer.fill += 128;
235 
236 	return clip;
237 }
238 #else
239 /* This is defined in assembler. */
240 void synth_1to1_sse_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
241 /* This is just a hull to use the mpg123 handle. */
242 int synth_1to1_sse(real *bandPtr, int channel, mpg123_handle *fr, int final)
243 {
244 #ifndef NO_EQUALIZER
245 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
246 #endif
247 	synth_1to1_sse_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
248 	if(final) fr->buffer.fill += 128;
249 	return 0;
250 }
251 #endif
252 #endif
253 
254 #if defined(OPT_3DNOWEXT) || defined(OPT_3DNOWEXT_VINTAGE)
255 /* This is defined in assembler. */
256 void synth_1to1_3dnowext_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
257 /* This is just a hull to use the mpg123 handle. */
258 int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final)
259 {
260 #ifndef NO_EQUALIZER
261 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
262 #endif
263 	synth_1to1_3dnowext_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
264 	if(final) fr->buffer.fill += 128;
265 	return 0;
266 }
267 #endif
268 
269 #ifdef OPT_X86_64
270 #ifdef ACCURATE_ROUNDING
271 /* Assembler routines. */
272 int synth_1to1_x86_64_accurate_asm(real *window, real *b0, short *samples, int bo1);
273 int synth_1to1_s_x86_64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
274 void dct64_real_x86_64(real *out0, real *out1, real *samples);
275 /* Hull for C mpg123 API */
276 int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
277 {
278 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
279 
280 	real *b0, **buf;
281 	int bo1;
282 	int clip;
283 #ifndef NO_EQUALIZER
284 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
285 #endif
286 	if(!channel)
287 	{
288 		fr->bo--;
289 		fr->bo &= 0xf;
290 		buf = fr->real_buffs[0];
291 	}
292 	else
293 	{
294 		samples++;
295 		buf = fr->real_buffs[1];
296 	}
297 
298 	if(fr->bo & 0x1)
299 	{
300 		b0 = buf[0];
301 		bo1 = fr->bo;
302 		dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
303 	}
304 	else
305 	{
306 		b0 = buf[1];
307 		bo1 = fr->bo+1;
308 		dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
309 	}
310 
311 	clip = synth_1to1_x86_64_accurate_asm(fr->decwin, b0, samples, bo1);
312 
313 	if(final) fr->buffer.fill += 128;
314 
315 	return clip;
316 }
317 
318 int synth_1to1_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
319 {
320 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
321 
322 	real *b0l, *b0r, **bufl, **bufr;
323 	int bo1;
324 	int clip;
325 #ifndef NO_EQUALIZER
326 	if(fr->have_eq_settings)
327 	{
328 		do_equalizer(bandPtr_l,0,fr->equalizer);
329 		do_equalizer(bandPtr_r,1,fr->equalizer);
330 	}
331 #endif
332 	fr->bo--;
333 	fr->bo &= 0xf;
334 	bufl = fr->real_buffs[0];
335 	bufr = fr->real_buffs[1];
336 
337 	if(fr->bo & 0x1)
338 	{
339 		b0l = bufl[0];
340 		b0r = bufr[0];
341 		bo1 = fr->bo;
342 		dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
343 		dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
344 	}
345 	else
346 	{
347 		b0l = bufl[1];
348 		b0r = bufr[1];
349 		bo1 = fr->bo+1;
350 		dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
351 		dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
352 	}
353 
354 	clip = synth_1to1_s_x86_64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
355 
356 	fr->buffer.fill += 128;
357 
358 	return clip;
359 }
360 #else
361 /* This is defined in assembler. */
362 int synth_1to1_x86_64_asm(short *window, short *b0, short *samples, int bo1);
363 int synth_1to1_s_x86_64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
364 void dct64_x86_64(short *out0, short *out1, real *samples);
365 /* This is just a hull to use the mpg123 handle. */
366 int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
367 {
368 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
369 	short *b0, **buf;
370 	int clip;
371 	int bo1;
372 #ifndef NO_EQUALIZER
373 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
374 #endif
375 	if(!channel)
376 	{
377 		fr->bo--;
378 		fr->bo &= 0xf;
379 		buf = fr->short_buffs[0];
380 	}
381 	else
382 	{
383 		samples++;
384 		buf = fr->short_buffs[1];
385 	}
386 
387 	if(fr->bo & 0x1)
388 	{
389 		b0 = buf[0];
390 		bo1 = fr->bo;
391 		dct64_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
392 	}
393 	else
394 	{
395 		b0 = buf[1];
396 		bo1 = fr->bo+1;
397 		dct64_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
398 	}
399 
400 	clip = synth_1to1_x86_64_asm((short *)fr->decwins, b0, samples, bo1);
401 
402 	if(final) fr->buffer.fill += 128;
403 
404 	return clip;
405 }
406 
407 int synth_1to1_stereo_x86_64(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
408 {
409 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
410 	short *b0l, *b0r, **bufl, **bufr;
411 	int clip;
412 	int bo1;
413 #ifndef NO_EQUALIZER
414 	if(fr->have_eq_settings)
415 	{
416 		do_equalizer(bandPtr_l,0,fr->equalizer);
417 		do_equalizer(bandPtr_r,1,fr->equalizer);
418 	}
419 #endif
420 	fr->bo--;
421 	fr->bo &= 0xf;
422 	bufl = fr->short_buffs[0];
423 	bufr = fr->short_buffs[1];
424 
425 	if(fr->bo & 0x1)
426 	{
427 		b0l = bufl[0];
428 		b0r = bufr[0];
429 		bo1 = fr->bo;
430 		dct64_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
431 		dct64_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
432 	}
433 	else
434 	{
435 		b0l = bufl[1];
436 		b0r = bufr[1];
437 		bo1 = fr->bo+1;
438 		dct64_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
439 		dct64_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
440 	}
441 
442 	clip = synth_1to1_s_x86_64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
443 
444 	fr->buffer.fill += 128;
445 
446 	return clip;
447 }
448 #endif
449 #endif
450 
451 #ifdef OPT_AVX
452 #ifdef ACCURATE_ROUNDING
453 /* Assembler routines. */
454 #ifndef OPT_X86_64
455 int synth_1to1_x86_64_accurate_asm(real *window, real *b0, short *samples, int bo1);
456 #endif
457 int synth_1to1_s_avx_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
458 void dct64_real_avx(real *out0, real *out1, real *samples);
459 /* Hull for C mpg123 API */
460 int synth_1to1_avx(real *bandPtr,int channel, mpg123_handle *fr, int final)
461 {
462 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
463 
464 	real *b0, **buf;
465 	int bo1;
466 	int clip;
467 #ifndef NO_EQUALIZER
468 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
469 #endif
470 	if(!channel)
471 	{
472 		fr->bo--;
473 		fr->bo &= 0xf;
474 		buf = fr->real_buffs[0];
475 	}
476 	else
477 	{
478 		samples++;
479 		buf = fr->real_buffs[1];
480 	}
481 
482 	if(fr->bo & 0x1)
483 	{
484 		b0 = buf[0];
485 		bo1 = fr->bo;
486 		dct64_real_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
487 	}
488 	else
489 	{
490 		b0 = buf[1];
491 		bo1 = fr->bo+1;
492 		dct64_real_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
493 	}
494 
495 	clip = synth_1to1_x86_64_accurate_asm(fr->decwin, b0, samples, bo1);
496 
497 	if(final) fr->buffer.fill += 128;
498 
499 	return clip;
500 }
501 
502 int synth_1to1_stereo_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
503 {
504 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
505 
506 	real *b0l, *b0r, **bufl, **bufr;
507 	int bo1;
508 	int clip;
509 #ifndef NO_EQUALIZER
510 	if(fr->have_eq_settings)
511 	{
512 		do_equalizer(bandPtr_l,0,fr->equalizer);
513 		do_equalizer(bandPtr_r,1,fr->equalizer);
514 	}
515 #endif
516 	fr->bo--;
517 	fr->bo &= 0xf;
518 	bufl = fr->real_buffs[0];
519 	bufr = fr->real_buffs[1];
520 
521 	if(fr->bo & 0x1)
522 	{
523 		b0l = bufl[0];
524 		b0r = bufr[0];
525 		bo1 = fr->bo;
526 		dct64_real_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
527 		dct64_real_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
528 	}
529 	else
530 	{
531 		b0l = bufl[1];
532 		b0r = bufr[1];
533 		bo1 = fr->bo+1;
534 		dct64_real_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
535 		dct64_real_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
536 	}
537 
538 	clip = synth_1to1_s_avx_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
539 
540 	fr->buffer.fill += 128;
541 
542 	return clip;
543 }
544 #else
545 /* This is defined in assembler. */
546 #ifndef OPT_X86_64
547 int synth_1to1_x86_64_asm(short *window, short *b0, short *samples, int bo1);
548 #endif
549 int synth_1to1_s_avx_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
550 void dct64_avx(short *out0, short *out1, real *samples);
551 /* This is just a hull to use the mpg123 handle. */
552 int synth_1to1_avx(real *bandPtr,int channel, mpg123_handle *fr, int final)
553 {
554 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
555 	short *b0, **buf;
556 	int clip;
557 	int bo1;
558 #ifndef NO_EQUALIZER
559 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
560 #endif
561 	if(!channel)
562 	{
563 		fr->bo--;
564 		fr->bo &= 0xf;
565 		buf = fr->short_buffs[0];
566 	}
567 	else
568 	{
569 		samples++;
570 		buf = fr->short_buffs[1];
571 	}
572 
573 	if(fr->bo & 0x1)
574 	{
575 		b0 = buf[0];
576 		bo1 = fr->bo;
577 		dct64_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
578 	}
579 	else
580 	{
581 		b0 = buf[1];
582 		bo1 = fr->bo+1;
583 		dct64_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
584 	}
585 
586 	clip = synth_1to1_x86_64_asm((short *)fr->decwins, b0, samples, bo1);
587 
588 	if(final) fr->buffer.fill += 128;
589 
590 	return clip;
591 }
592 
593 int synth_1to1_stereo_avx(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
594 {
595 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
596 	short *b0l, *b0r, **bufl, **bufr;
597 	int clip;
598 	int bo1;
599 #ifndef NO_EQUALIZER
600 	if(fr->have_eq_settings)
601 	{
602 		do_equalizer(bandPtr_l,0,fr->equalizer);
603 		do_equalizer(bandPtr_r,1,fr->equalizer);
604 	}
605 #endif
606 	fr->bo--;
607 	fr->bo &= 0xf;
608 	bufl = fr->short_buffs[0];
609 	bufr = fr->short_buffs[1];
610 
611 	if(fr->bo & 0x1)
612 	{
613 		b0l = bufl[0];
614 		b0r = bufr[0];
615 		bo1 = fr->bo;
616 		dct64_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
617 		dct64_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
618 	}
619 	else
620 	{
621 		b0l = bufl[1];
622 		b0r = bufr[1];
623 		bo1 = fr->bo+1;
624 		dct64_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
625 		dct64_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
626 	}
627 
628 	clip = synth_1to1_s_avx_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
629 
630 	fr->buffer.fill += 128;
631 
632 	return clip;
633 }
634 #endif
635 #endif
636 
637 #ifdef OPT_ARM
638 #ifdef ACCURATE_ROUNDING
639 /* Assembler routines. */
640 int synth_1to1_arm_accurate_asm(real *window, real *b0, short *samples, int bo1);
641 /* Hull for C mpg123 API */
642 int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
643 {
644 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
645 
646 	real *b0, **buf;
647 	int bo1;
648 	int clip;
649 #ifndef NO_EQUALIZER
650 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
651 #endif
652 	if(!channel)
653 	{
654 		fr->bo--;
655 		fr->bo &= 0xf;
656 		buf = fr->real_buffs[0];
657 	}
658 	else
659 	{
660 		samples++;
661 		buf = fr->real_buffs[1];
662 	}
663 
664 	if(fr->bo & 0x1)
665 	{
666 		b0 = buf[0];
667 		bo1 = fr->bo;
668 		dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
669 	}
670 	else
671 	{
672 		b0 = buf[1];
673 		bo1 = fr->bo+1;
674 		dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
675 	}
676 
677 	clip = synth_1to1_arm_accurate_asm(fr->decwin, b0, samples, bo1);
678 
679 	if(final) fr->buffer.fill += 128;
680 
681 	return clip;
682 }
683 #else
684 /* Assembler routines. */
685 int synth_1to1_arm_asm(real *window, real *b0, short *samples, int bo1);
686 /* Hull for C mpg123 API */
687 int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
688 {
689 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
690 
691 	real *b0, **buf;
692 	int bo1;
693 	int clip;
694 #ifndef NO_EQUALIZER
695 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
696 #endif
697 	if(!channel)
698 	{
699 		fr->bo--;
700 		fr->bo &= 0xf;
701 		buf = fr->real_buffs[0];
702 	}
703 	else
704 	{
705 		samples++;
706 		buf = fr->real_buffs[1];
707 	}
708 
709 	if(fr->bo & 0x1)
710 	{
711 		b0 = buf[0];
712 		bo1 = fr->bo;
713 		dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
714 	}
715 	else
716 	{
717 		b0 = buf[1];
718 		bo1 = fr->bo+1;
719 		dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
720 	}
721 
722 	clip = synth_1to1_arm_asm(fr->decwin, b0, samples, bo1);
723 
724 	if(final) fr->buffer.fill += 128;
725 
726 	return clip;
727 }
728 #endif
729 #endif
730 
731 #ifdef OPT_NEON
732 #ifdef ACCURATE_ROUNDING
733 /* This is defined in assembler. */
734 int synth_1to1_neon_accurate_asm(real *window, real *b0, short *samples, int bo1);
735 int synth_1to1_s_neon_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
736 void dct64_real_neon(real *out0, real *out1, real *samples);
737 /* Hull for C mpg123 API */
738 int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
739 {
740 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
741 
742 	real *b0, **buf;
743 	int bo1;
744 	int clip;
745 #ifndef NO_EQUALIZER
746 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
747 #endif
748 	if(!channel)
749 	{
750 		fr->bo--;
751 		fr->bo &= 0xf;
752 		buf = fr->real_buffs[0];
753 	}
754 	else
755 	{
756 		samples++;
757 		buf = fr->real_buffs[1];
758 	}
759 
760 	if(fr->bo & 0x1)
761 	{
762 		b0 = buf[0];
763 		bo1 = fr->bo;
764 		dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
765 	}
766 	else
767 	{
768 		b0 = buf[1];
769 		bo1 = fr->bo+1;
770 		dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
771 	}
772 
773 	clip = synth_1to1_neon_accurate_asm(fr->decwin, b0, samples, bo1);
774 
775 	if(final) fr->buffer.fill += 128;
776 
777 	return clip;
778 }
779 
780 int synth_1to1_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
781 {
782 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
783 
784 	real *b0l, *b0r, **bufl, **bufr;
785 	int bo1;
786 	int clip;
787 #ifndef NO_EQUALIZER
788 	if(fr->have_eq_settings)
789 	{
790 		do_equalizer(bandPtr_l,0,fr->equalizer);
791 		do_equalizer(bandPtr_r,1,fr->equalizer);
792 	}
793 #endif
794 	fr->bo--;
795 	fr->bo &= 0xf;
796 	bufl = fr->real_buffs[0];
797 	bufr = fr->real_buffs[1];
798 
799 	if(fr->bo & 0x1)
800 	{
801 		b0l = bufl[0];
802 		b0r = bufr[0];
803 		bo1 = fr->bo;
804 		dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
805 		dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
806 	}
807 	else
808 	{
809 		b0l = bufl[1];
810 		b0r = bufr[1];
811 		bo1 = fr->bo+1;
812 		dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
813 		dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
814 	}
815 
816 	clip = synth_1to1_s_neon_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
817 
818 	fr->buffer.fill += 128;
819 
820 	return clip;
821 }
822 #else
823 /* This is defined in assembler. */
824 int synth_1to1_neon_asm(short *window, short *b0, short *samples, int bo1);
825 int synth_1to1_s_neon_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
826 void dct64_neon(short *out0, short *out1, real *samples);
827 /* Hull for C mpg123 API */
828 int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
829 {
830 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
831 	short *b0, **buf;
832 	int clip;
833 	int bo1;
834 #ifndef NO_EQUALIZER
835 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
836 #endif
837 	if(!channel)
838 	{
839 		fr->bo--;
840 		fr->bo &= 0xf;
841 		buf = fr->short_buffs[0];
842 	}
843 	else
844 	{
845 		samples++;
846 		buf = fr->short_buffs[1];
847 	}
848 
849 	if(fr->bo & 0x1)
850 	{
851 		b0 = buf[0];
852 		bo1 = fr->bo;
853 		dct64_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
854 	}
855 	else
856 	{
857 		b0 = buf[1];
858 		bo1 = fr->bo+1;
859 		dct64_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
860 	}
861 
862 	clip = synth_1to1_neon_asm((short *)fr->decwins, b0, samples, bo1);
863 
864 	if(final) fr->buffer.fill += 128;
865 
866 	return clip;
867 }
868 
869 int synth_1to1_stereo_neon(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
870 {
871 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
872 	short *b0l, *b0r, **bufl, **bufr;
873 	int clip;
874 	int bo1;
875 #ifndef NO_EQUALIZER
876 	if(fr->have_eq_settings)
877 	{
878 		do_equalizer(bandPtr_l,0,fr->equalizer);
879 		do_equalizer(bandPtr_r,1,fr->equalizer);
880 	}
881 #endif
882 	fr->bo--;
883 	fr->bo &= 0xf;
884 	bufl = fr->short_buffs[0];
885 	bufr = fr->short_buffs[1];
886 
887 	if(fr->bo & 0x1)
888 	{
889 		b0l = bufl[0];
890 		b0r = bufr[0];
891 		bo1 = fr->bo;
892 		dct64_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
893 		dct64_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
894 	}
895 	else
896 	{
897 		b0l = bufl[1];
898 		b0r = bufr[1];
899 		bo1 = fr->bo+1;
900 		dct64_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
901 		dct64_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
902 	}
903 
904 	clip = synth_1to1_s_neon_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
905 
906 	fr->buffer.fill += 128;
907 
908 	return clip;
909 }
910 #endif
911 #endif
912 
913 #ifdef OPT_NEON64
914 #ifdef ACCURATE_ROUNDING
915 /* This is defined in assembler. */
916 int synth_1to1_neon64_accurate_asm(real *window, real *b0, short *samples, int bo1);
917 int synth_1to1_s_neon64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
918 void dct64_real_neon64(real *out0, real *out1, real *samples);
919 /* Hull for C mpg123 API */
920 int synth_1to1_neon64(real *bandPtr,int channel, mpg123_handle *fr, int final)
921 {
922 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
923 
924 	real *b0, **buf;
925 	int bo1;
926 	int clip;
927 #ifndef NO_EQUALIZER
928 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
929 #endif
930 	if(!channel)
931 	{
932 		fr->bo--;
933 		fr->bo &= 0xf;
934 		buf = fr->real_buffs[0];
935 	}
936 	else
937 	{
938 		samples++;
939 		buf = fr->real_buffs[1];
940 	}
941 
942 	if(fr->bo & 0x1)
943 	{
944 		b0 = buf[0];
945 		bo1 = fr->bo;
946 		dct64_real_neon64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
947 	}
948 	else
949 	{
950 		b0 = buf[1];
951 		bo1 = fr->bo+1;
952 		dct64_real_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
953 	}
954 
955 	clip = synth_1to1_neon64_accurate_asm(fr->decwin, b0, samples, bo1);
956 
957 	if(final) fr->buffer.fill += 128;
958 
959 	return clip;
960 }
961 
962 int synth_1to1_stereo_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
963 {
964 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
965 
966 	real *b0l, *b0r, **bufl, **bufr;
967 	int bo1;
968 	int clip;
969 #ifndef NO_EQUALIZER
970 	if(fr->have_eq_settings)
971 	{
972 		do_equalizer(bandPtr_l,0,fr->equalizer);
973 		do_equalizer(bandPtr_r,1,fr->equalizer);
974 	}
975 #endif
976 	fr->bo--;
977 	fr->bo &= 0xf;
978 	bufl = fr->real_buffs[0];
979 	bufr = fr->real_buffs[1];
980 
981 	if(fr->bo & 0x1)
982 	{
983 		b0l = bufl[0];
984 		b0r = bufr[0];
985 		bo1 = fr->bo;
986 		dct64_real_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
987 		dct64_real_neon64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
988 	}
989 	else
990 	{
991 		b0l = bufl[1];
992 		b0r = bufr[1];
993 		bo1 = fr->bo+1;
994 		dct64_real_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
995 		dct64_real_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
996 	}
997 
998 	clip = synth_1to1_s_neon64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
999 
1000 	fr->buffer.fill += 128;
1001 
1002 	return clip;
1003 }
1004 #else
1005 /* This is defined in assembler. */
1006 int synth_1to1_neon64_asm(short *window, short *b0, short *samples, int bo1);
1007 int synth_1to1_s_neon64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
1008 void dct64_neon64(short *out0, short *out1, real *samples);
1009 /* Hull for C mpg123 API */
1010 int synth_1to1_neon64(real *bandPtr,int channel, mpg123_handle *fr, int final)
1011 {
1012 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
1013 	short *b0, **buf;
1014 	int clip;
1015 	int bo1;
1016 #ifndef NO_EQUALIZER
1017 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
1018 #endif
1019 	if(!channel)
1020 	{
1021 		fr->bo--;
1022 		fr->bo &= 0xf;
1023 		buf = fr->short_buffs[0];
1024 	}
1025 	else
1026 	{
1027 		samples++;
1028 		buf = fr->short_buffs[1];
1029 	}
1030 
1031 	if(fr->bo & 0x1)
1032 	{
1033 		b0 = buf[0];
1034 		bo1 = fr->bo;
1035 		dct64_neon64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
1036 	}
1037 	else
1038 	{
1039 		b0 = buf[1];
1040 		bo1 = fr->bo+1;
1041 		dct64_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
1042 	}
1043 
1044 	clip = synth_1to1_neon64_asm((short *)fr->decwins, b0, samples, bo1);
1045 
1046 	if(final) fr->buffer.fill += 128;
1047 
1048 	return clip;
1049 }
1050 
1051 int synth_1to1_stereo_neon64(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
1052 {
1053 	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
1054 	short *b0l, *b0r, **bufl, **bufr;
1055 	int clip;
1056 	int bo1;
1057 #ifndef NO_EQUALIZER
1058 	if(fr->have_eq_settings)
1059 	{
1060 		do_equalizer(bandPtr_l,0,fr->equalizer);
1061 		do_equalizer(bandPtr_r,1,fr->equalizer);
1062 	}
1063 #endif
1064 	fr->bo--;
1065 	fr->bo &= 0xf;
1066 	bufl = fr->short_buffs[0];
1067 	bufr = fr->short_buffs[1];
1068 
1069 	if(fr->bo & 0x1)
1070 	{
1071 		b0l = bufl[0];
1072 		b0r = bufr[0];
1073 		bo1 = fr->bo;
1074 		dct64_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
1075 		dct64_neon64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
1076 	}
1077 	else
1078 	{
1079 		b0l = bufl[1];
1080 		b0r = bufr[1];
1081 		bo1 = fr->bo+1;
1082 		dct64_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
1083 		dct64_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
1084 	}
1085 
1086 	clip = synth_1to1_s_neon64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
1087 
1088 	fr->buffer.fill += 128;
1089 
1090 	return clip;
1091 }
1092 #endif
1093 #endif
1094 
1095 #ifndef NO_DOWNSAMPLE
1096 
1097 /*
1098 	Part 1b: 2to1 synth.
1099 	Only generic and i386 functions this time.
1100 */
1101 #define BLOCK 0x20 /* One decoding block is 32 samples. */
1102 
1103 #define SYNTH_NAME synth_2to1
1104 #include "synth.h"
1105 #undef SYNTH_NAME
1106 
1107 #ifdef OPT_DITHER /* Used for generic_dither and as fallback for i586_dither. */
1108 #define SYNTH_NAME synth_2to1_dither
1109 #define USE_DITHER
1110 #include "synth.h"
1111 #undef USE_DITHER
1112 #undef SYNTH_NAME
1113 #endif
1114 
1115 #define SYNTH_NAME       fr->synths.plain[r_2to1][f_16]
1116 #define MONO_NAME        synth_2to1_mono
1117 #define MONO2STEREO_NAME synth_2to1_m2s
1118 #include "synth_mono.h"
1119 #undef SYNTH_NAME
1120 #undef MONO_NAME
1121 #undef MONO2STEREO_NAME
1122 
1123 #ifdef OPT_X86
1124 #define NO_AUTOINCREMENT
1125 #define SYNTH_NAME synth_2to1_i386
1126 #include "synth.h"
1127 #undef SYNTH_NAME
1128 /* i386 uses the normal mono functions. */
1129 #undef NO_AUTOINCREMENT
1130 #endif
1131 
1132 #undef BLOCK
1133 
1134 /*
1135 	Part 1c: 4to1 synth.
1136 	Same procedure as above...
1137 */
1138 #define BLOCK 0x10 /* One decoding block is 16 samples. */
1139 
1140 #define SYNTH_NAME synth_4to1
1141 #include "synth.h"
1142 #undef SYNTH_NAME
1143 
1144 #ifdef OPT_DITHER
1145 #define SYNTH_NAME synth_4to1_dither
1146 #define USE_DITHER
1147 #include "synth.h"
1148 #undef USE_DITHER
1149 #undef SYNTH_NAME
1150 #endif
1151 
1152 #define SYNTH_NAME       fr->synths.plain[r_4to1][f_16] /* This is just for the _i386 one... gotta check if it is really useful... */
1153 #define MONO_NAME        synth_4to1_mono
1154 #define MONO2STEREO_NAME synth_4to1_m2s
1155 #include "synth_mono.h"
1156 #undef SYNTH_NAME
1157 #undef MONO_NAME
1158 #undef MONO2STEREO_NAME
1159 
1160 #ifdef OPT_X86
1161 #define NO_AUTOINCREMENT
1162 #define SYNTH_NAME synth_4to1_i386
1163 #include "synth.h"
1164 #undef SYNTH_NAME
1165 /* i386 uses the normal mono functions. */
1166 #undef NO_AUTOINCREMENT
1167 #endif
1168 
1169 #undef BLOCK
1170 
1171 #endif /* NO_DOWNSAMPLE */
1172 
1173 #ifndef NO_NTOM
1174 /*
1175 	Part 1d: ntom synth.
1176 	Same procedure as above... Just no extra play anymore, straight synth that uses the plain dct64.
1177 */
1178 
1179 /* These are all in one header, there's no flexibility to gain. */
1180 #define SYNTH_NAME       synth_ntom
1181 #define MONO_NAME        synth_ntom_mono
1182 #define MONO2STEREO_NAME synth_ntom_m2s
1183 #include "synth_ntom.h"
1184 #undef SYNTH_NAME
1185 #undef MONO_NAME
1186 #undef MONO2STEREO_NAME
1187 
1188 #endif
1189 
1190 /* Done with short output. */
1191 #undef SAMPLE_T
1192 #undef WRITE_SAMPLE
1193