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