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

Latest commit

 

History

History
261 lines (241 loc) · 10.5 KB

SDL_mixer.c

File metadata and controls

261 lines (241 loc) · 10.5 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Feb 1, 2006
Feb 1, 2006
3
Copyright (C) 1997-2006 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.
*/
May 28, 2006
May 28, 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)
May 28, 2006
May 28, 2006
92
void
May 29, 2006
May 29, 2006
93
SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
Apr 26, 2001
Apr 26, 2001
94
{
May 28, 2006
May 28, 2006
95
Uint16 format;
Apr 26, 2001
Apr 26, 2001
96
May 28, 2006
May 28, 2006
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
if (volume == 0) {
return;
}
/* Mix the user-level audio format */
if (current_audio) {
if (current_audio->convert.needed) {
format = current_audio->convert.src_format;
} else {
format = current_audio->spec.format;
}
} else {
/* HACK HACK HACK */
format = AUDIO_S16;
}
switch (format) {
Apr 26, 2001
Apr 26, 2001
112
May 28, 2006
May 28, 2006
113
114
case AUDIO_U8:
{
Feb 21, 2006
Feb 21, 2006
115
#if defined(__GNUC__) && defined(__M68000__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
116
117
118
SDL_MixAudio_m68k_U8((char *) dst, (char *) src,
(unsigned long) len, (long) volume,
(char *) mix8);
Jun 3, 2003
Jun 3, 2003
119
#else
May 28, 2006
May 28, 2006
120
Uint8 src_sample;
Apr 26, 2001
Apr 26, 2001
121
May 28, 2006
May 28, 2006
122
123
while (len--) {
src_sample = *src;
May 29, 2006
May 29, 2006
124
ADJUST_VOLUME_U8(src_sample, volume);
May 28, 2006
May 28, 2006
125
126
127
128
*dst = mix8[*dst + src_sample];
++dst;
++src;
}
Jun 3, 2003
Jun 3, 2003
129
#endif
May 28, 2006
May 28, 2006
130
131
}
break;
Apr 26, 2001
Apr 26, 2001
132
May 28, 2006
May 28, 2006
133
134
case AUDIO_S8:
{
Feb 21, 2006
Feb 21, 2006
135
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
136
137
138
if (SDL_HasMMX()) {
SDL_MixAudio_MMX_S8((char *) dst, (char *) src,
(unsigned int) len, (int) volume);
May 28, 2006
May 28, 2006
139
} else
Feb 26, 2006
Feb 26, 2006
140
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
141
142
143
if (SDL_HasMMX()) {
SDL_MixAudio_MMX_S8_VC((char *) dst, (char *) src,
(unsigned int) len, (int) volume);
May 28, 2006
May 28, 2006
144
} else
Nov 9, 2002
Nov 9, 2002
145
#endif
Feb 21, 2006
Feb 21, 2006
146
#if defined(__GNUC__) && defined(__M68000__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
147
148
SDL_MixAudio_m68k_S8((char *) dst, (char *) src,
(unsigned long) len, (long) volume);
Jun 3, 2003
Jun 3, 2003
149
#else
May 28, 2006
May 28, 2006
150
151
152
153
154
155
{
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
156
May 28, 2006
May 28, 2006
157
158
159
160
src8 = (Sint8 *) src;
dst8 = (Sint8 *) dst;
while (len--) {
src_sample = *src8;
May 29, 2006
May 29, 2006
161
ADJUST_VOLUME(src_sample, volume);
May 28, 2006
May 28, 2006
162
163
164
165
166
167
168
169
170
171
172
173
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
174
#endif
May 28, 2006
May 28, 2006
175
176
}
break;
Apr 26, 2001
Apr 26, 2001
177
May 28, 2006
May 28, 2006
178
179
case AUDIO_S16LSB:
{
Feb 21, 2006
Feb 21, 2006
180
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
181
182
183
if (SDL_HasMMX()) {
SDL_MixAudio_MMX_S16((char *) dst, (char *) src,
(unsigned int) len, (int) volume);
May 28, 2006
May 28, 2006
184
} else
Feb 26, 2006
Feb 26, 2006
185
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
186
187
188
if (SDL_HasMMX()) {
SDL_MixAudio_MMX_S16_VC((char *) dst, (char *) src,
(unsigned int) len, (int) volume);
May 28, 2006
May 28, 2006
189
} else
Nov 9, 2002
Nov 9, 2002
190
#endif
Feb 21, 2006
Feb 21, 2006
191
#if defined(__GNUC__) && defined(__M68000__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
192
193
SDL_MixAudio_m68k_S16LSB((short *) dst, (short *) src,
(unsigned long) len, (long) volume);
Jun 3, 2003
Jun 3, 2003
194
#else
May 28, 2006
May 28, 2006
195
196
197
198
199
{
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
200
May 28, 2006
May 28, 2006
201
202
203
len /= 2;
while (len--) {
src1 = ((src[1]) << 8 | src[0]);
May 29, 2006
May 29, 2006
204
ADJUST_VOLUME(src1, volume);
May 28, 2006
May 28, 2006
205
206
207
208
209
210
211
212
213
214
215
216
217
218
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
219
#endif
May 28, 2006
May 28, 2006
220
221
}
break;
Apr 26, 2001
Apr 26, 2001
222
May 28, 2006
May 28, 2006
223
224
case AUDIO_S16MSB:
{
Feb 21, 2006
Feb 21, 2006
225
#if defined(__GNUC__) && defined(__M68000__) && defined(SDL_ASSEMBLY_ROUTINES)
May 29, 2006
May 29, 2006
226
227
SDL_MixAudio_m68k_S16MSB((short *) dst, (short *) src,
(unsigned long) len, (long) volume);
Jun 3, 2003
Jun 3, 2003
228
#else
May 28, 2006
May 28, 2006
229
230
231
232
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
233
May 28, 2006
May 28, 2006
234
235
236
len /= 2;
while (len--) {
src1 = ((src[0]) << 8 | src[1]);
May 29, 2006
May 29, 2006
237
ADJUST_VOLUME(src1, volume);
May 28, 2006
May 28, 2006
238
239
240
241
242
243
244
245
246
247
248
249
250
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
251
#endif
May 28, 2006
May 28, 2006
252
253
}
break;
Apr 26, 2001
Apr 26, 2001
254
May 28, 2006
May 28, 2006
255
default: /* If this happens... FIXME! */
May 29, 2006
May 29, 2006
256
SDL_SetError("SDL_MixAudio(): unknown audio format");
May 28, 2006
May 28, 2006
257
258
return;
}
Apr 26, 2001
Apr 26, 2001
259
}
Jan 20, 2003
Jan 20, 2003
260
May 28, 2006
May 28, 2006
261
/* vi: set ts=4 sw=4 expandtab: */