ReactOS  0.4.15-dev-1207-g698a8e6
synth_real.c
Go to the documentation of this file.
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. */
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 */
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 
94 
95  if(final) fr->buffer.fill += 256;
96 
97  return 0;
98 }
99 
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 */
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 
186 
187  if(final) fr->buffer.fill += 256;
188 
189  return 0;
190 }
191 
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 */
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 
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 */
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 }
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 */
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 
455 
456  if(final) fr->buffer.fill += 256;
457 
458  return 0;
459 }
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 */
real equalizer[2][32]
Definition: frame.h:127
int synth_1to1_fltst_neon64(real *, real *, mpg123_handle *)
GLsizei samples
Definition: glext.h:7006
#define synth_1to1_real_s_neon64_asm
Definition: intsym.h:349
#define synth_1to1_real_s_avx_asm
Definition: intsym.h:344
int synth_1to1_real_stereo_neon(real *, real *, mpg123_handle *)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define synth_1to1_real_neon64_asm
Definition: intsym.h:334
#define synth_1to1_real_s_neon_asm
Definition: intsym.h:352
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define synth_1to1_real_sse_asm
Definition: intsym.h:340
_Tp _STLP_CALL real(const complex< _Tp > &__z)
Definition: _complex.h:727
struct outbuffer buffer
Definition: frame.h:267
int synth_1to1_fltst_avx(real *, real *, mpg123_handle *)
#define synth_1to1_real_s_sse_asm
Definition: intsym.h:355
real * real_buffs[2][2]
Definition: frame.h:106
int synth_1to1_real_stereo_x86_64(real *, real *, mpg123_handle *)
#define dct64_real_x86_64
Definition: intsym.h:323
int synth_1to1_real_neon(real *, int, mpg123_handle *, int)
#define do_equalizer
Definition: intsym.h:175
#define dct64_real_sse
Definition: intsym.h:321
#define synth_1to1_real_x86_64_asm
Definition: intsym.h:363
#define dct64_real_avx
Definition: intsym.h:313
int synth_1to1_real_sse(real *, int, mpg123_handle *, int)
static IHTMLWindow2 * window
Definition: events.c:77
#define dct64_real_neon64
Definition: intsym.h:318
int synth_1to1_real_stereo_sse(real *, real *, mpg123_handle *)
int synth_1to1_real_avx(real *, int, mpg123_handle *, int)
#define dct64_real_neon
Definition: intsym.h:319
#define synth_1to1_real_s_x86_64_asm
Definition: intsym.h:359
int synth_1to1_real_neon64(real *, int, mpg123_handle *, int)
int synth_1to1_real_x86_64(real *, int, mpg123_handle *, int)
#define synth_1to1_real_neon_asm
Definition: intsym.h:337