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