/
effect_position.c
2109 lines (1917 loc) · 78.1 KB
1
/*
2
SDL_mixer: An audio mixer library based on the SDL library
3
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
8
9
10
11
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
12
13
14
15
16
17
18
19
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
20
21
This file by Ryan C. Gordon (icculus@icculus.org)
22
23
24
These are some internally supported special effects that use SDL_mixer's
effect callback API. They are meant for speed over quality. :)
25
26
27
28
*/
#include <stdio.h>
#include <stdlib.h>
29
30
#include <string.h>
31
#include "SDL.h"
32
#include "SDL_endian.h"
33
34
#include "SDL_mixer.h"
#include "mixer.h"
35
36
#define MIX_INTERNAL_EFFECT__
37
38
39
40
41
42
43
#include "effects_internal.h"
/* profile code:
#include <sys/time.h>
#include <unistd.h>
struct timeval tv1;
struct timeval tv2;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
gettimeofday(&tv1, NULL);
... do your thing here ...
gettimeofday(&tv2, NULL);
printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
*/
/*
* Positional effects...panning, distance attenuation, etc.
*/
typedef struct _Eff_positionargs
{
volatile float left_f;
volatile float right_f;
volatile Uint8 left_u8;
volatile Uint8 right_u8;
64
65
66
67
68
69
70
71
volatile float left_rear_f;
volatile float right_rear_f;
volatile float center_f;
volatile float lfe_f;
volatile Uint8 left_rear_u8;
volatile Uint8 right_rear_u8;
volatile Uint8 center_u8;
volatile Uint8 lfe_u8;
72
73
volatile float distance_f;
volatile Uint8 distance_u8;
74
volatile Sint16 room_angle;
75
76
77
78
79
80
81
82
volatile int in_use;
volatile int channels;
} position_args;
static position_args **pos_args_array = NULL;
static position_args *pos_args_global = NULL;
static int position_channels = 0;
83
84
85
86
void _Eff_PositionDeinit(void)
{
int i;
for (i = 0; i < position_channels; i++) {
87
SDL_free(pos_args_array[i]);
88
89
}
90
91
position_channels = 0;
92
SDL_free(pos_args_global);
93
pos_args_global = NULL;
94
SDL_free(pos_args_array);
95
96
97
98
pos_args_array = NULL;
}
99
/* This just frees up the callback-specific data. */
100
static void SDLCALL _Eff_PositionDone(int channel, void *udata)
101
{
102
(void)udata;
103
104
105
if (channel < 0) {
if (pos_args_global != NULL) {
106
SDL_free(pos_args_global);
107
108
109
110
pos_args_global = NULL;
}
}
else if (pos_args_array[channel] != NULL) {
111
SDL_free(pos_args_array[channel]);
112
113
114
115
pos_args_array[channel] = NULL;
}
}
116
static void SDLCALL _Eff_position_u8(int chan, void *stream, int len, void *udata)
117
118
119
120
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
121
122
(void)chan;
123
124
125
126
127
128
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
129
if (len % (int)sizeof(Uint16) != 0) {
130
131
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
132
133
134
len--;
}
135
if (args->room_angle == 180)
136
for (i = 0; i < len; i += sizeof (Uint8) * 2) {
137
/* must adjust the sample so that 0 is the center */
138
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
139
140
* args->right_f) * args->distance_f) + 128);
ptr++;
141
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
142
143
144
145
* args->left_f) * args->distance_f) + 128);
ptr++;
}
else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
146
/* must adjust the sample so that 0 is the center */
147
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
148
* args->left_f) * args->distance_f) + 128);
149
ptr++;
150
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
151
* args->right_f) * args->distance_f) + 128);
152
ptr++;
153
154
}
}
155
156
static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
157
158
159
160
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
161
162
(void)chan;
163
164
165
166
167
168
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
169
if (len % (int)sizeof(Uint16) != 0) {
170
171
172
173
174
175
176
177
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
if (args->room_angle == 0)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
178
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
179
180
* args->left_f) * args->distance_f) + 128);
ptr++;
181
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
182
183
* args->right_f) * args->distance_f) + 128);
ptr++;
184
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
185
186
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
187
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
188
189
190
191
192
193
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 90)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
194
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
195
196
* args->right_f) * args->distance_f) + 128);
ptr++;
197
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
198
199
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
200
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
201
202
* args->left_f) * args->distance_f) + 128);
ptr++;
203
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
204
205
206
207
208
209
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
210
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
211
212
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
213
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
214
215
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
216
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
217
218
* args->right_f) * args->distance_f) + 128);
ptr++;
219
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
220
221
222
223
224
225
* args->left_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 270)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
226
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
227
228
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
229
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
230
231
* args->left_f) * args->distance_f) + 128);
ptr++;
232
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
233
234
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
235
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
236
237
238
239
240
241
* args->right_f) * args->distance_f) + 128);
ptr++;
}
}
242
static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
243
244
245
246
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
247
248
249
(void)chan;
(void)len;
250
251
252
253
254
255
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
256
if (len % (int)sizeof(Uint16) != 0) {
257
258
259
260
261
262
263
264
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
if (args->room_angle == 0)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
265
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
266
267
* args->left_f) * args->distance_f) + 128);
ptr++;
268
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
269
270
* args->right_f) * args->distance_f) + 128);
ptr++;
271
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
272
273
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
274
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
275
276
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
277
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
278
279
* args->center_f) * args->distance_f) + 128);
ptr++;
280
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
281
282
283
284
285
286
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 90)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
287
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
288
289
* args->right_f) * args->distance_f) + 128);
ptr++;
290
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
291
292
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
293
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
294
295
* args->left_f) * args->distance_f) + 128);
ptr++;
296
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
297
298
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
299
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
300
* args->right_rear_f) * args->distance_f/2) + 128)
301
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
302
303
* args->right_f) * args->distance_f/2) + 128);
ptr++;
304
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
305
306
307
308
309
310
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
311
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
312
313
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
314
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
315
316
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
317
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
318
319
* args->right_f) * args->distance_f) + 128);
ptr++;
320
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
321
322
* args->left_f) * args->distance_f) + 128);
ptr++;
323
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
324
* args->right_rear_f) * args->distance_f/2) + 128)
325
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
326
327
* args->left_rear_f) * args->distance_f/2) + 128);
ptr++;
328
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
329
330
331
332
333
334
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 270)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
335
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
336
337
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
338
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
339
340
* args->left_f) * args->distance_f) + 128);
ptr++;
341
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
342
343
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
344
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
345
346
* args->right_f) * args->distance_f) + 128);
ptr++;
347
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
348
* args->left_f) * args->distance_f/2) + 128)
349
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
350
351
* args->left_rear_f) * args->distance_f/2) + 128);
ptr++;
352
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
353
354
355
356
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
}
357
358
359
360
361
362
363
364
365
366
/*
* This one runs about 10.1 times faster than the non-table version, with
* no loss in quality. It does, however, require 64k of memory for the
* lookup table. Also, this will only update position information once per
* call; the non-table version always checks the arguments for each sample,
* in case the user has called Mix_SetPanning() or whatnot again while this
* callback is running.
*/
367
static void SDLCALL _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
368
369
370
371
372
373
374
375
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
Uint32 *p;
int i;
Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
376
377
(void)chan;
378
379
if (args->room_angle == 180) {
380
381
382
Uint8 *temp = l;
l = r;
r = temp;
383
}
384
385
386
387
388
/*
* if there's only a mono channnel, then l[] and r[] are always
* volume 255, and are therefore throwaways. Still, we have to
* be sure not to overrun the audio buffer...
*/
389
while (len % (int)sizeof(Uint32) != 0) {
390
391
392
393
394
395
*ptr = d[l[*ptr]];
ptr++;
if (args->channels > 1) {
*ptr = d[r[*ptr]];
ptr++;
}
396
397
398
399
400
401
len -= args->channels;
}
p = (Uint32 *) ptr;
for (i = 0; i < len; i += sizeof (Uint32)) {
402
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
403
404
405
*p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
(d[r[(*p & 0x00FF0000) >> 16]] << 16) |
(d[l[(*p & 0x0000FF00) >> 8]] << 8) |
406
(d[r[(*p & 0x000000FF) ]] ) ;
407
#else
408
409
410
*p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
(d[l[(*p & 0x00FF0000) >> 16]] << 16) |
(d[r[(*p & 0x0000FF00) >> 8]] << 8) |
411
(d[l[(*p & 0x000000FF) ]] ) ;
412
#endif
413
++p;
414
415
416
417
}
}
418
static void SDLCALL _Eff_position_s8(int chan, void *stream, int len, void *udata)
419
420
421
422
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
423
424
(void)chan;
425
426
427
428
429
430
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
431
if (len % (int)sizeof(Sint16) != 0) {
432
433
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
434
435
436
len--;
}
437
438
439
440
441
442
443
444
if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Sint8) * 2) {
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
ptr++;
}
else
445
for (i = 0; i < len; i += sizeof (Sint8) * 2) {
446
447
448
449
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
ptr++;
450
451
}
}
452
static void SDLCALL _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
453
454
455
456
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
457
458
(void)chan;
459
460
461
462
463
464
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
465
if (len % (int)sizeof(Sint16) != 0) {
466
467
468
469
470
471
472
473
474
475
476
477
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
for (i = 0; i < len; i += sizeof (Sint8) * 4) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
478
break;
479
480
481
482
483
case 90:
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
484
break;
485
486
487
488
489
case 180:
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
490
break;
491
492
493
494
495
case 270:
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
496
break;
497
498
499
}
}
}
500
static void SDLCALL _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
501
502
503
504
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
505
506
(void)chan;
507
508
509
510
511
512
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
513
if (len % (int)sizeof(Sint16) != 0) {
514
515
516
517
518
519
520
521
522
523
524
525
526
527
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
for (i = 0; i < len; i += sizeof (Sint8) * 6) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
528
break;
529
530
531
532
533
534
535
536
case 90:
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
537
break;
538
539
540
541
542
543
544
545
case 180:
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
546
break;
547
548
549
550
551
552
553
554
case 270:
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
555
break;
556
557
558
}
}
}
559
560
561
562
563
564
565
566
567
568
/*
* This one runs about 10.1 times faster than the non-table version, with
* no loss in quality. It does, however, require 64k of memory for the
* lookup table. Also, this will only update position information once per
* call; the non-table version always checks the arguments for each sample,
* in case the user has called Mix_SetPanning() or whatnot again while this
* callback is running.
*/
569
static void SDLCALL _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
570
571
572
573
574
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
Uint32 *p;
int i;
575
576
Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
577
Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
578
579
(void)chan;
580
581
if (args->room_angle == 180) {
582
583
584
Sint8 *temp = l;
l = r;
r = temp;
585
586
}
587
while (len % (int)sizeof(Uint32) != 0) {
588
589
590
591
592
593
*ptr = d[l[*ptr]];
ptr++;
if (args->channels > 1) {
*ptr = d[r[*ptr]];
ptr++;
}
594
595
596
597
598
599
len -= args->channels;
}
p = (Uint32 *) ptr;
for (i = 0; i < len; i += sizeof (Uint32)) {
600
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
601
602
603
*p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
(d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
(d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
604
(d[r[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
605
#else
606
607
608
*p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
(d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
(d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
609
(d[l[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
610
#endif
611
++p;
612
613
614
615
616
617
}
}
/* !!! FIXME : Optimize the code for 16-bit samples? */
618
static void SDLCALL _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
619
620
621
622
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
623
624
(void)chan;
625
626
for (i = 0; i < len; i += sizeof (Uint16) * 2) {
627
628
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
629
630
631
632
633
634
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
635
if (args->room_angle == 180) {
636
637
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
638
639
}
else {
640
641
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
642
}
643
644
}
}
645
static void SDLCALL _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
646
647
648
649
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
650
651
(void)chan;
652
653
654
655
656
657
for (i = 0; i < len; i += sizeof (Uint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
658
659
660
661
662
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
663
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
664
* args->distance_f) + 32768);
665
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
666
667
* args->distance_f) + 32768);
668
switch (args->room_angle) {
669
case 0:
670
671
672
673
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
674
675
break;
case 90:
676
677
678
679
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
680
681
break;
case 180:
682
683
684
685
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
686
687
break;
case 270:
688
689
690
691
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
692
break;
693
}
694
695
}
}
696
static void SDLCALL _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
697
698
699
700
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
701
702
(void)chan;
703
704
705
706
707
708
709
710
for (i = 0; i < len; i += sizeof (Uint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
711
712
713
714
715
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
716
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
717
* args->distance_f) + 32768);
718
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
719
* args->distance_f) + 32768);
720
Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
721
* args->distance_f) + 32768);
722
Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
723
724
* args->distance_f) + 32768);
725
switch (args->room_angle) {
726
case 0:
727
728
729
730
731
732
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapce);
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
733
734
break;
case 90:
735
736
737
738
739
740
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
741
742
break;
case 180:
743
744
745
746
747
748
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
749
750
break;
case 270:
751
752
753
754
755
756
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
757
break;
758
}
759
760
761
}
}
762
static void SDLCALL _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
763
764
765
766
767
{
/* 16 signed bits (lsb) * 2 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
768
769
(void)chan;
770
771
#if 0
772
if (len % (int)(sizeof(Sint16) * 2)) {
773
774
fprintf(stderr,"Not an even number of frames! len=%d\n", len);
return;
775
776
777
}
#endif
778
for (i = 0; i < len; i += sizeof (Sint16) * 2) {
779
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
780
args->left_f) * args->distance_f);
781
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
782
args->right_f) * args->distance_f);
783
if (args->room_angle == 180) {
784
785
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
786
787
}
else {
788
789
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
790
}
791
792
}
}
793
static void SDLCALL _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
794
795
796
797
798
{
/* 16 signed bits (lsb) * 4 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
799
800
(void)chan;
801
802
803
804
805
806
807
808
809
810
for (i = 0; i < len; i += sizeof (Sint16) * 4) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
args->right_rear_f) * args->distance_f);
811
switch (args->room_angle) {
812
case 0:
813
814
815
816
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
817
818
break;
case 90:
819
820
821
822
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
823
824
break;
case 180:
825
826
827
828
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
829
830
break;
case 270:
831
832
833
834
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
835
break;
836
}
837
838
839
}
}
840
static void SDLCALL _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
841
842
843
844
845
{
/* 16 signed bits (lsb) * 6 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
846
847
(void)chan;
848
849
850
851
852
853
854
855
856
857
858
859
860
861
for (i = 0; i < len; i += sizeof (Sint16) * 6) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
args->right_rear_f) * args->distance_f);
Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
args->center_f) * args->distance_f);
Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
args->lfe_f) * args->distance_f);
862
switch (args->room_angle) {
863
case 0:
864
865
866
867
868
869
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapce);
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
870
871
break;
case 90:
872
873
874
875
876
877
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
878
879
break;
case 180:
880
881
882
883
884
885
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
886
887
break;
case 270:
888
889
890
891
892
893
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
894
break;
895
}
896
897
898
}
}
899
static void SDLCALL _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
900
901
902
903
904
{
/* 16 signed bits (lsb) * 2 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
905
906
(void)chan;
907
908
for (i = 0; i < len; i += sizeof (Sint16) * 2) {
909
910
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
911
912
913
914
915
916
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
917
if (args->room_angle == 180) {
918
919
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
920
921
}
else {
922
923
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
924
}
925
926
}
}
927
928
static void SDLCALL _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
929
930
931
932
933
{
/* 16 signed bits (lsb) * 4 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
934
935
(void)chan;
936
937
938
939
940
941
for (i = 0; i < len; i += sizeof (Sint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
942
943
944
945
946
947
948
949
950
951
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
* args->distance_f) + 32768);
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
* args->distance_f) + 32768);
952
switch (args->room_angle) {
953
case 0:
954
955
956
957
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
958
959
break;
case 90:
960
961
962
963
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
964
965
break;
case 180:
966
967
968
969
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
970
971
break;
case 270:
972
973
974
975
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
976
break;
977
}
978
979
}
}
980
981
static void SDLCALL _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
982
983
984
985
986
{
/* 16 signed bits (lsb) * 6 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
987
988
(void)chan;
989
990
991
992
993
994
995
996
for (i = 0; i < len; i += sizeof (Sint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
997
998
999
1000
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)