1 /*
2 	synth_real.c: The functions for synthesizing real (float) 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 #include "sample.h"
11 #include "debug.h"
12 
13 #ifdef REAL_IS_FIXED
14 #error "Do not build this file with fixed point math!"
15 #else
16 /*
17 	Part 3: All synth functions that produce float output.
18 	What we need is just a special WRITE_SAMPLE. For the generic and i386 functions, that is.
19 	The optimized synths would need to be changed internally to support float output.
20 */
21 
22 #define SAMPLE_T real
23 #define WRITE_SAMPLE(samples,sum,clip) WRITE_REAL_SAMPLE(samples,sum,clip)
24 
25 /* Part 3a: All straight 1to1 decoding functions */
26 #define BLOCK 0x40 /* One decoding block is 64 samples. */
27 
28 #define SYNTH_NAME synth_1to1_real
29 #include "synth.h"
30 #undef SYNTH_NAME
31 
32 /* Mono-related synths; they wrap over _some_ synth_1to1_real (could be generic, could be i386). */
33 #define SYNTH_NAME       fr->synths.plain[r_1to1][f_real]
34 #define MONO_NAME        synth_1to1_real_mono
35 #define MONO2STEREO_NAME synth_1to1_real_m2s
36 #include "synth_mono.h"
37 #undef SYNTH_NAME
38 #undef MONO_NAME
39 #undef MONO2STEREO_NAME
40 
41 #ifdef OPT_X86
42 #define NO_AUTOINCREMENT
43 #define SYNTH_NAME synth_1to1_real_i386
44 #include "synth.h"
45 #undef SYNTH_NAME
46 /* i386 uses the normal mono functions. */
47 #undef NO_AUTOINCREMENT
48 #endif
49 
50 #undef BLOCK
51 
52 /* At least one optimized real decoder... */
53 #ifdef OPT_X86_64
54 /* Assembler routines. */
55 int synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);
56 int synth_1to1_real_s_x86_64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
57 void dct64_real_x86_64(real *out0, real *out1, real *samples);
58 /* Hull for C mpg123 API */
synth_1to1_real_x86_64(real * bandPtr,int channel,mpg123_handle * fr,int final)59 int synth_1to1_real_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
60 {
61 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
62 
63 	real *b0, **buf;
64 	int bo1;
65 #ifndef NO_EQUALIZER
66 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
67 #endif
68 	if(!channel)
69 	{
70 		fr->bo--;
71 		fr->bo &= 0xf;
72 		buf = fr->real_buffs[0];
73 	}
74 	else
75 	{
76 		samples++;
77 		buf = fr->real_buffs[1];
78 	}
79 
80 	if(fr->bo & 0x1)
81 	{
82 		b0 = buf[0];
83 		bo1 = fr->bo;
84 		dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
85 	}
86 	else
87 	{
88 		b0 = buf[1];
89 		bo1 = fr->bo+1;
90 		dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
91 	}
92 
93 	synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);
94 
95 	if(final) fr->buffer.fill += 256;
96 
97 	return 0;
98 }
99 
synth_1to1_real_stereo_x86_64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)100 int synth_1to1_real_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
101 {
102 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
103 
104 	real *b0l, *b0r, **bufl, **bufr;
105 	int bo1;
106 #ifndef NO_EQUALIZER
107 	if(fr->have_eq_settings)
108 	{
109 		do_equalizer(bandPtr_l,0,fr->equalizer);
110 		do_equalizer(bandPtr_r,1,fr->equalizer);
111 	}
112 #endif
113 	fr->bo--;
114 	fr->bo &= 0xf;
115 	bufl = fr->real_buffs[0];
116 	bufr = fr->real_buffs[1];
117 
118 	if(fr->bo & 0x1)
119 	{
120 		b0l = bufl[0];
121 		b0r = bufr[0];
122 		bo1 = fr->bo;
123 		dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
124 		dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
125 	}
126 	else
127 	{
128 		b0l = bufl[1];
129 		b0r = bufr[1];
130 		bo1 = fr->bo+1;
131 		dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
132 		dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
133 	}
134 
135 	synth_1to1_real_s_x86_64_asm(fr->decwin, b0l, b0r, samples, bo1);
136 
137 	fr->buffer.fill += 256;
138 
139 	return 0;
140 }
141 #endif
142 
143 #ifdef OPT_AVX
144 /* Assembler routines. */
145 #ifndef OPT_X86_64
146 int synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);
147 #endif
148 int synth_1to1_real_s_avx_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
149 void dct64_real_avx(real *out0, real *out1, real *samples);
150 /* Hull for C mpg123 API */
synth_1to1_real_avx(real * bandPtr,int channel,mpg123_handle * fr,int final)151 int synth_1to1_real_avx(real *bandPtr,int channel, mpg123_handle *fr, int final)
152 {
153 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
154 
155 	real *b0, **buf;
156 	int bo1;
157 #ifndef NO_EQUALIZER
158 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
159 #endif
160 	if(!channel)
161 	{
162 		fr->bo--;
163 		fr->bo &= 0xf;
164 		buf = fr->real_buffs[0];
165 	}
166 	else
167 	{
168 		samples++;
169 		buf = fr->real_buffs[1];
170 	}
171 
172 	if(fr->bo & 0x1)
173 	{
174 		b0 = buf[0];
175 		bo1 = fr->bo;
176 		dct64_real_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
177 	}
178 	else
179 	{
180 		b0 = buf[1];
181 		bo1 = fr->bo+1;
182 		dct64_real_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
183 	}
184 
185 	synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);
186 
187 	if(final) fr->buffer.fill += 256;
188 
189 	return 0;
190 }
191 
synth_1to1_fltst_avx(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)192 int synth_1to1_fltst_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
193 {
194 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
195 
196 	real *b0l, *b0r, **bufl, **bufr;
197 	int bo1;
198 #ifndef NO_EQUALIZER
199 	if(fr->have_eq_settings)
200 	{
201 		do_equalizer(bandPtr_l,0,fr->equalizer);
202 		do_equalizer(bandPtr_r,1,fr->equalizer);
203 	}
204 #endif
205 	fr->bo--;
206 	fr->bo &= 0xf;
207 	bufl = fr->real_buffs[0];
208 	bufr = fr->real_buffs[1];
209 
210 	if(fr->bo & 0x1)
211 	{
212 		b0l = bufl[0];
213 		b0r = bufr[0];
214 		bo1 = fr->bo;
215 		dct64_real_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
216 		dct64_real_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
217 	}
218 	else
219 	{
220 		b0l = bufl[1];
221 		b0r = bufr[1];
222 		bo1 = fr->bo+1;
223 		dct64_real_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
224 		dct64_real_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
225 	}
226 
227 	synth_1to1_real_s_avx_asm(fr->decwin, b0l, b0r, samples, bo1);
228 
229 	fr->buffer.fill += 256;
230 
231 	return 0;
232 }
233 #endif
234 
235 #if defined(OPT_SSE) || defined(OPT_SSE_VINTAGE)
236 /* Assembler routines. */
237 int synth_1to1_real_sse_asm(real *window, real *b0, real *samples, int bo1);
238 int synth_1to1_real_s_sse_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
239 void dct64_real_sse(real *out0, real *out1, real *samples);
240 /* Hull for C mpg123 API */
synth_1to1_real_sse(real * bandPtr,int channel,mpg123_handle * fr,int final)241 int synth_1to1_real_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)
242 {
243 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
244 
245 	real *b0, **buf;
246 	int bo1;
247 #ifndef NO_EQUALIZER
248 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
249 #endif
250 	if(!channel)
251 	{
252 		fr->bo--;
253 		fr->bo &= 0xf;
254 		buf = fr->real_buffs[0];
255 	}
256 	else
257 	{
258 		samples++;
259 		buf = fr->real_buffs[1];
260 	}
261 
262 	if(fr->bo & 0x1)
263 	{
264 		b0 = buf[0];
265 		bo1 = fr->bo;
266 		dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
267 	}
268 	else
269 	{
270 		b0 = buf[1];
271 		bo1 = fr->bo+1;
272 		dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
273 	}
274 
275 	synth_1to1_real_sse_asm(fr->decwin, b0, samples, bo1);
276 
277 	if(final) fr->buffer.fill += 256;
278 
279 	return 0;
280 }
281 
synth_1to1_real_stereo_sse(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)282 int synth_1to1_real_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
283 {
284 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
285 
286 	real *b0l, *b0r, **bufl, **bufr;
287 	int bo1;
288 #ifndef NO_EQUALIZER
289 	if(fr->have_eq_settings)
290 	{
291 		do_equalizer(bandPtr_l,0,fr->equalizer);
292 		do_equalizer(bandPtr_r,1,fr->equalizer);
293 	}
294 #endif
295 	fr->bo--;
296 	fr->bo &= 0xf;
297 	bufl = fr->real_buffs[0];
298 	bufr = fr->real_buffs[1];
299 
300 	if(fr->bo & 0x1)
301 	{
302 		b0l = bufl[0];
303 		b0r = bufr[0];
304 		bo1 = fr->bo;
305 		dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
306 		dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
307 	}
308 	else
309 	{
310 		b0l = bufl[1];
311 		b0r = bufr[1];
312 		bo1 = fr->bo+1;
313 		dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
314 		dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
315 	}
316 
317 	synth_1to1_real_s_sse_asm(fr->decwin, b0l, b0r, samples, bo1);
318 
319 	fr->buffer.fill += 256;
320 
321 	return 0;
322 }
323 #endif
324 
325 #ifdef OPT_NEON
326 /* Assembler routines. */
327 int synth_1to1_real_neon_asm(real *window, real *b0, real *samples, int bo1);
328 int synth_1to1_real_s_neon_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
329 void dct64_real_neon(real *out0, real *out1, real *samples);
330 /* Hull for C mpg123 API */
synth_1to1_real_neon(real * bandPtr,int channel,mpg123_handle * fr,int final)331 int synth_1to1_real_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
332 {
333 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
334 
335 	real *b0, **buf;
336 	int bo1;
337 #ifndef NO_EQUALIZER
338 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
339 #endif
340 	if(!channel)
341 	{
342 		fr->bo--;
343 		fr->bo &= 0xf;
344 		buf = fr->real_buffs[0];
345 	}
346 	else
347 	{
348 		samples++;
349 		buf = fr->real_buffs[1];
350 	}
351 
352 	if(fr->bo & 0x1)
353 	{
354 		b0 = buf[0];
355 		bo1 = fr->bo;
356 		dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
357 	}
358 	else
359 	{
360 		b0 = buf[1];
361 		bo1 = fr->bo+1;
362 		dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
363 	}
364 
365 	synth_1to1_real_neon_asm(fr->decwin, b0, samples, bo1);
366 
367 	if(final) fr->buffer.fill += 256;
368 
369 	return 0;
370 }
synth_1to1_real_stereo_neon(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)371 int synth_1to1_real_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
372 {
373 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
374 
375 	real *b0l, *b0r, **bufl, **bufr;
376 	int bo1;
377 #ifndef NO_EQUALIZER
378 	if(fr->have_eq_settings)
379 	{
380 		do_equalizer(bandPtr_l,0,fr->equalizer);
381 		do_equalizer(bandPtr_r,1,fr->equalizer);
382 	}
383 #endif
384 	fr->bo--;
385 	fr->bo &= 0xf;
386 	bufl = fr->real_buffs[0];
387 	bufr = fr->real_buffs[1];
388 
389 	if(fr->bo & 0x1)
390 	{
391 		b0l = bufl[0];
392 		b0r = bufr[0];
393 		bo1 = fr->bo;
394 		dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
395 		dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
396 	}
397 	else
398 	{
399 		b0l = bufl[1];
400 		b0r = bufr[1];
401 		bo1 = fr->bo+1;
402 		dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
403 		dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
404 	}
405 
406 	synth_1to1_real_s_neon_asm(fr->decwin, b0l, b0r, samples, bo1);
407 
408 	fr->buffer.fill += 256;
409 
410 	return 0;
411 }
412 #endif
413 
414 #ifdef OPT_NEON64
415 /* Assembler routines. */
416 int synth_1to1_real_neon64_asm(real *window, real *b0, real *samples, int bo1);
417 int synth_1to1_real_s_neon64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
418 void dct64_real_neon64(real *out0, real *out1, real *samples);
419 /* Hull for C mpg123 API */
synth_1to1_real_neon64(real * bandPtr,int channel,mpg123_handle * fr,int final)420 int synth_1to1_real_neon64(real *bandPtr,int channel, mpg123_handle *fr, int final)
421 {
422 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
423 
424 	real *b0, **buf;
425 	int bo1;
426 #ifndef NO_EQUALIZER
427 	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
428 #endif
429 	if(!channel)
430 	{
431 		fr->bo--;
432 		fr->bo &= 0xf;
433 		buf = fr->real_buffs[0];
434 	}
435 	else
436 	{
437 		samples++;
438 		buf = fr->real_buffs[1];
439 	}
440 
441 	if(fr->bo & 0x1)
442 	{
443 		b0 = buf[0];
444 		bo1 = fr->bo;
445 		dct64_real_neon64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
446 	}
447 	else
448 	{
449 		b0 = buf[1];
450 		bo1 = fr->bo+1;
451 		dct64_real_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
452 	}
453 
454 	synth_1to1_real_neon64_asm(fr->decwin, b0, samples, bo1);
455 
456 	if(final) fr->buffer.fill += 256;
457 
458 	return 0;
459 }
synth_1to1_fltst_neon64(real * bandPtr_l,real * bandPtr_r,mpg123_handle * fr)460 int synth_1to1_fltst_neon64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
461 {
462 	real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
463 
464 	real *b0l, *b0r, **bufl, **bufr;
465 	int bo1;
466 #ifndef NO_EQUALIZER
467 	if(fr->have_eq_settings)
468 	{
469 		do_equalizer(bandPtr_l,0,fr->equalizer);
470 		do_equalizer(bandPtr_r,1,fr->equalizer);
471 	}
472 #endif
473 	fr->bo--;
474 	fr->bo &= 0xf;
475 	bufl = fr->real_buffs[0];
476 	bufr = fr->real_buffs[1];
477 
478 	if(fr->bo & 0x1)
479 	{
480 		b0l = bufl[0];
481 		b0r = bufr[0];
482 		bo1 = fr->bo;
483 		dct64_real_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
484 		dct64_real_neon64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
485 	}
486 	else
487 	{
488 		b0l = bufl[1];
489 		b0r = bufr[1];
490 		bo1 = fr->bo+1;
491 		dct64_real_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
492 		dct64_real_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
493 	}
494 
495 	synth_1to1_real_s_neon64_asm(fr->decwin, b0l, b0r, samples, bo1);
496 
497 	fr->buffer.fill += 256;
498 
499 	return 0;
500 }
501 #endif
502 
503 #ifndef NO_DOWNSAMPLE
504 
505 /*
506 	Part 3b: 2to1 synth. Only generic and i386.
507 */
508 #define BLOCK 0x20 /* One decoding block is 32 samples. */
509 
510 #define SYNTH_NAME synth_2to1_real
511 #include "synth.h"
512 #undef SYNTH_NAME
513 
514 /* Mono-related synths; they wrap over _some_ synth_2to1_real (could be generic, could be i386). */
515 #define SYNTH_NAME       fr->synths.plain[r_2to1][f_real]
516 #define MONO_NAME        synth_2to1_real_mono
517 #define MONO2STEREO_NAME synth_2to1_real_m2s
518 #include "synth_mono.h"
519 #undef SYNTH_NAME
520 #undef MONO_NAME
521 #undef MONO2STEREO_NAME
522 
523 #ifdef OPT_X86
524 #define NO_AUTOINCREMENT
525 #define SYNTH_NAME synth_2to1_real_i386
526 #include "synth.h"
527 #undef SYNTH_NAME
528 /* i386 uses the normal mono functions. */
529 #undef NO_AUTOINCREMENT
530 #endif
531 
532 #undef BLOCK
533 
534 /*
535 	Part 3c: 4to1 synth. Only generic and i386.
536 */
537 #define BLOCK 0x10 /* One decoding block is 16 samples. */
538 
539 #define SYNTH_NAME synth_4to1_real
540 #include "synth.h"
541 #undef SYNTH_NAME
542 
543 /* Mono-related synths; they wrap over _some_ synth_4to1_real (could be generic, could be i386). */
544 #define SYNTH_NAME       fr->synths.plain[r_4to1][f_real]
545 #define MONO_NAME        synth_4to1_real_mono
546 #define MONO2STEREO_NAME synth_4to1_real_m2s
547 #include "synth_mono.h"
548 #undef SYNTH_NAME
549 #undef MONO_NAME
550 #undef MONO2STEREO_NAME
551 
552 #ifdef OPT_X86
553 #define NO_AUTOINCREMENT
554 #define SYNTH_NAME synth_4to1_real_i386
555 #include "synth.h"
556 #undef SYNTH_NAME
557 /* i386 uses the normal mono functions. */
558 #undef NO_AUTOINCREMENT
559 #endif
560 
561 #undef BLOCK
562 
563 #endif /* NO_DOWNSAMPLE */
564 
565 #ifndef NO_NTOM
566 /*
567 	Part 3d: ntom synth.
568 	Same procedure as above... Just no extra play anymore, straight synth that may use an optimized dct64.
569 */
570 
571 /* These are all in one header, there's no flexibility to gain. */
572 #define SYNTH_NAME       synth_ntom_real
573 #define MONO_NAME        synth_ntom_real_mono
574 #define MONO2STEREO_NAME synth_ntom_real_m2s
575 #include "synth_ntom.h"
576 #undef SYNTH_NAME
577 #undef MONO_NAME
578 #undef MONO2STEREO_NAME
579 
580 #endif
581 
582 #undef SAMPLE_T
583 #undef WRITE_SAMPLE
584 
585 #endif /* non-fixed type */
586