Subversion Repositories Kolibri OS

Rev

Rev 1905 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1905 serge 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
#include "sample.h"
11
#include "debug.h"
12
 
13
/*
14
	Part 1: All synth functions that produce signed short.
15
	That is:
16
		- synth_1to1 with cpu-specific variants (synth_1to1_i386, synth_1to1_i586 ...)
3960 Serge 17
		- synth_1to1_mono and synth_1to1_m2s; which use fr->synths.plain[r_1to1][f_16].
1905 serge 18
	Nearly every decoder variant has it's own synth_1to1, while the mono conversion is shared.
19
*/
20
 
21
#define SAMPLE_T short
22
#define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
23
 
24
/* Part 1a: All straight 1to1 decoding functions */
25
#define BLOCK 0x40 /* One decoding block is 64 samples. */
26
 
27
#define SYNTH_NAME synth_1to1
28
#include "synth.h"
29
#undef SYNTH_NAME
30
 
31
/* Mono-related synths; they wrap over _some_ synth_1to1. */
32
#define SYNTH_NAME       fr->synths.plain[r_1to1][f_16]
33
#define MONO_NAME        synth_1to1_mono
3960 Serge 34
#define MONO2STEREO_NAME synth_1to1_m2s
1905 serge 35
#include "synth_mono.h"
36
#undef SYNTH_NAME
37
#undef MONO_NAME
38
#undef MONO2STEREO_NAME
39
 
40
/* Now we have possibly some special synth_1to1 ...
41
   ... they produce signed short; the mono functions defined above work on the special synths, too. */
42
 
43
#ifdef OPT_GENERIC_DITHER
44
#define SYNTH_NAME synth_1to1_dither
45
/* We need the accurate sample writing... */
46
#undef WRITE_SAMPLE
47
#define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip)
48
 
49
#define USE_DITHER
50
#include "synth.h"
51
#undef USE_DITHER
52
#undef SYNTH_NAME
53
 
54
#undef WRITE_SAMPLE
55
#define WRITE_SAMPLE(samples,sum,clip) WRITE_SHORT_SAMPLE(samples,sum,clip)
56
 
57
#endif
58
 
59
#ifdef OPT_X86
60
/* The i386-specific C code, here as short variant, later 8bit and float. */
61
#define NO_AUTOINCREMENT
62
#define SYNTH_NAME synth_1to1_i386
63
#include "synth.h"
64
#undef SYNTH_NAME
65
/* i386 uses the normal mono functions. */
66
#undef NO_AUTOINCREMENT
67
#endif
68
 
69
#undef BLOCK /* Following functions are so special that they don't need this. */
70
 
71
#ifdef OPT_I586
72
/* This is defined in assembler. */
73
int synth_1to1_i586_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
74
/* This is just a hull to use the mpg123 handle. */
75
int synth_1to1_i586(real *bandPtr, int channel, mpg123_handle *fr, int final)
76
{
77
	int ret;
78
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
79
 
80
	ret = synth_1to1_i586_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
81
	if(final) fr->buffer.fill += 128;
82
	return ret;
83
}
84
#endif
85
 
86
#ifdef OPT_I586_DITHER
87
/* This is defined in assembler. */
88
int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin, float *dithernoise);
89
/* This is just a hull to use the mpg123 handle. */
90
int synth_1to1_i586_dither(real *bandPtr, int channel, mpg123_handle *fr, int final)
91
{
92
	int ret;
93
	int bo_dither[2]; /* Temporary workaround? Could expand the asm code. */
94
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
95
 
96
	/* Applying this hack, to change the asm only bit by bit (adding dithernoise pointer). */
97
	bo_dither[0] = fr->bo;
98
	bo_dither[1] = fr->ditherindex;
99
	ret = synth_1to1_i586_asm_dither(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, bo_dither, fr->decwin, fr->dithernoise);
100
	fr->bo          = bo_dither[0];
101
	fr->ditherindex = bo_dither[1];
102
 
103
	if(final) fr->buffer.fill += 128;
104
	return ret;
105
}
106
#endif
107
 
