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