SDL  2.0
SDL_mixer.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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  */
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_U16LSB:
206  {
207  Uint16 src1, src2;
208  int dst_sample;
209  const int max_audioval = 0xFFFF;
210 
211  len /= 2;
212  while (len--) {
213  src1 = ((src[1]) << 8 | src[0]);
214  ADJUST_VOLUME(src1, volume);
215  src2 = ((dst[1]) << 8 | dst[0]);
216  src += 2;
217  dst_sample = src1 + src2;
218  if (dst_sample > max_audioval) {
219  dst_sample = max_audioval;
220  }
221  dst[0] = dst_sample & 0xFF;
222  dst_sample >>= 8;
223  dst[1] = dst_sample & 0xFF;
224  dst += 2;
225  }
226  }
227  break;
228 
229  case AUDIO_U16MSB:
230  {
231  Uint16 src1, src2;
232  int dst_sample;
233  const int max_audioval = 0xFFFF;
234 
235  len /= 2;
236  while (len--) {
237  src1 = ((src[0]) << 8 | src[1]);
238  ADJUST_VOLUME(src1, volume);
239  src2 = ((dst[0]) << 8 | dst[1]);
240  src += 2;
241  dst_sample = src1 + src2;
242  if (dst_sample > max_audioval) {
243  dst_sample = max_audioval;
244  }
245  dst[1] = dst_sample & 0xFF;
246  dst_sample >>= 8;
247  dst[0] = dst_sample & 0xFF;
248  dst += 2;
249  }
250  }
251  break;
252 
253  case AUDIO_S32LSB:
254  {
255  const Uint32 *src32 = (Uint32 *) src;
256  Uint32 *dst32 = (Uint32 *) dst;
257  Sint64 src1, src2;
258  Sint64 dst_sample;
259  const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
260  const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
261 
262  len /= 4;
263  while (len--) {
264  src1 = (Sint64) ((Sint32) SDL_SwapLE32(*src32));
265  src32++;
266  ADJUST_VOLUME(src1, volume);
267  src2 = (Sint64) ((Sint32) SDL_SwapLE32(*dst32));
268  dst_sample = src1 + src2;
269  if (dst_sample > max_audioval) {
270  dst_sample = max_audioval;
271  } else if (dst_sample < min_audioval) {
272  dst_sample = min_audioval;
273  }
274  *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
275  }
276  }
277  break;
278 
279  case AUDIO_S32MSB:
280  {
281  const Uint32 *src32 = (Uint32 *) src;
282  Uint32 *dst32 = (Uint32 *) dst;
283  Sint64 src1, src2;
284  Sint64 dst_sample;
285  const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
286  const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
287 
288  len /= 4;
289  while (len--) {
290  src1 = (Sint64) ((Sint32) SDL_SwapBE32(*src32));
291  src32++;
292  ADJUST_VOLUME(src1, volume);
293  src2 = (Sint64) ((Sint32) SDL_SwapBE32(*dst32));
294  dst_sample = src1 + src2;
295  if (dst_sample > max_audioval) {
296  dst_sample = max_audioval;
297  } else if (dst_sample < min_audioval) {
298  dst_sample = min_audioval;
299  }
300  *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
301  }
302  }
303  break;
304 
305  case AUDIO_F32LSB:
306  {
307  const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
308  const float fvolume = (float) volume;
309  const float *src32 = (float *) src;
310  float *dst32 = (float *) dst;
311  float src1, src2;
312  double dst_sample;
313  /* !!! FIXME: are these right? */
314  const double max_audioval = 3.402823466e+38F;
315  const double min_audioval = -3.402823466e+38F;
316 
317  len /= 4;
318  while (len--) {
319  src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
320  src2 = SDL_SwapFloatLE(*dst32);
321  src32++;
322 
323  dst_sample = ((double) src1) + ((double) src2);
324  if (dst_sample > max_audioval) {
325  dst_sample = max_audioval;
326  } else if (dst_sample < min_audioval) {
327  dst_sample = min_audioval;
328  }
329  *(dst32++) = SDL_SwapFloatLE((float) dst_sample);
330  }
331  }
332  break;
333 
334  case AUDIO_F32MSB:
335  {
336  const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
337  const float fvolume = (float) volume;
338  const float *src32 = (float *) src;
339  float *dst32 = (float *) dst;
340  float src1, src2;
341  double dst_sample;
342  /* !!! FIXME: are these right? */
343  const double max_audioval = 3.402823466e+38F;
344  const double min_audioval = -3.402823466e+38F;
345 
346  len /= 4;
347  while (len--) {
348  src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
349  src2 = SDL_SwapFloatBE(*dst32);
350  src32++;
351 
352  dst_sample = ((double) src1) + ((double) src2);
353  if (dst_sample > max_audioval) {
354  dst_sample = max_audioval;
355  } else if (dst_sample < min_audioval) {
356  dst_sample = min_audioval;
357  }
358  *(dst32++) = SDL_SwapFloatBE((float) dst_sample);
359  }
360  }
361  break;
362 
363  default: /* If this happens... FIXME! */
364  SDL_SetError("SDL_MixAudioFormat(): unknown audio format");
365  return;
366  }
367 }
368 
369 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_MIX_MAXVOLUME
Definition: SDL_audio.h:615
#define ADJUST_VOLUME(s, v)
Definition: SDL_mixer.c:85
#define SDL_SwapFloatBE(X)
Definition: SDL_endian.h:239
#define AUDIO_S32MSB
Definition: SDL_audio.h:104
GLenum GLenum dst
#define AUDIO_U16LSB
Definition: SDL_audio.h:91
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
#define SDL_SwapFloatLE(X)
Definition: SDL_endian.h:235
uint32_t Uint32
Definition: SDL_stdinc.h:181
GLenum src
void SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, int volume)
Definition: SDL_mixer.c:90
GLenum GLsizei len
#define SDL_SwapBE32(X)
Definition: SDL_endian.h:237
#define AUDIO_F32MSB
Definition: SDL_audio.h:113
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
static const Uint8 mix8[]
Definition: SDL_mixer.c:34
#define AUDIO_U8
Definition: SDL_audio.h:89
int8_t Sint8
Definition: SDL_stdinc.h:151
uint8_t Uint8
Definition: SDL_stdinc.h:157
#define ADJUST_VOLUME_U8(s, v)
Definition: SDL_mixer.c:86
#define SDL_SwapLE32(X)
Definition: SDL_endian.h:233
#define AUDIO_F32LSB
Definition: SDL_audio.h:112
#define AUDIO_S32LSB
Definition: SDL_audio.h:103
int32_t Sint32
Definition: SDL_stdinc.h:175
#define SDL_SetError
#define AUDIO_S16MSB
Definition: SDL_audio.h:94
#define AUDIO_S16LSB
Definition: SDL_audio.h:92
uint16_t Uint16
Definition: SDL_stdinc.h:169
#define F(x, y, z)
Definition: SDL_test_md5.c:73
int64_t Sint64
Definition: SDL_stdinc.h:188
#define AUDIO_S8
Definition: SDL_audio.h:90
int16_t Sint16
Definition: SDL_stdinc.h:163
#define AUDIO_U16MSB
Definition: SDL_audio.h:93