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