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

Latest commit

 

History

History
1210 lines (1053 loc) · 34.8 KB

SDL_audio.c

File metadata and controls

1210 lines (1053 loc) · 34.8 KB
 
Apr 26, 2001
Apr 26, 2001
1
/*
Apr 8, 2011
Apr 8, 2011
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Apr 26, 2001
Apr 26, 2001
20
*/
Feb 21, 2006
Feb 21, 2006
21
#include "SDL_config.h"
Apr 26, 2001
Apr 26, 2001
22
23
24
25
/* Allow access to a raw mixing buffer */
#include "SDL.h"
Jan 4, 2009
Jan 4, 2009
26
#include "SDL_audio.h"
Apr 26, 2001
Apr 26, 2001
27
28
29
30
#include "SDL_audio_c.h"
#include "SDL_audiomem.h"
#include "SDL_sysaudio.h"
Aug 24, 2010
Aug 24, 2010
31
#define _THIS SDL_AudioDevice *_this
Oct 17, 2006
Oct 17, 2006
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
static SDL_AudioDriver current_audio;
static SDL_AudioDevice *open_devices[16];
/* !!! FIXME: These are wordy and unlocalized... */
#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
/*
* Not all of these will be compiled and linked in, but it's convenient
* to have a complete list here and saves yet-another block of #ifdefs...
* Please see bootstrap[], below, for the actual #ifdef mess.
*/
extern AudioBootStrap BSD_AUDIO_bootstrap;
extern AudioBootStrap DSP_bootstrap;
extern AudioBootStrap DMA_bootstrap;
extern AudioBootStrap ALSA_bootstrap;
Aug 20, 2007
Aug 20, 2007
50
extern AudioBootStrap PULSEAUDIO_bootstrap;
Mar 24, 2009
Mar 24, 2009
51
extern AudioBootStrap QSAAUDIO_bootstrap;
Oct 17, 2006
Oct 17, 2006
52
53
54
55
56
extern AudioBootStrap SUNAUDIO_bootstrap;
extern AudioBootStrap ARTS_bootstrap;
extern AudioBootStrap ESD_bootstrap;
extern AudioBootStrap NAS_bootstrap;
extern AudioBootStrap DSOUND_bootstrap;
Nov 11, 2006
Nov 11, 2006
57
extern AudioBootStrap WINWAVEOUT_bootstrap;
Oct 17, 2006
Oct 17, 2006
58
59
60
extern AudioBootStrap PAUDIO_bootstrap;
extern AudioBootStrap BEOSAUDIO_bootstrap;
extern AudioBootStrap COREAUDIO_bootstrap;
Oct 4, 2008
Oct 4, 2008
61
extern AudioBootStrap COREAUDIOIPHONE_bootstrap;
Oct 17, 2006
Oct 17, 2006
62
63
64
65
66
extern AudioBootStrap SNDMGR_bootstrap;
extern AudioBootStrap DISKAUD_bootstrap;
extern AudioBootStrap DUMMYAUD_bootstrap;
extern AudioBootStrap DCAUD_bootstrap;
extern AudioBootStrap DART_bootstrap;
Aug 27, 2008
Aug 27, 2008
67
extern AudioBootStrap NDSAUD_bootstrap;
Jan 1, 2009
Jan 1, 2009
68
extern AudioBootStrap FUSIONSOUND_bootstrap;
Jul 27, 2010
Jul 27, 2010
69
extern AudioBootStrap ANDROIDAUD_bootstrap;
Oct 17, 2006
Oct 17, 2006
70
Nov 23, 2005
Nov 23, 2005
71
Apr 26, 2001
Apr 26, 2001
72
/* Available audio drivers */
Jun 3, 2009
Jun 3, 2009
73
static const AudioBootStrap *const bootstrap[] = {
Jan 1, 2009
Jan 1, 2009
74
75
#if SDL_AUDIO_DRIVER_PULSEAUDIO
&PULSEAUDIO_bootstrap,
Apr 26, 2001
Apr 26, 2001
76
#endif
Feb 16, 2006
Feb 16, 2006
77
#if SDL_AUDIO_DRIVER_ALSA
Jul 10, 2006
Jul 10, 2006
78
&ALSA_bootstrap,
Apr 26, 2001
Apr 26, 2001
79
#endif
Jul 18, 2010
Jul 18, 2010
80
81
82
#if SDL_AUDIO_DRIVER_BSD
&BSD_AUDIO_bootstrap,
#endif
Jan 1, 2009
Jan 1, 2009
83
84
85
#if SDL_AUDIO_DRIVER_OSS
&DSP_bootstrap,
&DMA_bootstrap,
Aug 20, 2007
Aug 20, 2007
86
#endif
Mar 24, 2009
Mar 24, 2009
87
88
#if SDL_AUDIO_DRIVER_QSA
&QSAAUDIO_bootstrap,
Aug 4, 2003
Aug 4, 2003
89
#endif
Feb 16, 2006
Feb 16, 2006
90
#if SDL_AUDIO_DRIVER_SUNAUDIO
Jul 10, 2006
Jul 10, 2006
91
&SUNAUDIO_bootstrap,
Aug 9, 2001
Aug 9, 2001
92
#endif
Feb 16, 2006
Feb 16, 2006
93
#if SDL_AUDIO_DRIVER_ARTS
Jul 10, 2006
Jul 10, 2006
94
&ARTS_bootstrap,
Apr 26, 2001
Apr 26, 2001
95
#endif
Feb 16, 2006
Feb 16, 2006
96
#if SDL_AUDIO_DRIVER_ESD
Jul 10, 2006
Jul 10, 2006
97
&ESD_bootstrap,
Apr 26, 2001
Apr 26, 2001
98
#endif
Feb 16, 2006
Feb 16, 2006
99
#if SDL_AUDIO_DRIVER_NAS
Jul 10, 2006
Jul 10, 2006
100
&NAS_bootstrap,
Apr 26, 2001
Apr 26, 2001
101
#endif
Feb 16, 2006
Feb 16, 2006
102
#if SDL_AUDIO_DRIVER_DSOUND
Jul 10, 2006
Jul 10, 2006
103
&DSOUND_bootstrap,
Apr 26, 2001
Apr 26, 2001
104
#endif
Nov 11, 2006
Nov 11, 2006
105
106
#if SDL_AUDIO_DRIVER_WINWAVEOUT
&WINWAVEOUT_bootstrap,
Apr 26, 2001
Apr 26, 2001
107
#endif
Oct 17, 2006
Oct 17, 2006
108
109
#if SDL_AUDIO_DRIVER_PAUDIO
&PAUDIO_bootstrap,
Feb 16, 2006
Feb 16, 2006
110
#endif
Oct 17, 2006
Oct 17, 2006
111
112
#if SDL_AUDIO_DRIVER_BEOSAUDIO
&BEOSAUDIO_bootstrap,
Apr 26, 2001
Apr 26, 2001
113
#endif
Feb 16, 2006
Feb 16, 2006
114
#if SDL_AUDIO_DRIVER_COREAUDIO
Jul 10, 2006
Jul 10, 2006
115
&COREAUDIO_bootstrap,
Aug 21, 2004
Aug 21, 2004
116
#endif
Oct 4, 2008
Oct 4, 2008
117
118
119
#if SDL_AUDIO_DRIVER_COREAUDIOIPHONE
&COREAUDIOIPHONE_bootstrap,
#endif
Feb 16, 2006
Feb 16, 2006
120
#if SDL_AUDIO_DRIVER_DISK
Jul 10, 2006
Jul 10, 2006
121
&DISKAUD_bootstrap,
Oct 5, 2002
Oct 5, 2002
122
#endif
Mar 14, 2006
Mar 14, 2006
123
#if SDL_AUDIO_DRIVER_DUMMY
Jul 10, 2006
Jul 10, 2006
124
&DUMMYAUD_bootstrap,
Mar 14, 2006
Mar 14, 2006
125
#endif
Aug 27, 2008
Aug 27, 2008
126
127
#if SDL_AUDIO_DRIVER_NDS
&NDSAUD_bootstrap,
Jan 1, 2009
Jan 1, 2009
128
129
130
#endif
#if SDL_AUDIO_DRIVER_FUSIONSOUND
&FUSIONSOUND_bootstrap,
Jul 27, 2010
Jul 27, 2010
131
132
133
#endif
#if SDL_AUDIO_DRIVER_ANDROID
&ANDROIDAUD_bootstrap,
Jun 16, 2001
Jun 16, 2001
134
#endif
Jul 10, 2006
Jul 10, 2006
135
NULL
Apr 26, 2001
Apr 26, 2001
136
137
};
Oct 28, 2006
Oct 28, 2006
138
139
static SDL_AudioDevice *
get_audio_device(SDL_AudioDeviceID id)
Oct 17, 2006
Oct 17, 2006
140
141
{
id--;
Oct 28, 2006
Oct 28, 2006
142
if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
Oct 17, 2006
Oct 17, 2006
143
144
145
146
147
148
149
150
151
SDL_SetError("Invalid audio device ID");
return NULL;
}
return open_devices[id];
}
/* stubs for audio drivers that don't need a specific entry point... */
Oct 28, 2006
Oct 28, 2006
152
153
154
155
156
static int
SDL_AudioDetectDevices_Default(int iscapture)
{
return -1;
}
Aug 27, 2008
Aug 27, 2008
157
Oct 28, 2006
Oct 28, 2006
158
159
160
161
static void
SDL_AudioThreadInit_Default(_THIS)
{ /* no-op. */
}
Aug 27, 2008
Aug 27, 2008
162
Oct 28, 2006
Oct 28, 2006
163
164
165
166
static void
SDL_AudioWaitDevice_Default(_THIS)
{ /* no-op. */
}
Aug 27, 2008
Aug 27, 2008
167
Oct 28, 2006
Oct 28, 2006
168
169
170
171
static void
SDL_AudioPlayDevice_Default(_THIS)
{ /* no-op. */
}
Aug 27, 2008
Aug 27, 2008
172
Oct 28, 2006
Oct 28, 2006
173
174
175
176
177
static Uint8 *
SDL_AudioGetDeviceBuf_Default(_THIS)
{
return NULL;
}
Aug 27, 2008
Aug 27, 2008
178
Oct 28, 2006
Oct 28, 2006
179
180
181
182
static void
SDL_AudioWaitDone_Default(_THIS)
{ /* no-op. */
}
Aug 27, 2008
Aug 27, 2008
183
Oct 28, 2006
Oct 28, 2006
184
185
186
187
static void
SDL_AudioCloseDevice_Default(_THIS)
{ /* no-op. */
}
Aug 27, 2008
Aug 27, 2008
188
Oct 28, 2006
Oct 28, 2006
189
190
191
192
static void
SDL_AudioDeinitialize_Default(void)
{ /* no-op. */
}
Oct 17, 2006
Oct 17, 2006
193
194
195
196
197
198
199
static int
SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
{
return 0;
}
Oct 28, 2006
Oct 28, 2006
200
201
static const char *
SDL_AudioGetDeviceName_Default(int index, int iscapture)
Oct 17, 2006
Oct 17, 2006
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
{
SDL_SetError("No such device");
return NULL;
}
static void
SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
{
if (device->thread && (SDL_ThreadID() == device->threadid)) {
return;
}
SDL_mutexP(device->mixer_lock);
}
static void
SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
{
if (device->thread && (SDL_ThreadID() == device->threadid)) {
return;
}
SDL_mutexV(device->mixer_lock);
}
Oct 28, 2006
Oct 28, 2006
226
227
static void
finalize_audio_entry_points(void)
Oct 17, 2006
Oct 17, 2006
228
229
230
231
232
233
{
/*
* Fill in stub functions for unused driver entry points. This lets us
* blindly call them without having to check for validity first.
*/
Oct 28, 2006
Oct 28, 2006
234
#define FILL_STUB(x) \
Oct 17, 2006
Oct 17, 2006
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
if (current_audio.impl.x == NULL) { \
current_audio.impl.x = SDL_Audio##x##_Default; \
}
FILL_STUB(DetectDevices);
FILL_STUB(GetDeviceName);
FILL_STUB(OpenDevice);
FILL_STUB(ThreadInit);
FILL_STUB(WaitDevice);
FILL_STUB(PlayDevice);
FILL_STUB(GetDeviceBuf);
FILL_STUB(WaitDone);
FILL_STUB(CloseDevice);
FILL_STUB(LockDevice);
FILL_STUB(UnlockDevice);
FILL_STUB(Deinitialize);
Oct 28, 2006
Oct 28, 2006
250
#undef FILL_STUB
Oct 17, 2006
Oct 17, 2006
251
}
Apr 26, 2001
Apr 26, 2001
252
Aug 25, 2008
Aug 25, 2008
253
254
/* Streaming functions (for when the input and output buffer sizes are different) */
/* Write [length] bytes from buf into the streamer */
Jun 26, 2010
Jun 26, 2010
255
static void
Aug 25, 2008
Aug 25, 2008
256
257
258
259
260
261
262
263
264
265
266
SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;
for (i = 0; i < length; ++i) {
stream->buffer[stream->write_pos] = buf[i];
++stream->write_pos;
}
}
/* Read [length] bytes out of the streamer into buf */
Jun 26, 2010
Jun 26, 2010
267
static void
Aug 25, 2008
Aug 25, 2008
268
269
270
271
272
273
274
275
276
277
SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;
for (i = 0; i < length; ++i) {
buf[i] = stream->buffer[stream->read_pos];
++stream->read_pos;
}
}
Jun 26, 2010
Jun 26, 2010
278
static int
Aug 25, 2008
Aug 25, 2008
279
280
281
282
283
284
SDL_StreamLength(SDL_AudioStreamer * stream)
{
return (stream->write_pos - stream->read_pos) % stream->max_len;
}
/* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
Jul 12, 2010
Jul 12, 2010
285
#if 0
Jun 26, 2010
Jun 26, 2010
286
static int
Aug 25, 2008
Aug 25, 2008
287
288
289
SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
{
/* First try to allocate the buffer */
Aug 26, 2008
Aug 26, 2008
290
stream->buffer = (Uint8 *) SDL_malloc(max_len);
Aug 25, 2008
Aug 25, 2008
291
292
293
294
295
296
297
298
299
if (stream->buffer == NULL) {
return -1;
}
stream->max_len = max_len;
stream->read_pos = 0;
stream->write_pos = 0;
/* Zero out the buffer */
Aug 26, 2008
Aug 26, 2008
300
301
302
SDL_memset(stream->buffer, silence, max_len);
return 0;
Aug 25, 2008
Aug 25, 2008
303
}
Jul 12, 2010
Jul 12, 2010
304
#endif
Aug 25, 2008
Aug 25, 2008
305
306
/* Deinitialize the stream simply by freeing the buffer */
Jun 26, 2010
Jun 26, 2010
307
static void
Aug 25, 2008
Aug 25, 2008
308
309
310
SDL_StreamDeinit(SDL_AudioStreamer * stream)
{
if (stream->buffer != NULL) {
Aug 26, 2008
Aug 26, 2008
311
SDL_free(stream->buffer);
Aug 25, 2008
Aug 25, 2008
312
313
314
}
}
Aug 24, 2010
Aug 24, 2010
315
#if defined(ANDROID)
Jul 27, 2010
Jul 27, 2010
316
#include <android/log.h>
Aug 24, 2010
Aug 24, 2010
317
#endif
Jul 27, 2010
Jul 27, 2010
318
Apr 26, 2001
Apr 26, 2001
319
/* The general mixing thread function */
Jul 10, 2006
Jul 10, 2006
320
int SDLCALL
Oct 17, 2006
Oct 17, 2006
321
SDL_RunAudio(void *devicep)
Apr 26, 2001
Apr 26, 2001
322
{
Oct 17, 2006
Oct 17, 2006
323
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
Jul 10, 2006
Jul 10, 2006
324
325
326
327
328
Uint8 *stream;
int stream_len;
void *udata;
void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
int silence;
Oct 4, 2009
Oct 4, 2009
329
Uint32 delay;
Aug 25, 2008
Aug 25, 2008
330
331
/* For streaming when the buffer sizes don't match up */
Uint8 *istream;
Sep 16, 2010
Sep 16, 2010
332
int istream_len = 0;
Apr 26, 2001
Apr 26, 2001
333
Apr 3, 2011
Apr 3, 2011
334
335
336
/* The audio mixing is always a high priority thread */
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
Jul 10, 2006
Jul 10, 2006
337
/* Perform any thread setup */
Oct 17, 2006
Oct 17, 2006
338
339
device->threadid = SDL_ThreadID();
current_audio.impl.ThreadInit(device);
Apr 26, 2001
Apr 26, 2001
340
Jul 10, 2006
Jul 10, 2006
341
/* Set up the mixing function */
Oct 17, 2006
Oct 17, 2006
342
343
fill = device->spec.callback;
udata = device->spec.userdata;
May 10, 2001
May 10, 2001
344
Aug 25, 2008
Aug 25, 2008
345
346
347
/* By default do not stream */
device->use_streamer = 0;
Oct 17, 2006
Oct 17, 2006
348
349
if (device->convert.needed) {
if (device->convert.src_format == AUDIO_U8) {
Jul 10, 2006
Jul 10, 2006
350
351
352
353
silence = 0x80;
} else {
silence = 0;
}
Aug 25, 2008
Aug 25, 2008
354
Jan 14, 2009
Jan 14, 2009
355
#if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */
Aug 25, 2008
Aug 25, 2008
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
if (device->convert.len_mult != 1 || device->convert.len_div != 1) {
/* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
stream_max_len = 2 * device->spec.size;
if (device->convert.len_mult > device->convert.len_div) {
stream_max_len *= device->convert.len_mult;
stream_max_len /= device->convert.len_div;
}
if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
0)
return -1;
device->use_streamer = 1;
/* istream_len should be the length of what we grab from the callback and feed to conversion,
so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
*/
istream_len =
device->spec.size * device->convert.len_div /
device->convert.len_mult;
}
Jan 11, 2009
Jan 11, 2009
376
#endif
Aug 25, 2008
Aug 25, 2008
377
378
379
/* stream_len = device->convert.len; */
stream_len = device->spec.size;
Jul 10, 2006
Jul 10, 2006
380
} else {
Oct 17, 2006
Oct 17, 2006
381
382
silence = device->spec.silence;
stream_len = device->spec.size;
Jul 10, 2006
Jul 10, 2006
383
}
Mar 21, 2006
Mar 21, 2006
384
Oct 4, 2009
Oct 4, 2009
385
386
387
/* Calculate the delay while paused */
delay = ((device->spec.samples * 1000) / device->spec.freq);
Aug 25, 2008
Aug 25, 2008
388
389
/* Determine if the streamer is necessary here */
if (device->use_streamer == 1) {
Oct 4, 2009
Oct 4, 2009
390
/* This code is almost the same as the old code. The difference is, instead of reading
Aug 25, 2008
Aug 25, 2008
391
392
393
394
395
396
397
398
399
400
401
402
directly from the callback into "stream", then converting and sending the audio off,
we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
However, reading and writing with streamer are done separately:
- We only call the callback and write to the streamer when the streamer does not
contain enough samples to output to the device.
- We only read from the streamer and tell the device to play when the streamer
does have enough samples to output.
This allows us to perform resampling in the conversion step, where the output of the
resampling process can be any number. We will have to see what a good size for the
stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
*/
while (device->enabled) {
Oct 4, 2009
Oct 4, 2009
403
404
405
406
407
408
if (device->paused) {
SDL_Delay(delay);
continue;
}
Aug 25, 2008
Aug 25, 2008
409
410
411
412
413
414
415
416
417
418
/* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
if (SDL_StreamLength(&device->streamer) < stream_len) {
/* Set up istream */
if (device->convert.needed) {
if (device->convert.buf) {
istream = device->convert.buf;
} else {
continue;
}
} else {
Oct 4, 2009
Oct 4, 2009
419
420
421
/* FIXME: Ryan, this is probably wrong. I imagine we don't want to get
* a device buffer both here and below in the stream output.
*/
Aug 25, 2008
Aug 25, 2008
422
423
424
425
426
427
428
istream = current_audio.impl.GetDeviceBuf(device);
if (istream == NULL) {
istream = device->fake_stream;
}
}
/* Read from the callback into the _input_ stream */
Oct 4, 2009
Oct 4, 2009
429
430
431
SDL_mutexP(device->mixer_lock);
(*fill) (udata, istream, istream_len);
SDL_mutexV(device->mixer_lock);
Aug 25, 2008
Aug 25, 2008
432
433
434
435
436
437
438
439
440
441
442
443
444
/* Convert the audio if necessary and write to the streamer */
if (device->convert.needed) {
SDL_ConvertAudio(&device->convert);
if (istream == NULL) {
istream = device->fake_stream;
}
/*SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
SDL_StreamWrite(&device->streamer, device->convert.buf,
device->convert.len_cvt);
} else {
SDL_StreamWrite(&device->streamer, istream, istream_len);
}
Jul 10, 2006
Jul 10, 2006
445
}
Aug 25, 2008
Aug 25, 2008
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
/* Only output audio if the streamer has enough to output */
if (SDL_StreamLength(&device->streamer) >= stream_len) {
/* Set up the output stream */
if (device->convert.needed) {
if (device->convert.buf) {
stream = device->convert.buf;
} else {
continue;
}
} else {
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
}
/* Now read from the streamer */
SDL_StreamRead(&device->streamer, stream, stream_len);
/* Ready current buffer for play and change current buffer */
Oct 4, 2009
Oct 4, 2009
467
if (stream != device->fake_stream) {
Aug 25, 2008
Aug 25, 2008
468
current_audio.impl.PlayDevice(device);
Mar 23, 2009
Mar 23, 2009
469
/* Wait for an audio buffer to become available */
Aug 25, 2008
Aug 25, 2008
470
current_audio.impl.WaitDevice(device);
Mar 23, 2009
Mar 23, 2009
471
} else {
Oct 4, 2009
Oct 4, 2009
472
SDL_Delay(delay);
Aug 25, 2008
Aug 25, 2008
473
}
Jul 10, 2006
Jul 10, 2006
474
}
May 10, 2001
May 10, 2001
475
Jul 10, 2006
Jul 10, 2006
476
}
Aug 25, 2008
Aug 25, 2008
477
478
479
480
481
482
} else {
/* Otherwise, do not use the streamer. This is the old code. */
/* Loop, filling the audio buffers */
while (device->enabled) {
Oct 4, 2009
Oct 4, 2009
483
484
485
486
487
if (device->paused) {
SDL_Delay(delay);
continue;
}
Aug 25, 2008
Aug 25, 2008
488
489
490
491
492
493
494
495
496
497
498
499
500
/* Fill the current buffer with sound */
if (device->convert.needed) {
if (device->convert.buf) {
stream = device->convert.buf;
} else {
continue;
}
} else {
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
}
May 10, 2001
May 10, 2001
501
Oct 4, 2009
Oct 4, 2009
502
503
504
SDL_mutexP(device->mixer_lock);
(*fill) (udata, stream, stream_len);
SDL_mutexV(device->mixer_lock);
Jul 10, 2006
Jul 10, 2006
505
Aug 25, 2008
Aug 25, 2008
506
507
508
509
510
511
512
513
514
515
/* Convert the audio if necessary */
if (device->convert.needed) {
SDL_ConvertAudio(&device->convert);
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
SDL_memcpy(stream, device->convert.buf,
device->convert.len_cvt);
}
Jul 10, 2006
Jul 10, 2006
516
Aug 25, 2008
Aug 25, 2008
517
/* Ready current buffer for play and change current buffer */
Oct 4, 2009
Oct 4, 2009
518
if (stream != device->fake_stream) {
Aug 25, 2008
Aug 25, 2008
519
current_audio.impl.PlayDevice(device);
Mar 23, 2009
Mar 23, 2009
520
/* Wait for an audio buffer to become available */
Aug 25, 2008
Aug 25, 2008
521
current_audio.impl.WaitDevice(device);
Mar 23, 2009
Mar 23, 2009
522
} else {
Oct 4, 2009
Oct 4, 2009
523
SDL_Delay(delay);
Aug 25, 2008
Aug 25, 2008
524
}
Jul 10, 2006
Jul 10, 2006
525
526
527
528
}
}
/* Wait for the audio to drain.. */
Oct 17, 2006
Oct 17, 2006
529
current_audio.impl.WaitDone(device);
May 10, 2001
May 10, 2001
530
Aug 25, 2008
Aug 25, 2008
531
532
533
534
/* If necessary, deinit the streamer */
if (device->use_streamer == 1)
SDL_StreamDeinit(&device->streamer);
Jul 10, 2006
Jul 10, 2006
535
return (0);
Apr 26, 2001
Apr 26, 2001
536
537
}
Mar 30, 2002
Mar 30, 2002
538
Aug 24, 2006
Aug 24, 2006
539
static SDL_AudioFormat
Jul 10, 2006
Jul 10, 2006
540
SDL_ParseAudioFormat(const char *string)
May 9, 2006
May 9, 2006
541
{
Nov 29, 2006
Nov 29, 2006
542
#define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
Oct 17, 2006
Oct 17, 2006
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
CHECK_FMT_STRING(U8);
CHECK_FMT_STRING(S8);
CHECK_FMT_STRING(U16LSB);
CHECK_FMT_STRING(S16LSB);
CHECK_FMT_STRING(U16MSB);
CHECK_FMT_STRING(S16MSB);
CHECK_FMT_STRING(U16SYS);
CHECK_FMT_STRING(S16SYS);
CHECK_FMT_STRING(U16);
CHECK_FMT_STRING(S16);
CHECK_FMT_STRING(S32LSB);
CHECK_FMT_STRING(S32MSB);
CHECK_FMT_STRING(S32SYS);
CHECK_FMT_STRING(S32);
CHECK_FMT_STRING(F32LSB);
CHECK_FMT_STRING(F32MSB);
CHECK_FMT_STRING(F32SYS);
CHECK_FMT_STRING(F32);
Oct 28, 2006
Oct 28, 2006
561
#undef CHECK_FMT_STRING
Oct 17, 2006
Oct 17, 2006
562
return 0;
May 9, 2006
May 9, 2006
563
564
}
Jul 10, 2006
Jul 10, 2006
565
566
int
SDL_GetNumAudioDrivers(void)
Apr 26, 2001
Apr 26, 2001
567
{
Jul 10, 2006
Jul 10, 2006
568
569
return (SDL_arraysize(bootstrap) - 1);
}
Apr 26, 2001
Apr 26, 2001
570
Jul 10, 2006
Jul 10, 2006
571
572
573
574
575
576
577
578
579
580
581
582
const char *
SDL_GetAudioDriver(int index)
{
if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
return (bootstrap[index]->name);
}
return (NULL);
}
int
SDL_AudioInit(const char *driver_name)
{
Oct 17, 2006
Oct 17, 2006
583
584
585
int i = 0;
int initialized = 0;
int tried_to_init = 0;
Apr 26, 2001
Apr 26, 2001
586
Oct 17, 2006
Oct 17, 2006
587
if (SDL_WasInit(SDL_INIT_AUDIO)) {
Oct 28, 2006
Oct 28, 2006
588
SDL_AudioQuit(); /* shutdown driver if already running. */
Jul 10, 2006
Jul 10, 2006
589
590
}
Oct 28, 2006
Oct 28, 2006
591
592
SDL_memset(&current_audio, '\0', sizeof(current_audio));
SDL_memset(open_devices, '\0', sizeof(open_devices));
Oct 17, 2006
Oct 17, 2006
593
Jul 10, 2006
Jul 10, 2006
594
/* Select the proper audio driver */
Jul 15, 2006
Jul 15, 2006
595
596
597
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}
Oct 17, 2006
Oct 17, 2006
598
599
600
601
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
/* make sure we should even try this driver before doing so... */
const AudioBootStrap *backend = bootstrap[i];
Oct 28, 2006
Oct 28, 2006
602
603
if (((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) ||
((!driver_name) && (backend->demand_only))) {
Oct 17, 2006
Oct 17, 2006
604
continue;
Jul 10, 2006
Jul 10, 2006
605
}
Oct 17, 2006
Oct 17, 2006
606
607
tried_to_init = 1;
Oct 28, 2006
Oct 28, 2006
608
SDL_memset(&current_audio, 0, sizeof(current_audio));
Oct 17, 2006
Oct 17, 2006
609
610
current_audio.name = backend->name;
current_audio.desc = backend->desc;
Jan 26, 2010
Jan 26, 2010
611
initialized = backend->init(&current_audio.impl);
Jul 10, 2006
Jul 10, 2006
612
}
Oct 17, 2006
Oct 17, 2006
613
614
615
616
if (!initialized) {
/* specific drivers will set the error message if they fail... */
if (!tried_to_init) {
Jul 10, 2006
Jul 10, 2006
617
if (driver_name) {
Jan 26, 2010
Jan 26, 2010
618
SDL_SetError("Audio target '%s' not available", driver_name);
Jul 10, 2006
Jul 10, 2006
619
620
621
622
} else {
SDL_SetError("No available audio device");
}
}
Oct 17, 2006
Oct 17, 2006
623
Oct 28, 2006
Oct 28, 2006
624
625
SDL_memset(&current_audio, 0, sizeof(current_audio));
return (-1); /* No driver was available, so fail. */
Jul 10, 2006
Jul 10, 2006
626
}
Oct 17, 2006
Oct 17, 2006
627
628
629
finalize_audio_entry_points();
Jul 10, 2006
Jul 10, 2006
630
return (0);
Apr 26, 2001
Apr 26, 2001
631
632
}
Jul 10, 2006
Jul 10, 2006
633
634
635
636
637
/*
* Get the current audio driver name
*/
const char *
SDL_GetCurrentAudioDriver()
Apr 26, 2001
Apr 26, 2001
638
{
Oct 17, 2006
Oct 17, 2006
639
return current_audio.name;
Apr 26, 2001
Apr 26, 2001
640
641
}
Oct 17, 2006
Oct 17, 2006
642
Jul 10, 2006
Jul 10, 2006
643
int
Oct 17, 2006
Oct 17, 2006
644
SDL_GetNumAudioDevices(int iscapture)
Apr 26, 2001
Apr 26, 2001
645
{
Oct 17, 2006
Oct 17, 2006
646
647
648
649
650
651
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
return -1;
}
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
return 0;
}
Jul 10, 2006
Jul 10, 2006
652
Oct 17, 2006
Oct 17, 2006
653
654
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
return 1;
Jul 10, 2006
Jul 10, 2006
655
656
}
Oct 17, 2006
Oct 17, 2006
657
658
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
return 1;
Jul 10, 2006
Jul 10, 2006
659
660
}
Oct 17, 2006
Oct 17, 2006
661
662
663
664
665
666
667
668
669
670
return current_audio.impl.DetectDevices(iscapture);
}
const char *
SDL_GetAudioDeviceName(int index, int iscapture)
{
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_SetError("Audio subsystem is not initialized");
return NULL;
Jul 10, 2006
Jul 10, 2006
671
}
Oct 17, 2006
Oct 17, 2006
672
673
674
675
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
SDL_SetError("No capture support");
return NULL;
Jul 10, 2006
Jul 10, 2006
676
}
Oct 17, 2006
Oct 17, 2006
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
if (index < 0) {
SDL_SetError("No such device");
return NULL;
}
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
return DEFAULT_INPUT_DEVNAME;
}
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
return DEFAULT_OUTPUT_DEVNAME;
}
return current_audio.impl.GetDeviceName(index, iscapture);
}
static void
Oct 28, 2006
Oct 28, 2006
696
close_audio_device(SDL_AudioDevice * device)
Oct 17, 2006
Oct 17, 2006
697
698
699
700
701
702
703
{
device->enabled = 0;
if (device->thread != NULL) {
SDL_WaitThread(device->thread, NULL);
}
if (device->mixer_lock != NULL) {
SDL_DestroyMutex(device->mixer_lock);
Jul 10, 2006
Jul 10, 2006
704
}
Oct 17, 2006
Oct 17, 2006
705
706
if (device->fake_stream != NULL) {
SDL_FreeAudioMem(device->fake_stream);
Jul 10, 2006
Jul 10, 2006
707
}
Oct 17, 2006
Oct 17, 2006
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
if (device->convert.needed) {
SDL_FreeAudioMem(device->convert.buf);
}
if (device->opened) {
current_audio.impl.CloseDevice(device);
device->opened = 0;
}
SDL_FreeAudioMem(device);
}
/*
* Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
* Fills in a sanitized copy in (prepared).
* Returns non-zero if okay, zero on fatal parameters in (orig).
*/
static int
Oct 28, 2006
Oct 28, 2006
725
prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
Oct 17, 2006
Oct 17, 2006
726
{
Oct 28, 2006
Oct 28, 2006
727
SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
Oct 17, 2006
Oct 17, 2006
728
729
730
731
732
733
734
735
if (orig->callback == NULL) {
SDL_SetError("SDL_OpenAudio() passed a NULL callback");
return 0;
}
if (orig->freq == 0) {
const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
Oct 28, 2006
Oct 28, 2006
736
737
if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
prepared->freq = 22050; /* a reasonable default */
Jul 10, 2006
Jul 10, 2006
738
739
}
}
Oct 17, 2006
Oct 17, 2006
740
741
742
743
if (orig->format == 0) {
const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
Oct 28, 2006
Oct 28, 2006
744
prepared->format = AUDIO_S16; /* a reasonable default */
Oct 17, 2006
Oct 17, 2006
745
746
747
748
}
}
switch (orig->channels) {
Oct 28, 2006
Oct 28, 2006
749
750
case 0:{
const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
Jul 3, 2007
Jul 3, 2007
751
if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
Oct 28, 2006
Oct 28, 2006
752
753
754
prepared->channels = 2; /* a reasonable default */
}
break;
Oct 17, 2006
Oct 17, 2006
755
}
Jul 10, 2006
Jul 10, 2006
756
757
758
759
760
761
case 1: /* Mono */
case 2: /* Stereo */
case 4: /* surround */
case 6: /* surround with center and lfe */
break;
default:
Oct 17, 2006
Oct 17, 2006
762
763
SDL_SetError("Unsupported number of audio channels.");
return 0;
Jul 10, 2006
Jul 10, 2006
764
}
Oct 17, 2006
Oct 17, 2006
765
766
767
if (orig->samples == 0) {
const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
Oct 28, 2006
Oct 28, 2006
768
if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
Oct 17, 2006
Oct 17, 2006
769
770
771
772
773
774
775
776
/* Pick a default of ~46 ms at desired frequency */
/* !!! FIXME: remove this when the non-Po2 resampling is in. */
const int samples = (prepared->freq / 1000) * 46;
int power2 = 1;
while (power2 < samples) {
power2 *= 2;
}
prepared->samples = power2;
Jul 10, 2006
Jul 10, 2006
777
778
}
}
Oct 17, 2006
Oct 17, 2006
779
780
781
782
783
784
785
786
787
788
/* Calculate the silence and size of the audio specification */
SDL_CalculateAudioSpec(prepared);
return 1;
}
static SDL_AudioDeviceID
open_audio_device(const char *devname, int iscapture,
Dec 13, 2008
Dec 13, 2008
789
790
const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
int allowed_changes, int min_id)
Oct 17, 2006
Oct 17, 2006
791
792
{
SDL_AudioDeviceID id = 0;
Dec 13, 2008
Dec 13, 2008
793
SDL_AudioSpec _obtained;
Oct 17, 2006
Oct 17, 2006
794
SDL_AudioDevice *device;
Dec 13, 2008
Dec 13, 2008
795
SDL_bool build_cvt;
Oct 17, 2006
Oct 17, 2006
796
797
798
799
800
int i = 0;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_SetError("Audio subsystem is not initialized");
return 0;
Jul 10, 2006
Jul 10, 2006
801
}
Oct 17, 2006
Oct 17, 2006
802
803
804
805
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
SDL_SetError("No capture support");
return 0;
Jul 10, 2006
Jul 10, 2006
806
}
Apr 26, 2001
Apr 26, 2001
807
Dec 13, 2008
Dec 13, 2008
808
809
810
811
if (!obtained) {
obtained = &_obtained;
}
if (!prepare_audiospec(desired, obtained)) {
Oct 17, 2006
Oct 17, 2006
812
813
return 0;
}
Apr 26, 2001
Apr 26, 2001
814
Oct 17, 2006
Oct 17, 2006
815
816
817
818
/* If app doesn't care about a specific device, let the user override. */
if (devname == NULL) {
devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
}
May 10, 2001
May 10, 2001
819
Oct 17, 2006
Oct 17, 2006
820
821
822
823
824
825
826
827
828
/*
* Catch device names at the high level for the simple case...
* This lets us have a basic "device enumeration" for systems that
* don't have multiple devices, but makes sure the device name is
* always NULL when it hits the low level.
*
* Also make sure that the simple case prevents multiple simultaneous
* opens of the default system device.
*/
May 10, 2001
May 10, 2001
829
Oct 17, 2006
Oct 17, 2006
830
831
832
833
834
835
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
SDL_SetError("No such device");
return 0;
}
devname = NULL;
May 10, 2001
May 10, 2001
836
Oct 17, 2006
Oct 17, 2006
837
838
839
840
841
842
for (i = 0; i < SDL_arraysize(open_devices); i++) {
if ((open_devices[i]) && (open_devices[i]->iscapture)) {
SDL_SetError("Audio device already open");
return 0;
}
}
Jul 10, 2006
Jul 10, 2006
843
844
}
Oct 17, 2006
Oct 17, 2006
845
846
847
848
849
850
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
SDL_SetError("No such device");
return 0;
}
devname = NULL;
Jul 10, 2006
Jul 10, 2006
851
Oct 17, 2006
Oct 17, 2006
852
853
854
855
856
857
858
for (i = 0; i < SDL_arraysize(open_devices); i++) {
if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
SDL_SetError("Audio device already open");
return 0;
}
}
}
Jul 10, 2006
Jul 10, 2006
859
Oct 28, 2006
Oct 28, 2006
860
device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
Oct 17, 2006
Oct 17, 2006
861
862
863
if (device == NULL) {
SDL_OutOfMemory();
return 0;
Jul 10, 2006
Jul 10, 2006
864
}
Oct 28, 2006
Oct 28, 2006
865
SDL_memset(device, '\0', sizeof(SDL_AudioDevice));
Dec 13, 2008
Dec 13, 2008
866
device->spec = *obtained;
Oct 17, 2006
Oct 17, 2006
867
868
869
device->enabled = 1;
device->paused = 1;
device->iscapture = iscapture;
Jul 10, 2006
Jul 10, 2006
870
Oct 17, 2006
Oct 17, 2006
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
/* Create a semaphore for locking the sound buffers */
if (!current_audio.impl.SkipMixerLock) {
device->mixer_lock = SDL_CreateMutex();
if (device->mixer_lock == NULL) {
close_audio_device(device);
SDL_SetError("Couldn't create mixer lock");
return 0;
}
}
if (!current_audio.impl.OpenDevice(device, devname, iscapture)) {
close_audio_device(device);
return 0;
}
device->opened = 1;
Jul 10, 2006
Jul 10, 2006
886
887
/* Allocate a fake audio memory buffer */
Aug 24, 2010
Aug 24, 2010
888
device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
Oct 17, 2006
Oct 17, 2006
889
890
if (device->fake_stream == NULL) {
close_audio_device(device);
Jul 10, 2006
Jul 10, 2006
891
SDL_OutOfMemory();
Oct 17, 2006
Oct 17, 2006
892
return 0;
Jul 10, 2006
Jul 10, 2006
893
894
}
Dec 13, 2008
Dec 13, 2008
895
896
897
898
899
900
/* If the audio driver changes the buffer size, accept it */
if (device->spec.samples != obtained->samples) {
obtained->samples = device->spec.samples;
SDL_CalculateAudioSpec(obtained);
}
Jul 10, 2006
Jul 10, 2006
901
/* See if we need to do any conversion */
Dec 13, 2008
Dec 13, 2008
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
build_cvt = SDL_FALSE;
if (obtained->freq != device->spec.freq) {
if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
obtained->freq = device->spec.freq;
} else {
build_cvt = SDL_TRUE;
}
}
if (obtained->format != device->spec.format) {
if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
obtained->format = device->spec.format;
} else {
build_cvt = SDL_TRUE;
}
}
if (obtained->channels != device->spec.channels) {
if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
obtained->channels = device->spec.channels;
} else {
build_cvt = SDL_TRUE;
}
}
if (build_cvt) {
Jul 10, 2006
Jul 10, 2006
925
/* Build an audio conversion block */
Oct 17, 2006
Oct 17, 2006
926
if (SDL_BuildAudioCVT(&device->convert,
Dec 13, 2008
Dec 13, 2008
927
928
obtained->format, obtained->channels,
obtained->freq,
Oct 17, 2006
Oct 17, 2006
929
930
931
932
device->spec.format, device->spec.channels,
device->spec.freq) < 0) {
close_audio_device(device);
return 0;
Jul 10, 2006
Jul 10, 2006
933
}
Oct 17, 2006
Oct 17, 2006
934
if (device->convert.needed) {
Dec 13, 2008
Dec 13, 2008
935
device->convert.len = (int) (((double) obtained->size) /
Oct 28, 2006
Oct 28, 2006
936
device->convert.len_ratio);
Oct 27, 2006
Oct 27, 2006
937
Oct 17, 2006
Oct 17, 2006
938
939
940
941
942
device->convert.buf =
(Uint8 *) SDL_AllocAudioMem(device->convert.len *
device->convert.len_mult);
if (device->convert.buf == NULL) {
close_audio_device(device);
Jul 10, 2006
Jul 10, 2006
943
SDL_OutOfMemory();
Oct 17, 2006
Oct 17, 2006
944
return 0;
Jul 10, 2006
Jul 10, 2006
945
946
947
}
}
}
Oct 17, 2006
Oct 17, 2006
948
949
/* Find an available device ID and store the structure... */
Oct 28, 2006
Oct 28, 2006
950
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
Oct 17, 2006
Oct 17, 2006
951
952
953
954
955
956
957
958
959
960
961
962
if (open_devices[id] == NULL) {
open_devices[id] = device;
break;
}
}
if (id == SDL_arraysize(open_devices)) {
SDL_SetError("Too many open audio devices");
close_audio_device(device);
return 0;
}
Jul 10, 2006
Jul 10, 2006
963
/* Start the audio thread if necessary */
Oct 17, 2006
Oct 17, 2006
964
if (!current_audio.impl.ProvidesOwnCallbackThread) {
Jul 10, 2006
Jul 10, 2006
965
/* Start the audio thread */
Oct 17, 2006
Oct 17, 2006
966
/* !!! FIXME: this is nasty. */
Jan 24, 2011
Jan 24, 2011
967
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
Feb 6, 2006
Feb 6, 2006
968
#undef SDL_CreateThread
Oct 17, 2006
Oct 17, 2006
969
device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL);
Feb 6, 2006
Feb 6, 2006
970
#else
Oct 17, 2006
Oct 17, 2006
971
device->thread = SDL_CreateThread(SDL_RunAudio, device);
Jul 10, 2006
Jul 10, 2006
972
#endif
Oct 17, 2006
Oct 17, 2006
973
if (device->thread == NULL) {
Oct 28, 2006
Oct 28, 2006
974
SDL_CloseAudioDevice(id + 1);
Jul 10, 2006
Jul 10, 2006
975
SDL_SetError("Couldn't create audio thread");
Oct 17, 2006
Oct 17, 2006
976
977
978
979
return 0;
}
}
Oct 28, 2006
Oct 28, 2006
980
return id + 1;
Oct 17, 2006
Oct 17, 2006
981
982
983
984
}
int
Dec 13, 2008
Dec 13, 2008
985
SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
Oct 17, 2006
Oct 17, 2006
986
987
988
989
990
991
{
SDL_AudioDeviceID id = 0;
/* Start up the audio driver, if necessary. This is legacy behaviour! */
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
Jul 10, 2006
Jul 10, 2006
992
993
return (-1);
}
Oct 17, 2006
Oct 17, 2006
994
}
Jul 10, 2006
Jul 10, 2006
995
Oct 17, 2006
Oct 17, 2006
996
997
998
999
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
if (open_devices[0] != NULL) {
SDL_SetError("Audio device is already opened");
return (-1);
Jul 10, 2006
Jul 10, 2006
1000
}