PageRenderTime 135ms CodeModel.GetById 25ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sdl_mixer/effect_position.c

https://github.com/aichunyu/FFPlayer
C | 1617 lines | 1333 code | 140 blank | 144 comment | 233 complexity | 87120104d1d50c0c647ea1787836bc04 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2    SDL_mixer:  An audio mixer library based on the SDL library
   3    Copyright (C) 1997-2009 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: effect_position.c 5045 2009-10-11 02:59:12Z icculus $ */
  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
  57typedef 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
  78static position_args **pos_args_array = NULL;
  79static position_args *pos_args_global = NULL;
  80static int position_channels = 0;
  81
  82void _Eff_PositionDeinit(void)
  83{
  84    int i;
  85    for (i = 0; i < position_channels; i++) {
  86        free(pos_args_array[i]);
  87    }
  88
  89    position_channels = 0;
  90
  91    free(pos_args_global);
  92    pos_args_global = NULL;
  93    free(pos_args_array);
  94    pos_args_array = NULL;
  95}
  96
  97
  98/* This just frees up the callback-specific data. */
  99static void _Eff_PositionDone(int channel, void *udata)
 100{
 101    if (channel < 0) {
 102        if (pos_args_global != NULL) {
 103            free(pos_args_global);
 104            pos_args_global = NULL;
 105        }
 106    }
 107
 108    else if (pos_args_array[channel] != NULL) {
 109        free(pos_args_array[channel]);
 110        pos_args_array[channel] = NULL;
 111    }
 112}
 113
 114
 115static void _Eff_position_u8(int chan, void *stream, int len, void *udata)
 116{
 117    volatile position_args *args = (volatile position_args *) udata;
 118    Uint8 *ptr = (Uint8 *) stream;
 119    int i;
 120
 121        /*
 122         * if there's only a mono channnel (the only way we wouldn't have
 123         *  a len divisible by 2 here), then left_f and right_f are always
 124         *  1.0, and are therefore throwaways.
 125         */
 126    if (len % sizeof (Uint16) != 0) {
 127        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
 128        ptr++;
 129        len--;
 130    }
 131
 132    if (args->room_angle == 180)
 133    for (i = 0; i < len; i += sizeof (Uint8) * 2) {
 134        /* must adjust the sample so that 0 is the center */
 135        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 136            * args->right_f) * args->distance_f) + 128);
 137        ptr++;
 138        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 139            * args->left_f) * args->distance_f) + 128);
 140        ptr++;
 141    }
 142    else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
 143        /* must adjust the sample so that 0 is the center */
 144        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 145            * args->left_f) * args->distance_f) + 128);
 146        ptr++;
 147        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 148            * args->right_f) * args->distance_f) + 128);
 149        ptr++;
 150    }
 151}
 152static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
 153{
 154    volatile position_args *args = (volatile position_args *) udata;
 155    Uint8 *ptr = (Uint8 *) stream;
 156    int i;
 157
 158        /*
 159         * if there's only a mono channnel (the only way we wouldn't have
 160         *  a len divisible by 2 here), then left_f and right_f are always
 161         *  1.0, and are therefore throwaways.
 162         */
 163    if (len % sizeof (Uint16) != 0) {
 164        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
 165        ptr++;
 166        len--;
 167    }
 168
 169    if (args->room_angle == 0)
 170    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 171        /* must adjust the sample so that 0 is the center */
 172        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 173            * args->left_f) * args->distance_f) + 128);
 174        ptr++;
 175        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 176            * args->right_f) * args->distance_f) + 128);
 177        ptr++;
 178        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 179            * args->left_rear_f) * args->distance_f) + 128);
 180        ptr++;
 181        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 182            * args->right_rear_f) * args->distance_f) + 128);
 183        ptr++;
 184    }
 185    else if (args->room_angle == 90)
 186    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 187        /* must adjust the sample so that 0 is the center */
 188        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 189            * args->right_f) * args->distance_f) + 128);
 190        ptr++;
 191        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 192            * args->right_rear_f) * args->distance_f) + 128);
 193        ptr++;
 194        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 195            * args->left_f) * args->distance_f) + 128);
 196        ptr++;
 197        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 198            * args->left_rear_f) * args->distance_f) + 128);
 199        ptr++;
 200    }
 201    else if (args->room_angle == 180)
 202    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 203        /* must adjust the sample so that 0 is the center */
 204        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 205            * args->right_rear_f) * args->distance_f) + 128);
 206        ptr++;
 207        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 208            * args->left_rear_f) * args->distance_f) + 128);
 209        ptr++;
 210        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 211            * args->right_f) * args->distance_f) + 128);
 212        ptr++;
 213        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 214            * args->left_f) * args->distance_f) + 128);
 215        ptr++;
 216    }
 217    else if (args->room_angle == 270)
 218    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 219        /* must adjust the sample so that 0 is the center */
 220        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 221            * args->left_rear_f) * args->distance_f) + 128);
 222        ptr++;
 223        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 224            * args->left_f) * args->distance_f) + 128);
 225        ptr++;
 226        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 227            * args->right_rear_f) * args->distance_f) + 128);
 228        ptr++;
 229        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 230            * args->right_f) * args->distance_f) + 128);
 231        ptr++;
 232    }
 233}
 234
 235
 236static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
 237{
 238    volatile position_args *args = (volatile position_args *) udata;
 239    Uint8 *ptr = (Uint8 *) stream;
 240    int i;
 241
 242        /*
 243         * if there's only a mono channnel (the only way we wouldn't have
 244         *  a len divisible by 2 here), then left_f and right_f are always
 245         *  1.0, and are therefore throwaways.
 246         */
 247    if (len % sizeof (Uint16) != 0) {
 248        *ptr = (Uint8) (((float) *ptr) * args->distance_f);
 249        ptr++;
 250        len--;
 251    }
 252
 253    if (args->room_angle == 0)
 254    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 255        /* must adjust the sample so that 0 is the center */
 256        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 257            * args->left_f) * args->distance_f) + 128);
 258        ptr++;
 259        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 260            * args->right_f) * args->distance_f) + 128);
 261        ptr++;
 262        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 263            * args->left_rear_f) * args->distance_f) + 128);
 264        ptr++;
 265        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 266            * args->right_rear_f) * args->distance_f) + 128);
 267        ptr++;
 268        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 269            * args->center_f) * args->distance_f) + 128);
 270        ptr++;
 271        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 272            * args->lfe_f) * args->distance_f) + 128);
 273        ptr++;
 274    }
 275    else if (args->room_angle == 90)
 276    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 277        /* must adjust the sample so that 0 is the center */
 278        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 279            * args->right_f) * args->distance_f) + 128);
 280        ptr++;
 281        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 282            * args->right_rear_f) * args->distance_f) + 128);
 283        ptr++;
 284        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 285            * args->left_f) * args->distance_f) + 128);
 286        ptr++;
 287        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 288            * args->left_rear_f) * args->distance_f) + 128);
 289        ptr++;
 290        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 291            * args->right_rear_f) * args->distance_f/2) + 128)
 292            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 293            * args->right_f) * args->distance_f/2) + 128);
 294        ptr++;
 295        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 296            * args->lfe_f) * args->distance_f) + 128);
 297        ptr++;
 298    }
 299    else if (args->room_angle == 180)
 300    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 301        /* must adjust the sample so that 0 is the center */
 302        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 303            * args->right_rear_f) * args->distance_f) + 128);
 304        ptr++;
 305        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 306            * args->left_rear_f) * args->distance_f) + 128);
 307        ptr++;
 308        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 309            * args->right_f) * args->distance_f) + 128);
 310        ptr++;
 311        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 312            * args->left_f) * args->distance_f) + 128);
 313        ptr++;
 314        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 315            * args->right_rear_f) * args->distance_f/2) + 128)
 316            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 317            * args->left_rear_f) * args->distance_f/2) + 128);
 318        ptr++;
 319        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 320            * args->lfe_f) * args->distance_f) + 128);
 321        ptr++;
 322    }
 323    else if (args->room_angle == 270)
 324    for (i = 0; i < len; i += sizeof (Uint8) * 6) {
 325        /* must adjust the sample so that 0 is the center */
 326        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 327            * args->left_rear_f) * args->distance_f) + 128);
 328        ptr++;
 329        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 330            * args->left_f) * args->distance_f) + 128);
 331        ptr++;
 332        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 333            * args->right_rear_f) * args->distance_f) + 128);
 334        ptr++;
 335        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 336            * args->right_f) * args->distance_f) + 128);
 337        ptr++;
 338        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 339            * args->left_f) * args->distance_f/2) + 128)
 340            + (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 341            * args->left_rear_f) * args->distance_f/2) + 128);
 342        ptr++;
 343        *ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128)) 
 344            * args->lfe_f) * args->distance_f) + 128);
 345        ptr++;
 346    }
 347}
 348
 349
 350/*
 351 * This one runs about 10.1 times faster than the non-table version, with
 352 *  no loss in quality. It does, however, require 64k of memory for the
 353 *  lookup table. Also, this will only update position information once per
 354 *  call; the non-table version always checks the arguments for each sample,
 355 *  in case the user has called Mix_SetPanning() or whatnot again while this
 356 *  callback is running.
 357 */
 358static void _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
 359{
 360    volatile position_args *args = (volatile position_args *) udata;
 361    Uint8 *ptr = (Uint8 *) stream;
 362    Uint32 *p;
 363    int i;
 364    Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
 365    Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
 366    Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
 367
 368    if (args->room_angle == 180) {
 369	    Uint8 *temp = l;
 370	    l = r;
 371	    r = temp;
 372    }
 373        /*
 374         * if there's only a mono channnel, then l[] and r[] are always
 375         *  volume 255, and are therefore throwaways. Still, we have to
 376         *  be sure not to overrun the audio buffer...
 377         */
 378    while (len % sizeof (Uint32) != 0) {
 379        *ptr = d[l[*ptr]];
 380        ptr++;
 381        if (args->channels > 1) {
 382            *ptr = d[r[*ptr]];
 383            ptr++;
 384        }
 385        len -= args->channels;
 386    }
 387
 388    p = (Uint32 *) ptr;
 389
 390    for (i = 0; i < len; i += sizeof (Uint32)) {
 391#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
 392        *p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
 393             (d[r[(*p & 0x00FF0000) >> 16]] << 16) |
 394             (d[l[(*p & 0x0000FF00) >>  8]] <<  8) |
 395             (d[r[(*p & 0x000000FF)      ]]      ) ;
 396#else
 397        *p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
 398             (d[l[(*p & 0x00FF0000) >> 16]] << 16) |
 399             (d[r[(*p & 0x0000FF00) >>  8]] <<  8) |
 400             (d[l[(*p & 0x000000FF)      ]]      ) ;
 401#endif
 402        ++p;
 403    }
 404}
 405
 406
 407static void _Eff_position_s8(int chan, void *stream, int len, void *udata)
 408{
 409    volatile position_args *args = (volatile position_args *) udata;
 410    Sint8 *ptr = (Sint8 *) stream;
 411    int i;
 412
 413        /*
 414         * if there's only a mono channnel (the only way we wouldn't have
 415         *  a len divisible by 2 here), then left_f and right_f are always
 416         *  1.0, and are therefore throwaways.
 417         */
 418    if (len % sizeof (Sint16) != 0) {
 419        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
 420        ptr++;
 421        len--;
 422    }
 423
 424    if (args->room_angle == 180)
 425    for (i = 0; i < len; i += sizeof (Sint8) * 2) {
 426        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
 427        ptr++;
 428        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
 429        ptr++;
 430    }
 431    else
 432    for (i = 0; i < len; i += sizeof (Sint8) * 2) {
 433        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
 434        ptr++;
 435        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
 436        ptr++;
 437    }
 438}
 439static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
 440{
 441    volatile position_args *args = (volatile position_args *) udata;
 442    Sint8 *ptr = (Sint8 *) stream;
 443    int i;
 444
 445        /*
 446         * if there's only a mono channnel (the only way we wouldn't have
 447         *  a len divisible by 2 here), then left_f and right_f are always
 448         *  1.0, and are therefore throwaways.
 449         */
 450    if (len % sizeof (Sint16) != 0) {
 451        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
 452        ptr++;
 453        len--;
 454    }
 455
 456    for (i = 0; i < len; i += sizeof (Sint8) * 4) {
 457      switch (args->room_angle) {
 458       case 0:
 459        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 460        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 461        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 462        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 463	break;
 464       case 90:
 465        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 466        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 467        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 468        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 469	break;
 470       case 180:
 471        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 472        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 473        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 474        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 475	break;
 476       case 270:
 477        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 478        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 479        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 480        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 481	break;
 482      }
 483    }
 484}
 485static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
 486{
 487    volatile position_args *args = (volatile position_args *) udata;
 488    Sint8 *ptr = (Sint8 *) stream;
 489    int i;
 490
 491        /*
 492         * if there's only a mono channnel (the only way we wouldn't have
 493         *  a len divisible by 2 here), then left_f and right_f are always
 494         *  1.0, and are therefore throwaways.
 495         */
 496    if (len % sizeof (Sint16) != 0) {
 497        *ptr = (Sint8) (((float) *ptr) * args->distance_f);
 498        ptr++;
 499        len--;
 500    }
 501
 502    for (i = 0; i < len; i += sizeof (Sint8) * 6) {
 503      switch (args->room_angle) {
 504       case 0:
 505        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 506        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 507        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 508        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 509        *ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
 510        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
 511	break;
 512       case 90:
 513        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 514        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 515        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 516        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 517        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
 518           + (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
 519        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
 520	break;
 521       case 180:
 522        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 523        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 524        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 525        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 526        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
 527           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
 528        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
 529	break;
 530       case 270:
 531        *ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
 532        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
 533        *ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
 534        *ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
 535        *ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
 536           + (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
 537        *ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
 538	break;
 539      }
 540    }
 541}
 542
 543
 544/*
 545 * This one runs about 10.1 times faster than the non-table version, with
 546 *  no loss in quality. It does, however, require 64k of memory for the
 547 *  lookup table. Also, this will only update position information once per
 548 *  call; the non-table version always checks the arguments for each sample,
 549 *  in case the user has called Mix_SetPanning() or whatnot again while this
 550 *  callback is running.
 551 */
 552static void _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
 553{
 554    volatile position_args *args = (volatile position_args *) udata;
 555    Sint8 *ptr = (Sint8 *) stream;
 556    Uint32 *p;
 557    int i;
 558    Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
 559    Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
 560    Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
 561
 562    if (args->room_angle == 180) {
 563	    Sint8 *temp = l;
 564	    l = r;
 565	    r = temp;
 566    }
 567
 568
 569    while (len % sizeof (Uint32) != 0) {
 570        *ptr = d[l[*ptr]];
 571        ptr++;
 572        if (args->channels > 1) {
 573            *ptr = d[r[*ptr]];
 574            ptr++;
 575        }
 576        len -= args->channels;
 577    }
 578
 579    p = (Uint32 *) ptr;
 580
 581    for (i = 0; i < len; i += sizeof (Uint32)) {
 582#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
 583        *p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
 584             (d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
 585             (d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >>  8))+128]] <<  8) |
 586             (d[r[((Sint16)(Sint8)((*p & 0x000000FF)      ))+128]]      ) ;
 587#else
 588        *p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
 589             (d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
 590             (d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >>  8))+128]] <<  8) |
 591             (d[l[((Sint16)(Sint8)((*p & 0x000000FF)      ))+128]]      ) ;
 592#endif
 593        ++p;
 594    }
 595
 596
 597}
 598
 599
 600/* !!! FIXME : Optimize the code for 16-bit samples? */
 601
 602static void _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
 603{
 604    volatile position_args *args = (volatile position_args *) udata;
 605    Uint16 *ptr = (Uint16 *) stream;
 606    int i;
 607
 608    for (i = 0; i < len; i += sizeof (Uint16) * 2) {
 609        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
 610        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
 611        
 612        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 613                                    * args->distance_f) + 32768);
 614        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 615                                    * args->distance_f) + 32768);
 616
 617	if (args->room_angle == 180) {
 618        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 619        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 620	}
 621	else {
 622        	*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 623        	*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 624	}
 625    }
 626}
 627static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
 628{
 629    volatile position_args *args = (volatile position_args *) udata;
 630    Uint16 *ptr = (Uint16 *) stream;
 631    int i;
 632
 633    for (i = 0; i < len; i += sizeof (Uint16) * 4) {
 634        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
 635        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
 636        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
 637        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
 638        
 639        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 640                                    * args->distance_f) + 32768);
 641        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 642                                    * args->distance_f) + 32768);
 643        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
 644                                    * args->distance_f) + 32768);
 645        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
 646                                    * args->distance_f) + 32768);
 647
 648	switch (args->room_angle) {
 649		case 0:
 650        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 651        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 652        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 653        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 654			break;
 655		case 90:
 656        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 657        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 658        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 659        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 660			break;
 661		case 180:
 662        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 663        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 664        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 665        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 666			break;
 667		case 270:
 668        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 669        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 670        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 671        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 672			break;
 673	}
 674    }
 675}
 676static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
 677{
 678    volatile position_args *args = (volatile position_args *) udata;
 679    Uint16 *ptr = (Uint16 *) stream;
 680    int i;
 681
 682    for (i = 0; i < len; i += sizeof (Uint16) * 6) {
 683        Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
 684        Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
 685        Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
 686        Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
 687        Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
 688        Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
 689
 690        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 691                                    * args->distance_f) + 32768);
 692        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 693                                    * args->distance_f) + 32768);
 694        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
 695                                    * args->distance_f) + 32768);
 696        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
 697                                    * args->distance_f) + 32768);
 698        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
 699                                    * args->distance_f) + 32768);
 700        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
 701                                    * args->distance_f) + 32768);
 702
 703	switch (args->room_angle) {
 704		case 0:
 705        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 706        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 707        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 708        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 709        		*(ptr++) = (Uint16) SDL_SwapLE16(swapce);
 710        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
 711			break;
 712		case 90:
 713        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 714        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 715        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 716        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 717        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
 718        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
 719			break;
 720		case 180:
 721        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 722        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 723        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 724        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 725        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
 726        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
 727			break;
 728		case 270:
 729        		*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
 730        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
 731        		*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
 732        		*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
 733        		*(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
 734        		*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
 735			break;
 736	}
 737    }
 738}
 739
 740static void _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
 741{
 742    /* 16 signed bits (lsb) * 2 channels. */
 743    volatile position_args *args = (volatile position_args *) udata;
 744    Sint16 *ptr = (Sint16 *) stream;
 745    int i;
 746
 747#if 0
 748    if (len % (sizeof(Sint16) * 2)) {
 749	    fprintf(stderr,"Not an even number of frames! len=%d\n", len);
 750	    return;
 751    }
 752#endif
 753
 754    for (i = 0; i < len; i += sizeof (Sint16) * 2) {
 755        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
 756                                    args->left_f) * args->distance_f);
 757        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
 758                                    args->right_f) * args->distance_f);
 759	if (args->room_angle == 180) {
 760        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 761        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 762	}
 763	else {
 764        	*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 765        	*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 766	}
 767    }
 768}
 769static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
 770{
 771    /* 16 signed bits (lsb) * 4 channels. */
 772    volatile position_args *args = (volatile position_args *) udata;
 773    Sint16 *ptr = (Sint16 *) stream;
 774    int i;
 775
 776    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
 777        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
 778                                    args->left_f) * args->distance_f);
 779        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
 780                                    args->right_f) * args->distance_f);
 781        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
 782                                    args->left_rear_f) * args->distance_f);
 783        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
 784                                    args->right_rear_f) * args->distance_f);
 785	switch (args->room_angle) {
 786		case 0:
 787        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 788        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 789        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 790        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 791			break;
 792		case 90:
 793        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 794        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 795        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 796        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 797			break;
 798		case 180:
 799        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 800        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 801        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 802        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 803			break;
 804		case 270:
 805        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 806        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 807        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 808        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 809			break;
 810	}
 811    }
 812}
 813
 814static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
 815{
 816    /* 16 signed bits (lsb) * 6 channels. */
 817    volatile position_args *args = (volatile position_args *) udata;
 818    Sint16 *ptr = (Sint16 *) stream;
 819    int i;
 820
 821    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
 822        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
 823                                    args->left_f) * args->distance_f);
 824        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
 825                                    args->right_f) * args->distance_f);
 826        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
 827                                    args->left_rear_f) * args->distance_f);
 828        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
 829                                    args->right_rear_f) * args->distance_f);
 830        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
 831                                    args->center_f) * args->distance_f);
 832        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
 833                                    args->lfe_f) * args->distance_f);
 834	switch (args->room_angle) {
 835		case 0:
 836        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 837        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 838        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 839        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 840        		*(ptr++) = (Sint16) SDL_SwapLE16(swapce);
 841        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
 842			break;
 843		case 90:
 844        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 845        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 846        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 847        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 848        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
 849        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
 850			break;
 851		case 180:
 852        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 853        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 854        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 855        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 856        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
 857        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
 858			break;
 859		case 270:
 860        		*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
 861        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
 862        		*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
 863        		*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
 864        		*(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
 865        		*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
 866			break;
 867	}
 868    }
 869}
 870
 871static void _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
 872{
 873    /* 16 signed bits (lsb) * 2 channels. */
 874    volatile position_args *args = (volatile position_args *) udata;
 875    Uint16 *ptr = (Uint16 *) stream;
 876    int i;
 877
 878    for (i = 0; i < len; i += sizeof (Sint16) * 2) {
 879        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
 880        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
 881        
 882        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 883                                    * args->distance_f) + 32768);
 884        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 885                                    * args->distance_f) + 32768);
 886
 887	if (args->room_angle == 180) {
 888        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 889        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 890	}
 891	else {
 892        	*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 893        	*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 894	}
 895    }
 896}
 897static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
 898{
 899    /* 16 signed bits (lsb) * 4 channels. */
 900    volatile position_args *args = (volatile position_args *) udata;
 901    Uint16 *ptr = (Uint16 *) stream;
 902    int i;
 903
 904    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
 905        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
 906        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
 907        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
 908        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
 909        
 910        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 911                                    * args->distance_f) + 32768);
 912        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 913                                    * args->distance_f) + 32768);
 914        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
 915                                    * args->distance_f) + 32768);
 916        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
 917                                    * args->distance_f) + 32768);
 918
 919	switch (args->room_angle) {
 920		case 0:
 921        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 922        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 923        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 924        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 925			break;
 926		case 90:
 927        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 928        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 929        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 930        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 931			break;
 932		case 180:
 933        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 934        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 935        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 936        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 937			break;
 938		case 270:
 939        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 940        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 941        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 942        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 943			break;
 944	}
 945    }
 946}
 947static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
 948{
 949    /* 16 signed bits (lsb) * 6 channels. */
 950    volatile position_args *args = (volatile position_args *) udata;
 951    Uint16 *ptr = (Uint16 *) stream;
 952    int i;
 953
 954    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
 955        Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
 956        Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
 957        Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
 958        Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
 959        Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
 960        Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
 961        
 962        Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
 963                                    * args->distance_f) + 32768);
 964        Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
 965                                    * args->distance_f) + 32768);
 966        Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
 967                                    * args->distance_f) + 32768);
 968        Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
 969                                    * args->distance_f) + 32768);
 970        Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
 971                                    * args->distance_f) + 32768);
 972        Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
 973                                    * args->distance_f) + 32768);
 974
 975	switch (args->room_angle) {
 976		case 0:
 977        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 978        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 979        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 980        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 981        		*(ptr++) = (Uint16) SDL_SwapBE16(swapce);
 982        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
 983			break;
 984		case 90:
 985        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 986        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 987        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 988        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 989        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
 990        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
 991			break;
 992		case 180:
 993        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
 994        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
 995        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
 996        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
 997        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
 998        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
 999			break;
1000		case 270:
1001        		*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
1002        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
1003        		*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
1004        		*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
1005        		*(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
1006        		*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
1007			break;
1008	}
1009    }
1010}
1011
1012static void _Eff_position_s16msb(int chan, void *stream, int len, void *udata)
1013{
1014    /* 16 signed bits (lsb) * 2 channels. */
1015    volatile position_args *args = (volatile position_args *) udata;
1016    Sint16 *ptr = (Sint16 *) stream;
1017    int i;
1018
1019    for (i = 0; i < len; i += sizeof (Sint16) * 2) {
1020        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1021                                    args->left_f) * args->distance_f);
1022        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1023                                    args->right_f) * args->distance_f);
1024        *(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1025        *(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1026    }
1027}
1028static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
1029{
1030    /* 16 signed bits (lsb) * 4 channels. */
1031    volatile position_args *args = (volatile position_args *) udata;
1032    Sint16 *ptr = (Sint16 *) stream;
1033    int i;
1034
1035    for (i = 0; i < len; i += sizeof (Sint16) * 4) {
1036        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1037                                    args->left_f) * args->distance_f);
1038        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1039                                    args->right_f) * args->distance_f);
1040        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1041                                    args->left_rear_f) * args->distance_f);
1042        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1043                                    args->right_rear_f) * args->distance_f);
1044	switch (args->room_angle) {
1045		case 0:
1046        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1047        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1048        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1049        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1050			break;
1051		case 90:
1052        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1053        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1054        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1055        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1056			break;
1057		case 180:
1058        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1059        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1060        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1061        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1062			break;
1063		case 270:
1064        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1065        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1066        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1067        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1068			break;
1069	}
1070    }
1071}
1072static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
1073{
1074    /* 16 signed bits (lsb) * 6 channels. */
1075    volatile position_args *args = (volatile position_args *) udata;
1076    Sint16 *ptr = (Sint16 *) stream;
1077    int i;
1078
1079    for (i = 0; i < len; i += sizeof (Sint16) * 6) {
1080        Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
1081                                    args->left_f) * args->distance_f);
1082        Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
1083                                    args->right_f) * args->distance_f);
1084        Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
1085                                    args->left_rear_f) * args->distance_f);
1086        Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
1087                                    args->right_rear_f) * args->distance_f);
1088        Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
1089                                    args->center_f) * args->distance_f);
1090        Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
1091                                    args->lfe_f) * args->distance_f);
1092
1093	switch (args->room_angle) {
1094		case 0:
1095        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1096        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1097        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1098        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1099        		*(ptr++) = (Sint16) SDL_SwapBE16(swapce);
1100        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1101			break;
1102		case 90:
1103        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1104        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1105        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1106        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1107        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
1108        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1109			break;
1110		case 180:
1111        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1112        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1113        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1114        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1115        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1116        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1117			break;
1118		case 270:
1119        		*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
1120        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
1121        		*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
1122        		*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
1123        		*(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
1124        		*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
1125			break;
1126	}
1127    }
1128}
1129
1130static void init_position_args(position_args *args)
1131{
1132    memset(args, '\0', sizeof (position_args));
1133    args->in_use = 0;
1134    args->room_angle = 0;
1135    args->left_u8 = args->right_u8 = args->distance_u8 = 255;
1136    args->left_f  = args->right_f  = args->distance_f  = 1.0f;
1137    args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
1138    args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
1139    Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
1140}
1141
1142
1143static position_args *get_position_arg(int channel)
1144{
1145    void *rc;
1146    int i;
1147
1148    if (channel < 0) {
1149        if (pos_args_global == NULL) {
1150            pos_args_global = malloc(sizeof (position_args));
1151            if (pos_args_global == NULL) {
1152                Mix_SetError("Out of memory");
1153                return(NULL);
1154            }
1155            init_position_args(pos_args_global);
1156        }
1157
1158        return(pos_args_global);
1159    }
1160
1161    if (channel >= position_channels) {
1162        rc = realloc(pos_args_array, (channel + 1) * sizeof (position_args *));
1163        if (rc == NULL) {
1164            Mix_SetError("Out of memory");
1165            return(NULL);
1166        }
1167        pos_args_array = (position_args **) rc;
1168        for (i = position_channels; i <= channel; i++) {
1169            pos_args_array[i] = NULL;
1170        }
1171        position_channels = channel + 1;
1172    }
1173
1174    if (pos_args_array[channel] == NULL) {
1175        pos_args_array[channel] = (position_args *)malloc(sizeof(position_args));
1176        if (pos_args_array[channel] == NULL) {
1177            Mix_SetError("Out of memory");
1178            return(NULL);
1179        }
1180        init_position_args(pos_args_array[channel]);
1181    }
1182
1183    return(pos_args_array[channel]);
1184}
1185
1186
1187static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
1188{
1189    Mix_EffectFunc_t f = NULL;
1190
1191    switch (format) {
1192        case AUDIO_U8:
1193	    switch (channels) {
1194		    case 1:
1195		    case 2:
1196            		f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
1197                                                 		_Eff_position_u8;
1198	    		break;
1199	    	    case 4:
1200                        f = _Eff_position_u8_c4;
1201	    		break;
1202	    	    case 6:
1203                        f = _Eff_position_u8_c6;
1204	    		break;
1205	    }
1206            break;
1207
1208        case AUDIO_S8:
1209	    switch (channels) {
1210		    case 1:
1211		    case 2:
1212            		f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
1213                                                 		_Eff_position_s8;
1214	    		break;
1215	    	    case 4:
1216                        f = _Eff_position_s8_c4;
1217	    		break;
1218	    	    case 6:
1219                        f = _Eff_position_s8_c6;
1220	    		break;
1221	    }
1222            break;
1223
1224        case AUDIO_U16LSB:
1225	    switch (channels) {
1226		    case 1:
1227		    case 2:
1228            		f = _Eff_position_u16lsb;
1229	    		break;
1230	    	    case 4:
1231            		f = _Eff_position_u16lsb_c4;
1232	    		break;
1233	    	    case 6:
1234            		f = _Eff_position_u16lsb_c6;
1235	    		break;
1236	    }
1237            break;
1238
1239        case AUDIO_S16LSB:
1240	    switch (channels) {
1241		    case 1:
1242		    case 2:
1243            		f = _Eff_position_s16lsb;
1244	    		break;
1245	    	    case 4:
1246            		f = _Eff_position_s16lsb_c4;
1247	    		break;
1248	    	    case 6:
1249            		f = _Eff_position_s16lsb_c6;
1250	    		break;
1251	    }
1252            break;
1253
1254        case AUDIO_U16MSB:
1255	    switch (channels) {
1256		    case 1:
1257		    case 2:
1258            		f = _Eff_position_u16msb;
1259	    		break;
1260	    	    case 4:
1261            		f = _Eff_position_u16msb_c4;
1262	    		break;
1263	    	    case 6:
1264            		f = _Eff_position_u16msb_c6;
1265	    		break;
1266	    }
1267            break;
1268
1269        case AUDIO_S16MSB:
1270	    switch (channels) {
1271		    case 1:
1272		    case 2:
1273            		f = _Eff_position_s16msb;
1274	    		break;
1275	    	    case 4:
1276            		f = _Eff_position_s16msb_c4;
1277	    		break;
1278	    	    case 6:
1279            		f = _Eff_position_s16msb_c6;
1280	    		break;
1281	    }
1282            break;
1283
1284        default:
1285            Mix_SetError("Unsupported audio format");
1286    }
1287
1288    return(f);
1289}
1290
1291static Uint8 speaker_amplitude[6];
1292
1293static void set_amplitudes(int channels, int angle, int room_angle)
1294{
1295    int left = 255, right = 255;
1296    int left_rear = 255, right_rear = 255, center = 255;
1297
1298    angle = SDL_abs(angle) % 360;  /* make angle between 0 an…

Large files files are truncated, but you can click here to view the full file