Coverage Report

Created: 2024-07-27 06:25

/src/mpg123/src/libmpg123/synth_real.c
Line
Count
Source (jump to first uncovered line)
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 "../common/sample.h"
11
#include "../common/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
0
#define SAMPLE_T real
23
0
#define WRITE_SAMPLE(samples,sum,clip) WRITE_REAL_SAMPLE(samples,sum,clip)
24
25
/* Part 3a: All straight 1to1 decoding functions */
26
0
#define BLOCK 0x40 /* One decoding block is 64 samples. */
27
28
#define SYNTH_NAME INT123_synth_1to1_real
29
#include "synth.h"
30
#undef SYNTH_NAME
31
32
/* Mono-related synths; they wrap over _some_ INT123_synth_1to1_real (could be generic, could be i386). */
33
0
#define SYNTH_NAME       fr->synths.plain[r_1to1][f_real]
34
#define MONO_NAME        INT123_synth_1to1_real_mono
35
#define MONO2STEREO_NAME INT123_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 INT123_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 INT123_synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);
56
int INT123_synth_1to1_real_s_x86_64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
57
void INT123_dct64_real_x86_64(real *out0, real *out1, real *samples);
58
/* Hull for C mpg123 API */
59
int INT123_synth_1to1_real_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
60
0
{
61
0
  real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
62
63
0
  real *b0, **buf;
64
0
  int bo1;
65
0
#ifndef NO_EQUALIZER
66
0
  if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);
67
0
#endif
68
0
  if(!channel)
69
0
  {
70
0
    fr->bo--;
71
0
    fr->bo &= 0xf;
72
0
    buf = fr->real_buffs[0];
73
0
  }
74
0
  else
75
0
  {
76
0
    samples++;
77
0
    buf = fr->real_buffs[1];
78
0
  }
79
80
0
  if(fr->bo & 0x1)
81
0
  {
82
0
    b0 = buf[0];
83
0
    bo1 = fr->bo;
84
0
    INT123_dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
85
0
  }
86
0
  else
87
0
  {
88
0
    b0 = buf[1];
89
0
    bo1 = fr->bo+1;
90
0
    INT123_dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
91
0
  }
92
93
0
  INT123_synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);
94
95
0
  if(final) fr->buffer.fill += 256;
96
97
0
  return 0;
