src/audio/SDL_mixer.c
author Sam Lantinga
Mon, 09 Jan 2017 11:58:01 -0800
changeset 10802 6afc9b833867
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
We only need the first few keymaps corresponding to the following constants:
K_NORMTAB, K_SHIFTTAB, K_ALTTAB, K_ALTSHIFTTAB

In the normal case we'll load all the keymaps from the kernel, but this reduces the size of the SDL library for the fallback case when we can't get to the tty.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@0
    22
slouken@0
    23
/* This provides the default mixing callback for the SDL audio routines */
slouken@0
    24
slouken@1358
    25
#include "SDL_cpuinfo.h"
slouken@0
    26
#include "SDL_timer.h"
slouken@1358
    27
#include "SDL_audio.h"
slouken@0
    28
#include "SDL_sysaudio.h"
slouken@0
    29
slouken@0
    30
/* This table is used to add two sound values together and pin
slouken@0
    31
 * the value to avoid overflow.  (used with permission from ARDI)
slouken@0
    32
 * Changed to use 0xFE instead of 0xFF for better sound quality.
slouken@0
    33
 */
slouken@1895
    34
static const Uint8 mix8[] = {
slouken@1895
    35
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    36
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    37
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    38
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    39
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    40
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    41
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    42
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    43
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    44
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    45
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
slouken@1895
    46
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
slouken@1895
    47
    0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
slouken@1895
    48
    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
slouken@1895
    49
    0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
slouken@1895
    50
    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
slouken@1895
    51
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
slouken@1895
    52
    0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
slouken@1895
    53
    0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
slouken@1895
    54
    0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
slouken@1895
    55
    0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
slouken@1895
    56
    0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
slouken@1895
    57
    0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
slouken@1895
    58
    0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
slouken@1895
    59
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
slouken@1895
    60
    0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
slouken@1895
    61
    0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
slouken@1895
    62
    0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
slouken@1895
    63
    0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
slouken@1895
    64
    0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
slouken@1895
    65
    0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
slouken@1895
    66
    0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
slouken@1895
    67
    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
slouken@1895
    68
    0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
slouken@1895
    69
    0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE,
slouken@1895
    70
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    71
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    72
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    73
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    74
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    75
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    76
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    77
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    78
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    79
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    80
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
slouken@1895
    81
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE
slouken@0
    82
};
slouken@0
    83
slouken@0
    84
/* The volume ranges from 0 - 128 */
slouken@7191
    85
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
slouken@7191
    86
#define ADJUST_VOLUME_U8(s, v)  (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
slouken@0
    87
icculus@1982
    88
icculus@1982
    89
void
icculus@1982
    90
SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
icculus@1982
    91
                   Uint32 len, int volume)
