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