sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_audio.c (52469B)


      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_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: */