effect_position.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 17 Oct 2017 02:33:47 -0700
changeset 777 92882ef2ab81
parent 737 d3fa63933df2
child 800 cc4aef7fef64
permissions -rw-r--r--
Rewrote music.c to support any number of decode libraries using a compiled-in plugin interface
Mix_LoadWAV_RW() can now load sound formats that were previously available only as music.

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