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