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