icculus@1982
    92
{
icculus@1982
    93
    if (volume == 0) {
icculus@1982
    94
        return;
icculus@1982
    95
    }
icculus@1982
    96
slouken@1895
    97
    switch (format) {
slouken@0
    98
slouken@1895
    99
    case AUDIO_U8:
slouken@1895
   100
        {
icculus@3630
   101
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
slouken@1895
   102
            SDL_MixAudio_m68k_U8((char *) dst, (char *) src,
slouken@1895
   103
                                 (unsigned long) len, (long) volume,
slouken@1895
   104
                                 (char *) mix8);
patmandin@633
   105
#else
slouken@1895
   106
            Uint8 src_sample;
slouken@0
   107
slouken@1895
   108
            while (len--) {
slouken@1895
   109
                src_sample = *src;
slouken@1895
   110
                ADJUST_VOLUME_U8(src_sample, volume);
slouken@1895
   111
                *dst = mix8[*dst + src_sample];
slouken@1895
   112
                ++dst;
slouken@1895
   113
                ++src;
slouken@1895
   114
            }
patmandin@633
   115
#endif
slouken@1895
   116
        }
slouken@1895
   117
        break;
slouken@0
   118
slouken@1895
   119
    case AUDIO_S8:
slouken@1895
   120
        {
slouken@5536
   121
            Sint8 *dst8, *src8;
slouken@5536
   122
            Sint8 src_sample;
slouken@5536
   123
            int dst_sample;
slouken@5536
   124
            const int max_audioval = ((1 << (8 - 1)) - 1);
slouken@5536
   125
            const int min_audioval = -(1 << (8 - 1));
slouken@0
   126
slouken@5536
   127
            src8 = (Sint8 *) src;
slouken@5536
   128
            dst8 = (Sint8 *) dst;
slouken@5536
   129
            while (len--) {
slouken@5536
   130
                src_sample = *src8;
slouken@5536
   131
                ADJUST_VOLUME(src_sample, volume);
slouken@5536
   132
                dst_sample = *dst8 + src_sample;
slouken@5536
   133
                if (dst_sample > max_audioval) {
slouken@5536
   134
                    *dst8 = max_audioval;
slouken@5536
   135
                } else if (dst_sample < min_audioval) {
slouken@5536
   136
                    *dst8 = min_audioval;
slouken@5536
   137
                } else {
slouken@5536
   138
                    *dst8 = dst_sample;
slouken@1895
   139
                }
slouken@5536
   140
                ++dst8;
slouken@5536
   141
                ++src8;
slouken@1895
   142
            }
slouken@1895
   143
        }
slouken@1895
   144
        break;
slouken@0
   145
slouken@1895
   146
    case AUDIO_S16LSB:
slouken@1895
   147
        {
slouken@5536
   148
            Sint16 src1, src2;
slouken@5536
   149
            int dst_sample;
slouken@5536
   150
            const int max_audioval = ((1 << (16 - 1)) - 1);
slouken@5536
   151
            const int min_audioval = -(1 << (16 - 1));
slouken@0
   152
slouken@5536
   153
            len /= 2;
slouken@5536
   154
            while (len--) {
slouken@5536
   155
                src1 = ((src[1]) << 8 | src[0]);
slouken@5536
   156
                ADJUST_VOLUME(src1, volume);
slouken@5536
   157
                src2 = ((dst[1]) << 8 | dst[0]);
slouken@5536
   158
                src += 2;
slouken@5536
   159
                dst_sample = src1 + src2;
slouken@5536
   160
                if (dst_sample > max_audioval) {
slouken@5536
   161
                    dst_sample = max_audioval;
slouken@5536
   162
                } else if (dst_sample < min_audioval) {
slouken@5536
   163
                    dst_sample = min_audioval;
slouken@1895
   164
                }
slouken@5536
   165
                dst[0] = dst_sample & 0xFF;
slouken@5536
   166
                dst_sample >>= 8;
slouken@5536
   167
                dst[1] = dst_sample & 0xFF;
slouken@5536
   168
                dst += 2;
slouken@1895
   169
            }
slouken@1895
   170
        }
slouken@1895
   171
        break;
slouken@0
   172
slouken@1895
   173
    case AUDIO_S16MSB:
slouken@1895
   174
        {
icculus@3630
   175
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
slouken@1895
   176
            SDL_MixAudio_m68k_S16MSB((short *) dst, (short *) src,
slouken@1895
   177
                                     (unsigned long) len, (long) volume);
patmandin@633
   178
#else
slouken@1895
   179
            Sint16 src1, src2;
slouken@1895
   180
            int dst_sample;
slouken@1895
   181
            const int max_audioval = ((1 << (16 - 1)) - 1);
slouken@1895
   182
            const int min_audioval = -(1 << (16 - 1));
slouken@0
   183
slouken@1895
   184
            len /= 2;
slouken@1895
   185
            while (len--) {
slouken@1895
   186
                src1 = ((src[0]) << 8 | src[1]);
slouken@1895
   187
                ADJUST_VOLUME(src1, volume);
slouken@1895
   188
                src2 = ((dst[0]) << 8 | dst[1]);
slouken@1895
   189
                src += 2;
slouken@1895
   190
                dst_sample = src1 + src2;
slouken@1895
   191
                if (dst_sample > max_audioval) {
slouken@1895
   192
                    dst_sample = max_audioval;
slouken@1895
   193
                } else if (dst_sample < min_audioval) {
slouken@1895
   194
                    dst_sample = min_audioval;
slouken@1895
   195
                }
slouken@1895
   196
                dst[1] = dst_sample & 0xFF;
slouken@1895
   197
                dst_sample >>= 8;
slouken@1895
   198
                dst[0] = dst_sample & 0xFF;
slouken@1895
   199
                dst += 2;
slouken@1895
   200
            }
patmandin@633
   201
#endif
slouken@1895
   202
        }
slouken@1895
   203
        break;
slouken@0
   204
slouken@10483
   205
    case AUDIO_U16LSB:
slouken@10483
   206
        {
slouken@10483
   207
            Uint16 src1, src2;
slouken@10483
   208
            int dst_sample;
slouken@10483
   209
            const int max_audioval = 0xFFFF;
slouken@10483
   210
slouken@10483
   211
            len /= 2;
slouken@10483
   212
            while (len--) {
slouken@10483
   213
                src1 = ((src[1]) << 8 | src[0]);
slouken@10483
   214
                ADJUST_VOLUME(src1, volume);
slouken@10483
   215
                src2 = ((dst[1]) << 8 | dst[0]);
slouken@10483
   216
                src += 2;
slouken@10483
   217
                dst_sample = src1 + src2;
slouken@10483
   218
                if (dst_sample > max_audioval) {
slouken@10483
   219
                    dst_sample = max_audioval;
slouken@10483
   220
                }
slouken@10483
   221
                dst[0] = dst_sample & 0xFF;
slouken@10483
   222
                dst_sample >>= 8;
slouken@10483
   223
                dst[1] = dst_sample & 0xFF;
slouken@10483
   224
                dst += 2;
slouken@10483
   225
            }
slouken@10483
   226
        }
slouken@10483
   227
        break;
slouken@10483
   228
slouken@10483
   229
    case AUDIO_U16MSB:
slouken@10483
   230
        {
slouken@10483
   231
            Uint16 src1, src2;
slouken@10483
   232
            int dst_sample;
slouken@10483
   233
            const int max_audioval = 0xFFFF;
slouken@10483
   234
slouken@10483
   235
            len /= 2;
slouken@10483
   236
            while (len--) {
slouken@10483
   237
                src1 = ((src[0]) << 8 | src[1]);
slouken@10483
   238
                ADJUST_VOLUME(src1, volume);
slouken@10483
   239
                src2 = ((dst[0]) << 8 | dst[1]);
slouken@10483
   240
                src += 2;
slouken@10483
   241
                dst_sample = src1 + src2;
slouken@10483
   242
                if (dst_sample > max_audioval) {
slouken@10483
   243
                    dst_sample = max_audioval;
slouken@10483
   244
                }
slouken@10483
   245
                dst[1] = dst_sample & 0xFF;
slouken@10483
   246
                dst_sample >>= 8;
slouken@10483
   247
                dst[0] = dst_sample & 0xFF;
slouken@10483
   248
                dst += 2;
slouken@10483
   249
            }
slouken@10483
   250
        }
slouken@10483
   251
        break;
slouken@10483
   252
icculus@1982
   253
    case AUDIO_S32LSB:
icculus@1982
   254
        {
icculus@1982
   255
            const Uint32 *src32 = (Uint32 *) src;
icculus@1982
   256
            Uint32 *dst32 = (Uint32 *) dst;
icculus@2013
   257
            Sint64 src1, src2;
icculus@1982
   258
            Sint64 dst_sample;
slouken@1985
   259
            const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
slouken@1985
   260
            const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
icculus@1982
   261
icculus@1982
   262
            len /= 4;
icculus@1982
   263
            while (len--) {
icculus@2013
   264
                src1 = (Sint64) ((Sint32) SDL_SwapLE32(*src32));
icculus@1982
   265
                src32++;
icculus@1982
   266
                ADJUST_VOLUME(src1, volume);
icculus@2013
   267
                src2 = (Sint64) ((Sint32) SDL_SwapLE32(*dst32));
icculus@1982
   268
                dst_sample = src1 + src2;
icculus@1982
   269
                if (dst_sample > max_audioval) {
icculus@1982
   270
                    dst_sample = max_audioval;
icculus@1982
   271
                } else if (dst_sample < min_audioval) {
icculus@1982
   272
                    dst_sample = min_audioval;
icculus@1982
   273
                }
icculus@1982
   274
                *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
icculus@1982
   275
            }
icculus@1982
   276
        }
icculus@1982
   277
        break;
icculus@1982
   278
icculus@1982
   279
    case AUDIO_S32MSB:
icculus@1982
   280
        {
icculus@1982
   281
            const Uint32 *src32 = (Uint32 *) src;
icculus@1982
   282
            Uint32 *dst32 = (Uint32 *) dst;
icculus@2013
   283
            Sint64 src1, src2;
icculus@1982
   284
            Sint64 dst_sample;
slouken@1985
   285
            const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
slouken@1985
   286
            const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
icculus@1982
   287
icculus@1982
   288
            len /= 4;
icculus@1982
   289
            while (len--) {
icculus@2013
   290
                src1 = (Sint64) ((Sint32) SDL_SwapBE32(*src32));
icculus@1982
   291
                src32++;
icculus@1982
   292
                ADJUST_VOLUME(src1, volume);
icculus@2013
   293
                src2 = (Sint64) ((Sint32) SDL_SwapBE32(*dst32));
icculus@1982
   294
                dst_sample = src1 + src2;
icculus@1982
   295
                if (dst_sample > max_audioval) {
icculus@1982
   296
                    dst_sample = max_audioval;
icculus@1982
   297
                } else if (dst_sample < min_audioval) {
icculus@1982
   298
                    dst_sample = min_audioval;
icculus@1982
   299
                }
icculus@1982
   300
                *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
icculus@1982
   301
            }
icculus@1982
   302
        }
icculus@1982
   303
        break;
icculus@1982
   304
icculus@1982
   305
    case AUDIO_F32LSB:
icculus@1982
   306
        {
icculus@1982
   307
            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
icculus@1982
   308
            const float fvolume = (float) volume;
icculus@1982
   309
            const float *src32 = (float *) src;
icculus@1982
   310
            float *dst32 = (float *) dst;
icculus@1982
   311
            float src1, src2;
icculus@1982
   312
            double dst_sample;
icculus@1982
   313
            /* !!! FIXME: are these right? */
slouken@2130
   314
            const double max_audioval = 3.402823466e+38F;
slouken@2130
   315
            const double min_audioval = -3.402823466e+38F;
icculus@1982
   316
icculus@1982
   317
            len /= 4;
icculus@1982
   318
            while (len--) {
icculus@2014
   319
                src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
icculus@2014
   320
                src2 = SDL_SwapFloatLE(*dst32);
icculus@2014
   321
                src32++;
icculus@1982
   322
icculus@2014
   323
                dst_sample = ((double) src1) + ((double) src2);
icculus@1982
   324
                if (dst_sample > max_audioval) {
icculus@1982
   325
                    dst_sample = max_audioval;
icculus@1982
   326
                } else if (dst_sample < min_audioval) {
icculus@1982
   327
                    dst_sample = min_audioval;
icculus@1982
   328
                }
icculus@2014
   329
                *(dst32++) = SDL_SwapFloatLE((float) dst_sample);
icculus@1982
   330
            }
icculus@1982
   331
        }
icculus@1982
   332
        break;
icculus@1982
   333
icculus@1982
   334
    case AUDIO_F32MSB:
icculus@1982
   335
        {
icculus@1982
   336
            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
icculus@1982
   337
            const float fvolume = (float) volume;
icculus@1982
   338
            const float *src32 = (float *) src;
icculus@1982
   339
            float *dst32 = (float *) dst;
icculus@1982
   340
            float src1, src2;
icculus@1982
   341
            double dst_sample;
icculus@1982
   342
            /* !!! FIXME: are these right? */
slouken@2130
   343
            const double max_audioval = 3.402823466e+38F;
slouken@2130
   344
            const double min_audioval = -3.402823466e+38F;
icculus@1982
   345
icculus@1982
   346
            len /= 4;
icculus@1982
   347
            while (len--) {
icculus@2014
   348
                src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
icculus@2014
   349
                src2 = SDL_SwapFloatBE(*dst32);
icculus@2014
   350
                src32++;
icculus@1982
   351
icculus@2014
   352
                dst_sample = ((double) src1) + ((double) src2);
icculus@1982
   353
                if (dst_sample > max_audioval) {
icculus@1982
   354
                    dst_sample = max_audioval;
icculus@1982
   355
                } else if (dst_sample < min_audioval) {
icculus@1982
   356
                    dst_sample = min_audioval;
icculus@1982
   357
                }
icculus@2014
   358
                *(dst32++) = SDL_SwapFloatBE((float) dst_sample);
icculus@1982
   359
            }
icculus@1982
   360
        }
icculus@1982
   361
        break;
icculus@1982
   362
slouken@1895
   363
    default:                   /* If this happens... FIXME! */
slouken@10483
   364
        SDL_SetError("SDL_MixAudioFormat(): unknown audio format");
slouken@1895
   365
        return;
slouken@1895
   366
    }
slouken@0
   367
}
slouken@574
   368
slouken@1895
   369
/* vi: set ts=4 sw=4 expandtab: */