cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_mixer.c (12654B)


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