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