src/audio/SDL_audio.c
author Ryan C. Gordon
Mon, 16 Mar 2015 02:11:39 -0400
changeset 9393 ed79a66e57e5
parent 9392 92e23eff9b89
child 9394 bb28e5281770
permissions -rw-r--r--
Initial work on audio device hotplug support.

This fills in the core pieces and fully implements it for Mac OS X.

Most other platforms, at the moment, will report a disconnected device if
it fails to write audio, but don't notice if the system's device list changed
at all.
     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(int iscapture, SDL_AddAudioDevice addfn)
   165 {                               /* no-op. */
   166 }
   167 
   168 static void
   169 SDL_AudioThreadInit_Default(_THIS)
   170 {                               /* no-op. */
   171 }
   172 
   173 static void
   174 SDL_AudioWaitDevice_Default(_THIS)
   175 {                               /* no-op. */
   176 }
   177 
   178 static void
   179 SDL_AudioPlayDevice_Default(_THIS)
   180 {                               /* no-op. */
   181 }
   182 
   183 static int
   184 SDL_AudioGetPendingBytes_Default(_THIS)
   185 {
   186     return 0;
   187 }
   188 
   189 static Uint8 *
   190 SDL_AudioGetDeviceBuf_Default(_THIS)
   191 {
   192     return NULL;
   193 }
   194 
   195 static void
   196 SDL_AudioWaitDone_Default(_THIS)
   197 {                               /* no-op. */
   198 }
   199 
   200 static void
   201 SDL_AudioCloseDevice_Default(_THIS)
   202 {                               /* no-op. */
   203 }
   204 
   205 static void
   206 SDL_AudioDeinitialize_Default(void)
   207 {                               /* no-op. */
   208 }
   209 
   210 static int
   211 SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
   212 {
   213     return -1;
   214 }
   215 
   216 static SDL_INLINE SDL_bool
   217 is_in_audio_device_thread(SDL_AudioDevice * device)
   218 {
   219     /* The device thread locks the same mutex, but not through the public API.
   220        This check is in case the application, in the audio callback,
   221        tries to lock the thread that we've already locked from the
   222        device thread...just in case we only have non-recursive mutexes. */
   223     if (device->thread && (SDL_ThreadID() == device->threadid)) {
   224         return SDL_TRUE;
   225     }
   226 
   227     return SDL_FALSE;
   228 }
   229 
   230 static void
   231 SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
   232 {
   233     if (!is_in_audio_device_thread(device)) {
   234         SDL_LockMutex(device->mixer_lock);
   235     }
   236 }
   237 
   238 static void
   239 SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
   240 {
   241     if (!is_in_audio_device_thread(device)) {
   242         SDL_UnlockMutex(device->mixer_lock);
   243     }
   244 }
   245 
   246 
   247 static void
   248 finalize_audio_entry_points(void)
   249 {
   250     /*
   251      * Fill in stub functions for unused driver entry points. This lets us
   252      *  blindly call them without having to check for validity first.
   253      */
   254 
   255 #define FILL_STUB(x) \
   256         if (current_audio.impl.x == NULL) { \
   257             current_audio.impl.x = SDL_Audio##x##_Default; \
   258         }
   259     FILL_STUB(DetectDevices);
   260     FILL_STUB(OpenDevice);
   261     FILL_STUB(ThreadInit);
   262     FILL_STUB(WaitDevice);
   263     FILL_STUB(PlayDevice);
   264     FILL_STUB(GetPendingBytes);
   265     FILL_STUB(GetDeviceBuf);
   266     FILL_STUB(WaitDone);
   267     FILL_STUB(CloseDevice);
   268     FILL_STUB(LockDevice);
   269     FILL_STUB(UnlockDevice);
   270     FILL_STUB(Deinitialize);
   271 #undef FILL_STUB
   272 }
   273 
   274 #if 0  /* !!! FIXME: rewrite/remove this streamer code. */
   275 /* Streaming functions (for when the input and output buffer sizes are different) */
   276 /* Write [length] bytes from buf into the streamer */
   277 static void
   278 SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
   279 {
   280     int i;
   281 
   282     for (i = 0; i < length; ++i) {
   283         stream->buffer[stream->write_pos] = buf[i];
   284         ++stream->write_pos;
   285     }
   286 }
   287 
   288 /* Read [length] bytes out of the streamer into buf */
   289 static void
   290 SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
   291 {
   292     int i;
   293 
   294     for (i = 0; i < length; ++i) {
   295         buf[i] = stream->buffer[stream->read_pos];
   296         ++stream->read_pos;
   297     }
   298 }
   299 
   300 static int
   301 SDL_StreamLength(SDL_AudioStreamer * stream)
   302 {
   303     return (stream->write_pos - stream->read_pos) % stream->max_len;
   304 }
   305 
   306 /* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
   307 #if 0
   308 static int
   309 SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
   310 {
   311     /* First try to allocate the buffer */
   312     stream->buffer = (Uint8 *) SDL_malloc(max_len);
   313     if (stream->buffer == NULL) {
   314         return -1;
   315     }
   316 
   317     stream->max_len = max_len;
   318     stream->read_pos = 0;
   319     stream->write_pos = 0;
   320 
   321     /* Zero out the buffer */
   322     SDL_memset(stream->buffer, silence, max_len);
   323 
   324     return 0;
   325 }
   326 #endif
   327 
   328 /* Deinitialize the stream simply by freeing the buffer */
   329 static void
   330 SDL_StreamDeinit(SDL_AudioStreamer * stream)
   331 {
   332     SDL_free(stream->buffer);
   333 }
   334 #endif
   335 
   336 /* device hotplug support... */
   337 
   338 /* this function expects its caller to hold current_audio.detection_lock */
   339 static int
   340 add_audio_device(const char *_name, char ***_devices, int *_devCount)
   341 {
   342     char *name = SDL_strdup(_name);
   343     int retval = -1;
   344 
   345     if (name != NULL) {
   346         char **devices = *_devices;
   347         int devCount = *_devCount;
   348         void *ptr = SDL_realloc(devices, (devCount+1) * sizeof(char*));
   349         if (ptr == NULL) {
   350             SDL_free(name);
   351         } else {
   352             retval = devCount;
   353             devices = (char **) ptr;
   354             devices[devCount++] = name;
   355             *_devices = devices;
   356             *_devCount = devCount;
   357         }
   358     }
   359 
   360     return retval;
   361 }
   362 
   363 static int
   364 add_capture_device(const char *name)
   365 {
   366     /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
   367     return add_audio_device(name, &current_audio.inputDevices, &current_audio.inputDeviceCount);
   368 }
   369 
   370 static int
   371 add_output_device(const char *name)
   372 {
   373     return add_audio_device(name, &current_audio.outputDevices, &current_audio.outputDeviceCount);
   374 }
   375 
   376 static void
   377 free_device_list(char ***devices, int *devCount)
   378 {
   379     int i = *devCount;
   380     if ((i > 0) && (*devices != NULL)) {
   381         while (i--) {
   382             SDL_free((*devices)[i]);
   383         }
   384     }
   385 
   386     SDL_free(*devices);
   387 
   388     *devices = NULL;
   389     *devCount = 0;
   390 }
   391 
   392 static void
   393 perform_full_device_redetect(const int iscapture)
   394 {
   395     SDL_LockMutex(current_audio.detection_lock);
   396 
   397     if (iscapture) {
   398         if (!current_audio.impl.OnlyHasDefaultOutputDevice) {
   399             free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
   400             current_audio.impl.DetectDevices(SDL_FALSE, add_output_device);
   401         }
   402     } else {
   403         if ((current_audio.impl.HasCaptureSupport) && (!current_audio.impl.OnlyHasDefaultInputDevice)) {
   404             free_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount);
   405             current_audio.impl.DetectDevices(SDL_TRUE, add_capture_device);
   406         }
   407     }
   408 
   409     SDL_UnlockMutex(current_audio.detection_lock);
   410 }
   411 
   412 /* The audio backends call this when a new device is plugged in. */
   413 void
   414 SDL_AudioDeviceConnected(const int iscapture, const char *name)
   415 {
   416     int device_index = -1;
   417 
   418     SDL_LockMutex(current_audio.detection_lock);
   419     if (iscapture) {
   420         device_index = add_capture_device(name);
   421     } else {
   422         device_index = add_output_device(name);
   423     }
   424     SDL_UnlockMutex(current_audio.detection_lock);
   425 
   426     if (device_index != -1) {
   427         /* Post the event, if desired */
   428         if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
   429             SDL_Event event;
   430             event.adevice.type = SDL_AUDIODEVICEADDED;
   431             event.adevice.which = device_index;
   432             event.adevice.iscapture = iscapture;
   433             SDL_PushEvent(&event);
   434         }
   435     }
   436 }
   437 
   438 /* The audio backends call this when a device is unplugged. */
   439 void
   440 SDL_AudioDeviceDisconnected(const int iscapture, SDL_AudioDevice *device)
   441 {
   442     /* device==NULL means an unopened device was lost; do the redetect only. */
   443     if (device != NULL) {
   444         SDL_assert(get_audio_device(device->id) == device);
   445         SDL_assert(device->enabled);  /* called more than once?! */
   446 
   447         /* Ends the audio callback and mark the device as STOPPED, but the
   448            app still needs to close the device to free resources. */
   449         current_audio.impl.LockDevice(device);
   450         device->enabled = 0;
   451         current_audio.impl.UnlockDevice(device);
   452 
   453         /* Post the event, if desired */
   454         if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
   455             SDL_Event event;
   456             event.adevice.type = SDL_AUDIODEVICEREMOVED;
   457             event.adevice.which = device->id;
   458             event.adevice.iscapture = device->iscapture ? 1 : 0;
   459             SDL_PushEvent(&event);
   460         }
   461     }
   462 
   463     /* we don't really know which name (if any) was associated with this
   464        device in the device list, so drop the entire list and rebuild it.
   465        (we should probably change the API in 2.1 to make this more clear?) */
   466     if (iscapture) {
   467         current_audio.need_capture_device_redetect = SDL_TRUE;
   468     } else {
   469         current_audio.need_output_device_redetect = SDL_TRUE;
   470     }
   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.detection_lock = SDL_CreateMutex();
   970 
   971     finalize_audio_entry_points();
   972 
   973     /* Make sure we have a list of devices available at startup. */
   974     perform_full_device_redetect(SDL_TRUE);
   975     perform_full_device_redetect(SDL_FALSE);
   976 
   977     /* Post an add event for each initial device, if desired */
   978     if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
   979         SDL_Event event;
   980 
   981         SDL_zero(event);
   982         event.adevice.type = SDL_AUDIODEVICEADDED;
   983 
   984         event.adevice.iscapture = 0;
   985         for (i = 0; i < current_audio.outputDeviceCount; i++) {
   986             event.adevice.which = i;
   987             SDL_PushEvent(&event);
   988         }
   989 
   990         event.adevice.iscapture = 1;
   991         for (i = 0; i < current_audio.inputDeviceCount; i++) {
   992             event.adevice.which = i;
   993             SDL_PushEvent(&event);
   994         }
   995     }
   996 
   997     return 0;
   998 }
   999 
  1000 /*
  1001  * Get the current audio driver name
  1002  */
  1003 const char *
  1004 SDL_GetCurrentAudioDriver()
  1005 {
  1006     return current_audio.name;
  1007 }
  1008 
  1009 int
  1010 SDL_GetNumAudioDevices(int iscapture)
  1011 {
  1012     int retval = 0;
  1013 
  1014     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1015         return -1;
  1016     }
  1017 
  1018     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
  1019         return 0;
  1020     }
  1021 
  1022     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
  1023         return 1;
  1024     }
  1025 
  1026     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
  1027         return 1;
  1028     }
  1029 
  1030     if (current_audio.need_capture_device_redetect) {
  1031         current_audio.need_capture_device_redetect = SDL_FALSE;
  1032         perform_full_device_redetect(SDL_TRUE);
  1033     }
  1034 
  1035     if (current_audio.need_output_device_redetect) {
  1036         current_audio.need_output_device_redetect = SDL_FALSE;
  1037         perform_full_device_redetect(SDL_FALSE);
  1038     }
  1039 
  1040     SDL_LockMutex(current_audio.detection_lock);
  1041     retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
  1042     SDL_UnlockMutex(current_audio.detection_lock);
  1043 
  1044     return retval;
  1045 }
  1046 
  1047 
  1048 const char *
  1049 SDL_GetAudioDeviceName(int index, int iscapture)
  1050 {
  1051     const char *retval = NULL;
  1052 
  1053     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1054         SDL_SetError("Audio subsystem is not initialized");
  1055         return NULL;
  1056     }
  1057 
  1058     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
  1059         SDL_SetError("No capture support");
  1060         return NULL;
  1061     }
  1062 
  1063     if (index < 0) {
  1064         goto no_such_device;
  1065     }
  1066 
  1067     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
  1068         if (index > 0) {
  1069             goto no_such_device;
  1070         }
  1071         return DEFAULT_INPUT_DEVNAME;
  1072     }
  1073 
  1074     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
  1075         if (index > 0) {
  1076             goto no_such_device;
  1077         }
  1078         return DEFAULT_OUTPUT_DEVNAME;
  1079     }
  1080 
  1081     SDL_LockMutex(current_audio.detection_lock);
  1082     if (iscapture && (index < current_audio.inputDeviceCount)) {
  1083         retval = current_audio.inputDevices[index];
  1084     } else if (!iscapture && (index < current_audio.outputDeviceCount)) {
  1085         retval = current_audio.outputDevices[index];
  1086     }
  1087     SDL_UnlockMutex(current_audio.detection_lock);
  1088 
  1089     /* !!! FIXME: a device could be removed after being returned here, freeing retval's pointer. */
  1090 
  1091     if (retval != NULL) {
  1092         return retval;
  1093     }
  1094 
  1095 no_such_device:
  1096     SDL_SetError("No such device");
  1097     return NULL;
  1098 }
  1099 
  1100 
  1101 static void
  1102 close_audio_device(SDL_AudioDevice * device)
  1103 {
  1104     device->enabled = 0;
  1105     if (device->thread != NULL) {
  1106         SDL_WaitThread(device->thread, NULL);
  1107     }
  1108     if (device->mixer_lock != NULL) {
  1109         SDL_DestroyMutex(device->mixer_lock);
  1110     }
  1111     SDL_FreeAudioMem(device->fake_stream);
  1112     if (device->convert.needed) {
  1113         SDL_FreeAudioMem(device->convert.buf);
  1114     }
  1115     if (device->opened) {
  1116         current_audio.impl.CloseDevice(device);
  1117         device->opened = 0;
  1118     }
  1119 
  1120     free_audio_queue(device->buffer_queue_head);
  1121     free_audio_queue(device->buffer_queue_pool);
  1122 
  1123     SDL_FreeAudioMem(device);
  1124 }
  1125 
  1126 
  1127 /*
  1128  * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
  1129  *  Fills in a sanitized copy in (prepared).
  1130  *  Returns non-zero if okay, zero on fatal parameters in (orig).
  1131  */
  1132 static int
  1133 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
  1134 {
  1135     SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
  1136 
  1137     if (orig->freq == 0) {
  1138         const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
  1139         if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
  1140             prepared->freq = 22050;     /* a reasonable default */
  1141         }
  1142     }
  1143 
  1144     if (orig->format == 0) {
  1145         const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
  1146         if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
  1147             prepared->format = AUDIO_S16;       /* a reasonable default */
  1148         }
  1149     }
  1150 
  1151     switch (orig->channels) {
  1152     case 0:{
  1153             const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
  1154             if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
  1155                 prepared->channels = 2; /* a reasonable default */
  1156             }
  1157             break;
  1158         }
  1159     case 1:                    /* Mono */
  1160     case 2:                    /* Stereo */
  1161     case 4:                    /* surround */
  1162     case 6:                    /* surround with center and lfe */
  1163         break;
  1164     default:
  1165         SDL_SetError("Unsupported number of audio channels.");
  1166         return 0;
  1167     }
  1168 
  1169     if (orig->samples == 0) {
  1170         const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
  1171         if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
  1172             /* Pick a default of ~46 ms at desired frequency */
  1173             /* !!! FIXME: remove this when the non-Po2 resampling is in. */
  1174             const int samples = (prepared->freq / 1000) * 46;
  1175             int power2 = 1;
  1176             while (power2 < samples) {
  1177                 power2 *= 2;
  1178             }
  1179             prepared->samples = power2;
  1180         }
  1181     }
  1182 
  1183     /* Calculate the silence and size of the audio specification */
  1184     SDL_CalculateAudioSpec(prepared);
  1185 
  1186     return 1;
  1187 }
  1188 
  1189 static SDL_AudioDeviceID
  1190 open_audio_device(const char *devname, int iscapture,
  1191                   const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
  1192                   int allowed_changes, int min_id)
  1193 {
  1194     SDL_AudioDeviceID id = 0;
  1195     SDL_AudioSpec _obtained;
  1196     SDL_AudioDevice *device;
  1197     SDL_bool build_cvt;
  1198     int i = 0;
  1199 
  1200     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1201         SDL_SetError("Audio subsystem is not initialized");
  1202         return 0;
  1203     }
  1204 
  1205     if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
  1206         SDL_SetError("No capture support");
  1207         return 0;
  1208     }
  1209 
  1210     /* Find an available device ID... */
  1211     for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
  1212         if (open_devices[id] == NULL) {
  1213             break;
  1214         }
  1215     }
  1216 
  1217     if (id == SDL_arraysize(open_devices)) {
  1218         SDL_SetError("Too many open audio devices");
  1219         return 0;
  1220     }
  1221 
  1222     if (!obtained) {
  1223         obtained = &_obtained;
  1224     }
  1225     if (!prepare_audiospec(desired, obtained)) {
  1226         return 0;
  1227     }
  1228 
  1229     /* If app doesn't care about a specific device, let the user override. */
  1230     if (devname == NULL) {
  1231         devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
  1232     }
  1233 
  1234     /*
  1235      * Catch device names at the high level for the simple case...
  1236      * This lets us have a basic "device enumeration" for systems that
  1237      *  don't have multiple devices, but makes sure the device name is
  1238      *  always NULL when it hits the low level.
  1239      *
  1240      * Also make sure that the simple case prevents multiple simultaneous
  1241      *  opens of the default system device.
  1242      */
  1243 
  1244     if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
  1245         if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
  1246             SDL_SetError("No such device");
  1247             return 0;
  1248         }
  1249         devname = NULL;
  1250 
  1251         for (i = 0; i < SDL_arraysize(open_devices); i++) {
  1252             if ((open_devices[i]) && (open_devices[i]->iscapture)) {
  1253                 SDL_SetError("Audio device already open");
  1254                 return 0;
  1255             }
  1256         }
  1257     }
  1258 
  1259     if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
  1260         if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
  1261             SDL_SetError("No such device");
  1262             return 0;
  1263         }
  1264         devname = NULL;
  1265 
  1266         for (i = 0; i < SDL_arraysize(open_devices); i++) {
  1267             if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
  1268                 SDL_SetError("Audio device already open");
  1269                 return 0;
  1270             }
  1271         }
  1272     }
  1273 
  1274     device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
  1275     if (device == NULL) {
  1276         SDL_OutOfMemory();
  1277         return 0;
  1278     }
  1279     SDL_zerop(device);
  1280     device->id = id + 1;
  1281     device->spec = *obtained;
  1282     device->enabled = 1;
  1283     device->paused = 1;
  1284     device->iscapture = iscapture;
  1285 
  1286     /* Create a mutex for locking the sound buffers */
  1287     if (!current_audio.impl.SkipMixerLock) {
  1288         device->mixer_lock = SDL_CreateMutex();
  1289         if (device->mixer_lock == NULL) {
  1290             close_audio_device(device);
  1291             SDL_SetError("Couldn't create mixer lock");
  1292             return 0;
  1293         }
  1294     }
  1295 
  1296     if (current_audio.impl.OpenDevice(device, devname, iscapture) < 0) {
  1297         close_audio_device(device);
  1298         return 0;
  1299     }
  1300     device->opened = 1;
  1301 
  1302     /* Allocate a fake audio memory buffer */
  1303     device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
  1304     if (device->fake_stream == NULL) {
  1305         close_audio_device(device);
  1306         SDL_OutOfMemory();
  1307         return 0;
  1308     }
  1309 
  1310     /* See if we need to do any conversion */
  1311     build_cvt = SDL_FALSE;
  1312     if (obtained->freq != device->spec.freq) {
  1313         if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
  1314             obtained->freq = device->spec.freq;
  1315         } else {
  1316             build_cvt = SDL_TRUE;
  1317         }
  1318     }
  1319     if (obtained->format != device->spec.format) {
  1320         if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
  1321             obtained->format = device->spec.format;
  1322         } else {
  1323             build_cvt = SDL_TRUE;
  1324         }
  1325     }
  1326     if (obtained->channels != device->spec.channels) {
  1327         if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
  1328             obtained->channels = device->spec.channels;
  1329         } else {
  1330             build_cvt = SDL_TRUE;
  1331         }
  1332     }
  1333 
  1334     /* If the audio driver changes the buffer size, accept it.
  1335        This needs to be done after the format is modified above,
  1336        otherwise it might not have the correct buffer size.
  1337      */
  1338     if (device->spec.samples != obtained->samples) {
  1339         obtained->samples = device->spec.samples;
  1340         SDL_CalculateAudioSpec(obtained);
  1341     }
  1342 
  1343     if (build_cvt) {
  1344         /* Build an audio conversion block */
  1345         if (SDL_BuildAudioCVT(&device->convert,
  1346                               obtained->format, obtained->channels,
  1347                               obtained->freq,
  1348                               device->spec.format, device->spec.channels,
  1349                               device->spec.freq) < 0) {
  1350             close_audio_device(device);
  1351             return 0;
  1352         }
  1353         if (device->convert.needed) {
  1354             device->convert.len = (int) (((double) device->spec.size) /
  1355                                          device->convert.len_ratio);
  1356 
  1357             device->convert.buf =
  1358                 (Uint8 *) SDL_AllocAudioMem(device->convert.len *
  1359                                             device->convert.len_mult);
  1360             if (device->convert.buf == NULL) {
  1361                 close_audio_device(device);
  1362                 SDL_OutOfMemory();
  1363                 return 0;
  1364             }
  1365         }
  1366     }
  1367 
  1368     if (device->spec.callback == NULL) {  /* use buffer queueing? */
  1369         /* pool a few packets to start. Enough for two callbacks. */
  1370         const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;
  1371         const int wantbytes = ((device->convert.needed) ? device->convert.len : device->spec.size) * 2;
  1372         const int wantpackets = (wantbytes / packetlen) + ((wantbytes % packetlen) ? packetlen : 0);
  1373         for (i = 0; i < wantpackets; i++) {
  1374             SDL_AudioBufferQueue *packet = (SDL_AudioBufferQueue *) SDL_malloc(sizeof (SDL_AudioBufferQueue));
  1375             if (packet) { /* don't care if this fails, we'll deal later. */
  1376                 packet->datalen = 0;
  1377                 packet->startpos = 0;
  1378                 packet->next = device->buffer_queue_pool;
  1379                 device->buffer_queue_pool = packet;
  1380             }
  1381         }
  1382 
  1383         device->spec.callback = SDL_BufferQueueDrainCallback;
  1384         device->spec.userdata = device;
  1385     }
  1386 
  1387     /* add it to our list of open devices. */
  1388     open_devices[id] = device;
  1389 
  1390     /* Start the audio thread if necessary */
  1391     if (!current_audio.impl.ProvidesOwnCallbackThread) {
  1392         /* Start the audio thread */
  1393         char name[64];
  1394         SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
  1395 /* !!! FIXME: this is nasty. */
  1396 #if defined(__WIN32__) && !defined(HAVE_LIBC)
  1397 #undef SDL_CreateThread
  1398 #if SDL_DYNAMIC_API
  1399         device->thread = SDL_CreateThread_REAL(SDL_RunAudio, name, device, NULL, NULL);
  1400 #else
  1401         device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
  1402 #endif
  1403 #else
  1404         device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
  1405 #endif
  1406         if (device->thread == NULL) {
  1407             SDL_CloseAudioDevice(device->id);
  1408             SDL_SetError("Couldn't create audio thread");
  1409             return 0;
  1410         }
  1411     }
  1412 
  1413     return device->id;
  1414 }
  1415 
  1416 
  1417 int
  1418 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
  1419 {
  1420     SDL_AudioDeviceID id = 0;
  1421 
  1422     /* Start up the audio driver, if necessary. This is legacy behaviour! */
  1423     if (!SDL_WasInit(SDL_INIT_AUDIO)) {
  1424         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
  1425             return -1;
  1426         }
  1427     }
  1428 
  1429     /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
  1430     if (open_devices[0] != NULL) {
  1431         SDL_SetError("Audio device is already opened");
  1432         return -1;
  1433     }
  1434 
  1435     if (obtained) {
  1436         id = open_audio_device(NULL, 0, desired, obtained,
  1437                                SDL_AUDIO_ALLOW_ANY_CHANGE, 1);
  1438     } else {
  1439         id = open_audio_device(NULL, 0, desired, NULL, 0, 1);
  1440     }
  1441 
  1442     SDL_assert((id == 0) || (id == 1));
  1443     return (id == 0) ? -1 : 0;
  1444 }
  1445 
  1446 SDL_AudioDeviceID
  1447 SDL_OpenAudioDevice(const char *device, int iscapture,
  1448                     const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
  1449                     int allowed_changes)
  1450 {
  1451     return open_audio_device(device, iscapture, desired, obtained,
  1452                              allowed_changes, 2);
  1453 }
  1454 
  1455 SDL_AudioStatus
  1456 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
  1457 {
  1458     SDL_AudioDevice *device = get_audio_device(devid);
  1459     SDL_AudioStatus status = SDL_AUDIO_STOPPED;
  1460     if (device && device->enabled) {
  1461         if (device->paused) {
  1462             status = SDL_AUDIO_PAUSED;
  1463         } else {
  1464             status = SDL_AUDIO_PLAYING;
  1465         }
  1466     }
  1467     return status;
  1468 }
  1469 
  1470 
  1471 SDL_AudioStatus
  1472 SDL_GetAudioStatus(void)
  1473 {
  1474     return SDL_GetAudioDeviceStatus(1);
  1475 }
  1476 
  1477 void
  1478 SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
  1479 {
  1480     SDL_AudioDevice *device = get_audio_device(devid);
  1481     if (device) {
  1482         current_audio.impl.LockDevice(device);
  1483         device->paused = pause_on;
  1484         current_audio.impl.UnlockDevice(device);
  1485     }
  1486 }
  1487 
  1488 void
  1489 SDL_PauseAudio(int pause_on)
  1490 {
  1491     SDL_PauseAudioDevice(1, pause_on);
  1492 }
  1493 
  1494 
  1495 void
  1496 SDL_LockAudioDevice(SDL_AudioDeviceID devid)
  1497 {
  1498     /* Obtain a lock on the mixing buffers */
  1499     SDL_AudioDevice *device = get_audio_device(devid);
  1500     if (device) {
  1501         current_audio.impl.LockDevice(device);
  1502     }
  1503 }
  1504 
  1505 void
  1506 SDL_LockAudio(void)
  1507 {
  1508     SDL_LockAudioDevice(1);
  1509 }
  1510 
  1511 void
  1512 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
  1513 {
  1514     /* Obtain a lock on the mixing buffers */
  1515     SDL_AudioDevice *device = get_audio_device(devid);
  1516     if (device) {
  1517         current_audio.impl.UnlockDevice(device);
  1518     }
  1519 }
  1520 
  1521 void
  1522 SDL_UnlockAudio(void)
  1523 {
  1524     SDL_UnlockAudioDevice(1);
  1525 }
  1526 
  1527 void
  1528 SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
  1529 {
  1530     SDL_AudioDevice *device = get_audio_device(devid);
  1531     if (device) {
  1532         close_audio_device(device);
  1533         open_devices[devid - 1] = NULL;
  1534     }
  1535 }
  1536 
  1537 void
  1538 SDL_CloseAudio(void)
  1539 {
  1540     SDL_CloseAudioDevice(1);
  1541 }
  1542 
  1543 void
  1544 SDL_AudioQuit(void)
  1545 {
  1546     SDL_AudioDeviceID i;
  1547 
  1548     if (!current_audio.name) {  /* not initialized?! */
  1549         return;
  1550     }
  1551 
  1552     for (i = 0; i < SDL_arraysize(open_devices); i++) {
  1553         if (open_devices[i] != NULL) {
  1554             SDL_CloseAudioDevice(i+1);
  1555         }
  1556     }
  1557 
  1558     /* Free the driver data */
  1559     current_audio.impl.Deinitialize();
  1560 
  1561     free_device_list(&current_audio.outputDevices,
  1562                      &current_audio.outputDeviceCount);
  1563     free_device_list(&current_audio.inputDevices,
  1564                      &current_audio.inputDeviceCount);
  1565 
  1566     SDL_DestroyMutex(current_audio.detection_lock);
  1567 
  1568     SDL_zero(current_audio);
  1569     SDL_zero(open_devices);
  1570 }
  1571 
  1572 #define NUM_FORMATS 10
  1573 static int format_idx;
  1574 static int format_idx_sub;
  1575 static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
  1576     {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1577      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1578     {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
  1579      AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
  1580     {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
  1581      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1582     {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
  1583      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1584     {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
  1585      AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
  1586     {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
  1587      AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
  1588     {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB,
  1589      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1590     {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB,
  1591      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1592     {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB,
  1593      AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
  1594     {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB,
  1595      AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
  1596 };
  1597 
  1598 SDL_AudioFormat
  1599 SDL_FirstAudioFormat(SDL_AudioFormat format)
  1600 {
  1601     for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
  1602         if (format_list[format_idx][0] == format) {
  1603             break;
  1604         }
  1605     }
  1606     format_idx_sub = 0;
  1607     return SDL_NextAudioFormat();
  1608 }
  1609 
  1610 SDL_AudioFormat
  1611 SDL_NextAudioFormat(void)
  1612 {
  1613     if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
  1614         return 0;
  1615     }
  1616     return format_list[format_idx][format_idx_sub++];
  1617 }
  1618 
  1619 void
  1620 SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
  1621 {
  1622     switch (spec->format) {
  1623     case AUDIO_U8:
  1624         spec->silence = 0x80;
  1625         break;
  1626     default:
  1627         spec->silence = 0x00;
  1628         break;
  1629     }
  1630     spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
  1631     spec->size *= spec->channels;
  1632     spec->size *= spec->samples;
  1633 }
  1634 
  1635 
  1636 /*
  1637  * Moved here from SDL_mixer.c, since it relies on internals of an opened
  1638  *  audio device (and is deprecated, by the way!).
  1639  */
  1640 void
  1641 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
  1642 {
  1643     /* Mix the user-level audio format */
  1644     SDL_AudioDevice *device = get_audio_device(1);
  1645     if (device != NULL) {
  1646         SDL_AudioFormat format;
  1647         if (device->convert.needed) {
  1648             format = device->convert.src_format;
  1649         } else {
  1650             format = device->spec.format;
  1651         }
  1652         SDL_MixAudioFormat(dst, src, format, len, volume);
  1653     }
  1654 }
  1655 
  1656 /* vi: set ts=4 sw=4 expandtab: */