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