Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
361 lines (330 loc) · 14.1 KB

SDL_mixer.c

File metadata and controls

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