108
#ifdef OPT_3DNOW
109
/* Those are defined in assembler. */
110
void do_equalizer_3dnow(real *bandPtr,int channel, real equalizer[2][32]);
111
int synth_1to1_3dnow_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin);
112
/* This is just a hull to use the mpg123 handle. */
113
int synth_1to1_3dnow(real *bandPtr, int channel, mpg123_handle *fr, int final)
114
{
115
	int ret;
116
 
117
	if(fr->have_eq_settings) do_equalizer_3dnow(bandPtr,channel,fr->equalizer);
118
 
119
	/* this is in asm, can be dither or not */
120
	/* uh, is this return from pointer correct? */
121
	ret = (int) synth_1to1_3dnow_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, &fr->bo, fr->decwin);
122
	if(final) fr->buffer.fill += 128;
123
	return ret;
124
}
125
#endif
126
 
127
#ifdef OPT_MMX
128
/* This is defined in assembler. */
129
int synth_1to1_MMX(real *bandPtr, int channel, short *out, short *buffs, int *bo, float *decwins);
130
/* This is just a hull to use the mpg123 handle. */
131
int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
132
{
133
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
134
 
135
	/* in asm */
136
	synth_1to1_MMX(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
137
	if(final) fr->buffer.fill += 128;
138
	return 0;
139
}
140
#endif
141
 
142
#ifdef OPT_SSE
143
#ifdef ACCURATE_ROUNDING
144
/* This is defined in assembler. */
145
int synth_1to1_sse_accurate_asm(real *window, real *b0, short *samples, int bo1);
3960 Serge 146
int synth_1to1_s_sse_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
1905 serge 147
void dct64_real_sse(real *out0, real *out1, real *samples);
148
/* This is just a hull to use the mpg123 handle. */
149
int synth_1to1_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)
150
{
151
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
152
	real *b0, **buf;
153
	int clip;
154
	int bo1;
155
 
156
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
157
 
158
	if(!channel)
159
	{
160
		fr->bo--;
161
		fr->bo &= 0xf;
162
		buf = fr->real_buffs[0];
163
	}
164
	else
165
	{
166
		samples++;
167
		buf = fr->real_buffs[1];
168
	}
169
 
170
	if(fr->bo & 0x1)
171
	{
172
		b0 = buf[0];
173
		bo1 = fr->bo;
174
		dct64_real_sse(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
175
	}
176
	else
177
	{
178
		b0 = buf[1];
179
		bo1 = fr->bo+1;
180
		dct64_real_sse(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
181
	}
182
 
183
	clip = synth_1to1_sse_accurate_asm(fr->decwin, b0, samples, bo1);
184
 
185
	if(final) fr->buffer.fill += 128;
186
 
187
	return clip;
188
}
189
 
190
int synth_1to1_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
191
{
192
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
193
 
194
	real *b0l, *b0r, **bufl, **bufr;
195
	int bo1;
196
	int clip;
197
 
198
	if(fr->have_eq_settings)
199
	{
200
		do_equalizer(bandPtr_l,0,fr->equalizer);
201
		do_equalizer(bandPtr_r,1,fr->equalizer);
202
	}
203
 
204
	fr->bo--;
205
	fr->bo &= 0xf;
206
	bufl = fr->real_buffs[0];
207
	bufr = fr->real_buffs[1];
208
 
209
	if(fr->bo & 0x1)
210
	{
211
		b0l = bufl[0];
212
		b0r = bufr[0];
213
		bo1 = fr->bo;
214
		dct64_real_sse(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
215
		dct64_real_sse(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
216
	}
217
	else
218
	{
219
		b0l = bufl[1];
220
		b0r = bufr[1];
221
		bo1 = fr->bo+1;
222
		dct64_real_sse(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
223
		dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
224
	}
225
 
3960 Serge 226
	clip = synth_1to1_s_sse_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
1905 serge 227
 
228
	fr->buffer.fill += 128;
229
 
230
	return clip;
231
}
232
#else
233
/* This is defined in assembler. */
234
void synth_1to1_sse_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
235
/* This is just a hull to use the mpg123 handle. */
236
int synth_1to1_sse(real *bandPtr, int channel, mpg123_handle *fr, int final)
237
{
238
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
239
 
240
	synth_1to1_sse_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
241
	if(final) fr->buffer.fill += 128;
242
	return 0;
243
}
244
#endif
245
#endif
246
 
247
#ifdef OPT_3DNOWEXT
248
/* This is defined in assembler. */
249
void synth_1to1_3dnowext_asm(real *bandPtr, int channel, short *samples, short *buffs, int *bo, real *decwin);
250
/* This is just a hull to use the mpg123 handle. */
251
int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final)
252
{
253
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
254
 
255
	synth_1to1_3dnowext_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, &fr->bo, fr->decwins);
256
	if(final) fr->buffer.fill += 128;
257
	return 0;
258
}
259
#endif
260
 
261
#ifdef OPT_X86_64
262
#ifdef ACCURATE_ROUNDING
263
/* Assembler routines. */
264
int synth_1to1_x86_64_accurate_asm(real *window, real *b0, short *samples, int bo1);
3960 Serge 265
int synth_1to1_s_x86_64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
1905 serge 266
void dct64_real_x86_64(real *out0, real *out1, real *samples);
267
/* Hull for C mpg123 API */
268
int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
269
{
270
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
271
 
272
	real *b0, **buf;
273
	int bo1;
274
	int clip;
275
 
276
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
277
 
278
	if(!channel)
279
	{
280
		fr->bo--;
281
		fr->bo &= 0xf;
282
		buf = fr->real_buffs[0];
283
	}
284
	else
285
	{
286
		samples++;
287
		buf = fr->real_buffs[1];
288
	}
289
 
290
	if(fr->bo & 0x1)
291
	{
292
		b0 = buf[0];
293
		bo1 = fr->bo;
294
		dct64_real_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
295
	}
296
	else
297
	{
298
		b0 = buf[1];
299
		bo1 = fr->bo+1;
300
		dct64_real_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
301
	}
302
 
303
	clip = synth_1to1_x86_64_accurate_asm(fr->decwin, b0, samples, bo1);
304
 
305
	if(final) fr->buffer.fill += 128;
306
 
307
	return clip;
308
}
309
 
310
int synth_1to1_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
311
{
312
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
313
 
314
	real *b0l, *b0r, **bufl, **bufr;
315
	int bo1;
316
	int clip;
317
 
318
	if(fr->have_eq_settings)
319
	{
320
		do_equalizer(bandPtr_l,0,fr->equalizer);
321
		do_equalizer(bandPtr_r,1,fr->equalizer);
322
	}
323
 
324
	fr->bo--;
325
	fr->bo &= 0xf;
326
	bufl = fr->real_buffs[0];
327
	bufr = fr->real_buffs[1];
328
 
329
	if(fr->bo & 0x1)
330
	{
331
		b0l = bufl[0];
332
		b0r = bufr[0];
333
		bo1 = fr->bo;
334
		dct64_real_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
335
		dct64_real_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
336
	}
337
	else
338
	{
339
		b0l = bufl[1];
340
		b0r = bufr[1];
341
		bo1 = fr->bo+1;
342
		dct64_real_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
343
		dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
344
	}
345
 
3960 Serge 346
	clip = synth_1to1_s_x86_64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
1905 serge 347
 
348
	fr->buffer.fill += 128;
349
 
350
	return clip;
351
}
352
#else
353
/* This is defined in assembler. */
354
int synth_1to1_x86_64_asm(short *window, short *b0, short *samples, int bo1);
3960 Serge 355
int synth_1to1_s_x86_64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
1905 serge 356
void dct64_x86_64(short *out0, short *out1, real *samples);
357
/* This is just a hull to use the mpg123 handle. */
358
int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
359
{
360
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
361
	short *b0, **buf;
362
	int clip;
363
	int bo1;
364
 
365
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
366
 
367
	if(!channel)
368
	{
369
		fr->bo--;
370
		fr->bo &= 0xf;
371
		buf = fr->short_buffs[0];
372
	}
373
	else
374
	{
375
		samples++;
376
		buf = fr->short_buffs[1];
377
	}
378
 
379
	if(fr->bo & 0x1)
380
	{
381
		b0 = buf[0];
382
		bo1 = fr->bo;
383
		dct64_x86_64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
384
	}
385
	else
386
	{
387
		b0 = buf[1];
388
		bo1 = fr->bo+1;
389
		dct64_x86_64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
390
	}
391
 
392
	clip = synth_1to1_x86_64_asm((short *)fr->decwins, b0, samples, bo1);
393
 
394
	if(final) fr->buffer.fill += 128;
395
 
396
	return clip;
397
}
398
 
399
int synth_1to1_stereo_x86_64(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
400
{
401
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
402
	short *b0l, *b0r, **bufl, **bufr;
403
	int clip;
404
	int bo1;
405
 
406
	if(fr->have_eq_settings)
407
	{
408
		do_equalizer(bandPtr_l,0,fr->equalizer);
409
		do_equalizer(bandPtr_r,1,fr->equalizer);
410
	}
411
 
412
	fr->bo--;
413
	fr->bo &= 0xf;
414
	bufl = fr->short_buffs[0];
415
	bufr = fr->short_buffs[1];
416
 
417
	if(fr->bo & 0x1)
418
	{
419
		b0l = bufl[0];
420
		b0r = bufr[0];
421
		bo1 = fr->bo;
422
		dct64_x86_64(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
423
		dct64_x86_64(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
424
	}
425
	else
426
	{
427
		b0l = bufl[1];
428
		b0r = bufr[1];
429
		bo1 = fr->bo+1;
430
		dct64_x86_64(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
431
		dct64_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
432
	}
433
 
3960 Serge 434
	clip = synth_1to1_s_x86_64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
1905 serge 435
 
436
	fr->buffer.fill += 128;
437
 
438
	return clip;
439
}
440
#endif
441
#endif
442
 
443
#ifdef OPT_ARM
444
#ifdef ACCURATE_ROUNDING
445
/* Assembler routines. */
446
int synth_1to1_arm_accurate_asm(real *window, real *b0, short *samples, int bo1);
447
/* Hull for C mpg123 API */
448
int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
449
{
450
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
451
 
452
	real *b0, **buf;
453
	int bo1;
454
	int clip;
455
 
456
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
457
 
458
	if(!channel)
459
	{
460
		fr->bo--;
461
		fr->bo &= 0xf;
462
		buf = fr->real_buffs[0];
463
	}
464
	else
465
	{
466
		samples++;
467
		buf = fr->real_buffs[1];
468
	}
469
 
470
	if(fr->bo & 0x1)
471
	{
472
		b0 = buf[0];
473
		bo1 = fr->bo;
474
		dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
475
	}
476
	else
477
	{
478
		b0 = buf[1];
479
		bo1 = fr->bo+1;
480
		dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
481
	}
482
 
483
	clip = synth_1to1_arm_accurate_asm(fr->decwin, b0, samples, bo1);
484
 
485
	if(final) fr->buffer.fill += 128;
486
 
487
	return clip;
488
}
489
#else
490
/* Assembler routines. */
491
int synth_1to1_arm_asm(real *window, real *b0, short *samples, int bo1);
492
/* Hull for C mpg123 API */
493
int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
494
{
495
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
496
 
497
	real *b0, **buf;
498
	int bo1;
499
	int clip;
500
 
501
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
502
 
503
	if(!channel)
504
	{
505
		fr->bo--;
506
		fr->bo &= 0xf;
507
		buf = fr->real_buffs[0];
508
	}
509
	else
510
	{
511
		samples++;
512
		buf = fr->real_buffs[1];
513
	}
514
 
515
	if(fr->bo & 0x1)
516
	{
517
		b0 = buf[0];
518
		bo1 = fr->bo;
519
		dct64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
520
	}
521
	else
522
	{
523
		b0 = buf[1];
524
		bo1 = fr->bo+1;
525
		dct64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
526
	}
527
 
528
	clip = synth_1to1_arm_asm(fr->decwin, b0, samples, bo1);
529
 
530
	if(final) fr->buffer.fill += 128;
531
 
532
	return clip;
533
}
534
#endif
535
#endif
536
 
3960 Serge 537
#ifdef OPT_NEON
538
#ifdef ACCURATE_ROUNDING
539
/* This is defined in assembler. */
540
int synth_1to1_neon_accurate_asm(real *window, real *b0, short *samples, int bo1);
541
int synth_1to1_s_neon_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
542
void dct64_real_neon(real *out0, real *out1, real *samples);
543
/* Hull for C mpg123 API */
544
int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
545
{
546
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
547
 
548
	real *b0, **buf;
549
	int bo1;
550
	int clip;
551
 
552
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
553
 
554
	if(!channel)
555
	{
556
		fr->bo--;
557
		fr->bo &= 0xf;
558
		buf = fr->real_buffs[0];
559
	}
560
	else
561
	{
562
		samples++;
563
		buf = fr->real_buffs[1];
564
	}
565
 
566
	if(fr->bo & 0x1)
567
	{
568
		b0 = buf[0];
569
		bo1 = fr->bo;
570
		dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
571
	}
572
	else
573
	{
574
		b0 = buf[1];
575
		bo1 = fr->bo+1;
576
		dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
577
	}
578
 
579
	clip = synth_1to1_neon_accurate_asm(fr->decwin, b0, samples, bo1);
580
 
581
	if(final) fr->buffer.fill += 128;
582
 
583
	return clip;
584
}
585
 
586
int synth_1to1_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
587
{
588
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
589
 
590
	real *b0l, *b0r, **bufl, **bufr;
591
	int bo1;
592
	int clip;
593
 
594
	if(fr->have_eq_settings)
595
	{
596
		do_equalizer(bandPtr_l,0,fr->equalizer);
597
		do_equalizer(bandPtr_r,1,fr->equalizer);
598
	}
599
 
600
	fr->bo--;
601
	fr->bo &= 0xf;
602
	bufl = fr->real_buffs[0];
603
	bufr = fr->real_buffs[1];
604
 
605
	if(fr->bo & 0x1)
606
	{
607
		b0l = bufl[0];
608
		b0r = bufr[0];
609
		bo1 = fr->bo;
610
		dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
611
		dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
612
	}
613
	else
614
	{
615
		b0l = bufl[1];
616
		b0r = bufr[1];
617
		bo1 = fr->bo+1;
618
		dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
619
		dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
620
	}
621
 
622
	clip = synth_1to1_s_neon_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
623
 
624
	fr->buffer.fill += 128;
625
 
626
	return clip;
627
}
628
#else
629
/* This is defined in assembler. */
630
int synth_1to1_neon_asm(short *window, short *b0, short *samples, int bo1);
631
int synth_1to1_s_neon_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
632
void dct64_neon(short *out0, short *out1, real *samples);
633
/* Hull for C mpg123 API */
634
int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
635
{
636
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
637
	short *b0, **buf;
638
	int clip;
639
	int bo1;
640
 
641
	if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
642
 
643
	if(!channel)
644
	{
645
		fr->bo--;
646
		fr->bo &= 0xf;
647
		buf = fr->short_buffs[0];
648
	}
649
	else
650
	{
651
		samples++;
652
		buf = fr->short_buffs[1];
653
	}
654
 
655
	if(fr->bo & 0x1)
656
	{
657
		b0 = buf[0];
658
		bo1 = fr->bo;
659
		dct64_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
660
	}
661
	else
662
	{
663
		b0 = buf[1];
664
		bo1 = fr->bo+1;
665
		dct64_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
666
	}
667
 
668
	clip = synth_1to1_neon_asm((short *)fr->decwins, b0, samples, bo1);
669
 
670
	if(final) fr->buffer.fill += 128;
671
 
672
	return clip;
673
}
674
 
675
int synth_1to1_stereo_neon(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
676
{
677
	short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
678
	short *b0l, *b0r, **bufl, **bufr;
679
	int clip;
680
	int bo1;
681
 
682
	if(fr->have_eq_settings)
683
	{
684
		do_equalizer(bandPtr_l,0,fr->equalizer);
685
		do_equalizer(bandPtr_r,1,fr->equalizer);
686
	}
687
 
688
	fr->bo--;
689
	fr->bo &= 0xf;
690
	bufl = fr->short_buffs[0];
691
	bufr = fr->short_buffs[1];
692
 
693
	if(fr->bo & 0x1)
694
	{
695
		b0l = bufl[0];
696
		b0r = bufr[0];
697
		bo1 = fr->bo;
698
		dct64_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
699
		dct64_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
700
	}
701
	else
702
	{
703
		b0l = bufl[1];
704
		b0r = bufr[1];
705
		bo1 = fr->bo+1;
706
		dct64_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
707
		dct64_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
708
	}
709
 
710
	clip = synth_1to1_s_neon_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
711
 
712
	fr->buffer.fill += 128;
713
 
714
	return clip;
715
}
716
#endif
717
#endif
718
 
1905 serge 719
#ifndef NO_DOWNSAMPLE
720
 
721
/*
722
	Part 1b: 2to1 synth.
723
	Only generic and i386 functions this time.
724
*/
725
#define BLOCK 0x20 /* One decoding block is 32 samples. */
726
 
727
#define SYNTH_NAME synth_2to1
728
#include "synth.h"
729
#undef SYNTH_NAME
730
 
731
#ifdef OPT_DITHER /* Used for generic_dither and as fallback for i586_dither. */
732
#define SYNTH_NAME synth_2to1_dither
733
#define USE_DITHER
734
#include "synth.h"
735
#undef USE_DITHER
736
#undef SYNTH_NAME
737
#endif
738
 
739
#define SYNTH_NAME       fr->synths.plain[r_2to1][f_16]
740
#define MONO_NAME        synth_2to1_mono
3960 Serge 741
#define MONO2STEREO_NAME synth_2to1_m2s
1905 serge 742
#include "synth_mono.h"
743
#undef SYNTH_NAME
744
#undef MONO_NAME
745
#undef MONO2STEREO_NAME
746
 
747
#ifdef OPT_X86
748
#define NO_AUTOINCREMENT
749
#define SYNTH_NAME synth_2to1_i386
750
#include "synth.h"
751
#undef SYNTH_NAME
752
/* i386 uses the normal mono functions. */
753
#undef NO_AUTOINCREMENT
754
#endif
755
 
756
#undef BLOCK
757
 
758
/*
759
	Part 1c: 4to1 synth.
760
	Same procedure as above...
761
*/
762
#define BLOCK 0x10 /* One decoding block is 16 samples. */
763
 
764
#define SYNTH_NAME synth_4to1
765
#include "synth.h"
766
#undef SYNTH_NAME
767
 
768
#ifdef OPT_DITHER
769
#define SYNTH_NAME synth_4to1_dither
770
#define USE_DITHER
771
#include "synth.h"
772
#undef USE_DITHER
773
#undef SYNTH_NAME
774
#endif
775
 
776
#define SYNTH_NAME       fr->synths.plain[r_4to1][f_16] /* This is just for the _i386 one... gotta check if it is really useful... */
777
#define MONO_NAME        synth_4to1_mono
3960 Serge 778
#define MONO2STEREO_NAME synth_4to1_m2s
1905 serge 779
#include "synth_mono.h"
780
#undef SYNTH_NAME
781
#undef MONO_NAME
782
#undef MONO2STEREO_NAME
783
 
784
#ifdef OPT_X86
785
#define NO_AUTOINCREMENT
786
#define SYNTH_NAME synth_4to1_i386
787
#include "synth.h"
788
#undef SYNTH_NAME
789
/* i386 uses the normal mono functions. */
790
#undef NO_AUTOINCREMENT
791
#endif
792
 
793
#undef BLOCK
794
 
795
#endif /* NO_DOWNSAMPLE */
796
 
797
#ifndef NO_NTOM
798
/*
799
	Part 1d: ntom synth.
800
	Same procedure as above... Just no extra play anymore, straight synth that uses the plain dct64.
801
*/
802
 
803
/* These are all in one header, there's no flexibility to gain. */
804
#define SYNTH_NAME       synth_ntom
805
#define MONO_NAME        synth_ntom_mono
3960 Serge 806
#define MONO2STEREO_NAME synth_ntom_m2s
1905 serge 807
#include "synth_ntom.h"
808
#undef SYNTH_NAME
809
#undef MONO_NAME
810
#undef MONO2STEREO_NAME
811
 
812
#endif
813
 
814
/* Done with short output. */
815
#undef SAMPLE_T
816
#undef WRITE_SAMPLE