1 /*
2 SDL_mixer: An audio mixer library based on the SDL library
3 Copyright (C) 1997-2009 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 This file by Ryan C. Gordon (icculus@icculus.org)
20
21 These are some internally supported special effects that use SDL_mixer's
22 effect callback API. They are meant for speed over quality. :)
23 */
24
25 /* $Id: effect_position.c 5045 2009-10-11 02:59:12Z icculus $ */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "SDL.h"
32 #include "SDL_mixer.h"
33 #include "SDL_endian.h"
34
35 #define __MIX_INTERNAL_EFFECT__
36 #include "effects_internal.h"
37
38 /* profile code:
39 #include <sys/time.h>
40 #include <unistd.h>
41 struct timeval tv1;
42 struct timeval tv2;
43
44 gettimeofday(&tv1, NULL);
45
46 ... do your thing here ...
47
48 gettimeofday(&tv2, NULL);
49 printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
50 */
51
52
53 /*
54 * Positional effects...panning, distance attenuation, etc.
55 */
56
57 typedef struct _Eff_positionargs
58 {
59 volatile float left_f;
60 volatile float right_f;
61 volatile Uint8 left_u8;
62 volatile Uint8 right_u8;
63 volatile float left_rear_f;
64 volatile float right_rear_f;
65 volatile float center_f;
66 volatile float lfe_f;
67 volatile Uint8 left_rear_u8;
68 volatile Uint8 right_rear_u8;
69 volatile Uint8 center_u8;
70 volatile Uint8 lfe_u8;
71 volatile float distance_f;
72 volatile Uint8 distance_u8;
73 volatile Sint16 room_angle;
74 volatile int in_use;
75 volatile int channels;
76 } position_args;
77
78 static position_args **pos_args_array = NULL;
79 static position_args *pos_args_global = NULL;
80 static int position_channels = 0;
81
_Eff_PositionDeinit(void)82 void _Eff_PositionDeinit(void)
83 {
84 int i;
85 for (i = 0; i < position_channels; i++) {
86 free(pos_args_array[i]);
87 }
88
89 position_channels = 0;
90
91 free(pos_args_global);
92 pos_args_global = NULL;
93 free(pos_args_array);
94 pos_args_array = NULL;
95 }
96
97
98 /* This just frees up the callback-specific data. */
_Eff_PositionDone(int channel,void * udata)99 static void _Eff_PositionDone(int channel, void *udata)
100 {
101 if (channel < 0) {
102 if (pos_args_global != NULL) {
103 free(pos_args_global);
104 pos_args_global = NULL;
105 }
106 }
107
108 else if (pos_args_array[channel] != NULL) {
109 free(pos_args_array[channel]);
110 pos_args_array[channel] = NULL;
111 }
112 }
113
114
_Eff_position_u8(int chan,void * stream,int len,void * udata)115 static void _Eff_position_u8(int chan, void *stream, int len, void *udata)
116 {
117 volatile position_args *args = (volatile position_args *) udata;
118 Uint8 *ptr = (Uint8 *) stream;
119 int i;
120
121 /*
122 * if there's only a mono channnel (the only way we wouldn't have
123 * a len divisible by 2 here), then left_f and right_f are always
124 * 1.0, and are therefore throwaways.
125 */
126 if (len % sizeof (Uint16) != 0) {
127 *ptr = (Uint8) (((float) *ptr) * args->distance_f);
128 ptr++;
129 len--;
130 }
131
132 if (args->room_angle == 180)
133 for (i = 0; i < len; i += sizeof (Uint8) * 2) {
134 /* must adjust the sample so that 0 is the center */
135 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
136 * args->right_f) * args->distance_f) + 128);
137 ptr++;
138 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
139 * args->left_f) * args->distance_f) + 128);
140 ptr++;
141 }
142 else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
143 /* must adjust the sample so that 0 is the center */
144 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
145 * args->left_f) * args->distance_f) + 128);
146 ptr++;
147 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
148 * args->right_f) * args->distance_f) + 128);
149 ptr++;
150 }
151 }
_Eff_position_u8_c4(int chan,void * stream,int len,void * udata)152 static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
153 {
154 volatile position_args *args = (volatile position_args *) udata;
155 Uint8 *ptr = (Uint8 *) stream;
156 int i;
157
158 /*
159 * if there's only a mono channnel (the only way we wouldn't have
160 * a len divisible by 2 here), then left_f and right_f are always
161 * 1.0, and are therefore throwaways.
162 */
163 if (len % sizeof (Uint16) != 0) {
164 *ptr = (Uint8) (((float) *ptr) * args->distance_f);
165 ptr++;
166 len--;
167 }
168
169 if (args->room_angle == 0)
170 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
171 /* must adjust the sample so that 0 is the center */
172 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
173 * args->left_f) * args->distance_f) + 128);
174 ptr++;
175 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
176 * args->right_f) * args->distance_f) + 128);
177 ptr++;
178 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
179 * args->left_rear_f) * args->distance_f) + 128);
180 ptr++;
181 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
182 * args->right_rear_f) * args->distance_f) + 128);
183 ptr++;
184 }
185 else if (args->room_angle == 90)
186 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
187 /* must adjust the sample so that 0 is the center */
188 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
189 * args->right_f) * args->distance_f) + 128);
190 ptr++;
191 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
192 * args->right_rear_f) * args->distance_f) + 128);
193 ptr++;
194 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
195 * args->left_f) * args->distance_f) + 128);
196 ptr++;
197 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
198 * args->left_rear_f) * args->distance_f) + 128);
199 ptr++;
200 }
201 else if (args->room_angle == 180)
202 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
203 /* must adjust the sample so that 0 is the center */
204 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
205 * args->right_rear_f) * args->distance_f) + 128);
206 ptr++;
207 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
208 * args->left_rear_f) * args->distance_f) + 128);
209 ptr++;
210 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
211 * args->right_f) * args->distance_f) + 128);
212 ptr++;
213 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
214 * args->left_f) * args->distance_f) + 128);
215 ptr++;
216 }
217 else if (args->room_angle == 270)
218 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
219 /* must adjust the sample so that 0 is the center */
220 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
221 * args->left_rear_f) * args->distance_f) + 128);
222 ptr++;
223 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
224 * args->left_f) * args->distance_f) + 128);
225 ptr++;
226 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
227 * args->right_rear_f) * args->distance_f) + 128);
228 ptr++;
229 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
230 * args->right_f) * args->distance_f) + 128);
231 ptr++;
232 }
233 }
234
235
_Eff_position_u8_c6(int chan,void * stream,int len,void * udata)236 static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
237 {
238 volatile position_args *args = (volatile position_args *) udata;
239 Uint8 *ptr = (Uint8 *) stream;
240 int i;
241
242 /*
243 * if there's only a mono channnel (the only way we wouldn't have
244 * a len divisible by 2 here), then left_f and right_f are always
245 * 1.0, and are therefore throwaways.
246 */
247 if (len % sizeof (Uint16) != 0) {
248 *ptr = (Uint8) (((float) *ptr) * args->distance_f);
249 ptr++;
250 len--;
251 }
252
253 if (args->room_angle == 0)
254 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
255 /* must adjust the sample so that 0 is the center */
256 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
257 * args->left_f) * args->distance_f) + 128);
258 ptr++;
259 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
260 * args->right_f) * args->distance_f) + 128);
261 ptr++;
262 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
263 * args->left_rear_f) * args->distance_f) + 128);
264 ptr++;
265 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
266 * args->right_rear_f) * args->distance_f) + 128);
267 ptr++;
268 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
269 * args->center_f) * args->distance_f) + 128);
270 ptr++;
271 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
272 * args->lfe_f) * args->distance_f) + 128);
273 ptr++;
274 }
275 else if (args->room_angle == 90)
276 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
277 /* must adjust the sample so that 0 is the center */
278 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
279 * args->right_f) * args->distance_f) + 128);
280 ptr++;
281 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
282 * args->right_rear_f) * args->distance_f) + 128);
283 ptr++;
284 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
285 * args->left_f) * args->distance_f) + 128);
286 ptr++;
287 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
288 * args->left_rear_f) * args->distance_f) + 128);
289 ptr++;
290 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
291 * args->right_rear_f) * args->distance_f/2) + 128)
292 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
293 * args->right_f) * args->distance_f/2) + 128);
294 ptr++;
295 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
296 * args->lfe_f) * args->distance_f) + 128);
297 ptr++;
298 }
299 else if (args->room_angle == 180)
300 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
301 /* must adjust the sample so that 0 is the center */
302 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
303 * args->right_rear_f) * args->distance_f) + 128);
304 ptr++;
305 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
306 * args->left_rear_f) * args->distance_f) + 128);
307 ptr++;
308 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
309 * args->right_f) * args->distance_f) + 128);
310 ptr++;
311 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
312 * args->left_f) * args->distance_f) + 128);
313 ptr++;
314 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
315 * args->right_rear_f) * args->distance_f/2) + 128)
316 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
317 * args->left_rear_f) * args->distance_f/2) + 128);
318 ptr++;
319 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
320 * args->lfe_f) * args->distance_f) + 128);
321 ptr++;
322 }
323 else if (args->room_angle == 270)
324 for (i = 0; i < len; i += sizeof (Uint8) * 6) {
325 /* must adjust the sample so that 0 is the center */
326 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
327 * args->left_rear_f) * args->distance_f) + 128);
328 ptr++;
329 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
330 * args->left_f) * args->distance_f) + 128);
331 ptr++;
332 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
333 * args->right_rear_f) * args->distance_f) + 128);
334 ptr++;
335 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
336 * args->right_f) * args->distance_f) + 128);
337 ptr++;
338 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
339 * args->left_f) * args->distance_f/2) + 128)
340 + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
341 * args->left_rear_f) * args->distance_f/2) + 128);
342 ptr++;
343 *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
344 * args->lfe_f) * args->distance_f) + 128);
345 ptr++;
346 }
347 }
348
349
350 /*
351 * This one runs about 10.1 times faster than the non-table version, with
352 * no loss in quality. It does, however, require 64k of memory for the
353 * lookup table. Also, this will only update position information once per
354 * call; the non-table version always checks the arguments for each sample,
355 * in case the user has called Mix_SetPanning() or whatnot again while this
356 * callback is running.
357 */
_Eff_position_table_u8(int chan,void * stream,int len,void * udata)358 static void _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
359 {
360 volatile position_args *args = (volatile position_args *) udata;
361 Uint8 *ptr = (Uint8 *) stream;
362 Uint32 *p;
363 int i;
364 Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
365 Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
366 Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
367
368 if (args->room_angle == 180) {
369 Uint8 *temp = l;
370 l = r;
371 r = temp;
372 }
373 /*
374 * if there's only a mono channnel, then l[] and r[] are always
375 * volume 255, and are therefore throwaways. Still, we have to
376 * be sure not to overrun the audio buffer...
377 */
378 while (len % sizeof (Uint32) != 0) {
379 *ptr = d[l[*ptr]];
380 ptr++;
381 if (args->channels > 1) {
382 *ptr = d[r[*ptr]];
383 ptr++;
384 }
385 len -= args->channels;
386 }
387
388 p = (Uint32 *) ptr;
389
390 for (i = 0; i < len; i += sizeof (Uint32)) {
391 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
392 *p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
393 (d[r[(*p & 0x00FF0000) >> 16]] << 16) |
394 (d[l[(*p & 0x0000FF00) >> 8]] << 8) |
395 (d[r[(*p & 0x000000FF) ]] ) ;
396 #else
397 *p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
398 (d[l[(*p & 0x00FF0000) >> 16]] << 16) |
399 (d[r[(*p & 0x0000FF00) >> 8]] << 8) |
400 (d[l[(*p & 0x000000FF) ]] ) ;
401 #endif
402 ++p;
403 }
404 }
405
406
_Eff_position_s8(int chan,void * stream,int len,void * udata)407 static void _Eff_position_s8(int chan, void *stream, int len, void *udata)
408 {
409 volatile position_args *args = (volatile position_args *) udata;
410 Sint8 *ptr = (Sint8 *) stream;
411 int i;
412
413 /*
414 * if there's only a mono channnel (the only way we wouldn't have
415 * a len divisible by 2 here), then left_f and right_f are always
416 * 1.0, and are therefore throwaways.
417 */
418 if (len % sizeof (Sint16) != 0) {
419 *ptr = (Sint8) (((float) *ptr) * args->distance_f);
420 ptr++;
421 len--;
422 }
423
424 if (args->room_angle == 180)
425 for (i = 0; i < len; i += sizeof (Sint8) * 2) {
426 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
427 ptr++;
428 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
429 ptr++;
430 }
431 else
432 for (i = 0; i < len; i += sizeof (Sint8) * 2) {
433 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
434 ptr++;
435 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
436 ptr++;
437 }
438 }
_Eff_position_s8_c4(int chan,void * stream,int len,void * udata)439 static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
440 {
441 volatile position_args *args = (volatile position_args *) udata;
442 Sint8 *ptr = (Sint8 *) stream;
443 int i;
444
445 /*
446 * if there's only a mono channnel (the only way we wouldn't have
447 * a len divisible by 2 here), then left_f and right_f are always
448 * 1.0, and are therefore throwaways.
449 */
450 if (len % sizeof (Sint16) != 0) {
451 *ptr = (Sint8) (((float) *ptr) * args->distance_f);
452 ptr++;
453 len--;
454 }
455
456 for (i = 0; i < len; i += sizeof (Sint8) * 4) {
457 switch (args->room_angle) {
458 case 0:
459 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
460 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
461 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
462 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
463 break;
464 case 90:
465 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
466 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
467 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
468 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
469 break;
470 case 180:
471 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
472 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
473 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
474 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
475 break;
476 case 270:
477 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
478 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
479 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
480 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
481 break;
482 }
483 }
484 }
_Eff_position_s8_c6(int chan,void * stream,int len,void * udata)485 static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
486 {
487 volatile position_args *args = (volatile position_args *) udata;
488 Sint8 *ptr = (Sint8 *) stream;
489 int i;
490
491 /*
492 * if there's only a mono channnel (the only way we wouldn't have
493 * a len divisible by 2 here), then left_f and right_f are always
494 * 1.0, and are therefore throwaways.
495 */
496 if (len % sizeof (Sint16) != 0) {
497 *ptr = (Sint8) (((float) *ptr) * args->distance_f);
498 ptr++;
499 len--;
500 }
501
502 for (i = 0; i < len; i += sizeof (Sint8) * 6) {
503 switch (args->room_angle) {
504 case 0:
505 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
506 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
507 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
508 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
509 *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
510 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
511 break;
512 case 90:
513 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
514 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
515 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
516 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
517 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
518 + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
519 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
520 break;
521 case 180:
522 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
523 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
524 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
525 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
526 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
527 + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
528 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
529 break;
530 case 270:
531 *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
532 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
533 *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
534 *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
535 *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
536 + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
537 *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
538 break;
539 }
540 }
541 }
542
543
544 /*
545 * This one runs about 10.1 times faster than the non-table version, with
546 * no loss in quality. It does, however, require 64k of memory for the
547 * lookup table. Also, this will only update position information once per
548 * call; the non-table version always checks the arguments for each sample,
549 * in case the user has called Mix_SetPanning() or whatnot again while this
550 * callback is running.
551 */
_Eff_position_table_s8(int chan,void * stream,int len,void * udata)552 static void _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
553 {
554 volatile position_args *args = (volatile position_args *) udata;
555 Sint8 *ptr = (Sint8 *) stream;
556 Uint32 *p;
557 int i;
558 Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
559 Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
560 Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
561
562 if (args->room_angle == 180) {
563 Sint8 *temp = l;
564 l = r;
565 r = temp;
566 }
567
568
569 while (len % sizeof (Uint32) != 0) {
570 *ptr = d[l[*ptr]];
571 ptr++;
572 if (args->channels > 1) {
573 *ptr = d[r[*ptr]];
574 ptr++;
575 }
576 len -= args->channels;
577 }
578
579 p = (Uint32 *) ptr;
580
581 for (i = 0; i < len; i += sizeof (Uint32)) {
582 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
583 *p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
584 (d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
585 (d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
586 (d[r[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
587 #else
588 *p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
589 (d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
590 (d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
591 (d[l[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
592 #endif
593 ++p;
594 }
595
596
597 }
598
599
600 /* !!! FIXME : Optimize the code for 16-bit samples? */
601
_Eff_position_u16lsb(int chan,void * stream,int len,void * udata)602 static void _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
603 {
604 volatile position_args *args = (volatile position_args *) udata;
605 Uint16 *ptr = (Uint16 *) stream;
606 int i;
607
608 for (i = 0; i < len; i += sizeof (Uint16) * 2) {
609 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
610 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
611
612 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
613 * args->distance_f) + 32768);
614 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
615 * args->distance_f) + 32768);
616
617 if (args->room_angle == 180) {
618 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
619 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
620 }
621 else {
622 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
623 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
624 }
625 }
626 }
_Eff_position_u16lsb_c4(int chan,void * stream,int len,void * udata)627 static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
628 {
629 volatile position_args *args = (volatile position_args *) udata;
630 Uint16 *ptr = (Uint16 *) stream;
631 int i;
632
633 for (i = 0; i < len; i += sizeof (Uint16) * 4) {
634 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
635 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
636 Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
637 Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
638
639 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
640 * args->distance_f) + 32768);
641 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
642 * args->distance_f) + 32768);
643 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
644 * args->distance_f) + 32768);
645 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
646 * args->distance_f) + 32768);
647
648 switch (args->room_angle) {
649 case 0:
650 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
651 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
652 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
653 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
654 break;
655 case 90:
656 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
657 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
658 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
659 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
660 break;
661 case 180:
662 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
663 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
664 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
665 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
666 break;
667 case 270:
668 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
669 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
670 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
671 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
672 break;
673 }
674 }
675 }
_Eff_position_u16lsb_c6(int chan,void * stream,int len,void * udata)676 static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
677 {
678 volatile position_args *args = (volatile position_args *) udata;
679 Uint16 *ptr = (Uint16 *) stream;
680 int i;
681
682 for (i = 0; i < len; i += sizeof (Uint16) * 6) {
683 Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
684 Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
685 Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
686 Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
687 Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
688 Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
689
690 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
691 * args->distance_f) + 32768);
692 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
693 * args->distance_f) + 32768);
694 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
695 * args->distance_f) + 32768);
696 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
697 * args->distance_f) + 32768);
698 Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
699 * args->distance_f) + 32768);
700 Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
701 * args->distance_f) + 32768);
702
703 switch (args->room_angle) {
704 case 0:
705 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
706 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
707 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
708 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
709 *(ptr++) = (Uint16) SDL_SwapLE16(swapce);
710 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
711 break;
712 case 90:
713 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
714 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
715 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
716 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
717 *(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
718 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
719 break;
720 case 180:
721 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
722 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
723 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
724 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
725 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
726 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
727 break;
728 case 270:
729 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
730 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
731 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
732 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
733 *(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
734 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
735 break;
736 }
737 }
738 }
739
_Eff_position_s16lsb(int chan,void * stream,int len,void * udata)740 static void _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
741 {
742 /* 16 signed bits (lsb) * 2 channels. */
743 volatile position_args *args = (volatile position_args *) udata;
744 Sint16 *ptr = (Sint16 *) stream;
745 int i;
746
747 #if 0
748 if (len % (sizeof(Sint16) * 2)) {
749 fprintf(stderr,"Not an even number of frames! len=%d\n", len);
750 return;
751 }
752 #endif
753
754 for (i = 0; i < len; i += sizeof (Sint16) * 2) {
755 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
756 args->left_f) * args->distance_f);
757 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
758 args->right_f) * args->distance_f);
759 if (args->room_angle == 180) {
760 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
761 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
762 }
763 else {
764 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
765 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
766 }
767 }
768 }
_Eff_position_s16lsb_c4(int chan,void * stream,int len,void * udata)769 static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
770 {
771 /* 16 signed bits (lsb) * 4 channels. */
772 volatile position_args *args = (volatile position_args *) udata;
773 Sint16 *ptr = (Sint16 *) stream;
774 int i;
775
776 for (i = 0; i < len; i += sizeof (Sint16) * 4) {
777 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
778 args->left_f) * args->distance_f);
779 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
780 args->right_f) * args->distance_f);
781 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
782 args->left_rear_f) * args->distance_f);
783 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
784 args->right_rear_f) * args->distance_f);
785 switch (args->room_angle) {
786 case 0:
787 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
788 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
789 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
790 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
791 break;
792 case 90:
793 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
794 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
795 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
796 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
797 break;
798 case 180:
799 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
800 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
801 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
802 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
803 break;
804 case 270:
805 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
806 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
807 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
808 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
809 break;
810 }
811 }
812 }
813
_Eff_position_s16lsb_c6(int chan,void * stream,int len,void * udata)814 static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
815 {
816 /* 16 signed bits (lsb) * 6 channels. */
817 volatile position_args *args = (volatile position_args *) udata;
818 Sint16 *ptr = (Sint16 *) stream;
819 int i;
820
821 for (i = 0; i < len; i += sizeof (Sint16) * 6) {
822 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
823 args->left_f) * args->distance_f);
824 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
825 args->right_f) * args->distance_f);
826 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
827 args->left_rear_f) * args->distance_f);
828 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
829 args->right_rear_f) * args->distance_f);
830 Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
831 args->center_f) * args->distance_f);
832 Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
833 args->lfe_f) * args->distance_f);
834 switch (args->room_angle) {
835 case 0:
836 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
837 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
838 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
839 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
840 *(ptr++) = (Sint16) SDL_SwapLE16(swapce);
841 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
842 break;
843 case 90:
844 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
845 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
846 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
847 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
848 *(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
849 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
850 break;
851 case 180:
852 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
853 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
854 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
855 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
856 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
857 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
858 break;
859 case 270:
860 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
861 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
862 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
863 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
864 *(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
865 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
866 break;
867 }
868 }
869 }
870
_Eff_position_u16msb(int chan,void * stream,int len,void * udata)871 static void _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
872 {
873 /* 16 signed bits (lsb) * 2 channels. */
874 volatile position_args *args = (volatile position_args *) udata;
875 Uint16 *ptr = (Uint16 *) stream;
876 int i;
877
878 for (i = 0; i < len; i += sizeof (Sint16) * 2) {
879 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
880 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
881
882 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
883 * args->distance_f) + 32768);
884 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
885 * args->distance_f) + 32768);
886
887 if (args->room_angle == 180) {
888 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
889 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
890 }
891 else {
892 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
893 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
894 }
895 }
896 }
_Eff_position_u16msb_c4(int chan,void * stream,int len,void * udata)897 static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
898 {
899 /* 16 signed bits (lsb) * 4 channels. */
900 volatile position_args *args = (volatile position_args *) udata;
901 Uint16 *ptr = (Uint16 *) stream;
902 int i;
903
904 for (i = 0; i < len; i += sizeof (Sint16) * 4) {
905 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
906 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
907 Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
908 Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
909
910 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
911 * args->distance_f) + 32768);
912 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
913 * args->distance_f) + 32768);
914 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
915 * args->distance_f) + 32768);
916 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
917 * args->distance_f) + 32768);
918
919 switch (args->room_angle) {
920 case 0:
921 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
922 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
923 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
924 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
925 break;
926 case 90:
927 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
928 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
929 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
930 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
931 break;
932 case 180:
933 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
934 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
935 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
936 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
937 break;
938 case 270:
939 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
940 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
941 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
942 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
943 break;
944 }
945 }
946 }
_Eff_position_u16msb_c6(int chan,void * stream,int len,void * udata)947 static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
948 {
949 /* 16 signed bits (lsb) * 6 channels. */
950 volatile position_args *args = (volatile position_args *) udata;
951 Uint16 *ptr = (Uint16 *) stream;
952 int i;
953
954 for (i = 0; i < len; i += sizeof (Sint16) * 6) {
955 Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
956 Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
957 Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
958 Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
959 Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
960 Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
961
962 Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
963 * args->distance_f) + 32768);
964 Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
965 * args->distance_f) + 32768);
966 Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
967 * args->distance_f) + 32768);
968 Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
969 * args->distance_f) + 32768);
970 Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
971 * args->distance_f) + 32768);
972 Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
973 * args->distance_f) + 32768);
974
975 switch (args->room_angle) {
976 case 0:
977 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
978 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
979 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
980 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
981 *(ptr++) = (Uint16) SDL_SwapBE16(swapce);
982 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
983 break;
984 case 90:
985 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
986 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
987 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
988 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
989 *(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
990 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
991 break;
992 case 180:
993 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
994 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
995 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
996 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
997 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
998 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
999 break;
1000 case 270:
1001 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
1002 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
1003 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
1004 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
1005 *(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
1006 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
1007 break;
1008 }
1009 }
1010 }
1011
_Eff_position_s16msb(int chan,void * stream,int len,void * udata)1012 static void _Eff_position_s16msb(int chan, void *stream, int len, void *udata)
1013 {
1014 /* 16 signed bits (lsb) * 2 channels. */
1015 volatile position_args *args = (volatile position_args *) udata;
1016 Sint16 *ptr = (Sint16 *) stream;
1017 int i;
1018
1019 for (i = 0; i < len; i += sizeof (Sint16) * 2) {
1020 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1021 args->left_f) * args->distance_f);
1022 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1023 args->right_f) * args->distance_f);
1024 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1025 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1026 }
1027 }
_Eff_position_s16msb_c4(int chan,void * stream,int len,void * udata)1028 static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
1029 {
1030 /* 16 signed bits (lsb) * 4 channels. */
1031 volatile position_args *args = (volatile position_args *) udata;
1032 Sint16 *ptr = (Sint16 *) stream;
1033 int i;
1034
1035 for (i = 0; i < len; i += sizeof (Sint16) * 4) {
1036 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1037 args->left_f) * args->distance_f);
1038 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1039 args->right_f) * args->distance_f);
1040 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1041 args->left_rear_f) * args->distance_f);
1042 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1043 args->right_rear_f) * args->distance_f);
1044 switch (args->room_angle) {
1045 case 0:
1046 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1047 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1048 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1049 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1050 break;
1051 case 90:
1052 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1053 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1054 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1055 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1056 break;
1057 case 180:
1058 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1059 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1060 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1061 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1062 break;
1063 case 270:
1064 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1065 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1066 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1067 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1068 break;
1069 }
1070 }
1071 }
_Eff_position_s16msb_c6(int chan,void * stream,int len,void * udata)1072 static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
1073 {
1074 /* 16 signed bits (lsb) * 6 channels. */
1075 volatile position_args *args = (volatile position_args *) udata;
1076 Sint16 *ptr = (Sint16 *) stream;
1077 int i;
1078
1079 for (i = 0; i < len; i += sizeof (Sint16) * 6) {
1080 Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1081 args->left_f) * args->distance_f);
1082 Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1083 args->right_f) * args->distance_f);
1084 Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1085 args->left_rear_f) * args->distance_f);
1086 Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1087 args->right_rear_f) * args->distance_f);
1088 Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
1089 args->center_f) * args->distance_f);
1090 Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
1091 args->lfe_f) * args->distance_f);
1092
1093 switch (args->room_angle) {
1094 case 0:
1095 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1096 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1097 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1098 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1099 *(ptr++) = (Sint16) SDL_SwapBE16(swapce);
1100 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1101 break;
1102 case 90:
1103 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1104 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1105 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1106 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1107 *(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
1108 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1109 break;
1110 case 180:
1111 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1112 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1113 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1114 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1115 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1116 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1117 break;
1118 case 270:
1119 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1120 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1121 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1122 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1123 *(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1124 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1125 break;
1126 }
1127 }
1128 }
1129
init_position_args(position_args * args)1130 static void init_position_args(position_args *args)
1131 {
1132 memset(args, '\0', sizeof (position_args));
1133 args->in_use = 0;
1134 args->room_angle = 0;
1135 args->left_u8 = args->right_u8 = args->distance_u8 = 255;
1136 args->left_f = args->right_f = args->distance_f = 1.0f;
1137 args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
1138 args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
1139 Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
1140 }
1141
1142
get_position_arg(int channel)1143 static position_args *get_position_arg(int channel)
1144 {
1145 void *rc;
1146 int i;
1147
1148 if (channel < 0) {
1149 if (pos_args_global == NULL) {
1150 pos_args_global = malloc(sizeof (position_args));
1151 if (pos_args_global == NULL) {
1152 Mix_SetError("Out of memory");
1153 return(NULL);
1154 }
1155 init_position_args(pos_args_global);
1156 }
1157
1158 return(pos_args_global);
1159 }
1160
1161 if (channel >= position_channels) {
1162 rc = realloc(pos_args_array, (channel + 1) * sizeof (position_args *));
1163 if (rc == NULL) {
1164 Mix_SetError("Out of memory");
1165 return(NULL);
1166 }
1167 pos_args_array = (position_args **) rc;
1168 for (i = position_channels; i <= channel; i++) {
1169 pos_args_array[i] = NULL;
1170 }
1171 position_channels = channel + 1;
1172 }
1173
1174 if (pos_args_array[channel] == NULL) {
1175 pos_args_array[channel] = (position_args *)malloc(sizeof(position_args));
1176 if (pos_args_array[channel] == NULL) {
1177 Mix_SetError("Out of memory");
1178 return(NULL);
1179 }
1180 init_position_args(pos_args_array[channel]);
1181 }
1182
1183 return(pos_args_array[channel]);
1184 }
1185
1186
get_position_effect_func(Uint16 format,int channels)1187 static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
1188 {
1189 Mix_EffectFunc_t f = NULL;
1190
1191 switch (format) {
1192 case AUDIO_U8:
1193 switch (channels) {
1194 case 1:
1195 case 2:
1196 f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
1197 _Eff_position_u8;
1198 break;
1199 case 4:
1200 f = _Eff_position_u8_c4;
1201 break;
1202 case 6:
1203 f = _Eff_position_u8_c6;
1204 break;
1205 }
1206 break;
1207
1208 case AUDIO_S8:
1209 switch (channels) {
1210 case 1:
1211 case 2:
1212 f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
1213 _Eff_position_s8;
1214 break;
1215 case 4:
1216 f = _Eff_position_s8_c4;
1217 break;
1218 case 6:
1219 f = _Eff_position_s8_c6;
1220 break;
1221 }
1222 break;
1223
1224 case AUDIO_U16LSB:
1225 switch (channels) {
1226 case 1:
1227 case 2:
1228 f = _Eff_position_u16lsb;
1229 break;
1230 case 4:
1231 f = _Eff_position_u16lsb_c4;
1232 break;
1233 case 6:
1234 f = _Eff_position_u16lsb_c6;
1235 break;
1236 }
1237 break;
1238
1239 case AUDIO_S16LSB:
1240 switch (channels) {
1241 case 1:
1242 case 2:
1243 f = _Eff_position_s16lsb;
1244 break;
1245 case 4:
1246 f = _Eff_position_s16lsb_c4;
1247 break;
1248 case 6:
1249 f = _Eff_position_s16lsb_c6;
1250 break;
1251 }
1252 break;
1253
1254 case AUDIO_U16MSB:
1255 switch (channels) {
1256 case 1:
1257 case 2:
1258 f = _Eff_position_u16msb;
1259 break;
1260 case 4:
1261 f = _Eff_position_u16msb_c4;
1262 break;
1263 case 6:
1264 f = _Eff_position_u16msb_c6;
1265 break;
1266 }
1267 break;
1268
1269 case AUDIO_S16MSB:
1270 switch (channels) {
1271 case 1:
1272 case 2:
1273 f = _Eff_position_s16msb;
1274 break;
1275 case 4:
1276 f = _Eff_position_s16msb_c4;
1277 break;
1278 case 6:
1279 f = _Eff_position_s16msb_c6;
1280 break;
1281 }
1282 break;
1283
1284 default:
1285 Mix_SetError("Unsupported audio format");
1286 }
1287
1288 return(f);
1289 }
1290
1291 static Uint8 speaker_amplitude[6];
1292
set_amplitudes(int channels,int angle,int room_angle)1293 static void set_amplitudes(int channels, int angle, int room_angle)
1294 {
1295 int left = 255, right = 255;
1296 int left_rear = 255, right_rear = 255, center = 255;
1297
1298 angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
1299
1300 if (channels == 2)
1301 {
1302 /*
1303 * We only attenuate by position if the angle falls on the far side
1304 * of center; That is, an angle that's due north would not attenuate
1305 * either channel. Due west attenuates the right channel to 0.0, and
1306 * due east attenuates the left channel to 0.0. Slightly east of
1307 * center attenuates the left channel a little, and the right channel
1308 * not at all. I think of this as occlusion by one's own head. :)
1309 *
1310 * ...so, we split our angle circle into four quadrants...
1311 */
1312 if (angle < 90) {
1313 left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
1314 } else if (angle < 180) {
1315 left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
1316 } else if (angle < 270) {
1317 right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
1318 } else {
1319 right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
1320 }
1321 }
1322
1323 if (channels == 4 || channels == 6)
1324 {
1325 /*
1326 * An angle that's due north does not attenuate the center channel.
1327 * An angle in the first quadrant, 0-90, does not attenuate the RF.
1328 *
1329 * ...so, we split our angle circle into 8 ...
1330 *
1331 * CE
1332 * 0
1333 * LF | RF
1334 * |
1335 * 270<-------|----------->90
1336 * |
1337 * LR | RR
1338 * 180
1339 *
1340 */
1341 if (angle < 45) {
1342 left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
1343 left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
1344 right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
1345 } else if (angle < 90) {
1346 center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
1347 left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
1348 left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
1349 right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
1350 } else if (angle < 135) {
1351 center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
1352 left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
1353 right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
1354 left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
1355 } else if (angle < 180) {
1356 center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
1357 left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
1358 right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
1359 left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
1360 } else if (angle < 225) {
1361 center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
1362 left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
1363 right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
1364 right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
1365 } else if (angle < 270) {
1366 center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
1367 left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
1368 right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
1369 right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
1370 } else if (angle < 315) {
1371 center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
1372 right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
1373 left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
1374 right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
1375 } else {
1376 right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
1377 left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
1378 right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
1379 }
1380 }
1381
1382 if (left < 0) left = 0; if (left > 255) left = 255;
1383 if (right < 0) right = 0; if (right > 255) right = 255;
1384 if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
1385 if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
1386 if (center < 0) center = 0; if (center > 255) center = 255;
1387
1388 if (room_angle == 90) {
1389 speaker_amplitude[0] = (Uint8)left_rear;
1390 speaker_amplitude[1] = (Uint8)left;
1391 speaker_amplitude[2] = (Uint8)right_rear;
1392 speaker_amplitude[3] = (Uint8)right;
1393 }
1394 else if (room_angle == 180) {
1395 if (channels == 2) {
1396 speaker_amplitude[0] = (Uint8)right;
1397 speaker_amplitude[1] = (Uint8)left;
1398 }
1399 else {
1400 speaker_amplitude[0] = (Uint8)right_rear;
1401 speaker_amplitude[1] = (Uint8)left_rear;
1402 speaker_amplitude[2] = (Uint8)right;
1403 speaker_amplitude[3] = (Uint8)left;
1404 }
1405 }
1406 else if (room_angle == 270) {
1407 speaker_amplitude[0] = (Uint8)right;
1408 speaker_amplitude[1] = (Uint8)right_rear;
1409 speaker_amplitude[2] = (Uint8)left;
1410 speaker_amplitude[3] = (Uint8)left_rear;
1411 }
1412 else {
1413 speaker_amplitude[0] = (Uint8)left;
1414 speaker_amplitude[1] = (Uint8)right;
1415 speaker_amplitude[2] = (Uint8)left_rear;
1416 speaker_amplitude[3] = (Uint8)right_rear;
1417 }
1418 speaker_amplitude[4] = (Uint8)center;
1419 speaker_amplitude[5] = 255;
1420 }
1421
1422 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
1423
Mix_SetPanning(int channel,Uint8 left,Uint8 right)1424 int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
1425 {
1426 Mix_EffectFunc_t f = NULL;
1427 int channels;
1428 Uint16 format;
1429 position_args *args = NULL;
1430 int retval = 1;
1431
1432 Mix_QuerySpec(NULL, &format, &channels);
1433
1434 if (channels != 2 && channels != 4 && channels != 6) /* it's a no-op; we call that successful. */
1435 return(1);
1436
1437 if (channels > 2) {
1438 /* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */
1439 /* left = 255 => angle = -90; left = 0 => angle = +89 */
1440 int angle = 0;
1441 if ((left != 255) || (right != 255)) {
1442 angle = (int)left;
1443 angle = 127 - angle;
1444 angle = -angle;
1445 angle = angle * 90 / 128; /* Make it larger for more effect? */
1446 }
1447 return( Mix_SetPosition(channel, angle, 0) );
1448 }
1449
1450 f = get_position_effect_func(format, channels);
1451 if (f == NULL)
1452 return(0);
1453
1454 SDL_LockAudio();
1455 args = get_position_arg(channel);
1456 if (!args) {
1457 SDL_UnlockAudio();
1458 return(0);
1459 }
1460
1461 /* it's a no-op; unregister the effect, if it's registered. */
1462 if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) {
1463 if (args->in_use) {
1464 retval = _Mix_UnregisterEffect_locked(channel, f);
1465 SDL_UnlockAudio();
1466 return(retval);
1467 } else {
1468 SDL_UnlockAudio();
1469 return(1);
1470 }
1471 }
1472
1473 args->left_u8 = left;
1474 args->left_f = ((float) left) / 255.0f;
1475 args->right_u8 = right;
1476 args->right_f = ((float) right) / 255.0f;
1477 args->room_angle = 0;
1478
1479 if (!args->in_use) {
1480 args->in_use = 1;
1481 retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args);
1482 }
1483
1484 SDL_UnlockAudio();
1485 return(retval);
1486 }
1487
1488
Mix_SetDistance(int channel,Uint8 distance)1489 int Mix_SetDistance(int channel, Uint8 distance)
1490 {
1491 Mix_EffectFunc_t f = NULL;
1492 Uint16 format;
1493 position_args *args = NULL;
1494 int channels;
1495 int retval = 1;
1496
1497 Mix_QuerySpec(NULL, &format, &channels);
1498 f = get_position_effect_func(format, channels);
1499 if (f == NULL)
1500 return(0);
1501
1502 SDL_LockAudio();
1503 args = get_position_arg(channel);
1504 if (!args) {
1505 SDL_UnlockAudio();
1506 return(0);
1507 }
1508
1509 distance = 255 - distance; /* flip it to our scale. */
1510
1511 /* it's a no-op; unregister the effect, if it's registered. */
1512 if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) {
1513 if (args->in_use) {
1514 retval = _Mix_UnregisterEffect_locked(channel, f);
1515 SDL_UnlockAudio();
1516 return(retval);
1517 } else {
1518 SDL_UnlockAudio();
1519 return(1);
1520 }
1521 }
1522
1523 args->distance_u8 = distance;
1524 args->distance_f = ((float) distance) / 255.0f;
1525 if (!args->in_use) {
1526 args->in_use = 1;
1527 retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
1528 }
1529
1530 SDL_UnlockAudio();
1531 return(retval);
1532 }
1533
1534
Mix_SetPosition(int channel,Sint16 angle,Uint8 distance)1535 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
1536 {
1537 Mix_EffectFunc_t f = NULL;
1538 Uint16 format;
1539 int channels;
1540 position_args *args = NULL;
1541 Sint16 room_angle = 0;
1542 int retval = 1;
1543
1544 Mix_QuerySpec(NULL, &format, &channels);
1545 f = get_position_effect_func(format, channels);
1546 if (f == NULL)
1547 return(0);
1548
1549 angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
1550
1551 SDL_LockAudio();
1552 args = get_position_arg(channel);
1553 if (!args) {
1554 SDL_UnlockAudio();
1555 return(0);
1556 }
1557
1558 /* it's a no-op; unregister the effect, if it's registered. */
1559 if ((!distance) && (!angle)) {
1560 if (args->in_use) {
1561 retval = _Mix_UnregisterEffect_locked(channel, f);
1562 SDL_UnlockAudio();
1563 return(retval);
1564 } else {
1565 SDL_UnlockAudio();
1566 return(1);
1567 }
1568 }
1569
1570 if (channels == 2)
1571 {
1572 if (angle > 180)
1573 room_angle = 180; /* exchange left and right channels */
1574 else room_angle = 0;
1575 }
1576
1577 if (channels == 4 || channels == 6)
1578 {
1579 if (angle > 315) room_angle = 0;
1580 else if (angle > 225) room_angle = 270;
1581 else if (angle > 135) room_angle = 180;
1582 else if (angle > 45) room_angle = 90;
1583 else room_angle = 0;
1584 }
1585
1586
1587 distance = 255 - distance; /* flip it to scale Mix_SetDistance() uses. */
1588
1589 set_amplitudes(channels, angle, room_angle);
1590
1591 args->left_u8 = speaker_amplitude[0];
1592 args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
1593 args->right_u8 = speaker_amplitude[1];
1594 args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
1595 args->left_rear_u8 = speaker_amplitude[2];
1596 args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
1597 args->right_rear_u8 = speaker_amplitude[3];
1598 args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
1599 args->center_u8 = speaker_amplitude[4];
1600 args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
1601 args->lfe_u8 = speaker_amplitude[5];
1602 args->lfe_f = ((float) speaker_amplitude[5]) / 255.0f;
1603 args->distance_u8 = distance;
1604 args->distance_f = ((float) distance) / 255.0f;
1605 args->room_angle = room_angle;
1606 if (!args->in_use) {
1607 args->in_use = 1;
1608 retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
1609 }
1610
1611 SDL_UnlockAudio();
1612 return(retval);
1613 }
1614
1615
1616 /* end of effects_position.c ... */
1617
1618