2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "../SDL_internal.h"
23 /* This provides the default mixing callback for the SDL audio routines */
25 #include "SDL_cpuinfo.h"
26 #include "SDL_timer.h"
27 #include "SDL_audio.h"
28 #include "SDL_sysaudio.h"
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.
34 static 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
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)
90 SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
91 Uint32 len, int volume)
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,
110 ADJUST_VOLUME_U8(src_sample, volume);
111 *dst = mix8[*dst + src_sample];
124 const int max_audioval = ((1 << (8 - 1)) - 1);
125 const int min_audioval = -(1 << (8 - 1));
127 src8 = (Sint8 *) src;
128 dst8 = (Sint8 *) dst;
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;
150 const int max_audioval = ((1 << (16 - 1)) - 1);
151 const int min_audioval = -(1 << (16 - 1));
155 src1 = ((src[1]) << 8 | src[0]);
156 ADJUST_VOLUME(src1, volume);
157 src2 = ((dst[1]) << 8 | dst[0]);
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;
165 dst[0] = dst_sample & 0xFF;
167 dst[1] = dst_sample & 0xFF;
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);
181 const int max_audioval = ((1 << (16 - 1)) - 1);
182 const int min_audioval = -(1 << (16 - 1));
186 src1 = ((src[0]) << 8 | src[1]);
187 ADJUST_VOLUME(src1, volume);
188 src2 = ((dst[0]) << 8 | dst[1]);
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;
196 dst[1] = dst_sample & 0xFF;
198 dst[0] = dst_sample & 0xFF;
207 const Uint32 *src32 = (Uint32 *) src;
208 Uint32 *dst32 = (Uint32 *) dst;
211 const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
212 const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
216 src1 = (Sint64) ((Sint32) SDL_SwapLE32(*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;
226 *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
233 const Uint32 *src32 = (Uint32 *) src;
234 Uint32 *dst32 = (Uint32 *) dst;
237 const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
238 const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
242 src1 = (Sint64) ((Sint32) SDL_SwapBE32(*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;
252 *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
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;
265 /* !!! FIXME: are these right? */
266 const double max_audioval = 3.402823466e+38F;
267 const double min_audioval = -3.402823466e+38F;
271 src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
272 src2 = SDL_SwapFloatLE(*dst32);
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;
281 *(dst32++) = SDL_SwapFloatLE((float) dst_sample);
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;
294 /* !!! FIXME: are these right? */
295 const double max_audioval = 3.402823466e+38F;
296 const double min_audioval = -3.402823466e+38F;
300 src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
301 src2 = SDL_SwapFloatBE(*dst32);
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;
310 *(dst32++) = SDL_SwapFloatBE((float) dst_sample);
315 default: /* If this happens... FIXME! */
316 SDL_SetError("SDL_MixAudio(): unknown audio format");
321 /* vi: set ts=4 sw=4 expandtab: */