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 /* Allow access to a raw mixing buffer */
24 
25 #include "SDL.h"
26 #include "SDL_audio.h"
27 #include "SDL_audio_c.h"
28 #include "SDL_sysaudio.h"
29 #include "../thread/SDL_systhread.h"
30 
31 #define _THIS SDL_AudioDevice *_this
32 
33 static SDL_AudioDriver current_audio;
34 static SDL_AudioDevice *open_devices[16];
35 
36 /* Available audio drivers */
37 static const AudioBootStrap *const bootstrap[] = {
38 #if SDL_AUDIO_DRIVER_PULSEAUDIO
39     &PULSEAUDIO_bootstrap,
40 #endif
41 #if SDL_AUDIO_DRIVER_ALSA
42     &ALSA_bootstrap,
43 #endif
44 #if SDL_AUDIO_DRIVER_SNDIO
45     &SNDIO_bootstrap,
46 #endif
47 #if SDL_AUDIO_DRIVER_NETBSD
48     &NETBSDAUDIO_bootstrap,
49 #endif
50 #if SDL_AUDIO_DRIVER_OSS
51     &DSP_bootstrap,
52 #endif
53 #if SDL_AUDIO_DRIVER_QSA
54     &QSAAUDIO_bootstrap,
55 #endif
56 #if SDL_AUDIO_DRIVER_SUNAUDIO
57     &SUNAUDIO_bootstrap,
58 #endif
59 #if SDL_AUDIO_DRIVER_ARTS
60     &ARTS_bootstrap,
61 #endif
62 #if SDL_AUDIO_DRIVER_ESD
63     &ESD_bootstrap,
64 #endif
65 #if SDL_AUDIO_DRIVER_NACL
66     &NACLAUDIO_bootstrap,
67 #endif
68 #if SDL_AUDIO_DRIVER_NAS
69     &NAS_bootstrap,
70 #endif
71 #if SDL_AUDIO_DRIVER_WASAPI
72     &WASAPI_bootstrap,
73 #endif
74 #if SDL_AUDIO_DRIVER_DSOUND
75     &DSOUND_bootstrap,
76 #endif
77 #if SDL_AUDIO_DRIVER_WINMM
78     &WINMM_bootstrap,
79 #endif
80 #if SDL_AUDIO_DRIVER_PAUDIO
81     &PAUDIO_bootstrap,
82 #endif
83 #if SDL_AUDIO_DRIVER_HAIKU
84     &HAIKUAUDIO_bootstrap,
85 #endif
86 #if SDL_AUDIO_DRIVER_COREAUDIO
87     &COREAUDIO_bootstrap,
88 #endif
89 #if SDL_AUDIO_DRIVER_FUSIONSOUND
90     &FUSIONSOUND_bootstrap,
91 #endif
92 #if SDL_AUDIO_DRIVER_ANDROID
93     &ANDROIDAUDIO_bootstrap,
94 #endif
95 #if SDL_AUDIO_DRIVER_PSP
96     &PSPAUDIO_bootstrap,
97 #endif
98 #if SDL_AUDIO_DRIVER_EMSCRIPTEN
99     &EMSCRIPTENAUDIO_bootstrap,
100 #endif
101 #if SDL_AUDIO_DRIVER_JACK
102     &JACK_bootstrap,
103 #endif
104 #if SDL_AUDIO_DRIVER_DISK
105     &DISKAUDIO_bootstrap,
106 #endif
107 #if SDL_AUDIO_DRIVER_DUMMY
108     &DUMMYAUDIO_bootstrap,
109 #endif
110     NULL
111 };
112 
113 
114 #ifdef HAVE_LIBSAMPLERATE_H
115 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
116 static void *SRC_lib = NULL;
117 #endif
118 SDL_bool SRC_available = SDL_FALSE;
119 int SRC_converter = 0;
120 SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error) = NULL;
121 int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data) = NULL;
122 int (*SRC_src_reset)(SRC_STATE *state) = NULL;
123 SRC_STATE* (*SRC_src_delete)(SRC_STATE *state) = NULL;
124 const char* (*SRC_src_strerror)(int error) = NULL;
125 
126 static SDL_bool
LoadLibSampleRate(void)127 LoadLibSampleRate(void)
128 {
129     const char *hint = SDL_GetHint(SDL_HINT_AUDIO_RESAMPLING_MODE);
130 
131     SRC_available = SDL_FALSE;
132     SRC_converter = 0;
133 
134     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "default") == 0) {
135         return SDL_FALSE;  /* don't load anything. */
136     } else if (*hint == '1' || SDL_strcasecmp(hint, "fast") == 0) {
137         SRC_converter = SRC_SINC_FASTEST;
138     } else if (*hint == '2' || SDL_strcasecmp(hint, "medium") == 0) {
139         SRC_converter = SRC_SINC_MEDIUM_QUALITY;
140     } else if (*hint == '3' || SDL_strcasecmp(hint, "best") == 0) {
141         SRC_converter = SRC_SINC_BEST_QUALITY;
142     } else {
143         return SDL_FALSE;  /* treat it like "default", don't load anything. */
144     }
145 
146 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
147     SDL_assert(SRC_lib == NULL);
148     SRC_lib = SDL_LoadObject(SDL_LIBSAMPLERATE_DYNAMIC);
149     if (!SRC_lib) {
150         SDL_ClearError();
151         return SDL_FALSE;
152     }
153 
154     SRC_src_new = (SRC_STATE* (*)(int converter_type, int channels, int *error))SDL_LoadFunction(SRC_lib, "src_new");
155     SRC_src_process = (int (*)(SRC_STATE *state, SRC_DATA *data))SDL_LoadFunction(SRC_lib, "src_process");
156     SRC_src_reset = (int(*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_reset");
157     SRC_src_delete = (SRC_STATE* (*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_delete");
158     SRC_src_strerror = (const char* (*)(int error))SDL_LoadFunction(SRC_lib, "src_strerror");
159 
160     if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror) {
161         SDL_UnloadObject(SRC_lib);
162         SRC_lib = NULL;
163         return SDL_FALSE;
164     }
165 #else
166     SRC_src_new = src_new;
167     SRC_src_process = src_process;
168     SRC_src_reset = src_reset;
169     SRC_src_delete = src_delete;
170     SRC_src_strerror = src_strerror;
171 #endif
172 
173     SRC_available = SDL_TRUE;
174     return SDL_TRUE;
175 }
176 
177 static void
UnloadLibSampleRate(void)178 UnloadLibSampleRate(void)
179 {
180 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
181     if (SRC_lib != NULL) {
182         SDL_UnloadObject(SRC_lib);
183     }
184     SRC_lib = NULL;
185 #endif
186 
187     SRC_available = SDL_FALSE;
188     SRC_src_new = NULL;
189     SRC_src_process = NULL;
190     SRC_src_reset = NULL;
191     SRC_src_delete = NULL;
192     SRC_src_strerror = NULL;
193 }
194 #endif
195 
196 static SDL_AudioDevice *
get_audio_device(SDL_AudioDeviceID id)197 get_audio_device(SDL_AudioDeviceID id)
198 {
199     id--;
200     if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
201         SDL_SetError("Invalid audio device ID");
202         return NULL;
203     }
204 
205     return open_devices[id];
206 }
207 
208 
209 /* stubs for audio drivers that don't need a specific entry point... */
210 static void
SDL_AudioDetectDevices_Default(void)211 SDL_AudioDetectDevices_Default(void)
212 {
213     /* you have to write your own implementation if these assertions fail. */
214     SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
215     SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport);
216 
217     SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
218     if (current_audio.impl.HasCaptureSupport) {
219         SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
220     }
221 }
222 
223 static void
SDL_AudioThreadInit_Default(_THIS)224 SDL_AudioThreadInit_Default(_THIS)
225 {                               /* no-op. */
226 }
227 
228 static void
SDL_AudioThreadDeinit_Default(_THIS)229 SDL_AudioThreadDeinit_Default(_THIS)
230 {                               /* no-op. */
231 }
232 
233 static void
SDL_AudioBeginLoopIteration_Default(_THIS)234 SDL_AudioBeginLoopIteration_Default(_THIS)
235 {                               /* no-op. */
236 }
237 
238 static void
SDL_AudioWaitDevice_Default(_THIS)239 SDL_AudioWaitDevice_Default(_THIS)
240 {                               /* no-op. */
241 }
242 
243 static void
SDL_AudioPlayDevice_Default(_THIS)244 SDL_AudioPlayDevice_Default(_THIS)
245 {                               /* no-op. */
246 }
247 
248 static int
SDL_AudioGetPendingBytes_Default(_THIS)249 SDL_AudioGetPendingBytes_Default(_THIS)
250 {
251     return 0;
252 }
253 
254 static Uint8 *
SDL_AudioGetDeviceBuf_Default(_THIS)255 SDL_AudioGetDeviceBuf_Default(_THIS)
256 {
257     return NULL;
258 }
259 
260 static int
SDL_AudioCaptureFromDevice_Default(_THIS,void * buffer,int buflen)261 SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
262 {
263     return -1;  /* just fail immediately. */
264 }
265 
266 static void
SDL_AudioFlushCapture_Default(_THIS)267 SDL_AudioFlushCapture_Default(_THIS)
268 {                               /* no-op. */
269 }
270 
271 static void
SDL_AudioPrepareToClose_Default(_THIS)272 SDL_AudioPrepareToClose_Default(_THIS)
273 {                               /* no-op. */
274 }
275 
276 static void
SDL_AudioCloseDevice_Default(_THIS)277 SDL_AudioCloseDevice_Default(_THIS)
278 {                               /* no-op. */
279 }
280 
281 static void
SDL_AudioDeinitialize_Default(void)282 SDL_AudioDeinitialize_Default(void)
283 {                               /* no-op. */
284 }
285 
286 static void
SDL_AudioFreeDeviceHandle_Default(void * handle)287 SDL_AudioFreeDeviceHandle_Default(void *handle)
288 {                               /* no-op. */
289 }
290 
291 
292 static int
SDL_AudioOpenDevice_Default(_THIS,void * handle,const char * devname,int iscapture)293 SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
294 {
295     return SDL_Unsupported();
296 }
297 
298 static SDL_INLINE SDL_bool
is_in_audio_device_thread(SDL_AudioDevice * device)299 is_in_audio_device_thread(SDL_AudioDevice * device)
300 {
301     /* The device thread locks the same mutex, but not through the public API.
302        This check is in case the application, in the audio callback,
303        tries to lock the thread that we've already locked from the
304        device thread...just in case we only have non-recursive mutexes. */
305     if (device->thread && (SDL_ThreadID() == device->threadid)) {
306         return SDL_TRUE;
307     }
308 
309     return SDL_FALSE;
310 }
311 
312 static void
SDL_AudioLockDevice_Default(SDL_AudioDevice * device)313 SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
314 {
315     if (!is_in_audio_device_thread(device)) {
316         SDL_LockMutex(device->mixer_lock);
317     }
318 }
319 
320 static void
SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)321 SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
322 {
323     if (!is_in_audio_device_thread(device)) {
324         SDL_UnlockMutex(device->mixer_lock);
325     }
326 }
327 
328 static void
SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)329 SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
330 {
331 }
332 
333 static void
finish_audio_entry_points_init(void)334 finish_audio_entry_points_init(void)
335 {
336     /*
337      * Fill in stub functions for unused driver entry points. This lets us
338      *  blindly call them without having to check for validity first.
339      */
340 
341     if (current_audio.impl.SkipMixerLock) {
342         if (current_audio.impl.LockDevice == NULL) {
343             current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
344         }
345         if (current_audio.impl.UnlockDevice == NULL) {
346             current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
347         }
348     }
349 
350 #define FILL_STUB(x) \
351         if (current_audio.impl.x == NULL) { \
352             current_audio.impl.x = SDL_Audio##x##_Default; \
353         }
354     FILL_STUB(DetectDevices);
355     FILL_STUB(OpenDevice);
356     FILL_STUB(ThreadInit);
357     FILL_STUB(ThreadDeinit);
358     FILL_STUB(BeginLoopIteration);
359     FILL_STUB(WaitDevice);
360     FILL_STUB(PlayDevice);
361     FILL_STUB(GetPendingBytes);
362     FILL_STUB(GetDeviceBuf);
363     FILL_STUB(CaptureFromDevice);
364     FILL_STUB(FlushCapture);
365     FILL_STUB(PrepareToClose);
366     FILL_STUB(CloseDevice);
367     FILL_STUB(LockDevice);
368     FILL_STUB(UnlockDevice);
369     FILL_STUB(FreeDeviceHandle);
370     FILL_STUB(Deinitialize);
371 #undef FILL_STUB
372 }
373 
374 
375 /* device hotplug support... */
376 
377 static int
add_audio_device(const char * name,void * handle,SDL_AudioDeviceItem ** devices,int * devCount)378 add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
379 {
380     int retval = -1;
381     const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
382     SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
383     if (item == NULL) {
384         return -1;
385     }
386 
387     SDL_assert(handle != NULL);  /* we reserve NULL, audio backends can't use it. */
388 
389     item->handle = handle;
390     SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
391 
392     SDL_LockMutex(current_audio.detectionLock);
393     item->next = *devices;
394     *devices = item;
395     retval = (*devCount)++;
396     SDL_UnlockMutex(current_audio.detectionLock);
397 
398     return retval;
399 }
400 
401 static SDL_INLINE int
add_capture_device(const char * name,void * handle)402 add_capture_device(const char *name, void *handle)
403 {
404     SDL_assert(current_audio.impl.HasCaptureSupport);
405     return add_audio_device(name, handle, &current_audio.inputDevices, &current_audio.inputDeviceCount);
406 }
407 
408 static SDL_INLINE int
add_output_device(const char * name,void * handle)409 add_output_device(const char *name, void *handle)
410 {
411     return add_audio_device(name, handle, &current_audio.outputDevices, &current_audio.outputDeviceCount);
412 }
413 
414 static void
free_device_list(SDL_AudioDeviceItem ** devices,int * devCount)415 free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
416 {
417     SDL_AudioDeviceItem *item, *next;
418     for (item = *devices; item != NULL; item = next) {
419         next = item->next;
420         if (item->handle != NULL) {
421             current_audio.impl.FreeDeviceHandle(item->handle);
422         }
423         SDL_free(item);
424     }
425     *devices = NULL;
426     *devCount = 0;
427 }
428 
429 
430 /* The audio backends call this when a new device is plugged in. */
431 void
SDL_AddAudioDevice(const int iscapture,const char * name,void * handle)432 SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
433 {
434     const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
435     if (device_index != -1) {
436         /* Post the event, if desired */
437         if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
438             SDL_Event event;
439             SDL_zero(event);
440             event.adevice.type = SDL_AUDIODEVICEADDED;
441             event.adevice.which = device_index;
442             event.adevice.iscapture = iscapture;
443             SDL_PushEvent(&event);
444         }
445     }
446 }
447 
448 /* The audio backends call this when a currently-opened device is lost. */
SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice * device)449 void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
450 {
451     SDL_assert(get_audio_device(device->id) == device);
452 
453     if (!SDL_AtomicGet(&device->enabled)) {
454         return;
455     }
456 
457     /* Ends the audio callback and mark the device as STOPPED, but the
458        app still needs to close the device to free resources. */
459     current_audio.impl.LockDevice(device);
460     SDL_AtomicSet(&device->enabled, 0);
461     current_audio.impl.UnlockDevice(device);
462 
463     /* Post the event, if desired */
464     if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
465         SDL_Event event;
466         SDL_zero(event);
467         event.adevice.type = SDL_AUDIODEVICEREMOVED;
468         event.adevice.which = device->id;
469         event.adevice.iscapture = device->iscapture ? 1 : 0;
470         SDL_PushEvent(&event);
471     }
472 }
473 
474 static void
mark_device_removed(void * handle,SDL_AudioDeviceItem * devices,SDL_bool * removedFlag)475 mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
476 {
477     SDL_AudioDeviceItem *item;
478     SDL_assert(handle != NULL);
479     for (item = devices; item != NULL; item = item->next) {
480         if (item->handle == handle) {
481             item->handle = NULL;
482             *removedFlag = SDL_TRUE;
483             return;
484         }
485     }
486 }
487 
488 /* The audio backends call this when a device is removed from the system. */
489 void
SDL_RemoveAudioDevice(const int iscapture,void * handle)490 SDL_RemoveAudioDevice(const int iscapture, void *handle)
491 {
492     int device_index;
493     SDL_AudioDevice *device = NULL;
494 
495     SDL_LockMutex(current_audio.detectionLock);
496     if (iscapture) {
497         mark_device_removed(handle, current_audio.inputDevices, &current_audio.captureDevicesRemoved);
498     } else {
499         mark_device_removed(handle, current_audio.outputDevices, &current_audio.outputDevicesRemoved);
500     }
501     for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++)
502     {
503         device = open_devices[device_index];
504         if (device != NULL && device->handle == handle)
505         {
506             SDL_OpenedAudioDeviceDisconnected(device);
507             break;
508         }
509     }
510     SDL_UnlockMutex(current_audio.detectionLock);
511 
512     current_audio.impl.FreeDeviceHandle(handle);
513 }
514 
515 
516 
517 /* buffer queueing support... */
518 
519 static void SDLCALL
SDL_BufferQueueDrainCallback(void * userdata,Uint8 * stream,int len)520 SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
521 {
522     /* this function always holds the mixer lock before being called. */
523     SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
524     size_t dequeued;
525 
526     SDL_assert(device != NULL);  /* this shouldn't ever happen, right?! */
527     SDL_assert(!device->iscapture);  /* this shouldn't ever happen, right?! */
528     SDL_assert(len >= 0);  /* this shouldn't ever happen, right?! */
529 
530     dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len);
531     stream += dequeued;
532     len -= (int) dequeued;
533 
534     if (len > 0) {  /* fill any remaining space in the stream with silence. */
535         SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0);
536         SDL_memset(stream, device->spec.silence, len);
537     }
538 }
539 
540 static void SDLCALL
SDL_BufferQueueFillCallback(void * userdata,Uint8 * stream,int len)541 SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
542 {
543     /* this function always holds the mixer lock before being called. */
544     SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
545 
546     SDL_assert(device != NULL);  /* this shouldn't ever happen, right?! */
547     SDL_assert(device->iscapture);  /* this shouldn't ever happen, right?! */
548     SDL_assert(len >= 0);  /* this shouldn't ever happen, right?! */
549 
550     /* note that if this needs to allocate more space and run out of memory,
551        we have no choice but to quietly drop the data and hope it works out
552        later, but you probably have bigger problems in this case anyhow. */
553     SDL_WriteToDataQueue(device->buffer_queue, stream, len);
554 }
555 
556 int
SDL_QueueAudio(SDL_AudioDeviceID devid,const void * data,Uint32 len)557 SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
558 {
559     SDL_AudioDevice *device = get_audio_device(devid);
560     int rc = 0;
561 
562     if (!device) {
563         return -1;  /* get_audio_device() will have set the error state */
564     } else if (device->iscapture) {
565         return SDL_SetError("This is a capture device, queueing not allowed");
566     } else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) {
567         return SDL_SetError("Audio device has a callback, queueing not allowed");
568     }
569 
570     if (len > 0) {
571         current_audio.impl.LockDevice(device);
572         rc = SDL_WriteToDataQueue(device->buffer_queue, data, len);
573         current_audio.impl.UnlockDevice(device);
574     }
575 
576     return rc;
577 }
578 
579 Uint32
SDL_DequeueAudio(SDL_AudioDeviceID devid,void * data,Uint32 len)580 SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len)
581 {
582     SDL_AudioDevice *device = get_audio_device(devid);
583     Uint32 rc;
584 
585     if ( (len == 0) ||  /* nothing to do? */
586          (!device) ||  /* called with bogus device id */
587          (!device->iscapture) ||  /* playback devices can't dequeue */
588          (device->callbackspec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */
589         return 0;  /* just report zero bytes dequeued. */
590     }
591 
592     current_audio.impl.LockDevice(device);
593     rc = (Uint32) SDL_ReadFromDataQueue(device->buffer_queue, data, len);
594     current_audio.impl.UnlockDevice(device);
595     return rc;
596 }
597 
598 Uint32
SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)599 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
600 {
601     Uint32 retval = 0;
602     SDL_AudioDevice *device = get_audio_device(devid);
603 
604     if (!device) {
605         return 0;
606     }
607 
608     /* Nothing to do unless we're set up for queueing. */
609     if (device->callbackspec.callback == SDL_BufferQueueDrainCallback) {
610         current_audio.impl.LockDevice(device);
611         retval = ((Uint32) SDL_CountDataQueue(device->buffer_queue)) + current_audio.impl.GetPendingBytes(device);
612         current_audio.impl.UnlockDevice(device);
613     } else if (device->callbackspec.callback == SDL_BufferQueueFillCallback) {
614         current_audio.impl.LockDevice(device);
615         retval = (Uint32) SDL_CountDataQueue(device->buffer_queue);
616         current_audio.impl.UnlockDevice(device);
617     }
618 
619     return retval;
620 }
621 
622 void
SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)623 SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
624 {
625     SDL_AudioDevice *device = get_audio_device(devid);
626 
627     if (!device) {
628         return;  /* nothing to do. */
629     }
630 
631     /* Blank out the device and release the mutex. Free it afterwards. */
632     current_audio.impl.LockDevice(device);
633 
634     /* Keep up to two packets in the pool to reduce future malloc pressure. */
635     SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2);
636 
637     current_audio.impl.UnlockDevice(device);
638 }
639 
640 
641 /* The general mixing thread function */
642 static int SDLCALL
SDL_RunAudio(void * devicep)643 SDL_RunAudio(void *devicep)
644 {
645     SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
646     void *udata = device->callbackspec.userdata;
647     SDL_AudioCallback callback = device->callbackspec.callback;
648     int data_len = 0;
649     Uint8 *data;
650 
651     SDL_assert(!device->iscapture);
652 
653     /* The audio mixing is always a high priority thread */
654     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
655 
656     /* Perform any thread setup */
657     device->threadid = SDL_ThreadID();
658     current_audio.impl.ThreadInit(device);
659 
660     /* Loop, filling the audio buffers */
661     while (!SDL_AtomicGet(&device->shutdown)) {
662         current_audio.impl.BeginLoopIteration(device);
663         data_len = device->callbackspec.size;
664 
665         /* Fill the current buffer with sound */
666         if (!device->stream && SDL_AtomicGet(&device->enabled)) {
667             SDL_assert(data_len == device->spec.size);
668             data = current_audio.impl.GetDeviceBuf(device);
669         } else {
670             /* if the device isn't enabled, we still write to the
671                work_buffer, so the app's callback will fire with
672                a regular frequency, in case they depend on that
673                for timing or progress. They can use hotplug
674                now to know if the device failed.
675                Streaming playback uses work_buffer, too. */
676             data = NULL;
677         }
678 
679         if (data == NULL) {
680             data = device->work_buffer;
681         }
682 
683         /* !!! FIXME: this should be LockDevice. */
684         SDL_LockMutex(device->mixer_lock);
685         if (SDL_AtomicGet(&device->paused)) {
686             SDL_memset(data, device->spec.silence, data_len);
687         } else {
688             callback(udata, data, data_len);
689         }
690         SDL_UnlockMutex(device->mixer_lock);
691 
692         if (device->stream) {
693             /* Stream available audio to device, converting/resampling. */
694             /* if this fails...oh well. We'll play silence here. */
695             SDL_AudioStreamPut(device->stream, data, data_len);
696 
697             while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) {
698                 int got;
699                 data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL;
700                 got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size);
701                 SDL_assert((got < 0) || (got == device->spec.size));
702 
703                 if (data == NULL) {  /* device is having issues... */
704                     const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
705                     SDL_Delay(delay);  /* wait for as long as this buffer would have played. Maybe device recovers later? */
706                 } else {
707                     if (got != device->spec.size) {
708                         SDL_memset(data, device->spec.silence, device->spec.size);
709                     }
710                     current_audio.impl.PlayDevice(device);
711                     current_audio.impl.WaitDevice(device);
712                 }
713             }
714         } else if (data == device->work_buffer) {
715             /* nothing to do; pause like we queued a buffer to play. */
716             const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
717             SDL_Delay(delay);
718         } else {  /* writing directly to the device. */
719             /* queue this buffer and wait for it to finish playing. */
720             current_audio.impl.PlayDevice(device);
721             current_audio.impl.WaitDevice(device);
722         }
723     }
724 
725     current_audio.impl.PrepareToClose(device);
726 
727     /* Wait for the audio to drain. */
728     SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
729 
730     current_audio.impl.ThreadDeinit(device);
731 
732     return 0;
733 }
734 
735 /* !!! FIXME: this needs to deal with device spec changes. */
736 /* The general capture thread function */
737 static int SDLCALL
SDL_CaptureAudio(void * devicep)738 SDL_CaptureAudio(void *devicep)
739 {
740     SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
741     const int silence = (int) device->spec.silence;
742     const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
743     const int data_len = device->spec.size;
744     Uint8 *data;
745     void *udata = device->callbackspec.userdata;
746     SDL_AudioCallback callback = device->callbackspec.callback;
747 
748     SDL_assert(device->iscapture);
749 
750     /* The audio mixing is always a high priority thread */
751     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
752 
753     /* Perform any thread setup */
754     device->threadid = SDL_ThreadID();
755     current_audio.impl.ThreadInit(device);
756 
757     /* Loop, filling the audio buffers */
758     while (!SDL_AtomicGet(&device->shutdown)) {
759         int still_need;
760         Uint8 *ptr;
761 
762         current_audio.impl.BeginLoopIteration(device);
763 
764         if (SDL_AtomicGet(&device->paused)) {
765             SDL_Delay(delay);  /* just so we don't cook the CPU. */
766             if (device->stream) {
767                 SDL_AudioStreamClear(device->stream);
768             }
769             current_audio.impl.FlushCapture(device);  /* dump anything pending. */
770             continue;
771         }
772 
773         /* Fill the current buffer with sound */
774         still_need = data_len;
775 
776         /* Use the work_buffer to hold data read from the device. */
777         data = device->work_buffer;
778         SDL_assert(data != NULL);
779 
780         ptr = data;
781 
782         /* We still read from the device when "paused" to keep the state sane,
783            and block when there isn't data so this thread isn't eating CPU.
784            But we don't process it further or call the app's callback. */
785 
786         if (!SDL_AtomicGet(&device->enabled)) {
787             SDL_Delay(delay);  /* try to keep callback firing at normal pace. */
788         } else {
789             while (still_need > 0) {
790                 const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
791                 SDL_assert(rc <= still_need);  /* device should not overflow buffer. :) */
792                 if (rc > 0) {
793                     still_need -= rc;
794                     ptr += rc;
795                 } else {  /* uhoh, device failed for some reason! */
796                     SDL_OpenedAudioDeviceDisconnected(device);
797                     break;
798                 }
799             }
800         }
801 
802         if (still_need > 0) {
803             /* Keep any data we already read, silence the rest. */
804             SDL_memset(ptr, silence, still_need);
805         }
806 
807         if (device->stream) {
808             /* if this fails...oh well. */
809             SDL_AudioStreamPut(device->stream, data, data_len);
810 
811             while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) {
812                 const int got = SDL_AudioStreamGet(device->stream, device->work_buffer, device->callbackspec.size);
813                 SDL_assert((got < 0) || (got == device->callbackspec.size));
814                 if (got != device->callbackspec.size) {
815                     SDL_memset(device->work_buffer, device->spec.silence, device->callbackspec.size);
816                 }
817 
818                 /* !!! FIXME: this should be LockDevice. */
819                 SDL_LockMutex(device->mixer_lock);
820                 if (!SDL_AtomicGet(&device->paused)) {
821                     callback(udata, device->work_buffer, device->callbackspec.size);
822                 }
823                 SDL_UnlockMutex(device->mixer_lock);
824             }
825         } else {  /* feeding user callback directly without streaming. */
826             /* !!! FIXME: this should be LockDevice. */
827             SDL_LockMutex(device->mixer_lock);
828             if (!SDL_AtomicGet(&device->paused)) {
829                 callback(udata, data, device->callbackspec.size);
830             }
831             SDL_UnlockMutex(device->mixer_lock);
832         }
833     }
834 
835     current_audio.impl.FlushCapture(device);
836 
837     current_audio.impl.ThreadDeinit(device);
838 
839     return 0;
840 }
841 
842 
843 static SDL_AudioFormat
SDL_ParseAudioFormat(const char * string)844 SDL_ParseAudioFormat(const char *string)
845 {
846 #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
847     CHECK_FMT_STRING(U8);
848     CHECK_FMT_STRING(S8);
849     CHECK_FMT_STRING(U16LSB);
850     CHECK_FMT_STRING(S16LSB);
851     CHECK_FMT_STRING(U16MSB);
852     CHECK_FMT_STRING(S16MSB);
853     CHECK_FMT_STRING(U16SYS);
854     CHECK_FMT_STRING(S16SYS);
855     CHECK_FMT_STRING(U16);
856     CHECK_FMT_STRING(S16);
857     CHECK_FMT_STRING(S32LSB);
858     CHECK_FMT_STRING(S32MSB);
859     CHECK_FMT_STRING(S32SYS);
860     CHECK_FMT_STRING(S32);
861     CHECK_FMT_STRING(F32LSB);
862     CHECK_FMT_STRING(F32MSB);
863     CHECK_FMT_STRING(F32SYS);
864     CHECK_FMT_STRING(F32);
865 #undef CHECK_FMT_STRING
866     return 0;
867 }
868 
869 int
SDL_GetNumAudioDrivers(void)870 SDL_GetNumAudioDrivers(void)
871 {
872     return SDL_arraysize(bootstrap) - 1;
873 }
874 
875 const char *
SDL_GetAudioDriver(int index)876 SDL_GetAudioDriver(int index)
877 {
878     if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
879         return bootstrap[index]->name;
880     }
881     return NULL;
882 }
883 
884 int
SDL_AudioInit(const char * driver_name)885 SDL_AudioInit(const char *driver_name)
886 {
887     int i = 0;
888     int initialized = 0;
889     int tried_to_init = 0;
890 
891     if (SDL_WasInit(SDL_INIT_AUDIO)) {
892         SDL_AudioQuit();        /* shutdown driver if already running. */
893     }
894 
895     SDL_zero(current_audio);
896     SDL_zero(open_devices);
897 
898     /* Select the proper audio driver */
899     if (driver_name == NULL) {
900         driver_name = SDL_getenv("SDL_AUDIODRIVER");
901     }
902 
903     for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
904         /* make sure we should even try this driver before doing so... */
905         const AudioBootStrap *backend = bootstrap[i];
906         if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
907             (!driver_name && backend->demand_only)) {
908             continue;
909         }
910 
911         tried_to_init = 1;
912         SDL_zero(current_audio);
913         current_audio.name = backend->name;
914         current_audio.desc = backend->desc;
915         initialized = backend->init(&current_audio.impl);
916     }
917 
918     if (!initialized) {
919         /* specific drivers will set the error message if they fail... */
920         if (!tried_to_init) {
921             if (driver_name) {
922                 SDL_SetError("Audio target '%s' not available", driver_name);
923             } else {
924                 SDL_SetError("No available audio device");
925             }
926         }
927 
928         SDL_zero(current_audio);
929         return -1;            /* No driver was available, so fail. */
930     }
931 
932     current_audio.detectionLock = SDL_CreateMutex();
933 
934     finish_audio_entry_points_init();
935 
936     /* Make sure we have a list of devices available at startup. */
937     current_audio.impl.DetectDevices();
938 
939 #ifdef HAVE_LIBSAMPLERATE_H
940     LoadLibSampleRate();
941 #endif
942 
943     return 0;
944 }
945 
946 /*
947  * Get the current audio driver name
948  */
949 const char *
SDL_GetCurrentAudioDriver()950 SDL_GetCurrentAudioDriver()
951 {
952     return current_audio.name;
953 }
954 
955 /* Clean out devices that we've removed but had to keep around for stability. */
956 static void
clean_out_device_list(SDL_AudioDeviceItem ** devices,int * devCount,SDL_bool * removedFlag)957 clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
958 {
959     SDL_AudioDeviceItem *item = *devices;
960     SDL_AudioDeviceItem *prev = NULL;
961     int total = 0;
962 
963     while (item) {
964         SDL_AudioDeviceItem *next = item->next;
965         if (item->handle != NULL) {
966             total++;
967             prev = item;
968         } else {
969             if (prev) {
970                 prev->next = next;
971             } else {
972                 *devices = next;
973             }
974             SDL_free(item);
975         }
976         item = next;
977     }
978 
979     *devCount = total;
980     *removedFlag = SDL_FALSE;
981 }
982 
983 
984 int
SDL_GetNumAudioDevices(int iscapture)985 SDL_GetNumAudioDevices(int iscapture)
986 {
987     int retval = 0;
988 
989     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
990         return -1;
991     }
992 
993     SDL_LockMutex(current_audio.detectionLock);
994     if (iscapture && current_audio.captureDevicesRemoved) {
995         clean_out_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount, &current_audio.captureDevicesRemoved);
996     }
997 
998     if (!iscapture && current_audio.outputDevicesRemoved) {
999         clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
1000         current_audio.outputDevicesRemoved = SDL_FALSE;
1001     }
1002 
1003     retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
1004     SDL_UnlockMutex(current_audio.detectionLock);
1005 
1006     return retval;
1007 }
1008 
1009 
1010 const char *
SDL_GetAudioDeviceName(int index,int iscapture)1011 SDL_GetAudioDeviceName(int index, int iscapture)
1012 {
1013     const char *retval = NULL;
1014 
1015     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
1016         SDL_SetError("Audio subsystem is not initialized");
1017         return NULL;
1018     }
1019 
1020     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
1021         SDL_SetError("No capture support");
1022         return NULL;
1023     }
1024 
1025     if (index >= 0) {
1026         SDL_AudioDeviceItem *item;
1027         int i;
1028 
1029         SDL_LockMutex(current_audio.detectionLock);
1030         item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
1031         i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
1032         if (index < i) {
1033             for (i--; i > index; i--, item = item->next) {
1034                 SDL_assert(item != NULL);
1035             }
1036             SDL_assert(item != NULL);
1037             retval = item->name;
1038         }
1039         SDL_UnlockMutex(current_audio.detectionLock);
1040     }
1041 
1042     if (retval == NULL) {
1043         SDL_SetError("No such device");
1044     }
1045 
1046     return retval;
1047 }
1048 
1049 
1050 static void
close_audio_device(SDL_AudioDevice * device)1051 close_audio_device(SDL_AudioDevice * device)
1052 {
1053     if (!device) {
1054         return;
1055     }
1056 
1057     if (device->id > 0) {
1058         SDL_AudioDevice *opendev = open_devices[device->id - 1];
1059         SDL_assert((opendev == device) || (opendev == NULL));
1060         if (opendev == device) {
1061             open_devices[device->id - 1] = NULL;
1062         }
1063     }
1064 
1065     SDL_AtomicSet(&device->shutdown, 1);
1066     SDL_AtomicSet(&device->enabled, 0);
1067     if (device->thread != NULL) {
1068         SDL_WaitThread(device->thread, NULL);
1069     }
1070     if (device->mixer_lock != NULL) {
1071         SDL_DestroyMutex(device->mixer_lock);
1072     }
1073 
1074     SDL_free(device->work_buffer);
1075     SDL_FreeAudioStream(device->stream);
1076 
1077     if (device->hidden != NULL) {
1078         current_audio.impl.CloseDevice(device);
1079     }
1080 
1081     SDL_FreeDataQueue(device->buffer_queue);
1082 
1083     SDL_free(device);
1084 }
1085 
1086 
1087 /*
1088  * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
1089  *  Fills in a sanitized copy in (prepared).
1090  *  Returns non-zero if okay, zero on fatal parameters in (orig).
1091  */
1092 static int
prepare_audiospec(const SDL_AudioSpec * orig,SDL_AudioSpec * prepared)1093 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
1094 {
1095     SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
1096 
1097     if (orig->freq == 0) {
1098         const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
1099         if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
1100             prepared->freq = 22050;     /* a reasonable default */
1101         }
1102     }
1103 
1104     if (orig->format == 0) {
1105         const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
1106         if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
1107             prepared->format = AUDIO_S16;       /* a reasonable default */
1108         }
1109     }
1110 
1111     switch (orig->channels) {
1112     case 0:{
1113             const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
1114             if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
1115                 prepared->channels = 2; /* a reasonable default */
1116             }
1117             break;
1118         }
1119     case 1:                    /* Mono */
1120     case 2:                    /* Stereo */
1121     case 4:                    /* surround */
1122     case 6:                    /* surround with center and lfe */
1123         break;
1124     default:
1125         SDL_SetError("Unsupported number of audio channels.");
1126         return 0;
1127     }
1128 
1129     if (orig->samples == 0) {
1130         const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
1131         if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
1132             /* Pick a default of ~46 ms at desired frequency */
1133             /* !!! FIXME: remove this when the non-Po2 resampling is in. */
1134             const int samples = (prepared->freq / 1000) * 46;
1135             int power2 = 1;
1136             while (power2 < samples) {
1137                 power2 *= 2;
1138             }
1139             prepared->samples = power2;
1140         }
1141     }
1142 
1143     /* Calculate the silence and size of the audio specification */
1144     SDL_CalculateAudioSpec(prepared);
1145 
1146     return 1;
1147 }
1148 
1149 static SDL_AudioDeviceID
open_audio_device(const char * devname,int iscapture,const SDL_AudioSpec * desired,SDL_AudioSpec * obtained,int allowed_changes,int min_id)1150 open_audio_device(const char *devname, int iscapture,
1151                   const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
1152                   int allowed_changes, int min_id)
1153 {
1154     const SDL_bool is_internal_thread = (desired->callback == NULL);
1155     SDL_AudioDeviceID id = 0;
1156     SDL_AudioSpec _obtained;
1157     SDL_AudioDevice *device;
1158     SDL_bool build_stream;
1159     void *handle = NULL;
1160     int i = 0;
1161 
1162     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
1163         SDL_SetError("Audio subsystem is not initialized");
1164         return 0;
1165     }
1166 
1167     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
1168         SDL_SetError("No capture support");
1169         return 0;
1170     }
1171 
1172     /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */
1173     /* Find an available device ID... */
1174     for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
1175         if (open_devices[id] == NULL) {
1176             break;
1177         }
1178     }
1179 
1180     if (id == SDL_arraysize(open_devices)) {
1181         SDL_SetError("Too many open audio devices");
1182         return 0;
1183     }
1184 
1185     if (!obtained) {
1186         obtained = &_obtained;
1187     }
1188     if (!prepare_audiospec(desired, obtained)) {
1189         return 0;
1190     }
1191 
1192     /* If app doesn't care about a specific device, let the user override. */
1193     if (devname == NULL) {
1194         devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
1195     }
1196 
1197     /*
1198      * Catch device names at the high level for the simple case...
1199      * This lets us have a basic "device enumeration" for systems that
1200      *  don't have multiple devices, but makes sure the device name is
1201      *  always NULL when it hits the low level.
1202      *
1203      * Also make sure that the simple case prevents multiple simultaneous
1204      *  opens of the default system device.
1205      */
1206 
1207     if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
1208         if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
1209             SDL_SetError("No such device");
1210             return 0;
1211         }
1212         devname = NULL;
1213 
1214         for (i = 0; i < SDL_arraysize(open_devices); i++) {
1215             if ((open_devices[i]) && (open_devices[i]->iscapture)) {
1216                 SDL_SetError("Audio device already open");
1217                 return 0;
1218             }
1219         }
1220     } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
1221         if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
1222             SDL_SetError("No such device");
1223             return 0;
1224         }
1225         devname = NULL;
1226 
1227         for (i = 0; i < SDL_arraysize(open_devices); i++) {
1228             if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
1229                 SDL_SetError("Audio device already open");
1230                 return 0;
1231             }
1232         }
1233     } else if (devname != NULL) {
1234         /* if the app specifies an exact string, we can pass the backend
1235            an actual device handle thingey, which saves them the effort of
1236            figuring out what device this was (such as, reenumerating
1237            everything again to find the matching human-readable name).
1238            It might still need to open a device based on the string for,
1239            say, a network audio server, but this optimizes some cases. */
1240         SDL_AudioDeviceItem *item;
1241         SDL_LockMutex(current_audio.detectionLock);
1242         for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
1243             if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
1244                 handle = item->handle;
1245                 break;
1246             }
1247         }
1248         SDL_UnlockMutex(current_audio.detectionLock);
1249     }
1250 
1251     if (!current_audio.impl.AllowsArbitraryDeviceNames) {
1252         /* has to be in our device list, or the default device. */
1253         if ((handle == NULL) && (devname != NULL)) {
1254             SDL_SetError("No such device.");
1255             return 0;
1256         }
1257     }
1258 
1259     device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice));
1260     if (device == NULL) {
1261         SDL_OutOfMemory();
1262         return 0;
1263     }
1264     device->id = id + 1;
1265     device->spec = *obtained;
1266     device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
1267     device->handle = handle;
1268 
1269     SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
1270     SDL_AtomicSet(&device->paused, 1);
1271     SDL_AtomicSet(&device->enabled, 1);
1272 
1273     /* Create a mutex for locking the sound buffers */
1274     if (!current_audio.impl.SkipMixerLock) {
1275         device->mixer_lock = SDL_CreateMutex();
1276         if (device->mixer_lock == NULL) {
1277             close_audio_device(device);
1278             SDL_SetError("Couldn't create mixer lock");
1279             return 0;
1280         }
1281     }
1282 
1283     if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
1284         close_audio_device(device);
1285         return 0;
1286     }
1287 
1288     /* if your target really doesn't need it, set it to 0x1 or something. */
1289     /* otherwise, close_audio_device() won't call impl.CloseDevice(). */
1290     SDL_assert(device->hidden != NULL);
1291 
1292     /* See if we need to do any conversion */
1293     build_stream = SDL_FALSE;
1294     if (obtained->freq != device->spec.freq) {
1295         if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
1296             obtained->freq = device->spec.freq;
1297         } else {
1298             build_stream = SDL_TRUE;
1299         }
1300     }
1301     if (obtained->format != device->spec.format) {
1302         if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
1303             obtained->format = device->spec.format;
1304         } else {
1305             build_stream = SDL_TRUE;
1306         }
1307     }
1308     if (obtained->channels != device->spec.channels) {
1309         if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
1310             obtained->channels = device->spec.channels;
1311         } else {
1312             build_stream = SDL_TRUE;
1313         }
1314     }
1315 
1316     /* !!! FIXME in 2.1: add SDL_AUDIO_ALLOW_SAMPLES_CHANGE flag?
1317        As of 2.0.6, we will build a stream to buffer the difference between
1318        what the app wants to feed and the device wants to eat, so everyone
1319        gets their way. In prior releases, SDL would force the callback to
1320        feed at the rate the device requested, adjusted for resampling.
1321      */
1322     if (device->spec.samples != obtained->samples) {
1323         build_stream = SDL_TRUE;
1324     }
1325 
1326     SDL_CalculateAudioSpec(obtained);  /* recalc after possible changes. */
1327 
1328     device->callbackspec = *obtained;
1329 
1330     if (build_stream) {
1331         if (iscapture) {
1332             device->stream = SDL_NewAudioStream(device->spec.format,
1333                                   device->spec.channels, device->spec.freq,
1334                                   obtained->format, obtained->channels, obtained->freq);
1335         } else {
1336             device->stream = SDL_NewAudioStream(obtained->format, obtained->channels,
1337                                   obtained->freq, device->spec.format,
1338                                   device->spec.channels, device->spec.freq);
1339         }
1340 
1341         if (!device->stream) {
1342             close_audio_device(device);
1343             return 0;
1344         }
1345     }
1346 
1347     if (device->spec.callback == NULL) {  /* use buffer queueing? */
1348         /* pool a few packets to start. Enough for two callbacks. */
1349         device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2);
1350         if (!device->buffer_queue) {
1351             close_audio_device(device);
1352             SDL_SetError("Couldn't create audio buffer queue");
1353             return 0;
1354         }
1355         device->callbackspec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback;
1356         device->callbackspec.userdata = device;
1357     }
1358 
1359     /* Allocate a scratch audio buffer */
1360     device->work_buffer_len = build_stream ? device->callbackspec.size : 0;
1361     if (device->spec.size > device->work_buffer_len) {
1362         device->work_buffer_len = device->spec.size;
1363     }
1364     SDL_assert(device->work_buffer_len > 0);
1365 
1366     device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len);
1367     if (device->work_buffer == NULL) {
1368         close_audio_device(device);
1369         SDL_OutOfMemory();
1370         return 0;
1371     }
1372 
1373     open_devices[id] = device;  /* add it to our list of open devices. */
1374 
1375     /* Start the audio thread if necessary */
1376     if (!current_audio.impl.ProvidesOwnCallbackThread) {
1377         /* Start the audio thread */
1378         /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */
1379         /* buffer queueing callback only needs a few bytes, so make the stack tiny. */
1380         const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
1381         char threadname[64];
1382 
1383         SDL_snprintf(threadname, sizeof (threadname), "SDLAudio%c%d", (iscapture) ? 'C' : 'P', (int) device->id);
1384         device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device);
1385 
1386         if (device->thread == NULL) {
1387             close_audio_device(device);
1388             SDL_SetError("Couldn't create audio thread");
1389             return 0;
1390         }
1391     }
1392 
1393     return device->id;
1394 }
1395 
1396 
1397 int
SDL_OpenAudio(SDL_AudioSpec * desired,SDL_AudioSpec * obtained)1398 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
1399 {
1400     SDL_AudioDeviceID id = 0;
1401 
1402     /* Start up the audio driver, if necessary. This is legacy behaviour! */
1403     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
1404         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
1405             return -1;
1406         }
1407     }
1408 
1409     /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
1410     if (open_devices[0] != NULL) {
1411         SDL_SetError("Audio device is already opened");
1412         return -1;
1413     }
1414 
1415     if (obtained) {
1416         id = open_audio_device(NULL, 0, desired, obtained,
1417                                SDL_AUDIO_ALLOW_ANY_CHANGE, 1);
1418     } else {
1419         SDL_AudioSpec _obtained;
1420         SDL_zero(_obtained);
1421         id = open_audio_device(NULL, 0, desired, &_obtained, 0, 1);
1422         /* On successful open, copy calculated values into 'desired'. */
1423         if (id > 0) {
1424             desired->size = _obtained.size;
1425             desired->silence = _obtained.silence;
1426         }
1427     }
1428 
1429     SDL_assert((id == 0) || (id == 1));
1430     return (id == 0) ? -1 : 0;
1431 }
1432 
1433 SDL_AudioDeviceID
SDL_OpenAudioDevice(const char * device,int iscapture,const SDL_AudioSpec * desired,SDL_AudioSpec * obtained,int allowed_changes)1434 SDL_OpenAudioDevice(const char *device, int iscapture,
1435                     const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
1436                     int allowed_changes)
1437 {
1438     return open_audio_device(device, iscapture, desired, obtained,
1439                              allowed_changes, 2);
1440 }
1441 
1442 SDL_AudioStatus
SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)1443 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
1444 {
1445     SDL_AudioDevice *device = get_audio_device(devid);
1446     SDL_AudioStatus status = SDL_AUDIO_STOPPED;
1447     if (device && SDL_AtomicGet(&device->enabled)) {
1448         if (SDL_AtomicGet(&device->paused)) {
1449             status = SDL_AUDIO_PAUSED;
1450         } else {
1451             status = SDL_AUDIO_PLAYING;
1452         }
1453     }
1454     return status;
1455 }
1456 
1457 
1458 SDL_AudioStatus
SDL_GetAudioStatus(void)1459 SDL_GetAudioStatus(void)
1460 {
1461     return SDL_GetAudioDeviceStatus(1);
1462 }
1463 
1464 void
SDL_PauseAudioDevice(SDL_AudioDeviceID devid,int pause_on)1465 SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
1466 {
1467     SDL_AudioDevice *device = get_audio_device(devid);
1468     if (device) {
1469         current_audio.impl.LockDevice(device);
1470         SDL_AtomicSet(&device->paused, pause_on ? 1 : 0);
1471         current_audio.impl.UnlockDevice(device);
1472     }
1473 }
1474 
1475 void
SDL_PauseAudio(int pause_on)1476 SDL_PauseAudio(int pause_on)
1477 {
1478     SDL_PauseAudioDevice(1, pause_on);
1479 }
1480 
1481 
1482 void
SDL_LockAudioDevice(SDL_AudioDeviceID devid)1483 SDL_LockAudioDevice(SDL_AudioDeviceID devid)
1484 {
1485     /* Obtain a lock on the mixing buffers */
1486     SDL_AudioDevice *device = get_audio_device(devid);
1487     if (device) {
1488         current_audio.impl.LockDevice(device);
1489     }
1490 }
1491 
1492 void
SDL_LockAudio(void)1493 SDL_LockAudio(void)
1494 {
1495     SDL_LockAudioDevice(1);
1496 }
1497 
1498 void
SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)1499 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
1500 {
1501     /* Obtain a lock on the mixing buffers */
1502     SDL_AudioDevice *device = get_audio_device(devid);
1503     if (device) {
1504         current_audio.impl.UnlockDevice(device);
1505     }
1506 }
1507 
1508 void
SDL_UnlockAudio(void)1509 SDL_UnlockAudio(void)
1510 {
1511     SDL_UnlockAudioDevice(1);
1512 }
1513 
1514 void
SDL_CloseAudioDevice(SDL_AudioDeviceID devid)1515 SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
1516 {
1517     close_audio_device(get_audio_device(devid));
1518 }
1519 
1520 void
SDL_CloseAudio(void)1521 SDL_CloseAudio(void)
1522 {
1523     SDL_CloseAudioDevice(1);
1524 }
1525 
1526 void
SDL_AudioQuit(void)1527 SDL_AudioQuit(void)
1528 {
1529     SDL_AudioDeviceID i;
1530 
1531     if (!current_audio.name) {  /* not initialized?! */
1532         return;
1533     }
1534 
1535     for (i = 0; i < SDL_arraysize(open_devices); i++) {
1536         close_audio_device(open_devices[i]);
1537     }
1538 
1539     free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
1540     free_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount);
1541 
1542     /* Free the driver data */
1543     current_audio.impl.Deinitialize();
1544 
1545     SDL_DestroyMutex(current_audio.detectionLock);
1546 
1547     SDL_zero(current_audio);
1548     SDL_zero(open_devices);
1549 
1550 #ifdef HAVE_LIBSAMPLERATE_H
1551     UnloadLibSampleRate();
1552 #endif
1553 
1554     SDL_FreeResampleFilter();
1555 }
1556 
1557 #define NUM_FORMATS 10
1558 static int format_idx;
1559 static int format_idx_sub;
1560 static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
1561     {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
1562      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
1563     {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
1564      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
1565     {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
1566      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
1567     {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
1568      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
1569     {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
1570      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
1571     {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
1572      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
1573     {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB,
1574      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
1575     {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB,
1576      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
1577     {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB,
1578      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
1579     {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB,
1580      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
1581 };
1582 
1583 SDL_AudioFormat
SDL_FirstAudioFormat(SDL_AudioFormat format)1584 SDL_FirstAudioFormat(SDL_AudioFormat format)
1585 {
1586     for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
1587         if (format_list[format_idx][0] == format) {
1588             break;
1589         }
1590     }
1591     format_idx_sub = 0;
1592     return SDL_NextAudioFormat();
1593 }
1594 
1595 SDL_AudioFormat
SDL_NextAudioFormat(void)1596 SDL_NextAudioFormat(void)
1597 {
1598     if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
1599         return 0;
1600     }
1601     return format_list[format_idx][format_idx_sub++];
1602 }
1603 
1604 void
SDL_CalculateAudioSpec(SDL_AudioSpec * spec)1605 SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
1606 {
1607     switch (spec->format) {
1608     case AUDIO_U8:
1609         spec->silence = 0x80;
1610         break;
1611     default:
1612         spec->silence = 0x00;
1613         break;
1614     }
1615     spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
1616     spec->size *= spec->channels;
1617     spec->size *= spec->samples;
1618 }
1619 
1620 
1621 /*
1622  * Moved here from SDL_mixer.c, since it relies on internals of an opened
1623  *  audio device (and is deprecated, by the way!).
1624  */
1625 void
SDL_MixAudio(Uint8 * dst,const Uint8 * src,Uint32 len,int volume)1626 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
1627 {
1628     /* Mix the user-level audio format */
1629     SDL_AudioDevice *device = get_audio_device(1);
1630     if (device != NULL) {
1631         SDL_MixAudioFormat(dst, src, device->callbackspec.format, len, volume);
1632     }
1633 }
1634 
1635 /* vi: set ts=4 sw=4 expandtab: */
1636