effect_position.c
changeset 245 63b3650714de
parent 241 503416fca921
child 250 cf822f8dc1bf
     1.1 --- a/effect_position.c	Fri Aug 20 19:32:09 2004 +0000
     1.2 +++ b/effect_position.c	Sat Aug 21 12:27:02 2004 +0000
     1.3 @@ -60,8 +60,17 @@
     1.4      volatile float right_f;
     1.5      volatile Uint8 left_u8;
     1.6      volatile Uint8 right_u8;
     1.7 +    volatile float left_rear_f;
     1.8 +    volatile float right_rear_f;
     1.9 +    volatile float center_f;
    1.10 +    volatile float lfe_f;
    1.11 +    volatile Uint8 left_rear_u8;
    1.12 +    volatile Uint8 right_rear_u8;
    1.13 +    volatile Uint8 center_u8;
    1.14 +    volatile Uint8 lfe_u8;
    1.15      volatile float distance_f;
    1.16      volatile Uint8 distance_u8;
    1.17 +    volatile Sint16 room_angle;
    1.18      volatile int in_use;
    1.19      volatile int channels;
    1.20  } position_args;
    1.21 @@ -104,9 +113,19 @@
    1.22          len--;
    1.23      }
    1.24  
    1.25 +    if (args->room_angle == 0)
    1.26      for (i = 0; i < len; i += sizeof (Uint8) * 2) {
    1.27          /* must adjust the sample so that 0 is the center */
    1.28          *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.29 +            * args->right_f) * args->distance_f) + 128);
    1.30 +        ptr++;
    1.31 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.32 +            * args->left_f) * args->distance_f) + 128);
    1.33 +        ptr++;
    1.34 +    }
    1.35 +    else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
    1.36 +        /* must adjust the sample so that 0 is the center */
    1.37 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.38              * args->left_f) * args->distance_f) + 128);
    1.39          ptr++;
    1.40          *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.41 @@ -114,6 +133,202 @@
    1.42          ptr++;
    1.43      }
    1.44  }
    1.45 +static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
    1.46 +{
    1.47 +    volatile position_args *args = (volatile position_args *) udata;
    1.48 +    Uint8 *ptr = (Uint8 *) stream;
    1.49 +    int i;
    1.50 +
    1.51 +        /*
    1.52 +         * if there's only a mono channnel (the only way we wouldn't have
    1.53 +         *  a len divisible by 2 here), then left_f and right_f are always
    1.54 +         *  1.0, and are therefore throwaways.
    1.55 +         */
    1.56 +    if (len % sizeof (Uint16) != 0) {
    1.57 +        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
    1.58 +        ptr++;
    1.59 +        len--;
    1.60 +    }
    1.61 +
    1.62 +    if (args->room_angle == 0)
    1.63 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    1.64 +        /* must adjust the sample so that 0 is the center */
    1.65 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.66 +            * args->left_f) * args->distance_f) + 128);
    1.67 +        ptr++;
    1.68 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.69 +            * args->right_f) * args->distance_f) + 128);
    1.70 +        ptr++;
    1.71 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.72 +            * args->left_rear_f) * args->distance_f) + 128);
    1.73 +        ptr++;
    1.74 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.75 +            * args->right_rear_f) * args->distance_f) + 128);
    1.76 +        ptr++;
    1.77 +    }
    1.78 +    else if (args->room_angle == 90)
    1.79 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    1.80 +        /* must adjust the sample so that 0 is the center */
    1.81 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.82 +            * args->right_f) * args->distance_f) + 128);
    1.83 +        ptr++;
    1.84 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.85 +            * args->right_rear_f) * args->distance_f) + 128);
    1.86 +        ptr++;
    1.87 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.88 +            * args->left_f) * args->distance_f) + 128);
    1.89 +        ptr++;
    1.90 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.91 +            * args->left_rear_f) * args->distance_f) + 128);
    1.92 +        ptr++;
    1.93 +    }
    1.94 +    else if (args->room_angle == 180)
    1.95 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
    1.96 +        /* must adjust the sample so that 0 is the center */
    1.97 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
    1.98 +            * args->right_rear_f) * args->distance_f) + 128);
    1.99 +        ptr++;
   1.100 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.101 +            * args->left_rear_f) * args->distance_f) + 128);
   1.102 +        ptr++;
   1.103 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.104 +            * args->right_f) * args->distance_f) + 128);
   1.105 +        ptr++;
   1.106 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.107 +            * args->left_f) * args->distance_f) + 128);
   1.108 +        ptr++;
   1.109 +    }
   1.110 +    else if (args->room_angle == 270)
   1.111 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   1.112 +        /* must adjust the sample so that 0 is the center */
   1.113 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.114 +            * args->left_rear_f) * args->distance_f) + 128);
   1.115 +        ptr++;
   1.116 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.117 +            * args->left_f) * args->distance_f) + 128);
   1.118 +        ptr++;
   1.119 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.120 +            * args->right_rear_f) * args->distance_f) + 128);
   1.121 +        ptr++;
   1.122 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.123 +            * args->right_f) * args->distance_f) + 128);
   1.124 +        ptr++;
   1.125 +    }
   1.126 +}
   1.127 +
   1.128 +
   1.129 +static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
   1.130 +{
   1.131 +    volatile position_args *args = (volatile position_args *) udata;
   1.132 +    Uint8 *ptr = (Uint8 *) stream;
   1.133 +    int i;
   1.134 +
   1.135 +        /*
   1.136 +         * if there's only a mono channnel (the only way we wouldn't have
   1.137 +         *  a len divisible by 2 here), then left_f and right_f are always
   1.138 +         *  1.0, and are therefore throwaways.
   1.139 +         */
   1.140 +    if (len % sizeof (Uint16) != 0) {
   1.141 +        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
   1.142 +        ptr++;
   1.143 +        len--;
   1.144 +    }
   1.145 +
   1.146 +    if (args->room_angle == 0)
   1.147 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   1.148 +        /* must adjust the sample so that 0 is the center */
   1.149 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.150 +            * args->left_f) * args->distance_f) + 128);
   1.151 +        ptr++;
   1.152 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.153 +            * args->right_f) * args->distance_f) + 128);
   1.154 +        ptr++;
   1.155 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.156 +            * args->left_rear_f) * args->distance_f) + 128);
   1.157 +        ptr++;
   1.158 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.159 +            * args->right_rear_f) * args->distance_f) + 128);
   1.160 +        ptr++;
   1.161 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.162 +            * args->center_f) * args->distance_f) + 128);
   1.163 +        ptr++;
   1.164 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.165 +            * args->lfe_f) * args->distance_f) + 128);
   1.166 +        ptr++;
   1.167 +    }
   1.168 +    else if (args->room_angle == 90)
   1.169 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   1.170 +        /* must adjust the sample so that 0 is the center */
   1.171 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.172 +            * args->right_f) * args->distance_f) + 128);
   1.173 +        ptr++;
   1.174 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.175 +            * args->right_rear_f) * args->distance_f) + 128);
   1.176 +        ptr++;
   1.177 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.178 +            * args->left_f) * args->distance_f) + 128);
   1.179 +        ptr++;
   1.180 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.181 +            * args->left_rear_f) * args->distance_f) + 128);
   1.182 +        ptr++;
   1.183 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.184 +            * args->right_rear_f) * args->distance_f/2) + 128)
   1.185 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.186 +            * args->right_f) * args->distance_f/2) + 128);
   1.187 +        ptr++;
   1.188 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.189 +            * args->lfe_f) * args->distance_f) + 128);
   1.190 +        ptr++;
   1.191 +    }
   1.192 +    else if (args->room_angle == 180)
   1.193 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   1.194 +        /* must adjust the sample so that 0 is the center */
   1.195 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.196 +            * args->right_rear_f) * args->distance_f) + 128);
   1.197 +        ptr++;
   1.198 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.199 +            * args->left_rear_f) * args->distance_f) + 128);
   1.200 +        ptr++;
   1.201 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.202 +            * args->right_f) * args->distance_f) + 128);
   1.203 +        ptr++;
   1.204 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.205 +            * args->left_f) * args->distance_f) + 128);
   1.206 +        ptr++;
   1.207 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.208 +            * args->right_rear_f) * args->distance_f/2) + 128)
   1.209 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.210 +            * args->left_rear_f) * args->distance_f/2) + 128);
   1.211 +        ptr++;
   1.212 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.213 +            * args->lfe_f) * args->distance_f) + 128);
   1.214 +        ptr++;
   1.215 +    }
   1.216 +    else if (args->room_angle == 270)
   1.217 +    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
   1.218 +        /* must adjust the sample so that 0 is the center */
   1.219 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.220 +            * args->left_rear_f) * args->distance_f) + 128);
   1.221 +        ptr++;
   1.222 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.223 +            * args->left_f) * args->distance_f) + 128);
   1.224 +        ptr++;
   1.225 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.226 +            * args->right_rear_f) * args->distance_f) + 128);
   1.227 +        ptr++;
   1.228 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.229 +            * args->right_f) * args->distance_f) + 128);
   1.230 +        ptr++;
   1.231 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.232 +            * args->left_f) * args->distance_f/2) + 128)
   1.233 +            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.234 +            * args->left_rear_f) * args->distance_f/2) + 128);
   1.235 +        ptr++;
   1.236 +        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
   1.237 +            * args->lfe_f) * args->distance_f) + 128);
   1.238 +        ptr++;
   1.239 +    }
   1.240 +}
   1.241  
   1.242  
   1.243  /*
   1.244 @@ -134,6 +349,11 @@
   1.245      Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
   1.246      Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
   1.247  
   1.248 +    if (args->room_angle == 180) {
   1.249 +	    Uint8 *temp = l;
   1.250 +	    l = r;
   1.251 +	    r = temp;
   1.252 +    }
   1.253          /*
   1.254           * if there's only a mono channnel, then l[] and r[] are always
   1.255           *  volume 255, and are therefore throwaways. Still, we have to
   1.256 @@ -184,6 +404,14 @@
   1.257          len--;
   1.258      }
   1.259  
   1.260 +    if (args->room_angle == 180)
   1.261 +    for (i = 0; i < len; i += sizeof (Sint8) * 2) {
   1.262 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
   1.263 +        ptr++;
   1.264 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
   1.265 +        ptr++;
   1.266 +    }
   1.267 +    else
   1.268      for (i = 0; i < len; i += sizeof (Sint8) * 2) {
   1.269          *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
   1.270          ptr++;
   1.271 @@ -191,6 +419,109 @@
   1.272          ptr++;
   1.273      }
   1.274  }
   1.275 +static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
   1.276 +{
   1.277 +    volatile position_args *args = (volatile position_args *) udata;
   1.278 +    Sint8 *ptr = (Sint8 *) stream;
   1.279 +    int i;
   1.280 +
   1.281 +        /*
   1.282 +         * if there's only a mono channnel (the only way we wouldn't have
   1.283 +         *  a len divisible by 2 here), then left_f and right_f are always
   1.284 +         *  1.0, and are therefore throwaways.
   1.285 +         */
   1.286 +    if (len % sizeof (Sint16) != 0) {
   1.287 +        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
   1.288 +        ptr++;
   1.289 +        len--;
   1.290 +    }
   1.291 +
   1.292 +    for (i = 0; i < len; i += sizeof (Sint8) * 4) {
   1.293 +      switch (args->room_angle) {
   1.294 +       case 0:
   1.295 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.296 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.297 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.298 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.299 +	break;
   1.300 +       case 90:
   1.301 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.302 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.303 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.304 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.305 +	break;
   1.306 +       case 180:
   1.307 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.308 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.309 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.310 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.311 +	break;
   1.312 +       case 270:
   1.313 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.314 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.315 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.316 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.317 +	break;
   1.318 +      }
   1.319 +    }
   1.320 +}
   1.321 +static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
   1.322 +{
   1.323 +    volatile position_args *args = (volatile position_args *) udata;
   1.324 +    Sint8 *ptr = (Sint8 *) stream;
   1.325 +    int i;
   1.326 +
   1.327 +        /*
   1.328 +         * if there's only a mono channnel (the only way we wouldn't have
   1.329 +         *  a len divisible by 2 here), then left_f and right_f are always
   1.330 +         *  1.0, and are therefore throwaways.
   1.331 +         */
   1.332 +    if (len % sizeof (Sint16) != 0) {
   1.333 +        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
   1.334 +        ptr++;
   1.335 +        len--;
   1.336 +    }
   1.337 +
   1.338 +    for (i = 0; i < len; i += sizeof (Sint8) * 6) {
   1.339 +      switch (args->room_angle) {
   1.340 +       case 0:
   1.341 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.342 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.343 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.344 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.345 +        *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
   1.346 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   1.347 +	break;
   1.348 +       case 90:
   1.349 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.350 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.351 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.352 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.353 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
   1.354 +           + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
   1.355 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   1.356 +	break;
   1.357 +       case 180:
   1.358 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.359 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.360 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.361 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.362 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
   1.363 +           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
   1.364 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   1.365 +	break;
   1.366 +       case 270:
   1.367 +        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
   1.368 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
   1.369 +        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
   1.370 +        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
   1.371 +        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
   1.372 +           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
   1.373 +        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
   1.374 +	break;
   1.375 +      }
   1.376 +    }
   1.377 +}
   1.378  
   1.379  
   1.380  /*
   1.381 @@ -211,6 +542,12 @@
   1.382      Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
   1.383      Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
   1.384  
   1.385 +    if (args->room_angle == 180) {
   1.386 +	    Sint8 *temp = l;
   1.387 +	    l = r;
   1.388 +	    r = temp;
   1.389 +    }
   1.390 +
   1.391  
   1.392      while (len % sizeof (Uint32) != 0) {
   1.393          *ptr = d[l[*ptr]];
   1.394 @@ -259,8 +596,126 @@
   1.395          Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.396                                      * args->distance_f) + 32768);
   1.397  
   1.398 -        *(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.399 -        *(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.400 +	if (args->room_angle == 180) {
   1.401 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.402 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.403 +	}
   1.404 +	else {
   1.405 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.406 +        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.407 +	}
   1.408 +    }
   1.409 +}
   1.410 +static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
   1.411 +{
   1.412 +    volatile position_args *args = (volatile position_args *) udata;
   1.413 +    Uint16 *ptr = (Uint16 *) stream;
   1.414 +    int i;
   1.415 +
   1.416 +    for (i = 0; i < len; i += sizeof (Uint16) * 4) {
   1.417 +        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
   1.418 +        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
   1.419 +        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
   1.420 +        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
   1.421 +        
   1.422 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   1.423 +                                    * args->distance_f) + 32768);
   1.424 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.425 +                                    * args->distance_f) + 32768);
   1.426 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_f)
   1.427 +                                    * args->distance_f) + 32768);
   1.428 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_f)
   1.429 +                                    * args->distance_f) + 32768);
   1.430 +
   1.431 +	switch (args->room_angle) {
   1.432 +		case 0:
   1.433 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.434 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.435 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.436 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.437 +			break;
   1.438 +		case 90:
   1.439 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.440 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.441 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.442 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.443 +			break;
   1.444 +		case 180:
   1.445 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.446 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.447 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.448 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.449 +			break;
   1.450 +		case 270:
   1.451 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.452 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.453 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.454 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.455 +			break;
   1.456 +	}
   1.457 +    }
   1.458 +}
   1.459 +static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
   1.460 +{
   1.461 +    volatile position_args *args = (volatile position_args *) udata;
   1.462 +    Uint16 *ptr = (Uint16 *) stream;
   1.463 +    int i;
   1.464 +
   1.465 +    for (i = 0; i < len; i += sizeof (Uint16) * 6) {
   1.466 +        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
   1.467 +        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
   1.468 +        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
   1.469 +        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
   1.470 +        Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
   1.471 +        Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
   1.472 +        
   1.473 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   1.474 +                                    * args->distance_f) + 32768);
   1.475 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.476 +                                    * args->distance_f) + 32768);
   1.477 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_f)
   1.478 +                                    * args->distance_f) + 32768);
   1.479 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_f)
   1.480 +                                    * args->distance_f) + 32768);
   1.481 +        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->left_f)
   1.482 +                                    * args->distance_f) + 32768);
   1.483 +        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->right_f)
   1.484 +                                    * args->distance_f) + 32768);
   1.485 +
   1.486 +	switch (args->room_angle) {
   1.487 +		case 0:
   1.488 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.489 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.490 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.491 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.492 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapce);
   1.493 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   1.494 +			break;
   1.495 +		case 90:
   1.496 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.497 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.498 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.499 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.500 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
   1.501 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   1.502 +			break;
   1.503 +		case 180:
   1.504 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.505 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.506 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.507 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.508 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
   1.509 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   1.510 +			break;
   1.511 +		case 270:
   1.512 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
   1.513 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
   1.514 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
   1.515 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
   1.516 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
   1.517 +        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
   1.518 +			break;
   1.519 +	}
   1.520      }
   1.521  }
   1.522  
   1.523 @@ -271,13 +726,127 @@
   1.524      Sint16 *ptr = (Sint16 *) stream;
   1.525      int i;
   1.526  
   1.527 +#if 0
   1.528 +    if (len % (sizeof(Sint16) * 2)) {
   1.529 +	    fprintf(stderr,"Not an even number of frames! len=%d\n", len);
   1.530 +	    return;
   1.531 +    }
   1.532 +#endif
   1.533 +
   1.534      for (i = 0; i < len; i += sizeof (Sint16) * 2) {
   1.535          Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   1.536                                      args->left_f) * args->distance_f);
   1.537          Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   1.538                                      args->right_f) * args->distance_f);
   1.539 -        *(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.540 -        *(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.541 +	if (args->room_angle == 180) {
   1.542 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.543 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.544 +	}
   1.545 +	else {
   1.546 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.547 +        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.548 +	}
   1.549 +    }
   1.550 +}
   1.551 +static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
   1.552 +{
   1.553 +    /* 16 signed bits (lsb) * 4 channels. */
   1.554 +    volatile position_args *args = (volatile position_args *) udata;
   1.555 +    Sint16 *ptr = (Sint16 *) stream;
   1.556 +    int i;
   1.557 +
   1.558 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   1.559 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   1.560 +                                    args->left_f) * args->distance_f);
   1.561 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   1.562 +                                    args->right_f) * args->distance_f);
   1.563 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   1.564 +                                    args->left_rear_f) * args->distance_f);
   1.565 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
   1.566 +                                    args->right_rear_f) * args->distance_f);
   1.567 +	switch (args->room_angle) {
   1.568 +		case 0:
   1.569 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.570 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.571 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.572 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.573 +			break;
   1.574 +		case 90:
   1.575 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.576 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.577 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.578 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.579 +			break;
   1.580 +		case 180:
   1.581 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.582 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.583 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.584 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.585 +			break;
   1.586 +		case 270:
   1.587 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.588 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.589 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.590 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.591 +			break;
   1.592 +	}
   1.593 +    }
   1.594 +}
   1.595 +
   1.596 +static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
   1.597 +{
   1.598 +    /* 16 signed bits (lsb) * 6 channels. */
   1.599 +    volatile position_args *args = (volatile position_args *) udata;
   1.600 +    Sint16 *ptr = (Sint16 *) stream;
   1.601 +    int i;
   1.602 +
   1.603 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   1.604 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
   1.605 +                                    args->left_f) * args->distance_f);
   1.606 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
   1.607 +                                    args->right_f) * args->distance_f);
   1.608 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
   1.609 +                                    args->left_rear_f) * args->distance_f);
   1.610 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
   1.611 +                                    args->right_rear_f) * args->distance_f);
   1.612 +        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
   1.613 +                                    args->center_f) * args->distance_f);
   1.614 +        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
   1.615 +                                    args->lfe_f) * args->distance_f);
   1.616 +	switch (args->room_angle) {
   1.617 +		case 0:
   1.618 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.619 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.620 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.621 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.622 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapce);
   1.623 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   1.624 +			break;
   1.625 +		case 90:
   1.626 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.627 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.628 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.629 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.630 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
   1.631 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   1.632 +			break;
   1.633 +		case 180:
   1.634 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.635 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.636 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.637 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.638 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
   1.639 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   1.640 +			break;
   1.641 +		case 270:
   1.642 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
   1.643 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
   1.644 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
   1.645 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
   1.646 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
   1.647 +        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
   1.648 +			break;
   1.649 +	}
   1.650      }
   1.651  }
   1.652  
   1.653 @@ -297,8 +866,128 @@
   1.654          Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.655                                      * args->distance_f) + 32768);
   1.656  
   1.657 -        *(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.658 -        *(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.659 +	if (args->room_angle == 180) {
   1.660 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.661 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.662 +	}
   1.663 +	else {
   1.664 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.665 +        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.666 +	}
   1.667 +    }
   1.668 +}
   1.669 +static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
   1.670 +{
   1.671 +    /* 16 signed bits (lsb) * 4 channels. */
   1.672 +    volatile position_args *args = (volatile position_args *) udata;
   1.673 +    Uint16 *ptr = (Uint16 *) stream;
   1.674 +    int i;
   1.675 +
   1.676 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   1.677 +        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
   1.678 +        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
   1.679 +        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
   1.680 +        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
   1.681 +        
   1.682 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   1.683 +                                    * args->distance_f) + 32768);
   1.684 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.685 +                                    * args->distance_f) + 32768);
   1.686 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
   1.687 +                                    * args->distance_f) + 32768);
   1.688 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
   1.689 +                                    * args->distance_f) + 32768);
   1.690 +
   1.691 +	switch (args->room_angle) {
   1.692 +		case 0:
   1.693 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.694 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.695 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.696 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.697 +			break;
   1.698 +		case 90:
   1.699 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.700 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.701 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.702 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.703 +			break;
   1.704 +		case 180:
   1.705 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.706 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.707 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.708 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.709 +			break;
   1.710 +		case 270:
   1.711 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.712 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.713 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.714 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.715 +			break;
   1.716 +	}
   1.717 +    }
   1.718 +}
   1.719 +static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
   1.720 +{
   1.721 +    /* 16 signed bits (lsb) * 6 channels. */
   1.722 +    volatile position_args *args = (volatile position_args *) udata;
   1.723 +    Uint16 *ptr = (Uint16 *) stream;
   1.724 +    int i;
   1.725 +
   1.726 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   1.727 +        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
   1.728 +        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
   1.729 +        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
   1.730 +        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
   1.731 +        Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
   1.732 +        Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
   1.733 +        
   1.734 +        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
   1.735 +                                    * args->distance_f) + 32768);
   1.736 +        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
   1.737 +                                    * args->distance_f) + 32768);
   1.738 +        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
   1.739 +                                    * args->distance_f) + 32768);
   1.740 +        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
   1.741 +                                    * args->distance_f) + 32768);
   1.742 +        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
   1.743 +                                    * args->distance_f) + 32768);
   1.744 +        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
   1.745 +                                    * args->distance_f) + 32768);
   1.746 +
   1.747 +	switch (args->room_angle) {
   1.748 +		case 0:
   1.749 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.750 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.751 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.752 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.753 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapce);
   1.754 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   1.755 +			break;
   1.756 +		case 90:
   1.757 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.758 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.759 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.760 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.761 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
   1.762 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   1.763 +			break;
   1.764 +		case 180:
   1.765 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.766 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.767 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.768 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.769 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
   1.770 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   1.771 +			break;
   1.772 +		case 270:
   1.773 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
   1.774 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
   1.775 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
   1.776 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
   1.777 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
   1.778 +        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
   1.779 +			break;
   1.780 +	}
   1.781      }
   1.782  }
   1.783  
   1.784 @@ -318,14 +1007,117 @@
   1.785          *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.786      }
   1.787  }
   1.788 +static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
   1.789 +{
   1.790 +    /* 16 signed bits (lsb) * 4 channels. */
   1.791 +    volatile position_args *args = (volatile position_args *) udata;
   1.792 +    Sint16 *ptr = (Sint16 *) stream;
   1.793 +    int i;
   1.794  
   1.795 +    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
   1.796 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
   1.797 +                                    args->left_f) * args->distance_f);
   1.798 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
   1.799 +                                    args->right_f) * args->distance_f);
   1.800 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
   1.801 +                                    args->left_rear_f) * args->distance_f);
   1.802 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
   1.803 +                                    args->right_rear_f) * args->distance_f);
   1.804 +	switch (args->room_angle) {
   1.805 +		case 0:
   1.806 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.807 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.808 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.809 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.810 +			break;
   1.811 +		case 90:
   1.812 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.813 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.814 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.815 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.816 +			break;
   1.817 +		case 180:
   1.818 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.819 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.820 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.821 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.822 +			break;
   1.823 +		case 270:
   1.824 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.825 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.826 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.827 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.828 +			break;
   1.829 +	}
   1.830 +    }
   1.831 +}
   1.832 +static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
   1.833 +{
   1.834 +    /* 16 signed bits (lsb) * 6 channels. */
   1.835 +    volatile position_args *args = (volatile position_args *) udata;
   1.836 +    Sint16 *ptr = (Sint16 *) stream;
   1.837 +    int i;
   1.838 +
   1.839 +    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
   1.840 +        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
   1.841 +                                    args->left_f) * args->distance_f);
   1.842 +        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
   1.843 +                                    args->right_f) * args->distance_f);
   1.844 +        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
   1.845 +                                    args->left_rear_f) * args->distance_f);
   1.846 +        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
   1.847 +                                    args->right_rear_f) * args->distance_f);
   1.848 +        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
   1.849 +                                    args->center_f) * args->distance_f);
   1.850 +        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
   1.851 +                                    args->lfe_f) * args->distance_f);
   1.852 +
   1.853 +	switch (args->room_angle) {
   1.854 +		case 0:
   1.855 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.856 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.857 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.858 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.859 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapce);
   1.860 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   1.861 +			break;
   1.862 +		case 90:
   1.863 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.864 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.865 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.866 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.867 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
   1.868 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   1.869 +			break;
   1.870 +		case 180:
   1.871 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.872 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.873 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.874 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.875 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
   1.876 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   1.877 +			break;
   1.878 +		case 270:
   1.879 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
   1.880 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
   1.881 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
   1.882 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
   1.883 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
   1.884 +        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
   1.885 +			break;
   1.886 +	}
   1.887 +    }
   1.888 +}
   1.889  
   1.890  static void init_position_args(position_args *args)
   1.891  {
   1.892      memset(args, '\0', sizeof (position_args));
   1.893      args->in_use = 0;
   1.894 +    args->room_angle = 0;
   1.895      args->left_u8 = args->right_u8 = args->distance_u8 = 255;
   1.896      args->left_f  = args->right_f  = args->distance_f  = 1.0f;
   1.897 +    args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
   1.898 +    args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
   1.899      Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
   1.900  }
   1.901  
   1.902 @@ -374,35 +1166,101 @@
   1.903  }
   1.904  
   1.905  
   1.906 -static Mix_EffectFunc_t get_position_effect_func(Uint16 format)
   1.907 +static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
   1.908  {
   1.909      Mix_EffectFunc_t f = NULL;
   1.910  
   1.911      switch (format) {
   1.912          case AUDIO_U8:
   1.913 -            f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
   1.914 -                                                 _Eff_position_u8;
   1.915 +	    switch (channels) {
   1.916 +		    case 1:
   1.917 +		    case 2:
   1.918 +            		f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
   1.919 +                                                 		_Eff_position_u8;
   1.920 +	    		break;
   1.921 +	    	    case 4:
   1.922 +                        _Eff_position_u8_c4;
   1.923 +	    		break;
   1.924 +	    	    case 6:
   1.925 +                        _Eff_position_u8_c6;
   1.926 +	    		break;
   1.927 +	    }
   1.928              break;
   1.929  
   1.930          case AUDIO_S8:
   1.931 -            f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
   1.932 -                                                 _Eff_position_s8;
   1.933 +	    switch (channels) {
   1.934 +		    case 1:
   1.935 +		    case 2:
   1.936 +            		f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
   1.937 +                                                 		_Eff_position_s8;
   1.938 +	    		break;
   1.939 +	    	    case 4:
   1.940 +                        _Eff_position_s8_c4;
   1.941 +	    		break;
   1.942 +	    	    case 6:
   1.943 +                        _Eff_position_s8_c6;
   1.944 +	    		break;
   1.945 +	    }
   1.946              break;
   1.947  
   1.948          case AUDIO_U16LSB:
   1.949 -            f = _Eff_position_u16lsb;
   1.950 +	    switch (channels) {
   1.951 +		    case 1:
   1.952 +		    case 2:
   1.953 +            		f = _Eff_position_u16lsb;
   1.954 +	    		break;
   1.955 +	    	    case 4:
   1.956 +            		f = _Eff_position_u16lsb_c4;
   1.957 +	    		break;
   1.958 +	    	    case 6:
   1.959 +            		f = _Eff_position_u16lsb_c6;
   1.960 +	    		break;
   1.961 +	    }
   1.962              break;
   1.963  
   1.964          case AUDIO_S16LSB:
   1.965 -            f = _Eff_position_s16lsb;
   1.966 +	    switch (channels) {
   1.967 +		    case 1:
   1.968 +		    case 2:
   1.969 +            		f = _Eff_position_s16lsb;
   1.970 +	    		break;
   1.971 +	    	    case 4:
   1.972 +            		f = _Eff_position_s16lsb_c4;
   1.973 +	    		break;
   1.974 +	    	    case 6:
   1.975 +            		f = _Eff_position_s16lsb_c6;
   1.976 +	    		break;
   1.977 +	    }
   1.978              break;
   1.979  
   1.980          case AUDIO_U16MSB:
   1.981 -            f = _Eff_position_u16msb;
   1.982 +	    switch (channels) {
   1.983 +		    case 1:
   1.984 +		    case 2:
   1.985 +            		f = _Eff_position_u16msb;
   1.986 +	    		break;
   1.987 +	    	    case 4:
   1.988 +            		f = _Eff_position_u16msb_c4;
   1.989 +	    		break;
   1.990 +	    	    case 6:
   1.991 +            		f = _Eff_position_u16msb_c6;
   1.992 +	    		break;
   1.993 +	    }
   1.994              break;
   1.995  
   1.996          case AUDIO_S16MSB:
   1.997 -            f = _Eff_position_s16msb;
   1.998 +	    switch (channels) {
   1.999 +		    case 1:
  1.1000 +		    case 2:
  1.1001 +            		f = _Eff_position_s16msb;
  1.1002 +	    		break;
  1.1003 +	    	    case 4:
  1.1004 +            		f = _Eff_position_s16msb_c4;
  1.1005 +	    		break;
  1.1006 +	    	    case 6:
  1.1007 +            		f = _Eff_position_s16msb_c6;
  1.1008 +	    		break;
  1.1009 +	    }
  1.1010              break;
  1.1011  
  1.1012          default:
  1.1013 @@ -412,6 +1270,140 @@
  1.1014      return(f);
  1.1015  }
  1.1016  
  1.1017 +static Uint8 speaker_amplitude[6];
  1.1018 +
  1.1019 +static void set_amplitudes(int channels, int angle, int room_angle)
  1.1020 +{
  1.1021 +    int left = 255, right = 255;
  1.1022 +    int left_rear = 255, right_rear = 255, center = 255;
  1.1023 +
  1.1024 +        /* unwind the angle...it'll be between 0 and 359. */
  1.1025 +    while (angle >= 360) angle -= 360;
  1.1026 +    while (angle < 0) angle += 360;
  1.1027 +
  1.1028 +    if (channels == 2)
  1.1029 +    {
  1.1030 +        /*
  1.1031 +         * We only attenuate by position if the angle falls on the far side
  1.1032 +         *  of center; That is, an angle that's due north would not attenuate
  1.1033 +         *  either channel. Due west attenuates the right channel to 0.0, and
  1.1034 +         *  due east attenuates the left channel to 0.0. Slightly east of
  1.1035 +         *  center attenuates the left channel a little, and the right channel
  1.1036 +         *  not at all. I think of this as occlusion by one's own head.  :)
  1.1037 +         *
  1.1038 +         *   ...so, we split our angle circle into four quadrants...
  1.1039 +         */
  1.1040 +        if (angle < 90) {
  1.1041 +            left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
  1.1042 +        } else if (angle < 180) {
  1.1043 +            left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
  1.1044 +        } else if (angle < 270) {
  1.1045 +            right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
  1.1046 +        } else {
  1.1047 +            right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
  1.1048 +        }
  1.1049 +    }
  1.1050 +
  1.1051 +    if (channels == 4 || channels == 6)
  1.1052 +    {
  1.1053 +        /*
  1.1054 +         *  An angle that's due north does not attenuate the center channel.
  1.1055 +         *  An angle in the first quadrant, 0-90, does not attenuate the RF.
  1.1056 +         *
  1.1057 +         *   ...so, we split our angle circle into 8 ...
  1.1058 +	 *
  1.1059 +	 *             CE
  1.1060 +	 *             0
  1.1061 +	 *     LF      |         RF
  1.1062 +	 *             |
  1.1063 +	 *  270<-------|----------->90
  1.1064 +	 *             |
  1.1065 +	 *     LR      |         RR
  1.1066 +	 *            180
  1.1067 +	 *   
  1.1068 +         */
  1.1069 +        if (angle < 45) {
  1.1070 +            left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  1.1071 +            left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
  1.1072 +            right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
  1.1073 +        } else if (angle < 90) {
  1.1074 +            center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  1.1075 +            left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
  1.1076 +            left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
  1.1077 +            right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
  1.1078 +        } else if (angle < 135) {
  1.1079 +            center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
  1.1080 +            left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
  1.1081 +            right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  1.1082 +            left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  1.1083 +        } else if (angle < 180) {
  1.1084 +            center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
  1.1085 +            left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
  1.1086 +            right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
  1.1087 +            left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
  1.1088 +        } else if (angle < 225) {
  1.1089 +            center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
  1.1090 +            left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  1.1091 +            right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
  1.1092 +            right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  1.1093 +        } else if (angle < 270) {
  1.1094 +            center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  1.1095 +            left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
  1.1096 +            right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
  1.1097 +            right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
  1.1098 +        } else if (angle < 315) {
  1.1099 +            center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
  1.1100 +            right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  1.1101 +            left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  1.1102 +            right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
  1.1103 +        } else {
  1.1104 +            right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
  1.1105 +            left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
  1.1106 +            right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
  1.1107 +        }
  1.1108 +    }
  1.1109 +
  1.1110 +    if (left < 0) left = 0; if (left > 255) left = 255;
  1.1111 +    if (right < 0) right = 0; if (right > 255) right = 255;
  1.1112 +    if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
  1.1113 +    if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
  1.1114 +    if (center < 0) center = 0; if (center > 255) center = 255;
  1.1115 +
  1.1116 +    if (room_angle == 90) {
  1.1117 +    	speaker_amplitude[0] = (Uint8)left_rear;
  1.1118 +    	speaker_amplitude[1] = (Uint8)left;
  1.1119 +    	speaker_amplitude[2] = (Uint8)right_rear;
  1.1120 +    	speaker_amplitude[3] = (Uint8)right;
  1.1121 +    }
  1.1122 +    else if (room_angle == 180) {
  1.1123 +	if (channels == 2) {
  1.1124 +    	    speaker_amplitude[0] = (Uint8)right;
  1.1125 +    	    speaker_amplitude[1] = (Uint8)left;
  1.1126 +	}
  1.1127 +	else {
  1.1128 +    	    speaker_amplitude[0] = (Uint8)right_rear;
  1.1129 +    	    speaker_amplitude[1] = (Uint8)left_rear;
  1.1130 +    	    speaker_amplitude[2] = (Uint8)right;
  1.1131 +    	    speaker_amplitude[3] = (Uint8)left;
  1.1132 +	}
  1.1133 +    }
  1.1134 +    else if (room_angle == 270) {
  1.1135 +    	speaker_amplitude[0] = (Uint8)right;
  1.1136 +    	speaker_amplitude[1] = (Uint8)right_rear;
  1.1137 +    	speaker_amplitude[2] = (Uint8)left;
  1.1138 +    	speaker_amplitude[3] = (Uint8)left_rear;
  1.1139 +    }
  1.1140 +    else {
  1.1141 +    	speaker_amplitude[0] = (Uint8)left;
  1.1142 +    	speaker_amplitude[1] = (Uint8)right;
  1.1143 +    	speaker_amplitude[2] = (Uint8)left_rear;
  1.1144 +    	speaker_amplitude[3] = (Uint8)right_rear;
  1.1145 +    }
  1.1146 +    speaker_amplitude[4] = (Uint8)center;
  1.1147 +    speaker_amplitude[5] = 255;
  1.1148 +}
  1.1149 +
  1.1150 +int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
  1.1151  
  1.1152  int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
  1.1153  {
  1.1154 @@ -419,13 +1411,21 @@
  1.1155      int channels;
  1.1156      Uint16 format;
  1.1157      position_args *args = NULL;
  1.1158 -
  1.1159      Mix_QuerySpec(NULL, &format, &channels);
  1.1160  
  1.1161 -    if (channels != 2)    /* it's a no-op; we call that successful. */
  1.1162 +    if (channels != 2 && channels != 4 && channels != 6)    /* it's a no-op; we call that successful. */
  1.1163          return(1);
  1.1164  
  1.1165 -    f = get_position_effect_func(format);
  1.1166 +    if (channels > 2) {
  1.1167 +    	/* left = 255 =>  angle = -90;  left = 0 => angle = +89 */
  1.1168 +    	int angle = (int)left;
  1.1169 +    	angle = 127 - angle;
  1.1170 +	angle = -angle;
  1.1171 +    	angle = angle * 90 / 128; /* Make it larger for more effect? */
  1.1172 +	return( Mix_SetPosition(channel, angle, 0) );
  1.1173 +    }
  1.1174 +
  1.1175 +    f = get_position_effect_func(format, channels);
  1.1176      if (f == NULL)
  1.1177          return(0);
  1.1178  
  1.1179 @@ -441,9 +1441,11 @@
  1.1180      }
  1.1181  
  1.1182      args->left_u8 = left;
  1.1183 +    args->left_f = ((float) left) / 255.0f;
  1.1184      args->right_u8 = right;
  1.1185 -    args->left_f = ((float) left) / 255.0f;
  1.1186      args->right_f = ((float) right) / 255.0f;
  1.1187 +    args->room_angle = 0;
  1.1188 +
  1.1189      if (!args->in_use) {
  1.1190          args->in_use = 1;
  1.1191          return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
  1.1192 @@ -458,9 +1460,10 @@
  1.1193      Mix_EffectFunc_t f = NULL;
  1.1194      Uint16 format;
  1.1195      position_args *args = NULL;
  1.1196 +    int channels;
  1.1197  
  1.1198 -    Mix_QuerySpec(NULL, &format, NULL);
  1.1199 -    f = get_position_effect_func(format);
  1.1200 +    Mix_QuerySpec(NULL, &format, &channels);
  1.1201 +    f = get_position_effect_func(format, channels);
  1.1202      if (f == NULL)
  1.1203          return(0);
  1.1204  
  1.1205 @@ -494,10 +1497,10 @@
  1.1206      Uint16 format;
  1.1207      int channels;
  1.1208      position_args *args = NULL;
  1.1209 -    Uint8 left = 255, right = 255;
  1.1210 +    Sint16 room_angle;
  1.1211  
  1.1212      Mix_QuerySpec(NULL, &format, &channels);
  1.1213 -    f = get_position_effect_func(format);
  1.1214 +    f = get_position_effect_func(format, channels);
  1.1215      if (f == NULL)
  1.1216          return(0);
  1.1217  
  1.1218 @@ -515,35 +1518,40 @@
  1.1219  
  1.1220      if (channels == 2)
  1.1221      {
  1.1222 -        /*
  1.1223 -         * We only attenuate by position if the angle falls on the far side
  1.1224 -         *  of center; That is, an angle that's due north would not attenuate
  1.1225 -         *  either channel. Due west attenuates the right channel to 0.0, and
  1.1226 -         *  due east attenuates the left channel to 0.0. Slightly east of
  1.1227 -         *  center attenuates the left channel a little, and the right channel
  1.1228 -         *  not at all. I think of this as occlusion by one's own head.  :)
  1.1229 -         *
  1.1230 -         *   ...so, we split our angle circle into four quadrants...
  1.1231 -         */
  1.1232 -        if (angle < 90) {
  1.1233 -            left = 255 - ((Uint8) (255.0f * (((float) angle) / 89.0f)));
  1.1234 -        } else if (angle < 180) {
  1.1235 -            left = (Uint8) (255.0f * (((float) (angle - 90)) / 89.0f));
  1.1236 -        } else if (angle < 270) {
  1.1237 -            right = 255 - ((Uint8) (255.0f * (((float) (angle - 180)) / 89.0f)));
  1.1238 -        } else {
  1.1239 -            right = (Uint8) (255.0f * (((float) (angle - 270)) / 89.0f));
  1.1240 -        }
  1.1241 +	if (angle > 180)
  1.1242 +		room_angle = 180; /* exchange left and right channels */
  1.1243 +	else room_angle = 0;
  1.1244      }
  1.1245  
  1.1246 +    if (channels == 4 || channels == 6)
  1.1247 +    {
  1.1248 +	if (angle > 315) room_angle = 0;
  1.1249 +	else if (angle > 225) room_angle = 270;
  1.1250 +	else if (angle > 135) room_angle = 180;
  1.1251 +	else if (angle > 45) room_angle = 90;
  1.1252 +	else room_angle = 0;
  1.1253 +    }
  1.1254 +
  1.1255 +
  1.1256      distance = 255 - distance;  /* flip it to scale Mix_SetDistance() uses. */
  1.1257  
  1.1258 -    args->left_u8 = left;
  1.1259 -    args->left_f = ((float) left) / 255.0f;
  1.1260 -    args->right_u8 = right;
  1.1261 -    args->right_f = ((float) right) / 255.0f;
  1.1262 +    set_amplitudes(channels, angle, room_angle);
  1.1263 +
  1.1264 +    args->left_u8 = speaker_amplitude[0];
  1.1265 +    args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
  1.1266 +    args->right_u8 = speaker_amplitude[1];
  1.1267 +    args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
  1.1268 +    args->left_rear_u8 = speaker_amplitude[2];
  1.1269 +    args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
  1.1270 +    args->right_rear_u8 = speaker_amplitude[3];
  1.1271 +    args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
  1.1272 +    args->center_u8 = speaker_amplitude[4];
  1.1273 +    args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
  1.1274 +    args->lfe_u8 = 255;
  1.1275 +    args->lfe_f = 255.0f;
  1.1276      args->distance_u8 = distance;
  1.1277      args->distance_f = ((float) distance) / 255.0f;
  1.1278 +    args->room_angle = room_angle;
  1.1279      if (!args->in_use) {
  1.1280          args->in_use = 1;
  1.1281          return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));