zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_mixer.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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  */
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
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 
89 void
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: */
#define SDL_MIX_MAXVOLUME
Definition: SDL_audio.h:456
#define ADJUST_VOLUME(s, v)
Definition: SDL_mixer.c:85
#define SDL_SwapFloatBE(X)
Definition: SDL_endian.h:218
#define AUDIO_S32MSB
Definition: SDL_audio.h:104
int32_t Sint32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:141
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
#define SDL_SwapFloatLE(X)
Definition: SDL_endian.h:214
GLenum GLsizei len
Definition: glew.h:7035
#define SDL_SwapBE32(X)
Definition: SDL_endian.h:216
#define AUDIO_F32MSB
Definition: SDL_audio.h:113
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
static const Uint8 mix8[]
Definition: SDL_mixer.c:34
#define AUDIO_U8
Definition: SDL_audio.h:89
GLenum GLenum dst
Definition: glew.h:2396
#define ADJUST_VOLUME_U8(s, v)
Definition: SDL_mixer.c:86
#define SDL_SwapLE32(X)
Definition: SDL_endian.h:212
#define AUDIO_F32LSB
Definition: SDL_audio.h:112
#define AUDIO_S32LSB
Definition: SDL_audio.h:103
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, int volume)
Definition: SDL_mixer.c:90
#define AUDIO_S16MSB
Definition: SDL_audio.h:94
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
#define AUDIO_S16LSB
Definition: SDL_audio.h:92
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:133
#define F(x, y, z)
Definition: SDL_test_md5.c:73
GLenum src
Definition: glew.h:2396
#define AUDIO_S8
Definition: SDL_audio.h:90
int64_t Sint64
A signed 64-bit integer type.
Definition: SDL_stdinc.h:150
int8_t Sint8
A signed 8-bit integer type.
Definition: SDL_stdinc.h:125