1 /*
2   SDL_mixer:  An audio mixer library based on the SDL library
3   Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   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   These are some internally supported special effects that use SDL_mixer's
24   effect callback API. They are meant for speed over quality.  :)
25 */
26 
27 /* $Id$ */
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "SDL.h"
34 #include "SDL_endian.h"
35 #include "SDL_mixer.h"
36 #include "mixer.h"
37 
38 #define __MIX_INTERNAL_EFFECT__
39 #include "effects_internal.h"
40 
41 /* profile code:
42     #include <sys/time.h>
43     #include <unistd.h>
44     struct timeval tv1;
45     struct timeval tv2;
46 
47     gettimeofday(&tv1, NULL);
48 
49         ... do your thing here ...
50 
51     gettimeofday(&tv2, NULL);
52     printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
53 */
54 
55 
56 /*
57  * Positional effects...panning, distance attenuation, etc.
58  */
59 
60 typedef struct _Eff_positionargs
61 {
62     volatile float left_f;
63     volatile float right_f;
64     volatile Uint8 left_u8;
65     volatile Uint8 right_u8;
66     volatile float left_rear_f;
67     volatile float right_rear_f;
68     volatile float center_f;
69     volatile float lfe_f;
70     volatile Uint8 left_rear_u8;
71     volatile Uint8 right_rear_u8;
72     volatile Uint8 center_u8;
73     volatile Uint8 lfe_u8;
74     volatile float distance_f;
75     volatile Uint8 distance_u8;
76     volatile Sint16 room_angle;
77     volatile int in_use;
78     volatile int channels;
79 } position_args;
80 
81 static position_args **pos_args_array = NULL;
82 static position_args *pos_args_global = NULL;
83 static int position_channels = 0;
84 
_Eff_PositionDeinit(void)85 void _Eff_PositionDeinit(void)
86 {
87     int i;
88     for (i = 0; i < position_channels; i++) {
89         SDL_free(pos_args_array[i]);
90     }
91 
92     position_channels = 0;
93 
94     SDL_free(pos_args_global);
95     pos_args_global = NULL;
96     SDL_free(pos_args_array);
97     pos_args_array = NULL;
98 }
99 
100 
101 /* This just frees up the callback-specific data. */
_Eff_PositionDone(int channel,void * udata)102 static void SDLCALL _Eff_PositionDone(int channel, void *udata)
103 {
104     if (channel < 0) {
105         if (pos_args_global != NULL) {
106             SDL_free(pos_args_global);
107             pos_args_global = NULL;
108         }
109     }
110 
111     else if (pos_args_array[channel] != NULL) {
112         SDL_free(pos_args_array[channel]);
113         pos_args_array[channel] = NULL;
114     }
115 }
116 
117 
_Eff_position_u8(int chan,void * stream,int len,void * udata)118 static void SDLCALL _Eff_position_u8(int chan, void *stream, int len, void *udata)
119 {
120     volatile position_args *args = (volatile position_args *) udata;
121     Uint8 *ptr = (Uint8 *) stream;
122     int i;
123 
124         /*
125          * if there's only a mono channnel (the only way we wouldn't have
126          *  a len divisible by 2 here), then left_f and right_f are always
127          *  1.0, and are therefore throwaways.
128          */
129     if (len % sizeof (Uint16) != 0) {
130         *ptr = (Uint8) (((float) *ptr) * args->distance_f);
131         ptr++;
132         len--;
133     }
134 
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             * args->right_f) * args->distance_f) + 128);
140         ptr++;
141         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
142             * args->left_f) * args->distance_f) + 128);
143         ptr++;
144     }
145     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 }
_Eff_position_u8_c4(int chan,void * stream,int len,void * udata)155 static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
156 {
157     volatile position_args *args = (volatile position_args *) udata;
158     Uint8 *ptr = (Uint8 *) stream;
159     int i;
160 
161         /*
162          * if there's only a mono channnel (the only way we wouldn't have
163          *  a len divisible by 2 here), then left_f and right_f are always
164          *  1.0, and are therefore throwaways.
165          */
166     if (len % sizeof (Uint16) != 0) {
167         *ptr = (Uint8) (((float) *ptr) * args->distance_f);
168         ptr++;
169         len--;
170     }
171 
172     if (args->room_angle == 0)
173     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
174         /* must adjust the sample so that 0 is the center */
175         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
176             * args->left_f) * args->distance_f) + 128);
177         ptr++;
178         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
179             * args->right_f) * args->distance_f) + 128);
180         ptr++;
181         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
182             * args->left_rear_f) * args->distance_f) + 128);
183         ptr++;
184         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
185             * args->right_rear_f) * args->distance_f) + 128);
186         ptr++;
187     }
188     else if (args->room_angle == 90)
189     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
190         /* must adjust the sample so that 0 is the center */
191         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
192             * args->right_f) * args->distance_f) + 128);
193         ptr++;
194         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
195             * args->right_rear_f) * args->distance_f) + 128);
196         ptr++;
197         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
198             * args->left_f) * args->distance_f) + 128);
199         ptr++;
200         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
201             * args->left_rear_f) * args->distance_f) + 128);
202         ptr++;
203     }
204     else if (args->room_angle == 180)
205     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
206         /* must adjust the sample so that 0 is the center */
207         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
208             * args->right_rear_f) * args->distance_f) + 128);
209         ptr++;
210         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
211             * args->left_rear_f) * args->distance_f) + 128);
212         ptr++;
213         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
214             * args->right_f) * args->distance_f) + 128);
215         ptr++;
216         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
217             * args->left_f) * args->distance_f) + 128);
218         ptr++;
219     }
220     else if (args->room_angle == 270)
221     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
222         /* must adjust the sample so that 0 is the center */
223         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
224             * args->left_rear_f) * args->distance_f) + 128);
225         ptr++;
226         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
227             * args->left_f) * args->distance_f) + 128);
228         ptr++;
229         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
230             * args->right_rear_f) * args->distance_f) + 128);
231         ptr++;
232         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
233             * args->right_f) * args->distance_f) + 128);
234         ptr++;
235     }
236 }
237 
238 
_Eff_position_u8_c6(int chan,void * stream,int len,void * udata)239 static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
240 {
241     volatile position_args *args = (volatile position_args *) udata;
242     Uint8 *ptr = (Uint8 *) stream;
243     int i;
244 
245         /*
246          * if there's only a mono channnel (the only way we wouldn't have
247          *  a len divisible by 2 here), then left_f and right_f are always
248          *  1.0, and are therefore throwaways.
249          */
250     if (len % sizeof (Uint16) != 0) {
251         *ptr = (Uint8) (((float) *ptr) * args->distance_f);
252         ptr++;
253         len--;
254     }
255 
256     if (args->room_angle == 0)
257     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
258         /* must adjust the sample so that 0 is the center */
259         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
260             * args->left_f) * args->distance_f) + 128);
261         ptr++;
262         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
263             * args->right_f) * args->distance_f) + 128);
264         ptr++;
265         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
266             * args->left_rear_f) * args->distance_f) + 128);
267         ptr++;
268         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
269             * args->right_rear_f) * args->distance_f) + 128);
270         ptr++;
271         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
272             * args->center_f) * args->distance_f) + 128);
273         ptr++;
274         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
275             * args->lfe_f) * args->distance_f) + 128);
276         ptr++;
277     }
278     else if (args->room_angle == 90)
279     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
280         /* must adjust the sample so that 0 is the center */
281         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
282             * args->right_f) * args->distance_f) + 128);
283         ptr++;
284         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
285             * args->right_rear_f) * args->distance_f) + 128);
286         ptr++;
287         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
288             * args->left_f) * args->distance_f) + 128);
289         ptr++;
290         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
291             * args->left_rear_f) * args->distance_f) + 128);
292         ptr++;
293         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
294             * args->right_rear_f) * args->distance_f/2) + 128)
295             + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
296             * args->right_f) * args->distance_f/2) + 128);
297         ptr++;
298         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
299             * args->lfe_f) * args->distance_f) + 128);
300         ptr++;
301     }
302     else if (args->room_angle == 180)
303     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
304         /* must adjust the sample so that 0 is the center */
305         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
306             * args->right_rear_f) * args->distance_f) + 128);
307         ptr++;
308         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
309             * args->left_rear_f) * args->distance_f) + 128);
310         ptr++;
311         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
312             * args->right_f) * args->distance_f) + 128);
313         ptr++;
314         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
315             * args->left_f) * args->distance_f) + 128);
316         ptr++;
317         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
318             * args->right_rear_f) * args->distance_f/2) + 128)
319             + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
320             * args->left_rear_f) * args->distance_f/2) + 128);
321         ptr++;
322         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
323             * args->lfe_f) * args->distance_f) + 128);
324         ptr++;
325     }
326     else if (args->room_angle == 270)
327     for (i = 0; i < len; i += sizeof (Uint8) * 6) {
328         /* must adjust the sample so that 0 is the center */
329         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
330             * args->left_rear_f) * args->distance_f) + 128);
331         ptr++;
332         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
333             * args->left_f) * args->distance_f) + 128);
334         ptr++;
335         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
336             * args->right_rear_f) * args->distance_f) + 128);
337         ptr++;
338         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
339             * args->right_f) * args->distance_f) + 128);
340         ptr++;
341         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
342             * args->left_f) * args->distance_f/2) + 128)
343             + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
344             * args->left_rear_f) * args->distance_f/2) + 128);
345         ptr++;
346         *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
347             * args->lfe_f) * args->distance_f) + 128);
348         ptr++;
349     }
350 }
351 
352 
353 /*
354  * This one runs about 10.1 times faster than the non-table version, with
355  *  no loss in quality. It does, however, require 64k of memory for the
356  *  lookup table. Also, this will only update position information once per
357  *  call; the non-table version always checks the arguments for each sample,
358  *  in case the user has called Mix_SetPanning() or whatnot again while this
359  *  callback is running.
360  */
_Eff_position_table_u8(int chan,void * stream,int len,void * udata)361 static void SDLCALL _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
362 {
363     volatile position_args *args = (volatile position_args *) udata;
364     Uint8 *ptr = (Uint8 *) stream;
365     Uint32 *p;
366     int i;
367     Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
368     Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
369     Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
370 
371     if (args->room_angle == 180) {
372         Uint8 *temp = l;
373         l = r;
374         r = temp;
375     }
376         /*
377          * if there's only a mono channnel, then l[] and r[] are always
378          *  volume 255, and are therefore throwaways. Still, we have to
379          *  be sure not to overrun the audio buffer...
380          */
381     while (len % sizeof (Uint32) != 0) {
382         *ptr = d[l[*ptr]];
383         ptr++;
384         if (args->channels > 1) {
385             *ptr = d[r[*ptr]];
386             ptr++;
387         }
388         len -= args->channels;
389     }
390 
391     p = (Uint32 *) ptr;
392 
393     for (i = 0; i < len; i += sizeof (Uint32)) {
394 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
395         *p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
396              (d[r[(*p & 0x00FF0000) >> 16]] << 16) |
397              (d[l[(*p & 0x0000FF00) >>  8]] <<  8) |
398              (d[r[(*p & 0x000000FF)      ]]     ) ;
399 #else
400         *p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
401              (d[l[(*p & 0x00FF0000) >> 16]] << 16) |
402              (d[r[(*p & 0x0000FF00) >>  8]] <<  8) |
403              (d[l[(*p & 0x000000FF)      ]]     ) ;
404 #endif
405         ++p;
406     }
407 }
408 
409 
_Eff_position_s8(int chan,void * stream,int len,void * udata)410 static void SDLCALL _Eff_position_s8(int chan, void *stream, int len, void *udata)
411 {
412     volatile position_args *args = (volatile position_args *) udata;
413     Sint8 *ptr = (Sint8 *) stream;
414     int i;
415 
416         /*
417          * if there's only a mono channnel (the only way we wouldn't have
418          *  a len divisible by 2 here), then left_f and right_f are always
419          *  1.0, and are therefore throwaways.
420          */
421     if (len % sizeof (Sint16) != 0) {
422         *ptr = (Sint8) (((float) *ptr) * args->distance_f);
423         ptr++;
424         len--;
425     }
426 
427     if (args->room_angle == 180)
428     for (i = 0; i < len; i += sizeof (Sint8) * 2) {
429         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
430         ptr++;
431         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
432         ptr++;
433     }
434     else
435     for (i = 0; i < len; i += sizeof (Sint8) * 2) {
436         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
437         ptr++;
438         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
439         ptr++;
440     }
441 }
_Eff_position_s8_c4(int chan,void * stream,int len,void * udata)442 static void SDLCALL _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
443 {
444     volatile position_args *args = (volatile position_args *) udata;
445     Sint8 *ptr = (Sint8 *) stream;
446     int i;
447 
448         /*
449          * if there's only a mono channnel (the only way we wouldn't have
450          *  a len divisible by 2 here), then left_f and right_f are always
451          *  1.0, and are therefore throwaways.
452          */
453     if (len % sizeof (Sint16) != 0) {
454         *ptr = (Sint8) (((float) *ptr) * args->distance_f);
455         ptr++;
456         len--;
457     }
458 
459     for (i = 0; i < len; i += sizeof (Sint8) * 4) {
460       switch (args->room_angle) {
461        case 0:
462         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
463         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
464         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
465         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
466     break;
467        case 90:
468         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
469         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
470         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
471         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
472     break;
473        case 180:
474         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
475         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
476         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
477         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
478     break;
479        case 270:
480         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
481         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
482         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
483         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
484     break;
485       }
486     }
487 }
_Eff_position_s8_c6(int chan,void * stream,int len,void * udata)488 static void SDLCALL _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
489 {
490     volatile position_args *args = (volatile position_args *) udata;
491     Sint8 *ptr = (Sint8 *) stream;
492     int i;
493 
494         /*
495          * if there's only a mono channnel (the only way we wouldn't have
496          *  a len divisible by 2 here), then left_f and right_f are always
497          *  1.0, and are therefore throwaways.
498          */
499     if (len % sizeof (Sint16) != 0) {
500         *ptr = (Sint8) (((float) *ptr) * args->distance_f);
501         ptr++;
502         len--;
503     }
504 
505     for (i = 0; i < len; i += sizeof (Sint8) * 6) {
506       switch (args->room_angle) {
507        case 0:
508         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
509         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
510         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
511         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
512         *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
513         *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
514     break;
515        case 90:
516         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
517         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
518         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
519         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
520         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
521            + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
522         *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
523     break;
524        case 180:
525         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
526         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
527         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
528         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
529         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
530            + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
531         *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
532     break;
533        case 270:
534         *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
535         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
536         *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
537         *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
538         *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
539            + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
540         *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
541     break;
542       }
543     }
544 }
545 
546 
547 /*
548  * This one runs about 10.1 times faster than the non-table version, with
549  *  no loss in quality. It does, however, require 64k of memory for the
550  *  lookup table. Also, this will only update position information once per
551  *  call; the non-table version always checks the arguments for each sample,
552  *  in case the user has called Mix_SetPanning() or whatnot again while this
553  *  callback is running.
554  */
_Eff_position_table_s8(int chan,void * stream,int len,void * udata)555 static void SDLCALL _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
556 {
557     volatile position_args *args = (volatile position_args *) udata;
558     Sint8 *ptr = (Sint8 *) stream;
559     Uint32 *p;
560     int i;
561     Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
562     Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
563     Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
564 
565     if (args->room_angle == 180) {
566         Sint8 *temp = l;
567         l = r;
568         r = temp;
569     }
570 
571 
572     while (len % sizeof (Uint32) != 0) {
573         *ptr = d[l[*ptr]];
574         ptr++;
575         if (args->channels > 1) {
576             *ptr = d[r[*ptr]];
577             ptr++;
578         }
579         len -= args->channels;
580     }
581 
582     p = (Uint32 *) ptr;
583 
584     for (i = 0; i < len; i += sizeof (Uint32)) {
585 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
586         *p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
587              (d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
588              (d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >>  8))+128]] <<  8) |
589              (d[r[((Sint16)(Sint8)((*p & 0x000000FF)     ))+128]]     ) ;
590 #else
591         *p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
592              (d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
593              (d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >>  8))+128]] <<  8) |
594              (d[l[((Sint16)(Sint8)((*p & 0x000000FF)     ))+128]]     ) ;
595 #endif
596         ++p;
597     }
598 
599 
600 }
601 
602 
603 /* !!! FIXME : Optimize the code for 16-bit samples? */
604 
_Eff_position_u16lsb(int chan,void * stream,int len,void * udata)605 static void SDLCALL _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
606 {
607     volatile position_args *args = (volatile position_args *) udata;
608     Uint16 *ptr = (Uint16 *) stream;
609     int i;
610 
611     for (i = 0; i < len; i += sizeof (Uint16) * 2) {
612         Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
613         Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
614 
615         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
616                                     * args->distance_f) + 32768);
617         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
618                                     * args->distance_f) + 32768);
619 
620     if (args->room_angle == 180) {
621             *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
622             *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
623     }
624     else {
625             *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
626             *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
627     }
628     }
629 }
_Eff_position_u16lsb_c4(int chan,void * stream,int len,void * udata)630 static void SDLCALL _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
631 {
632     volatile position_args *args = (volatile position_args *) udata;
633     Uint16 *ptr = (Uint16 *) stream;
634     int i;
635 
636     for (i = 0; i < len; i += sizeof (Uint16) * 4) {
637         Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
638         Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
639         Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
640         Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
641 
642         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
643                                     * args->distance_f) + 32768);
644         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
645                                     * args->distance_f) + 32768);
646         Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
647                                     * args->distance_f) + 32768);
648         Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
649                                     * args->distance_f) + 32768);
650 
651     switch (args->room_angle) {
652         case 0:
653                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
654                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
655                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
656                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
657             break;
658         case 90:
659                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
660                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
661                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
662                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
663             break;
664         case 180:
665                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
666                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
667                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
668                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
669             break;
670         case 270:
671                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
672                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
673                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
674                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
675             break;
676     }
677     }
678 }
_Eff_position_u16lsb_c6(int chan,void * stream,int len,void * udata)679 static void SDLCALL _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
680 {
681     volatile position_args *args = (volatile position_args *) udata;
682     Uint16 *ptr = (Uint16 *) stream;
683     int i;
684 
685     for (i = 0; i < len; i += sizeof (Uint16) * 6) {
686         Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
687         Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
688         Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
689         Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
690         Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
691         Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
692 
693         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
694                                     * args->distance_f) + 32768);
695         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
696                                     * args->distance_f) + 32768);
697         Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
698                                     * args->distance_f) + 32768);
699         Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
700                                     * args->distance_f) + 32768);
701         Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
702                                     * args->distance_f) + 32768);
703         Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
704                                     * args->distance_f) + 32768);
705 
706     switch (args->room_angle) {
707         case 0:
708                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
709                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
710                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
711                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
712                 *(ptr++) = (Uint16) SDL_SwapLE16(swapce);
713                 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
714             break;
715         case 90:
716                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
717                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
718                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
719                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
720                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
721                 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
722             break;
723         case 180:
724                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
725                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
726                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
727                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
728                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
729                 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
730             break;
731         case 270:
732                 *(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
733                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
734                 *(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
735                 *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
736                 *(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
737                 *(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
738             break;
739     }
740     }
741 }
742 
_Eff_position_s16lsb(int chan,void * stream,int len,void * udata)743 static void SDLCALL _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
744 {
745     /* 16 signed bits (lsb) * 2 channels. */
746     volatile position_args *args = (volatile position_args *) udata;
747     Sint16 *ptr = (Sint16 *) stream;
748     int i;
749 
750 #if 0
751     if (len % (sizeof(Sint16) * 2)) {
752         fprintf(stderr,"Not an even number of frames! len=%d\n", len);
753         return;
754     }
755 #endif
756 
757     for (i = 0; i < len; i += sizeof (Sint16) * 2) {
758         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
759                                     args->left_f) * args->distance_f);
760         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
761                                     args->right_f) * args->distance_f);
762     if (args->room_angle == 180) {
763             *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
764             *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
765     }
766     else {
767             *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
768             *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
769     }
770     }
771 }
_Eff_position_s16lsb_c4(int chan,void * stream,int len,void * udata)772 static void SDLCALL _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
773 {
774     /* 16 signed bits (lsb) * 4 channels. */
775     volatile position_args *args = (volatile position_args *) udata;
776     Sint16 *ptr = (Sint16 *) stream;
777     int i;
778 
779     for (i = 0; i < len; i += sizeof (Sint16) * 4) {
780         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
781                                     args->left_f) * args->distance_f);
782         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
783                                     args->right_f) * args->distance_f);
784         Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
785                                     args->left_rear_f) * args->distance_f);
786         Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
787                                     args->right_rear_f) * args->distance_f);
788     switch (args->room_angle) {
789         case 0:
790                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
791                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
792                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
793                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
794             break;
795         case 90:
796                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
797                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
798                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
799                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
800             break;
801         case 180:
802                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
803                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
804                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
805                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
806             break;
807         case 270:
808                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
809                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
810                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
811                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
812             break;
813     }
814     }
815 }
816 
_Eff_position_s16lsb_c6(int chan,void * stream,int len,void * udata)817 static void SDLCALL _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
818 {
819     /* 16 signed bits (lsb) * 6 channels. */
820     volatile position_args *args = (volatile position_args *) udata;
821     Sint16 *ptr = (Sint16 *) stream;
822     int i;
823 
824     for (i = 0; i < len; i += sizeof (Sint16) * 6) {
825         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
826                                     args->left_f) * args->distance_f);
827         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
828                                     args->right_f) * args->distance_f);
829         Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
830                                     args->left_rear_f) * args->distance_f);
831         Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
832                                     args->right_rear_f) * args->distance_f);
833         Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
834                                     args->center_f) * args->distance_f);
835         Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
836                                     args->lfe_f) * args->distance_f);
837     switch (args->room_angle) {
838         case 0:
839                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
840                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
841                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
842                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
843                 *(ptr++) = (Sint16) SDL_SwapLE16(swapce);
844                 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
845             break;
846         case 90:
847                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
848                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
849                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
850                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
851                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
852                 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
853             break;
854         case 180:
855                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
856                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
857                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
858                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
859                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
860                 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
861             break;
862         case 270:
863                 *(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
864                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
865                 *(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
866                 *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
867                 *(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
868                 *(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
869             break;
870     }
871     }
872 }
873 
_Eff_position_u16msb(int chan,void * stream,int len,void * udata)874 static void SDLCALL _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
875 {
876     /* 16 signed bits (lsb) * 2 channels. */
877     volatile position_args *args = (volatile position_args *) udata;
878     Uint16 *ptr = (Uint16 *) stream;
879     int i;
880 
881     for (i = 0; i < len; i += sizeof (Sint16) * 2) {
882         Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
883         Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
884 
885         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
886                                     * args->distance_f) + 32768);
887         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
888                                     * args->distance_f) + 32768);
889 
890     if (args->room_angle == 180) {
891             *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
892             *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
893     }
894     else {
895             *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
896             *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
897     }
898     }
899 }
_Eff_position_u16msb_c4(int chan,void * stream,int len,void * udata)900 static void SDLCALL _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
901 {
902     /* 16 signed bits (lsb) * 4 channels. */
903     volatile position_args *args = (volatile position_args *) udata;
904     Uint16 *ptr = (Uint16 *) stream;
905     int i;
906 
907     for (i = 0; i < len; i += sizeof (Sint16) * 4) {
908         Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
909         Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
910         Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
911         Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
912 
913         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
914                                     * args->distance_f) + 32768);
915         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
916                                     * args->distance_f) + 32768);
917         Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
918                                     * args->distance_f) + 32768);
919         Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
920                                     * args->distance_f) + 32768);
921 
922     switch (args->room_angle) {
923         case 0:
924                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
925                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
926                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
927                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
928             break;
929         case 90:
930                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
931                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
932                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
933                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
934             break;
935         case 180:
936                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
937                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
938                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
939                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
940             break;
941         case 270:
942                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
943                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
944                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
945                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
946             break;
947     }
948     }
949 }
_Eff_position_u16msb_c6(int chan,void * stream,int len,void * udata)950 static void SDLCALL _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
951 {
952     /* 16 signed bits (lsb) * 6 channels. */
953     volatile position_args *args = (volatile position_args *) udata;
954     Uint16 *ptr = (Uint16 *) stream;
955     int i;
956 
957     for (i = 0; i < len; i += sizeof (Sint16) * 6) {
958         Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
959         Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
960         Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
961         Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
962         Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
963         Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
964 
965         Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
966                                     * args->distance_f) + 32768);
967         Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
968                                     * args->distance_f) + 32768);
969         Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
970                                     * args->distance_f) + 32768);
971         Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
972                                     * args->distance_f) + 32768);
973         Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
974                                     * args->distance_f) + 32768);
975         Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
976                                     * args->distance_f) + 32768);
977 
978     switch (args->room_angle) {
979         case 0:
980                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
981                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
982                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
983                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
984                 *(ptr++) = (Uint16) SDL_SwapBE16(swapce);
985                 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
986             break;
987         case 90:
988                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
989                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
990                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
991                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
992                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
993                 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
994             break;
995         case 180:
996                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
997                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
998                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
999                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
1000                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
1001                 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
1002             break;
1003         case 270:
1004                 *(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
1005                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
1006                 *(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
1007                 *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
1008                 *(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
1009                 *(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
1010             break;
1011     }
1012     }
1013 }
1014 
_Eff_position_s16msb(int chan,void * stream,int len,void * udata)1015 static void SDLCALL _Eff_position_s16msb(int chan, void *stream, int len, void *udata)
1016 {
1017     /* 16 signed bits (lsb) * 2 channels. */
1018     volatile position_args *args = (volatile position_args *) udata;
1019     Sint16 *ptr = (Sint16 *) stream;
1020     int i;
1021 
1022     for (i = 0; i < len; i += sizeof (Sint16) * 2) {
1023         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1024                                     args->left_f) * args->distance_f);
1025         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1026                                     args->right_f) * args->distance_f);
1027         *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1028         *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1029     }
1030 }
_Eff_position_s16msb_c4(int chan,void * stream,int len,void * udata)1031 static void SDLCALL _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
1032 {
1033     /* 16 signed bits (lsb) * 4 channels. */
1034     volatile position_args *args = (volatile position_args *) udata;
1035     Sint16 *ptr = (Sint16 *) stream;
1036     int i;
1037 
1038     for (i = 0; i < len; i += sizeof (Sint16) * 4) {
1039         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1040                                     args->left_f) * args->distance_f);
1041         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1042                                     args->right_f) * args->distance_f);
1043         Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1044                                     args->left_rear_f) * args->distance_f);
1045         Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1046                                     args->right_rear_f) * args->distance_f);
1047     switch (args->room_angle) {
1048         case 0:
1049                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1050                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1051                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1052                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1053             break;
1054         case 90:
1055                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1056                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1057                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1058                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1059             break;
1060         case 180:
1061                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1062                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1063                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1064                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1065             break;
1066         case 270:
1067                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1068                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1069                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1070                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1071             break;
1072     }
1073     }
1074 }
_Eff_position_s16msb_c6(int chan,void * stream,int len,void * udata)1075 static void SDLCALL _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
1076 {
1077     /* 16 signed bits (lsb) * 6 channels. */
1078     volatile position_args *args = (volatile position_args *) udata;
1079     Sint16 *ptr = (Sint16 *) stream;
1080     int i;
1081 
1082     for (i = 0; i < len; i += sizeof (Sint16) * 6) {
1083         Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1084                                     args->left_f) * args->distance_f);
1085         Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1086                                     args->right_f) * args->distance_f);
1087         Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1088                                     args->left_rear_f) * args->distance_f);
1089         Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1090                                     args->right_rear_f) * args->distance_f);
1091         Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
1092                                     args->center_f) * args->distance_f);
1093         Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
1094                                     args->lfe_f) * args->distance_f);
1095 
1096     switch (args->room_angle) {
1097         case 0:
1098                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1099                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1100                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1101                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1102                 *(ptr++) = (Sint16) SDL_SwapBE16(swapce);
1103                 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1104             break;
1105         case 90:
1106                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1107                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1108                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1109                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1110                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
1111                 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1112             break;
1113         case 180:
1114                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1115                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1116                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1117                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1118                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1119                 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1120             break;
1121         case 270:
1122                 *(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1123                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1124                 *(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1125                 *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1126                 *(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1127                 *(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1128             break;
1129     }
1130     }
1131 }
1132 
_Eff_position_s32lsb(int chan,void * stream,int len,void * udata)1133 static void SDLCALL _Eff_position_s32lsb(int chan, void *stream, int len, void *udata)
1134 {
1135     /* 32 signed bits (lsb) * 2 channels. */
1136     volatile position_args *args = (volatile position_args *) udata;
1137     Sint32 *ptr = (Sint32 *) stream;
1138     int i;
1139 
1140 #if 0
1141     if (len % (sizeof(Sint32) * 2)) {
1142         fprintf(stderr,"Not an even number of frames! len=%d\n", len);
1143         return;
1144     }
1145 #endif
1146 
1147     for (i = 0; i < len; i += sizeof (Sint32) * 2) {
1148         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
1149                                     args->left_f) * args->distance_f);
1150         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
1151                                     args->right_f) * args->distance_f);
1152     if (args->room_angle == 180) {
1153             *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1154             *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1155     }
1156     else {
1157             *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1158             *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1159     }
1160     }
1161 }
_Eff_position_s32lsb_c4(int chan,void * stream,int len,void * udata)1162 static void SDLCALL _Eff_position_s32lsb_c4(int chan, void *stream, int len, void *udata)
1163 {
1164     /* 32 signed bits (lsb) * 4 channels. */
1165     volatile position_args *args = (volatile position_args *) udata;
1166     Sint32 *ptr = (Sint32 *) stream;
1167     int i;
1168 
1169     for (i = 0; i < len; i += sizeof (Sint32) * 4) {
1170         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
1171                                     args->left_f) * args->distance_f);
1172         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
1173                                     args->right_f) * args->distance_f);
1174         Sint32 swaplr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
1175                                     args->left_rear_f) * args->distance_f);
1176         Sint32 swaprr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+2))) *
1177                                     args->right_rear_f) * args->distance_f);
1178     switch (args->room_angle) {
1179         case 0:
1180                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1181                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1182                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1183                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1184             break;
1185         case 90:
1186                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1187                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1188                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1189                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1190             break;
1191         case 180:
1192                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1193                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1194                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1195                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1196             break;
1197         case 270:
1198                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1199                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1200                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1201                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1202             break;
1203     }
1204     }
1205 }
1206 
_Eff_position_s32lsb_c6(int chan,void * stream,int len,void * udata)1207 static void SDLCALL _Eff_position_s32lsb_c6(int chan, void *stream, int len, void *udata)
1208 {
1209     /* 32 signed bits (lsb) * 6 channels. */
1210     volatile position_args *args = (volatile position_args *) udata;
1211     Sint32 *ptr = (Sint32 *) stream;
1212     int i;
1213 
1214     for (i = 0; i < len; i += sizeof (Sint32) * 6) {
1215         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
1216                                     args->left_f) * args->distance_f);
1217         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
1218                                     args->right_f) * args->distance_f);
1219         Sint32 swaplr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+2))) *
1220                                     args->left_rear_f) * args->distance_f);
1221         Sint32 swaprr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+3))) *
1222                                     args->right_rear_f) * args->distance_f);
1223         Sint32 swapce = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+4))) *
1224                                     args->center_f) * args->distance_f);
1225         Sint32 swapwf = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+5))) *
1226                                     args->lfe_f) * args->distance_f);
1227     switch (args->room_angle) {
1228         case 0:
1229                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1230                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1231                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1232                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1233                 *(ptr++) = (Sint32) SDL_SwapLE32(swapce);
1234                 *(ptr++) = (Sint32) SDL_SwapLE32(swapwf);
1235             break;
1236         case 90:
1237                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1238                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1239                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1240                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1241                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr)/2 + (Sint32) SDL_SwapLE32(swaprr)/2;
1242                 *(ptr++) = (Sint32) SDL_SwapLE32(swapwf);
1243             break;
1244         case 180:
1245                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1246                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1247                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1248                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1249                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr)/2 + (Sint32) SDL_SwapLE32(swaplr)/2;
1250                 *(ptr++) = (Sint32) SDL_SwapLE32(swapwf);
1251             break;
1252         case 270:
1253                 *(ptr++) = (Sint32) SDL_SwapLE32(swaplr);
1254                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl);
1255                 *(ptr++) = (Sint32) SDL_SwapLE32(swaprr);
1256                 *(ptr++) = (Sint32) SDL_SwapLE32(swapr);
1257                 *(ptr++) = (Sint32) SDL_SwapLE32(swapl)/2 + (Sint32) SDL_SwapLE32(swaplr)/2;
1258                 *(ptr++) = (Sint32) SDL_SwapLE32(swapwf);
1259             break;
1260     }
1261     }
1262 }
1263 
_Eff_position_s32msb(int chan,void * stream,int len,void * udata)1264 static void SDLCALL _Eff_position_s32msb(int chan, void *stream, int len, void *udata)
1265 {
1266     /* 32 signed bits (lsb) * 2 channels. */
1267     volatile position_args *args = (volatile position_args *) udata;
1268     Sint32 *ptr = (Sint32 *) stream;
1269     int i;
1270 
1271     for (i = 0; i < len; i += sizeof (Sint32) * 2) {
1272         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
1273                                     args->left_f) * args->distance_f);
1274         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
1275                                     args->right_f) * args->distance_f);
1276         *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1277         *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1278     }
1279 }
_Eff_position_s32msb_c4(int chan,void * stream,int len,void * udata)1280 static void SDLCALL _Eff_position_s32msb_c4(int chan, void *stream, int len, void *udata)
1281 {
1282     /* 32 signed bits (lsb) * 4 channels. */
1283     volatile position_args *args = (volatile position_args *) udata;
1284     Sint32 *ptr = (Sint32 *) stream;
1285     int i;
1286 
1287     for (i = 0; i < len; i += sizeof (Sint32) * 4) {
1288         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
1289                                     args->left_f) * args->distance_f);
1290         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
1291                                     args->right_f) * args->distance_f);
1292         Sint32 swaplr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+2))) *
1293                                     args->left_rear_f) * args->distance_f);
1294         Sint32 swaprr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+3))) *
1295                                     args->right_rear_f) * args->distance_f);
1296     switch (args->room_angle) {
1297         case 0:
1298                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1299                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1300                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1301                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1302             break;
1303         case 90:
1304                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1305                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1306                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1307                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1308             break;
1309         case 180:
1310                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1311                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1312                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1313                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1314             break;
1315         case 270:
1316                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1317                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1318                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1319                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1320             break;
1321     }
1322     }
1323 }
_Eff_position_s32msb_c6(int chan,void * stream,int len,void * udata)1324 static void SDLCALL _Eff_position_s32msb_c6(int chan, void *stream, int len, void *udata)
1325 {
1326     /* 32 signed bits (lsb) * 6 channels. */
1327     volatile position_args *args = (volatile position_args *) udata;
1328     Sint32 *ptr = (Sint32 *) stream;
1329     int i;
1330 
1331     for (i = 0; i < len; i += sizeof (Sint32) * 6) {
1332         Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
1333                                     args->left_f) * args->distance_f);
1334         Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
1335                                     args->right_f) * args->distance_f);
1336         Sint32 swaplr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+2))) *
1337                                     args->left_rear_f) * args->distance_f);
1338         Sint32 swaprr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+3))) *
1339                                     args->right_rear_f) * args->distance_f);
1340         Sint32 swapce = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+4))) *
1341                                     args->center_f) * args->distance_f);
1342         Sint32 swapwf = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+5))) *
1343                                     args->lfe_f) * args->distance_f);
1344 
1345     switch (args->room_angle) {
1346         case 0:
1347                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1348                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1349                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1350                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1351                 *(ptr++) = (Sint32) SDL_SwapBE32(swapce);
1352                 *(ptr++) = (Sint32) SDL_SwapBE32(swapwf);
1353             break;
1354         case 90:
1355                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1356                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1357                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1358                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1359                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr)/2 + (Sint32) SDL_SwapBE32(swaprr)/2;
1360                 *(ptr++) = (Sint32) SDL_SwapBE32(swapwf);
1361             break;
1362         case 180:
1363                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1364                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1365                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1366                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1367                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr)/2 + (Sint32) SDL_SwapBE32(swaplr)/2;
1368                 *(ptr++) = (Sint32) SDL_SwapBE32(swapwf);
1369             break;
1370         case 270:
1371                 *(ptr++) = (Sint32) SDL_SwapBE32(swaplr);
1372                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl);
1373                 *(ptr++) = (Sint32) SDL_SwapBE32(swaprr);
1374                 *(ptr++) = (Sint32) SDL_SwapBE32(swapr);
1375                 *(ptr++) = (Sint32) SDL_SwapBE32(swapl)/2 + (Sint32) SDL_SwapBE32(swaplr)/2;
1376                 *(ptr++) = (Sint32) SDL_SwapBE32(swapwf);
1377             break;
1378     }
1379     }
1380 }
1381 
_Eff_position_f32sys(int chan,void * stream,int len,void * udata)1382 static void SDLCALL _Eff_position_f32sys(int chan, void *stream, int len, void *udata)
1383 {
1384     /* float * 2 channels. */
1385     volatile position_args *args = (volatile position_args *) udata;
1386     float *ptr = (float *) stream;
1387     int i;
1388 
1389     for (i = 0; i < len; i += sizeof (float) * 2) {
1390         float swapl = ((*(ptr+0) * args->left_f) * args->distance_f);
1391         float swapr = ((*(ptr+1) * args->right_f) * args->distance_f);
1392         *(ptr++) = swapl;
1393         *(ptr++) = swapr;
1394     }
1395 }
_Eff_position_f32sys_c4(int chan,void * stream,int len,void * udata)1396 static void SDLCALL _Eff_position_f32sys_c4(int chan, void *stream, int len, void *udata)
1397 {
1398     /* float * 4 channels. */
1399     volatile position_args *args = (volatile position_args *) udata;
1400     float *ptr = (float *) stream;
1401     int i;
1402 
1403     for (i = 0; i < len; i += sizeof (float) * 4) {
1404         float swapl = ((*(ptr+0) * args->left_f) * args->distance_f);
1405         float swapr = ((*(ptr+1) * args->right_f) * args->distance_f);
1406         float swaplr = ((*(ptr+2) * args->left_rear_f) * args->distance_f);
1407         float swaprr = ((*(ptr+3) * args->right_rear_f) * args->distance_f);
1408         switch (args->room_angle) {
1409         case 0:
1410                 *(ptr++) = swapl;
1411                 *(ptr++) = swapr;
1412                 *(ptr++) = swaplr;
1413                 *(ptr++) = swaprr;
1414             break;
1415         case 90:
1416                 *(ptr++) = swapr;
1417                 *(ptr++) = swaprr;
1418                 *(ptr++) = swapl;
1419                 *(ptr++) = swaplr;
1420             break;
1421         case 180:
1422                 *(ptr++) = swaprr;
1423                 *(ptr++) = swaplr;
1424                 *(ptr++) = swapr;
1425                 *(ptr++) = swapl;
1426             break;
1427         case 270:
1428                 *(ptr++) = swaplr;
1429                 *(ptr++) = swapl;
1430                 *(ptr++) = swaprr;
1431                 *(ptr++) = swapr;
1432             break;
1433         }
1434     }
1435 }
_Eff_position_f32sys_c6(int chan,void * stream,int len,void * udata)1436 static void SDLCALL _Eff_position_f32sys_c6(int chan, void *stream, int len, void *udata)
1437 {
1438     /* float * 6 channels. */
1439     volatile position_args *args = (volatile position_args *) udata;
1440     float *ptr = (float *) stream;
1441     int i;
1442 
1443     for (i = 0; i < len; i += sizeof (float) * 6) {
1444         float swapl = ((*(ptr+0) * args->left_f) * args->distance_f);
1445         float swapr = ((*(ptr+1) * args->right_f) * args->distance_f);
1446         float swaplr = ((*(ptr+2) * args->left_rear_f) * args->distance_f);
1447         float swaprr = ((*(ptr+3) * args->right_rear_f) * args->distance_f);
1448         float swapce = ((*(ptr+4) * args->center_f) * args->distance_f);
1449         float swapwf = ((*(ptr+5) * args->lfe_f) * args->distance_f);
1450 
1451     switch (args->room_angle) {
1452         case 0:
1453                 *(ptr++) = swapl;
1454                 *(ptr++) = swapr;
1455                 *(ptr++) = swaplr;
1456                 *(ptr++) = swaprr;
1457                 *(ptr++) = swapce;
1458                 *(ptr++) = swapwf;
1459             break;
1460         case 90:
1461                 *(ptr++) = swapr;
1462                 *(ptr++) = swaprr;
1463                 *(ptr++) = swapl;
1464                 *(ptr++) = swaplr;
1465                 *(ptr++) = swapr/2.0f + swaprr/2.0f;
1466                 *(ptr++) = swapwf;
1467             break;
1468         case 180:
1469                 *(ptr++) = swaprr;
1470                 *(ptr++) = swaplr;
1471                 *(ptr++) = swapr;
1472                 *(ptr++) = swapl;
1473                 *(ptr++) = swaprr/2.0f + swaplr/2.0f;
1474                 *(ptr++) = swapwf;
1475             break;
1476         case 270:
1477                 *(ptr++) = swaplr;
1478                 *(ptr++) = swapl;
1479                 *(ptr++) = swaprr;
1480                 *(ptr++) = swapr;
1481                 *(ptr++) = swapl/2.0f + swaplr/2.0f;
1482                 *(ptr++) = swapwf;
1483             break;
1484     }
1485     }
1486 }
1487 
init_position_args(position_args * args)1488 static void init_position_args(position_args *args)
1489 {
1490     SDL_memset(args, '\0', sizeof (position_args));
1491     args->in_use = 0;
1492     args->room_angle = 0;
1493     args->left_u8 = args->right_u8 = args->distance_u8 = 255;
1494     args->left_f  = args->right_f  = args->distance_f  = 1.0f;
1495     args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
1496     args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
1497     Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
1498 }
1499 
1500 
get_position_arg(int channel)1501 static position_args *get_position_arg(int channel)
1502 {
1503     void *rc;
1504     int i;
1505 
1506     if (channel < 0) {
1507         if (pos_args_global == NULL) {
1508             pos_args_global = SDL_malloc(sizeof (position_args));
1509             if (pos_args_global == NULL) {
1510                 Mix_SetError("Out of memory");
1511                 return(NULL);
1512             }
1513             init_position_args(pos_args_global);
1514         }
1515 
1516         return(pos_args_global);
1517     }
1518 
1519     if (channel >= position_channels) {
1520         rc = SDL_realloc(pos_args_array, (channel + 1) * sizeof (position_args *));
1521         if (rc == NULL) {
1522             Mix_SetError("Out of memory");
1523             return(NULL);
1524         }
1525         pos_args_array = (position_args **) rc;
1526         for (i = position_channels; i <= channel; i++) {
1527             pos_args_array[i] = NULL;
1528         }
1529         position_channels = channel + 1;
1530     }
1531 
1532     if (pos_args_array[channel] == NULL) {
1533         pos_args_array[channel] = (position_args *)SDL_malloc(sizeof(position_args));
1534         if (pos_args_array[channel] == NULL) {
1535             Mix_SetError("Out of memory");
1536             return(NULL);
1537         }
1538         init_position_args(pos_args_array[channel]);
1539     }
1540 
1541     return(pos_args_array[channel]);
1542 }
1543 
1544 
get_position_effect_func(Uint16 format,int channels)1545 static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
1546 {
1547     Mix_EffectFunc_t f = NULL;
1548 
1549     switch (format) {
1550         case AUDIO_U8:
1551         switch (channels) {
1552             case 1:
1553             case 2:
1554                 f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
1555                                                         _Eff_position_u8;
1556                 break;
1557             case 4:
1558                 f = _Eff_position_u8_c4;
1559                 break;
1560             case 6:
1561                 f = _Eff_position_u8_c6;
1562                 break;
1563             default:
1564                 Mix_SetError("Unsupported audio channels");
1565                 break;
1566         }
1567         break;
1568 
1569         case AUDIO_S8:
1570         switch (channels) {
1571             case 1:
1572             case 2:
1573                 f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
1574                                                         _Eff_position_s8;
1575                 break;
1576             case 4:
1577                 f = _Eff_position_s8_c4;
1578                 break;
1579             case 6:
1580                 f = _Eff_position_s8_c6;
1581                 break;
1582             default:
1583                 Mix_SetError("Unsupported audio channels");
1584                 break;
1585         }
1586         break;
1587 
1588         case AUDIO_U16LSB:
1589         switch (channels) {
1590             case 1:
1591             case 2:
1592                 f = _Eff_position_u16lsb;
1593                 break;
1594             case 4:
1595                 f = _Eff_position_u16lsb_c4;
1596                 break;
1597             case 6:
1598                 f = _Eff_position_u16lsb_c6;
1599                 break;
1600             default:
1601                 Mix_SetError("Unsupported audio channels");
1602                 break;
1603         }
1604         break;
1605 
1606         case AUDIO_S16LSB:
1607         switch (channels) {
1608             case 1:
1609             case 2:
1610                 f = _Eff_position_s16lsb;
1611                 break;
1612             case 4:
1613                 f = _Eff_position_s16lsb_c4;
1614                 break;
1615             case 6:
1616                 f = _Eff_position_s16lsb_c6;
1617                 break;
1618             default:
1619                 Mix_SetError("Unsupported audio channels");
1620                 break;
1621         }
1622         break;
1623 
1624         case AUDIO_U16MSB:
1625         switch (channels) {
1626             case 1:
1627             case 2:
1628                 f = _Eff_position_u16msb;
1629                 break;
1630             case 4:
1631                 f = _Eff_position_u16msb_c4;
1632                 break;
1633             case 6:
1634                 f = _Eff_position_u16msb_c6;
1635                 break;
1636             default:
1637                 Mix_SetError("Unsupported audio channels");
1638                 break;
1639         }
1640         break;
1641 
1642         case AUDIO_S16MSB:
1643         switch (channels) {
1644             case 1:
1645             case 2:
1646                 f = _Eff_position_s16msb;
1647                 break;
1648             case 4:
1649                 f = _Eff_position_s16msb_c4;
1650                 break;
1651             case 6:
1652                 f = _Eff_position_s16msb_c6;
1653                 break;
1654             default:
1655                 Mix_SetError("Unsupported audio channels");
1656                 break;
1657         }
1658         break;
1659 
1660         case AUDIO_S32MSB:
1661         switch (channels) {
1662             case 1:
1663             case 2:
1664                 f = _Eff_position_s32msb;
1665                 break;
1666             case 4:
1667                 f = _Eff_position_s32msb_c4;
1668                 break;
1669             case 6:
1670                 f = _Eff_position_s32msb_c6;
1671                 break;
1672             default:
1673                 Mix_SetError("Unsupported audio channels");
1674                 break;
1675         }
1676         break;
1677 
1678         case AUDIO_S32LSB:
1679         switch (channels) {
1680             case 1:
1681             case 2:
1682                 f = _Eff_position_s32lsb;
1683                 break;
1684             case 4:
1685                 f = _Eff_position_s32lsb_c4;
1686                 break;
1687             case 6:
1688                 f = _Eff_position_s32lsb_c6;
1689                 break;
1690             default:
1691                 Mix_SetError("Unsupported audio channels");
1692                 break;
1693         }
1694         break;
1695 
1696         case AUDIO_F32SYS:
1697         switch (channels) {
1698             case 1:
1699             case 2:
1700                 f = _Eff_position_f32sys;
1701                 break;
1702             case 4:
1703                 f = _Eff_position_f32sys_c4;
1704                 break;
1705             case 6:
1706                 f = _Eff_position_f32sys_c6;
1707                 break;
1708             default:
1709                 Mix_SetError("Unsupported audio channels");
1710                 break;
1711         }
1712         break;
1713 
1714         default:
1715             Mix_SetError("Unsupported audio format");
1716             break;
1717     }
1718 
1719     return(f);
1720 }
1721 
1722 static Uint8 speaker_amplitude[6];
1723 
set_amplitudes(int channels,int angle,int room_angle)1724 static void set_amplitudes(int channels, int angle, int room_angle)
1725 {
1726     int left = 255, right = 255;
1727     int left_rear = 255, right_rear = 255, center = 255;
1728 
1729     angle = SDL_abs(angle) % 360;  /* make angle between 0 and 359. */
1730 
1731     if (channels == 2)
1732     {
1733         /*
1734          * We only attenuate by position if the angle falls on the far side
1735          *  of center; That is, an angle that's due north would not attenuate
1736          *  either channel. Due west attenuates the right channel to 0.0, and
1737          *  due east attenuates the left channel to 0.0. Slightly east of
1738          *  center attenuates the left channel a little, and the right channel
1739          *  not at all. I think of this as occlusion by one's own head.  :)
1740          *
1741          *   ...so, we split our angle circle into four quadrants...
1742          */
1743         if (angle < 90) {
1744             left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
1745         } else if (angle < 180) {
1746             left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
1747         } else if (angle < 270) {
1748             right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
1749         } else {
1750             right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
1751         }
1752     }
1753 
1754     if (channels == 4 || channels == 6)
1755     {
1756         /*
1757          *  An angle that's due north does not attenuate the center channel.
1758          *  An angle in the first quadrant, 0-90, does not attenuate the RF.
1759          *
1760          *   ...so, we split our angle circle into 8 ...
1761          *
1762          *             CE
1763          *             0
1764          *     LF      |         RF
1765          *             |
1766          *  270<-------|----------->90
1767          *             |
1768          *     LR      |         RR
1769          *            180
1770          *
1771          */
1772         if (angle < 45) {
1773             left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
1774             left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
1775             right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
1776         } else if (angle < 90) {
1777             center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
1778             left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
1779             left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
1780             right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
1781         } else if (angle < 135) {
1782             center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
1783             left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
1784             right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
1785             left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
1786         } else if (angle < 180) {
1787             center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
1788             left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
1789             right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
1790             left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
1791         } else if (angle < 225) {
1792             center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
1793             left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
1794             right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
1795             right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
1796         } else if (angle < 270) {
1797             center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
1798             left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
1799             right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
1800             right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
1801         } else if (angle < 315) {
1802             center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
1803             right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
1804             left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
1805             right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
1806         } else {
1807             right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
1808             left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
1809             right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
1810         }
1811     }
1812 
1813     if (left < 0) left = 0; if (left > 255) left = 255;
1814     if (right < 0) right = 0; if (right > 255) right = 255;
1815     if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
1816     if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
1817     if (center < 0) center = 0; if (center > 255) center = 255;
1818 
1819     if (room_angle == 90) {
1820         speaker_amplitude[0] = (Uint8)left_rear;
1821         speaker_amplitude[1] = (Uint8)left;
1822         speaker_amplitude[2] = (Uint8)right_rear;
1823         speaker_amplitude[3] = (Uint8)right;
1824     }
1825     else if (room_angle == 180) {
1826     if (channels == 2) {
1827             speaker_amplitude[0] = (Uint8)right;
1828             speaker_amplitude[1] = (Uint8)left;
1829     }
1830     else {
1831             speaker_amplitude[0] = (Uint8)right_rear;
1832             speaker_amplitude[1] = (Uint8)left_rear;
1833             speaker_amplitude[2] = (Uint8)right;
1834             speaker_amplitude[3] = (Uint8)left;
1835     }
1836     }
1837     else if (room_angle == 270) {
1838         speaker_amplitude[0] = (Uint8)right;
1839         speaker_amplitude[1] = (Uint8)right_rear;
1840         speaker_amplitude[2] = (Uint8)left;
1841         speaker_amplitude[3] = (Uint8)left_rear;
1842     }
1843     else {
1844         speaker_amplitude[0] = (Uint8)left;
1845         speaker_amplitude[1] = (Uint8)right;
1846         speaker_amplitude[2] = (Uint8)left_rear;
1847         speaker_amplitude[3] = (Uint8)right_rear;
1848     }
1849     speaker_amplitude[4] = (Uint8)center;
1850     speaker_amplitude[5] = 255;
1851 }
1852 
1853 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
1854 
Mix_SetPanning(int channel,Uint8 left,Uint8 right)1855 int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
1856 {
1857     Mix_EffectFunc_t f = NULL;
1858     int channels;
1859     Uint16 format;
1860     position_args *args = NULL;
1861     int retval = 1;
1862 
1863     Mix_QuerySpec(NULL, &format, &channels);
1864 
1865     if (channels != 2 && channels != 4 && channels != 6)    /* it's a no-op; we call that successful. */
1866         return(1);
1867 
1868     if (channels > 2) {
1869         /* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */
1870         /* left = 255 =>  angle = -90;  left = 0 => angle = +89 */
1871         int angle = 0;
1872         if ((left != 255) || (right != 255)) {
1873         angle = (int)left;
1874             angle = 127 - angle;
1875         angle = -angle;
1876             angle = angle * 90 / 128; /* Make it larger for more effect? */
1877         }
1878         return(Mix_SetPosition(channel, angle, 0));
1879     }
1880 
1881     f = get_position_effect_func(format, channels);
1882     if (f == NULL)
1883         return(0);
1884 
1885     Mix_LockAudio();
1886     args = get_position_arg(channel);
1887     if (!args) {
1888         Mix_UnlockAudio();
1889         return(0);
1890     }
1891 
1892         /* it's a no-op; unregister the effect, if it's registered. */
1893     if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) {
1894         if (args->in_use) {
1895             retval = _Mix_UnregisterEffect_locked(channel, f);
1896             Mix_UnlockAudio();
1897             return(retval);
1898         } else {
1899             Mix_UnlockAudio();
1900             return(1);
1901         }
1902     }
1903 
1904     args->left_u8 = left;
1905     args->left_f = ((float) left) / 255.0f;
1906     args->right_u8 = right;
1907     args->right_f = ((float) right) / 255.0f;
1908     args->room_angle = 0;
1909 
1910     if (!args->in_use) {
1911         args->in_use = 1;
1912         retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args);
1913     }
1914 
1915     Mix_UnlockAudio();
1916     return(retval);
1917 }
1918 
1919 
Mix_SetDistance(int channel,Uint8 distance)1920 int Mix_SetDistance(int channel, Uint8 distance)
1921 {
1922     Mix_EffectFunc_t f = NULL;
1923     Uint16 format;
1924     position_args *args = NULL;
1925     int channels;
1926     int retval = 1;
1927 
1928     Mix_QuerySpec(NULL, &format, &channels);
1929     f = get_position_effect_func(format, channels);
1930     if (f == NULL)
1931         return(0);
1932 
1933     Mix_LockAudio();
1934     args = get_position_arg(channel);
1935     if (!args) {
1936         Mix_UnlockAudio();
1937         return(0);
1938     }
1939 
1940     distance = 255 - distance;  /* flip it to our scale. */
1941 
1942         /* it's a no-op; unregister the effect, if it's registered. */
1943     if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) {
1944         if (args->in_use) {
1945             retval = _Mix_UnregisterEffect_locked(channel, f);
1946             Mix_UnlockAudio();
1947             return(retval);
1948         } else {
1949             Mix_UnlockAudio();
1950             return(1);
1951         }
1952     }
1953 
1954     args->distance_u8 = distance;
1955     args->distance_f = ((float) distance) / 255.0f;
1956     if (!args->in_use) {
1957         args->in_use = 1;
1958         retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
1959     }
1960 
1961     Mix_UnlockAudio();
1962     return(retval);
1963 }
1964 
1965 
Mix_SetPosition(int channel,Sint16 angle,Uint8 distance)1966 int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
1967 {
1968     Mix_EffectFunc_t f = NULL;
1969     Uint16 format;
1970     int channels;
1971     position_args *args = NULL;
1972     Sint16 room_angle = 0;
1973     int retval = 1;
1974 
1975     Mix_QuerySpec(NULL, &format, &channels);
1976     f = get_position_effect_func(format, channels);
1977     if (f == NULL)
1978         return(0);
1979 
1980     angle = SDL_abs(angle) % 360;  /* make angle between 0 and 359. */
1981 
1982     Mix_LockAudio();
1983     args = get_position_arg(channel);
1984     if (!args) {
1985         Mix_UnlockAudio();
1986         return(0);
1987     }
1988 
1989         /* it's a no-op; unregister the effect, if it's registered. */
1990     if ((!distance) && (!angle)) {
1991         if (args->in_use) {
1992             retval = _Mix_UnregisterEffect_locked(channel, f);
1993             Mix_UnlockAudio();
1994             return(retval);
1995         } else {
1996             Mix_UnlockAudio();
1997             return(1);
1998         }
1999     }
2000 
2001     if (channels == 2)
2002     {
2003     if (angle > 180)
2004         room_angle = 180; /* exchange left and right channels */
2005     else room_angle = 0;
2006     }
2007 
2008     if (channels == 4 || channels == 6)
2009     {
2010     if (angle > 315) room_angle = 0;
2011     else if (angle > 225) room_angle = 270;
2012     else if (angle > 135) room_angle = 180;
2013     else if (angle > 45) room_angle = 90;
2014     else room_angle = 0;
2015     }
2016 
2017 
2018     distance = 255 - distance;  /* flip it to scale Mix_SetDistance() uses. */
2019 
2020     set_amplitudes(channels, angle, room_angle);
2021 
2022     args->left_u8 = speaker_amplitude[0];
2023     args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
2024     args->right_u8 = speaker_amplitude[1];
2025     args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
2026     args->left_rear_u8 = speaker_amplitude[2];
2027     args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
2028     args->right_rear_u8 = speaker_amplitude[3];
2029     args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
2030     args->center_u8 = speaker_amplitude[4];
2031     args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
2032     args->lfe_u8 = speaker_amplitude[5];
2033     args->lfe_f = ((float) speaker_amplitude[5]) / 255.0f;
2034     args->distance_u8 = distance;
2035     args->distance_f = ((float) distance) / 255.0f;
2036     args->room_angle = room_angle;
2037     if (!args->in_use) {
2038         args->in_use = 1;
2039         retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
2040     }
2041 
2042     Mix_UnlockAudio();
2043     return(retval);
2044 }
2045 
2046 
2047 /* end of effects_position.c ... */
2048 
2049 /* vi: set ts=4 sw=4 expandtab: */
2050