1 /*
2 synth.c: The functions for synthesizing samples, at the end of decoding.
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. */
synth_1to1_i586(real * bandPtr,int channel,mpg123_handle * fr,int final)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. */
synth_1to1_i586_dither(real * bandPtr,int channel,mpg123_handle * fr,int final)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. */
synth_1to1_3dnow(real * bandPtr,int channel,mpg123_handle * fr,int final)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. */
synth_1to1_mmx(real * bandPtr,int channel,mpg123_handle * fr,int final)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. */
synth_1to1_sse(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_sse(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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. */
synth_1to1_sse(real * bandPtr,int channel,mpg123_handle * fr,int final)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. */
synth_1to1_3dnowext(real * bandPtr,int channel,mpg123_handle * fr,int final)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 */
synth_1to1_x86_64(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_x86_64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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. */
synth_1to1_x86_64(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_x86_64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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 */
synth_1to1_avx(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_avx(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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. */
synth_1to1_avx(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_avx(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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 */
synth_1to1_arm(real * bandPtr,int channel,mpg123_handle * fr,int final)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 */
synth_1to1_arm(real * bandPtr,int channel,mpg123_handle * fr,int final)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 */
synth_1to1_neon(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_neon(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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 */
synth_1to1_neon(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_neon(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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 */
synth_1to1_neon64(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_neon64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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 */
synth_1to1_neon64(real * bandPtr,int channel,mpg123_handle * fr,int final)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
synth_1to1_stereo_neon64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)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