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: */