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