src/audio/SDL_audio.c
author Ryan C. Gordon
Wed, 18 Jan 2017 02:11:56 -0500
changeset 10817 efc103e60c5b
parent 10815 71bbe3233508
child 10849 bc671e6906ae
permissions -rw-r--r--
audio: Several fixes to "simple" resampler (thanks, Vitaly!).

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