98
0
}
99
100
int INT123_synth_1to1_real_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
101
0
{
102
0
  real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
103
104
0
  real *b0l, *b0r, **bufl, **bufr;
105
0
  int bo1;
106
0
#ifndef NO_EQUALIZER
107
0
  if(fr->have_eq_settings)
108
0
  {
109
0
    INT123_do_equalizer(bandPtr_l,0,fr->equalizer);
110
0
    INT123_do_equalizer(bandPtr_r,1,fr->equalizer);
111
0
  }
112
0
#endif
113
0
  fr->bo--;
114
0
  fr->bo &= 0xf;
115
0
  bufl = fr->real_buffs[0];
116
0
  bufr = fr->real_buffs[1];
117
118
0
  if(fr->bo & 0x1)
119
0
  {
120
0
    b0l = bufl[0];
121
0
    b0r = bufr[0];
122
0
    bo1 = fr->bo;
123
0
    INT123_dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
124
0
    INT123_dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
125
0
  }
126
0
  else
127
0
  {
128
0
    b0l = bufl[1];
129
0
    b0r = bufr[1];
130
0
    bo1 = fr->bo+1;
131
0
    INT123_dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
132
0
    INT123_dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
133
0
  }
134
135
0
  INT123_synth_1to1_real_s_x86_64_asm(fr->decwin, b0l, b0r, samples, bo1);
136
137
0
  fr->buffer.fill += 256;
138
139
0
  return 0;
140
0
}
141
#endif
142
143
#ifdef OPT_AVX
144
/* Assembler routines. */
145
#ifndef OPT_X86_64
146
int INT123_synth_1to1_real_x86_64_asm(real *window, real *b0, real *samples, int bo1);
147
#endif
148
int INT123_synth_1to1_real_s_avx_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
149
void INT123_dct64_real_avx(real *out0, real *out1, real *samples);
150
/* Hull for C mpg123 API */
151
int INT123_synth_1to1_real_avx(real *bandPtr,int channel, mpg123_handle *fr, int final)
152
0
{
153
0
  real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
154
155
0
  real *b0, **buf;
156
0
  int bo1;
157
0
#ifndef NO_EQUALIZER
158
0
  if(fr->have_eq_settings) INT123_do_equalizer(bandPtr,channel,fr->equalizer);
159
0
#endif
160
0
  if(!channel)
161
0
  {
162
0
    fr->bo--;
163
0
    fr->bo &= 0xf;
164
0
    buf = fr->real_buffs[0];
165
0
  }
166
0
  else
167
0
  {
168
0
    samples++;
169
0
    buf = fr->real_buffs[1];
170
0
  }
171
172
0
  if(fr->bo & 0x1)
173
0
  {
174
0
    b0 = buf[0];
175
0
    bo1 = fr->bo;
176
0
    INT123_dct64_real_avx(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
177
0
  }
178
0
  else
179
0
  {
180
0
    b0 = buf[1];
181
0
    bo1 = fr->bo+1;
182
0
    INT123_dct64_real_avx(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
183
0
  }
184
185
0
  INT123_synth_1to1_real_x86_64_asm(fr->decwin, b0, samples, bo1);
186
187
0
  if(final) fr->buffer.fill += 256;
188
189
0
  return 0;
190
0
}
191
192
int INT123_synth_1to1_fltst_avx(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
193
0
{
194
0
  real *samples = (real *) (fr->buffer.data+fr->buffer.fill);
195
196
0
  real *b0l, *b0r, **bufl, **bufr;
197
0
  int bo1;
198
0
#ifndef NO_EQUALIZER
199
0
  if(fr->have_eq_settings)
200
0
  {
201
0
    INT123_do_equalizer(bandPtr_l,0,fr->equalizer);
202
0
    INT123_do_equalizer(bandPtr_r,1,fr->equalizer);
203
0
  }
204
0
#endif
205
0
  fr->bo--;
206
0
  fr->bo &= 0xf;
207
0
  bufl = fr->real_buffs[0];
208
0
  bufr = fr->real_buffs[1];
209
210
0
  if(fr->bo & 0x1)
211
0
  {
212
0
    b0l = bufl[0];
213
0
    b0r = bufr[0];
214
0
    bo1 = fr->bo;
215
0
    INT123_dct64_real_avx(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
216
0
    INT123_dct64_real_avx(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
217
0
  }
218
0
  else
219
0
  {
220
0
    b0l = bufl[1];
221
0
    b0r = bufr[1];
222
0
    bo1 = fr->bo+1;
223
0
    INT123_dct64_real_avx(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
224
0
    INT123_dct64_real_avx(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
225
0
  }
226
227
0
  INT123_synth_1to1_real_s_avx_asm(fr->decwin, b0l, b0r, samples, bo1);
228
229
0
  fr->buffer.fill += 256;
230
231
0
  return 0;
232
0
}
233
#endif
234
235
#if defined(OPT_SSE) || defined(OPT_SSE_VINTAGE)
236
/* Assembler routines. */
237
int INT123_synth_1to1_real_sse_asm(real *window, real *b0, real *samples, int bo1);
238
int INT123_synth_1to1_real_s_sse_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
239
void INT123_dct64_real_sse(real *out0, real *out1, real *samples);
240
/* Hull for C mpg123 API */
241
int INT123_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) INT123_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
    INT123_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
    INT123_dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
273
  }
274
275
  INT123_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 INT123_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
    INT123_do_equalizer(bandPtr_l,0,fr->equalizer);
292
    INT123_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
    INT123_dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
306
    INT123_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
    INT123_dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
314
    INT123_dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
315
  }
316
317
  INT123_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 INT123_synth_1to1_real_neon_asm(real *window, real *b0, real *samples, int bo1);
328
int INT123_synth_1to1_real_s_neon_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
329
void INT123_dct64_real_neon(real *out0, real *out1, real *samples);
330
/* Hull for C mpg123 API */
331
int INT123_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) INT123_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
    INT123_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
    INT123_dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
363
  }
364
365
  INT123_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 INT123_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
    INT123_do_equalizer(bandPtr_l,0,fr->equalizer);
381
    INT123_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
    INT123_dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
395
    INT123_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
    INT123_dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
403
    INT123_dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
404
  }
405
406
  INT123_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 INT123_synth_1to1_real_neon64_asm(real *window, real *b0, real *samples, int bo1);
417
int INT123_synth_1to1_real_s_neon64_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
418
void INT123_dct64_real_neon64(real *out0, real *out1, real *samples);
419
/* Hull for C mpg123 API */
420
int INT123_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) INT123_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
    INT123_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
    INT123_dct64_real_neon64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
452
  }
453
454
  INT123_synth_1to1_real_neon64_asm(fr->decwin, b0, samples, bo1);
455
456
  if(final) fr->buffer.fill += 256;
457
458
  return 0;
459
}
460
int INT123_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
    INT123_do_equalizer(bandPtr_l,0,fr->equalizer);
470
    INT123_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
    INT123_dct64_real_neon64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
484
    INT123_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
    INT123_dct64_real_neon64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
492
    INT123_dct64_real_neon64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
493
  }
494
495
  INT123_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
0
#define BLOCK 0x20 /* One decoding block is 32 samples. */
509
510
#define SYNTH_NAME INT123_synth_2to1_real
511
#include "synth.h"
512
#undef SYNTH_NAME
513
514
/* Mono-related synths; they wrap over _some_ INT123_synth_2to1_real (could be generic, could be i386). */
515
0
#define SYNTH_NAME       fr->synths.plain[r_2to1][f_real]
516
#define MONO_NAME        INT123_synth_2to1_real_mono
517
#define MONO2STEREO_NAME INT123_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 INT123_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
0
#define BLOCK 0x10 /* One decoding block is 16 samples. */
538
539
#define SYNTH_NAME INT123_synth_4to1_real
540
#include "synth.h"
541
#undef SYNTH_NAME
542
543
/* Mono-related synths; they wrap over _some_ INT123_synth_4to1_real (could be generic, could be i386). */
544
0
#define SYNTH_NAME       fr->synths.plain[r_4to1][f_real]
545
#define MONO_NAME        INT123_synth_4to1_real_mono
546
#define MONO2STEREO_NAME INT123_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 INT123_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 INT123_dct64.
569
*/
570
571
/* These are all in one header, there's no flexibility to gain. */
572
0
#define SYNTH_NAME       INT123_synth_ntom_real
573
#define MONO_NAME        INT123_synth_ntom_real_mono
574
#define MONO2STEREO_NAME INT123_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 */