diff options
Diffstat (limited to 'Source/3rdParty/SDL2/src/audio')
60 files changed, 0 insertions, 18896 deletions
diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audio.c b/Source/3rdParty/SDL2/src/audio/SDL_audio.c deleted file mode 100644 index f4999f1..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audio.c +++ /dev/null @@ -1,1690 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* Allow access to a raw mixing buffer */ - -#include "SDL.h" -#include "SDL_audio.h" -#include "SDL_audio_c.h" -#include "SDL_sysaudio.h" -#include "../thread/SDL_systhread.h" - -#define _THIS SDL_AudioDevice *_this - -static SDL_AudioDriver current_audio; -static SDL_AudioDevice *open_devices[16]; - -/* Available audio drivers */ -static const AudioBootStrap *const bootstrap[] = { -#if SDL_AUDIO_DRIVER_PULSEAUDIO - &PULSEAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_ALSA - &ALSA_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_SNDIO - &SNDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_NETBSD - &NETBSDAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_OSS - &DSP_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_QSA - &QSAAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_SUNAUDIO - &SUNAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_ARTS - &ARTS_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_ESD - &ESD_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_NACL - &NACLAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_NAS - &NAS_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_WASAPI - &WASAPI_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_DSOUND - &DSOUND_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_WINMM - &WINMM_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_PAUDIO - &PAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_HAIKU - &HAIKUAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_COREAUDIO - &COREAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_FUSIONSOUND - &FUSIONSOUND_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_ANDROID - &ANDROIDAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_PSP - &PSPAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_EMSCRIPTEN - &EMSCRIPTENAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_JACK - &JACK_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_DISK - &DISKAUDIO_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_DUMMY - &DUMMYAUDIO_bootstrap, -#endif - NULL -}; - - -#ifdef HAVE_LIBSAMPLERATE_H -#ifdef SDL_LIBSAMPLERATE_DYNAMIC -static void *SRC_lib = NULL; -#endif -SDL_bool SRC_available = SDL_FALSE; -int SRC_converter = 0; -SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error) = NULL; -int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data) = NULL; -int (*SRC_src_reset)(SRC_STATE *state) = NULL; -SRC_STATE* (*SRC_src_delete)(SRC_STATE *state) = NULL; -const char* (*SRC_src_strerror)(int error) = NULL; - -static SDL_bool -LoadLibSampleRate(void) -{ - const char *hint = SDL_GetHint(SDL_HINT_AUDIO_RESAMPLING_MODE); - - SRC_available = SDL_FALSE; - SRC_converter = 0; - - if (!hint || *hint == '0' || SDL_strcasecmp(hint, "default") == 0) { - return SDL_FALSE; /* don't load anything. */ - } else if (*hint == '1' || SDL_strcasecmp(hint, "fast") == 0) { - SRC_converter = SRC_SINC_FASTEST; - } else if (*hint == '2' || SDL_strcasecmp(hint, "medium") == 0) { - SRC_converter = SRC_SINC_MEDIUM_QUALITY; - } else if (*hint == '3' || SDL_strcasecmp(hint, "best") == 0) { - SRC_converter = SRC_SINC_BEST_QUALITY; - } else { - return SDL_FALSE; /* treat it like "default", don't load anything. */ - } - -#ifdef SDL_LIBSAMPLERATE_DYNAMIC - SDL_assert(SRC_lib == NULL); - SRC_lib = SDL_LoadObject(SDL_LIBSAMPLERATE_DYNAMIC); - if (!SRC_lib) { - SDL_ClearError(); - return SDL_FALSE; - } - - SRC_src_new = (SRC_STATE* (*)(int converter_type, int channels, int *error))SDL_LoadFunction(SRC_lib, "src_new"); - SRC_src_process = (int (*)(SRC_STATE *state, SRC_DATA *data))SDL_LoadFunction(SRC_lib, "src_process"); - SRC_src_reset = (int(*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_reset"); - SRC_src_delete = (SRC_STATE* (*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_delete"); - SRC_src_strerror = (const char* (*)(int error))SDL_LoadFunction(SRC_lib, "src_strerror"); - - if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror) { - SDL_UnloadObject(SRC_lib); - SRC_lib = NULL; - return SDL_FALSE; - } -#else - SRC_src_new = src_new; - SRC_src_process = src_process; - SRC_src_reset = src_reset; - SRC_src_delete = src_delete; - SRC_src_strerror = src_strerror; -#endif - - SRC_available = SDL_TRUE; - return SDL_TRUE; -} - -static void -UnloadLibSampleRate(void) -{ -#ifdef SDL_LIBSAMPLERATE_DYNAMIC - if (SRC_lib != NULL) { - SDL_UnloadObject(SRC_lib); - } - SRC_lib = NULL; -#endif - - SRC_available = SDL_FALSE; - SRC_src_new = NULL; - SRC_src_process = NULL; - SRC_src_reset = NULL; - SRC_src_delete = NULL; - SRC_src_strerror = NULL; -} -#endif - -static SDL_AudioDevice * -get_audio_device(SDL_AudioDeviceID id) -{ - id--; - if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) { - SDL_SetError("Invalid audio device ID"); - return NULL; - } - - return open_devices[id]; -} - - -/* stubs for audio drivers that don't need a specific entry point... */ -static void -SDL_AudioDetectDevices_Default(void) -{ - /* you have to write your own implementation if these assertions fail. */ - SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice); - SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport); - - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1)); - if (current_audio.impl.HasCaptureSupport) { - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2)); - } -} - -static void -SDL_AudioThreadInit_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioThreadDeinit_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioBeginLoopIteration_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioWaitDevice_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioPlayDevice_Default(_THIS) -{ /* no-op. */ -} - -static int -SDL_AudioGetPendingBytes_Default(_THIS) -{ - return 0; -} - -static Uint8 * -SDL_AudioGetDeviceBuf_Default(_THIS) -{ - return NULL; -} - -static int -SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen) -{ - return -1; /* just fail immediately. */ -} - -static void -SDL_AudioFlushCapture_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioPrepareToClose_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioCloseDevice_Default(_THIS) -{ /* no-op. */ -} - -static void -SDL_AudioDeinitialize_Default(void) -{ /* no-op. */ -} - -static void -SDL_AudioFreeDeviceHandle_Default(void *handle) -{ /* no-op. */ -} - - -static int -SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture) -{ - return SDL_Unsupported(); -} - -static SDL_INLINE SDL_bool -is_in_audio_device_thread(SDL_AudioDevice * device) -{ - /* The device thread locks the same mutex, but not through the public API. - This check is in case the application, in the audio callback, - tries to lock the thread that we've already locked from the - device thread...just in case we only have non-recursive mutexes. */ - if (device->thread && (SDL_ThreadID() == device->threadid)) { - return SDL_TRUE; - } - - return SDL_FALSE; -} - -static void -SDL_AudioLockDevice_Default(SDL_AudioDevice * device) -{ - if (!is_in_audio_device_thread(device)) { - SDL_LockMutex(device->mixer_lock); - } -} - -static void -SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device) -{ - if (!is_in_audio_device_thread(device)) { - SDL_UnlockMutex(device->mixer_lock); - } -} - -static void -SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device) -{ -} - -static void -finish_audio_entry_points_init(void) -{ - /* - * Fill in stub functions for unused driver entry points. This lets us - * blindly call them without having to check for validity first. - */ - - if (current_audio.impl.SkipMixerLock) { - if (current_audio.impl.LockDevice == NULL) { - current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; - } - if (current_audio.impl.UnlockDevice == NULL) { - current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; - } - } - -#define FILL_STUB(x) \ - if (current_audio.impl.x == NULL) { \ - current_audio.impl.x = SDL_Audio##x##_Default; \ - } - FILL_STUB(DetectDevices); - FILL_STUB(OpenDevice); - FILL_STUB(ThreadInit); - FILL_STUB(ThreadDeinit); - FILL_STUB(BeginLoopIteration); - FILL_STUB(WaitDevice); - FILL_STUB(PlayDevice); - FILL_STUB(GetPendingBytes); - FILL_STUB(GetDeviceBuf); - FILL_STUB(CaptureFromDevice); - FILL_STUB(FlushCapture); - FILL_STUB(PrepareToClose); - FILL_STUB(CloseDevice); - FILL_STUB(LockDevice); - FILL_STUB(UnlockDevice); - FILL_STUB(FreeDeviceHandle); - FILL_STUB(Deinitialize); -#undef FILL_STUB -} - - -/* device hotplug support... */ - -static int -add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount) -{ - int retval = -1; - SDL_AudioDeviceItem *item; - const SDL_AudioDeviceItem *i; - int dupenum = 0; - - SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */ - SDL_assert(name != NULL); - - item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem)); - if (!item) { - return SDL_OutOfMemory(); - } - - item->original_name = SDL_strdup(name); - if (!item->original_name) { - SDL_free(item); - return SDL_OutOfMemory(); - } - - item->dupenum = 0; - item->name = item->original_name; - item->handle = handle; - - SDL_LockMutex(current_audio.detectionLock); - - for (i = *devices; i != NULL; i = i->next) { - if (SDL_strcmp(name, i->original_name) == 0) { - dupenum = i->dupenum + 1; - break; /* stop at the highest-numbered dupe. */ - } - } - - if (dupenum) { - const size_t len = SDL_strlen(name) + 16; - char *replacement = (char *) SDL_malloc(len); - if (!replacement) { - SDL_UnlockMutex(current_audio.detectionLock); - SDL_free(item->original_name); - SDL_free(item); - SDL_OutOfMemory(); - return -1; - } - - SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1); - item->dupenum = dupenum; - item->name = replacement; - } - - item->next = *devices; - *devices = item; - retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */ - - SDL_UnlockMutex(current_audio.detectionLock); - - return retval; -} - -static SDL_INLINE int -add_capture_device(const char *name, void *handle) -{ - SDL_assert(current_audio.impl.HasCaptureSupport); - return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); -} - -static SDL_INLINE int -add_output_device(const char *name, void *handle) -{ - return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); -} - -static void -free_device_list(SDL_AudioDeviceItem **devices, int *devCount) -{ - SDL_AudioDeviceItem *item, *next; - for (item = *devices; item != NULL; item = next) { - next = item->next; - if (item->handle != NULL) { - current_audio.impl.FreeDeviceHandle(item->handle); - } - /* these two pointers are the same if not a duplicate devname */ - if (item->name != item->original_name) { - SDL_free(item->name); - } - SDL_free(item->original_name); - SDL_free(item); - } - *devices = NULL; - *devCount = 0; -} - - -/* The audio backends call this when a new device is plugged in. */ -void -SDL_AddAudioDevice(const int iscapture, const char *name, void *handle) -{ - const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle); - if (device_index != -1) { - /* Post the event, if desired */ - if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) { - SDL_Event event; - SDL_zero(event); - event.adevice.type = SDL_AUDIODEVICEADDED; - event.adevice.which = device_index; - event.adevice.iscapture = iscapture; - SDL_PushEvent(&event); - } - } -} - -/* The audio backends call this when a currently-opened device is lost. */ -void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) -{ - SDL_assert(get_audio_device(device->id) == device); - - if (!SDL_AtomicGet(&device->enabled)) { - return; /* don't report disconnects more than once. */ - } - - if (SDL_AtomicGet(&device->shutdown)) { - return; /* don't report disconnect if we're trying to close device. */ - } - - /* Ends the audio callback and mark the device as STOPPED, but the - app still needs to close the device to free resources. */ - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->enabled, 0); - current_audio.impl.UnlockDevice(device); - - /* Post the event, if desired */ - if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) { - SDL_Event event; - SDL_zero(event); - event.adevice.type = SDL_AUDIODEVICEREMOVED; - event.adevice.which = device->id; - event.adevice.iscapture = device->iscapture ? 1 : 0; - SDL_PushEvent(&event); - } -} - -static void -mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) -{ - SDL_AudioDeviceItem *item; - SDL_assert(handle != NULL); - for (item = devices; item != NULL; item = item->next) { - if (item->handle == handle) { - item->handle = NULL; - *removedFlag = SDL_TRUE; - return; - } - } -} - -/* The audio backends call this when a device is removed from the system. */ -void -SDL_RemoveAudioDevice(const int iscapture, void *handle) -{ - int device_index; - SDL_AudioDevice *device = NULL; - - SDL_LockMutex(current_audio.detectionLock); - if (iscapture) { - mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); - } else { - mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); - } - for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) - { - device = open_devices[device_index]; - if (device != NULL && device->handle == handle) - { - SDL_OpenedAudioDeviceDisconnected(device); - break; - } - } - SDL_UnlockMutex(current_audio.detectionLock); - - current_audio.impl.FreeDeviceHandle(handle); -} - - - -/* buffer queueing support... */ - -static void SDLCALL -SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len) -{ - /* this function always holds the mixer lock before being called. */ - SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; - size_t dequeued; - - SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ - SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */ - SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ - - dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len); - stream += dequeued; - len -= (int) dequeued; - - if (len > 0) { /* fill any remaining space in the stream with silence. */ - SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0); - SDL_memset(stream, device->spec.silence, len); - } -} - -static void SDLCALL -SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) -{ - /* this function always holds the mixer lock before being called. */ - SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; - - SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ - SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */ - SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ - - /* note that if this needs to allocate more space and run out of memory, - we have no choice but to quietly drop the data and hope it works out - later, but you probably have bigger problems in this case anyhow. */ - SDL_WriteToDataQueue(device->buffer_queue, stream, len); -} - -int -SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) -{ - SDL_AudioDevice *device = get_audio_device(devid); - int rc = 0; - - if (!device) { - return -1; /* get_audio_device() will have set the error state */ - } else if (device->iscapture) { - return SDL_SetError("This is a capture device, queueing not allowed"); - } else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) { - return SDL_SetError("Audio device has a callback, queueing not allowed"); - } - - if (len > 0) { - current_audio.impl.LockDevice(device); - rc = SDL_WriteToDataQueue(device->buffer_queue, data, len); - current_audio.impl.UnlockDevice(device); - } - - return rc; -} - -Uint32 -SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len) -{ - SDL_AudioDevice *device = get_audio_device(devid); - Uint32 rc; - - if ( (len == 0) || /* nothing to do? */ - (!device) || /* called with bogus device id */ - (!device->iscapture) || /* playback devices can't dequeue */ - (device->callbackspec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */ - return 0; /* just report zero bytes dequeued. */ - } - - current_audio.impl.LockDevice(device); - rc = (Uint32) SDL_ReadFromDataQueue(device->buffer_queue, data, len); - current_audio.impl.UnlockDevice(device); - return rc; -} - -Uint32 -SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) -{ - Uint32 retval = 0; - SDL_AudioDevice *device = get_audio_device(devid); - - if (!device) { - return 0; - } - - /* Nothing to do unless we're set up for queueing. */ - if (device->callbackspec.callback == SDL_BufferQueueDrainCallback) { - current_audio.impl.LockDevice(device); - retval = ((Uint32) SDL_CountDataQueue(device->buffer_queue)) + current_audio.impl.GetPendingBytes(device); - current_audio.impl.UnlockDevice(device); - } else if (device->callbackspec.callback == SDL_BufferQueueFillCallback) { - current_audio.impl.LockDevice(device); - retval = (Uint32) SDL_CountDataQueue(device->buffer_queue); - current_audio.impl.UnlockDevice(device); - } - - return retval; -} - -void -SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) -{ - SDL_AudioDevice *device = get_audio_device(devid); - - if (!device) { - return; /* nothing to do. */ - } - - /* Blank out the device and release the mutex. Free it afterwards. */ - current_audio.impl.LockDevice(device); - - /* Keep up to two packets in the pool to reduce future malloc pressure. */ - SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2); - - current_audio.impl.UnlockDevice(device); -} - - -/* The general mixing thread function */ -static int SDLCALL -SDL_RunAudio(void *devicep) -{ - SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; - void *udata = device->callbackspec.userdata; - SDL_AudioCallback callback = device->callbackspec.callback; - int data_len = 0; - Uint8 *data; - - SDL_assert(!device->iscapture); - - /* The audio mixing is always a high priority thread */ - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); - - /* Perform any thread setup */ - device->threadid = SDL_ThreadID(); - current_audio.impl.ThreadInit(device); - - /* Loop, filling the audio buffers */ - while (!SDL_AtomicGet(&device->shutdown)) { - current_audio.impl.BeginLoopIteration(device); - data_len = device->callbackspec.size; - - /* Fill the current buffer with sound */ - if (!device->stream && SDL_AtomicGet(&device->enabled)) { - SDL_assert(data_len == device->spec.size); - data = current_audio.impl.GetDeviceBuf(device); - } else { - /* if the device isn't enabled, we still write to the - work_buffer, so the app's callback will fire with - a regular frequency, in case they depend on that - for timing or progress. They can use hotplug - now to know if the device failed. - Streaming playback uses work_buffer, too. */ - data = NULL; - } - - if (data == NULL) { - data = device->work_buffer; - } - - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (SDL_AtomicGet(&device->paused)) { - SDL_memset(data, device->spec.silence, data_len); - } else { - callback(udata, data, data_len); - } - SDL_UnlockMutex(device->mixer_lock); - - if (device->stream) { - /* Stream available audio to device, converting/resampling. */ - /* if this fails...oh well. We'll play silence here. */ - SDL_AudioStreamPut(device->stream, data, data_len); - - while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) { - int got; - data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL; - got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size); - SDL_assert((got < 0) || (got == device->spec.size)); - - if (data == NULL) { /* device is having issues... */ - const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); - SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */ - } else { - if (got != device->spec.size) { - SDL_memset(data, device->spec.silence, device->spec.size); - } - current_audio.impl.PlayDevice(device); - current_audio.impl.WaitDevice(device); - } - } - } else if (data == device->work_buffer) { - /* nothing to do; pause like we queued a buffer to play. */ - const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); - SDL_Delay(delay); - } else { /* writing directly to the device. */ - /* queue this buffer and wait for it to finish playing. */ - current_audio.impl.PlayDevice(device); - current_audio.impl.WaitDevice(device); - } - } - - current_audio.impl.PrepareToClose(device); - - /* Wait for the audio to drain. */ - SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); - - current_audio.impl.ThreadDeinit(device); - - return 0; -} - -/* !!! FIXME: this needs to deal with device spec changes. */ -/* The general capture thread function */ -static int SDLCALL -SDL_CaptureAudio(void *devicep) -{ - SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; - const int silence = (int) device->spec.silence; - const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); - const int data_len = device->spec.size; - Uint8 *data; - void *udata = device->callbackspec.userdata; - SDL_AudioCallback callback = device->callbackspec.callback; - - SDL_assert(device->iscapture); - - /* The audio mixing is always a high priority thread */ - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); - - /* Perform any thread setup */ - device->threadid = SDL_ThreadID(); - current_audio.impl.ThreadInit(device); - - /* Loop, filling the audio buffers */ - while (!SDL_AtomicGet(&device->shutdown)) { - int still_need; - Uint8 *ptr; - - current_audio.impl.BeginLoopIteration(device); - - if (SDL_AtomicGet(&device->paused)) { - SDL_Delay(delay); /* just so we don't cook the CPU. */ - if (device->stream) { - SDL_AudioStreamClear(device->stream); - } - current_audio.impl.FlushCapture(device); /* dump anything pending. */ - continue; - } - - /* Fill the current buffer with sound */ - still_need = data_len; - - /* Use the work_buffer to hold data read from the device. */ - data = device->work_buffer; - SDL_assert(data != NULL); - - ptr = data; - - /* We still read from the device when "paused" to keep the state sane, - and block when there isn't data so this thread isn't eating CPU. - But we don't process it further or call the app's callback. */ - - if (!SDL_AtomicGet(&device->enabled)) { - SDL_Delay(delay); /* try to keep callback firing at normal pace. */ - } else { - while (still_need > 0) { - const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need); - SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ - if (rc > 0) { - still_need -= rc; - ptr += rc; - } else { /* uhoh, device failed for some reason! */ - SDL_OpenedAudioDeviceDisconnected(device); - break; - } - } - } - - if (still_need > 0) { - /* Keep any data we already read, silence the rest. */ - SDL_memset(ptr, silence, still_need); - } - - if (device->stream) { - /* if this fails...oh well. */ - SDL_AudioStreamPut(device->stream, data, data_len); - - while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) { - const int got = SDL_AudioStreamGet(device->stream, device->work_buffer, device->callbackspec.size); - SDL_assert((got < 0) || (got == device->callbackspec.size)); - if (got != device->callbackspec.size) { - SDL_memset(device->work_buffer, device->spec.silence, device->callbackspec.size); - } - - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (!SDL_AtomicGet(&device->paused)) { - callback(udata, device->work_buffer, device->callbackspec.size); - } - SDL_UnlockMutex(device->mixer_lock); - } - } else { /* feeding user callback directly without streaming. */ - /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (!SDL_AtomicGet(&device->paused)) { - callback(udata, data, device->callbackspec.size); - } - SDL_UnlockMutex(device->mixer_lock); - } - } - - current_audio.impl.PrepareToClose(device); - - current_audio.impl.FlushCapture(device); - - current_audio.impl.ThreadDeinit(device); - - return 0; -} - - -static SDL_AudioFormat -SDL_ParseAudioFormat(const char *string) -{ -#define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x - CHECK_FMT_STRING(U8); - CHECK_FMT_STRING(S8); - CHECK_FMT_STRING(U16LSB); - CHECK_FMT_STRING(S16LSB); - CHECK_FMT_STRING(U16MSB); - CHECK_FMT_STRING(S16MSB); - CHECK_FMT_STRING(U16SYS); - CHECK_FMT_STRING(S16SYS); - CHECK_FMT_STRING(U16); - CHECK_FMT_STRING(S16); - CHECK_FMT_STRING(S32LSB); - CHECK_FMT_STRING(S32MSB); - CHECK_FMT_STRING(S32SYS); - CHECK_FMT_STRING(S32); - CHECK_FMT_STRING(F32LSB); - CHECK_FMT_STRING(F32MSB); - CHECK_FMT_STRING(F32SYS); - CHECK_FMT_STRING(F32); -#undef CHECK_FMT_STRING - return 0; -} - -int -SDL_GetNumAudioDrivers(void) -{ - return SDL_arraysize(bootstrap) - 1; -} - -const char * -SDL_GetAudioDriver(int index) -{ - if (index >= 0 && index < SDL_GetNumAudioDrivers()) { - return bootstrap[index]->name; - } - return NULL; -} - -int -SDL_AudioInit(const char *driver_name) -{ - int i = 0; - int initialized = 0; - int tried_to_init = 0; - - if (SDL_WasInit(SDL_INIT_AUDIO)) { - SDL_AudioQuit(); /* shutdown driver if already running. */ - } - - SDL_zero(current_audio); - SDL_zero(open_devices); - - /* Select the proper audio driver */ - if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_AUDIODRIVER"); - } - - for (i = 0; (!initialized) && (bootstrap[i]); ++i) { - /* make sure we should even try this driver before doing so... */ - const AudioBootStrap *backend = bootstrap[i]; - if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) || - (!driver_name && backend->demand_only)) { - continue; - } - - tried_to_init = 1; - SDL_zero(current_audio); - current_audio.name = backend->name; - current_audio.desc = backend->desc; - initialized = backend->init(¤t_audio.impl); - } - - if (!initialized) { - /* specific drivers will set the error message if they fail... */ - if (!tried_to_init) { - if (driver_name) { - SDL_SetError("Audio target '%s' not available", driver_name); - } else { - SDL_SetError("No available audio device"); - } - } - - SDL_zero(current_audio); - return -1; /* No driver was available, so fail. */ - } - - current_audio.detectionLock = SDL_CreateMutex(); - - finish_audio_entry_points_init(); - - /* Make sure we have a list of devices available at startup. */ - current_audio.impl.DetectDevices(); - -#ifdef HAVE_LIBSAMPLERATE_H - LoadLibSampleRate(); -#endif - - return 0; -} - -/* - * Get the current audio driver name - */ -const char * -SDL_GetCurrentAudioDriver() -{ - return current_audio.name; -} - -/* Clean out devices that we've removed but had to keep around for stability. */ -static void -clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag) -{ - SDL_AudioDeviceItem *item = *devices; - SDL_AudioDeviceItem *prev = NULL; - int total = 0; - - while (item) { - SDL_AudioDeviceItem *next = item->next; - if (item->handle != NULL) { - total++; - prev = item; - } else { - if (prev) { - prev->next = next; - } else { - *devices = next; - } - /* these two pointers are the same if not a duplicate devname */ - if (item->name != item->original_name) { - SDL_free(item->name); - } - SDL_free(item->original_name); - SDL_free(item); - } - item = next; - } - - *devCount = total; - *removedFlag = SDL_FALSE; -} - - -int -SDL_GetNumAudioDevices(int iscapture) -{ - int retval = 0; - - if (!SDL_WasInit(SDL_INIT_AUDIO)) { - return -1; - } - - SDL_LockMutex(current_audio.detectionLock); - if (iscapture && current_audio.captureDevicesRemoved) { - clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved); - } - - if (!iscapture && current_audio.outputDevicesRemoved) { - clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved); - } - - retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; - SDL_UnlockMutex(current_audio.detectionLock); - - return retval; -} - - -const char * -SDL_GetAudioDeviceName(int index, int iscapture) -{ - const char *retval = NULL; - - if (!SDL_WasInit(SDL_INIT_AUDIO)) { - SDL_SetError("Audio subsystem is not initialized"); - return NULL; - } - - if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { - SDL_SetError("No capture support"); - return NULL; - } - - if (index >= 0) { - SDL_AudioDeviceItem *item; - int i; - - SDL_LockMutex(current_audio.detectionLock); - item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; - i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; - if (index < i) { - for (i--; i > index; i--, item = item->next) { - SDL_assert(item != NULL); - } - SDL_assert(item != NULL); - retval = item->name; - } - SDL_UnlockMutex(current_audio.detectionLock); - } - - if (retval == NULL) { - SDL_SetError("No such device"); - } - - return retval; -} - - -static void -close_audio_device(SDL_AudioDevice * device) -{ - if (!device) { - return; - } - - /* make sure the device is paused before we do anything else, so the - audio callback definitely won't fire again. */ - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, 1); - SDL_AtomicSet(&device->shutdown, 1); - SDL_AtomicSet(&device->enabled, 0); - current_audio.impl.UnlockDevice(device); - - if (device->thread != NULL) { - SDL_WaitThread(device->thread, NULL); - } - if (device->mixer_lock != NULL) { - SDL_DestroyMutex(device->mixer_lock); - } - - SDL_free(device->work_buffer); - SDL_FreeAudioStream(device->stream); - - if (device->id > 0) { - SDL_AudioDevice *opendev = open_devices[device->id - 1]; - SDL_assert((opendev == device) || (opendev == NULL)); - if (opendev == device) { - open_devices[device->id - 1] = NULL; - } - } - - if (device->hidden != NULL) { - current_audio.impl.CloseDevice(device); - } - - SDL_FreeDataQueue(device->buffer_queue); - - SDL_free(device); -} - - -/* - * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig). - * Fills in a sanitized copy in (prepared). - * Returns non-zero if okay, zero on fatal parameters in (orig). - */ -static int -prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared) -{ - SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec)); - - if (orig->freq == 0) { - const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); - if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) { - prepared->freq = 22050; /* a reasonable default */ - } - } - - if (orig->format == 0) { - const char *env = SDL_getenv("SDL_AUDIO_FORMAT"); - if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) { - prepared->format = AUDIO_S16; /* a reasonable default */ - } - } - - switch (orig->channels) { - case 0:{ - const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); - if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) { - prepared->channels = 2; /* a reasonable default */ - } - break; - } - case 1: /* Mono */ - case 2: /* Stereo */ - case 4: /* Quadrophonic */ - case 6: /* 5.1 surround */ - case 8: /* 7.1 surround */ - break; - default: - SDL_SetError("Unsupported number of audio channels."); - return 0; - } - - if (orig->samples == 0) { - const char *env = SDL_getenv("SDL_AUDIO_SAMPLES"); - if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) { - /* Pick a default of ~46 ms at desired frequency */ - /* !!! FIXME: remove this when the non-Po2 resampling is in. */ - const int samples = (prepared->freq / 1000) * 46; - int power2 = 1; - while (power2 < samples) { - power2 *= 2; - } - prepared->samples = power2; - } - } - - /* Calculate the silence and size of the audio specification */ - SDL_CalculateAudioSpec(prepared); - - return 1; -} - -static SDL_AudioDeviceID -open_audio_device(const char *devname, int iscapture, - const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, - int allowed_changes, int min_id) -{ - const SDL_bool is_internal_thread = (desired->callback == NULL); - SDL_AudioDeviceID id = 0; - SDL_AudioSpec _obtained; - SDL_AudioDevice *device; - SDL_bool build_stream; - void *handle = NULL; - int i = 0; - - if (!SDL_WasInit(SDL_INIT_AUDIO)) { - SDL_SetError("Audio subsystem is not initialized"); - return 0; - } - - if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { - SDL_SetError("No capture support"); - return 0; - } - - /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */ - /* Find an available device ID... */ - for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { - if (open_devices[id] == NULL) { - break; - } - } - - if (id == SDL_arraysize(open_devices)) { - SDL_SetError("Too many open audio devices"); - return 0; - } - - if (!obtained) { - obtained = &_obtained; - } - if (!prepare_audiospec(desired, obtained)) { - return 0; - } - - /* If app doesn't care about a specific device, let the user override. */ - if (devname == NULL) { - devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME"); - } - - /* - * Catch device names at the high level for the simple case... - * This lets us have a basic "device enumeration" for systems that - * don't have multiple devices, but makes sure the device name is - * always NULL when it hits the low level. - * - * Also make sure that the simple case prevents multiple simultaneous - * opens of the default system device. - */ - - if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) { - if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) { - SDL_SetError("No such device"); - return 0; - } - devname = NULL; - - for (i = 0; i < SDL_arraysize(open_devices); i++) { - if ((open_devices[i]) && (open_devices[i]->iscapture)) { - SDL_SetError("Audio device already open"); - return 0; - } - } - } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { - if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { - SDL_SetError("No such device"); - return 0; - } - devname = NULL; - - for (i = 0; i < SDL_arraysize(open_devices); i++) { - if ((open_devices[i]) && (!open_devices[i]->iscapture)) { - SDL_SetError("Audio device already open"); - return 0; - } - } - } else if (devname != NULL) { - /* if the app specifies an exact string, we can pass the backend - an actual device handle thingey, which saves them the effort of - figuring out what device this was (such as, reenumerating - everything again to find the matching human-readable name). - It might still need to open a device based on the string for, - say, a network audio server, but this optimizes some cases. */ - SDL_AudioDeviceItem *item; - SDL_LockMutex(current_audio.detectionLock); - for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) { - if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) { - handle = item->handle; - break; - } - } - SDL_UnlockMutex(current_audio.detectionLock); - } - - if (!current_audio.impl.AllowsArbitraryDeviceNames) { - /* has to be in our device list, or the default device. */ - if ((handle == NULL) && (devname != NULL)) { - SDL_SetError("No such device."); - return 0; - } - } - - device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice)); - if (device == NULL) { - SDL_OutOfMemory(); - return 0; - } - device->id = id + 1; - device->spec = *obtained; - device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; - device->handle = handle; - - SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ - SDL_AtomicSet(&device->paused, 1); - SDL_AtomicSet(&device->enabled, 1); - - /* Create a mutex for locking the sound buffers */ - if (!current_audio.impl.SkipMixerLock) { - device->mixer_lock = SDL_CreateMutex(); - if (device->mixer_lock == NULL) { - close_audio_device(device); - SDL_SetError("Couldn't create mixer lock"); - return 0; - } - } - - if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) { - close_audio_device(device); - return 0; - } - - /* if your target really doesn't need it, set it to 0x1 or something. */ - /* otherwise, close_audio_device() won't call impl.CloseDevice(). */ - SDL_assert(device->hidden != NULL); - - /* See if we need to do any conversion */ - build_stream = SDL_FALSE; - if (obtained->freq != device->spec.freq) { - if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) { - obtained->freq = device->spec.freq; - } else { - build_stream = SDL_TRUE; - } - } - if (obtained->format != device->spec.format) { - if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) { - obtained->format = device->spec.format; - } else { - build_stream = SDL_TRUE; - } - } - if (obtained->channels != device->spec.channels) { - if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) { - obtained->channels = device->spec.channels; - } else { - build_stream = SDL_TRUE; - } - } - if (device->spec.samples != obtained->samples) { - if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) { - obtained->samples = device->spec.samples; - } else { - build_stream = SDL_TRUE; - } - } - - SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ - - device->callbackspec = *obtained; - - if (build_stream) { - if (iscapture) { - device->stream = SDL_NewAudioStream(device->spec.format, - device->spec.channels, device->spec.freq, - obtained->format, obtained->channels, obtained->freq); - } else { - device->stream = SDL_NewAudioStream(obtained->format, obtained->channels, - obtained->freq, device->spec.format, - device->spec.channels, device->spec.freq); - } - - if (!device->stream) { - close_audio_device(device); - return 0; - } - } - - if (device->spec.callback == NULL) { /* use buffer queueing? */ - /* pool a few packets to start. Enough for two callbacks. */ - device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2); - if (!device->buffer_queue) { - close_audio_device(device); - SDL_SetError("Couldn't create audio buffer queue"); - return 0; - } - device->callbackspec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback; - device->callbackspec.userdata = device; - } - - /* Allocate a scratch audio buffer */ - device->work_buffer_len = build_stream ? device->callbackspec.size : 0; - if (device->spec.size > device->work_buffer_len) { - device->work_buffer_len = device->spec.size; - } - SDL_assert(device->work_buffer_len > 0); - - device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len); - if (device->work_buffer == NULL) { - close_audio_device(device); - SDL_OutOfMemory(); - return 0; - } - - open_devices[id] = device; /* add it to our list of open devices. */ - - /* Start the audio thread if necessary */ - if (!current_audio.impl.ProvidesOwnCallbackThread) { - /* Start the audio thread */ - /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */ - /* buffer queueing callback only needs a few bytes, so make the stack tiny. */ - const size_t stacksize = is_internal_thread ? 64 * 1024 : 0; - char threadname[64]; - - SDL_snprintf(threadname, sizeof (threadname), "SDLAudio%c%d", (iscapture) ? 'C' : 'P', (int) device->id); - device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device); - - if (device->thread == NULL) { - close_audio_device(device); - SDL_SetError("Couldn't create audio thread"); - return 0; - } - } - - return device->id; -} - - -int -SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) -{ - SDL_AudioDeviceID id = 0; - - /* Start up the audio driver, if necessary. This is legacy behaviour! */ - if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { - return -1; - } - } - - /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */ - if (open_devices[0] != NULL) { - SDL_SetError("Audio device is already opened"); - return -1; - } - - if (obtained) { - id = open_audio_device(NULL, 0, desired, obtained, - SDL_AUDIO_ALLOW_ANY_CHANGE, 1); - } else { - SDL_AudioSpec _obtained; - SDL_zero(_obtained); - id = open_audio_device(NULL, 0, desired, &_obtained, 0, 1); - /* On successful open, copy calculated values into 'desired'. */ - if (id > 0) { - desired->size = _obtained.size; - desired->silence = _obtained.silence; - } - } - - SDL_assert((id == 0) || (id == 1)); - return (id == 0) ? -1 : 0; -} - -SDL_AudioDeviceID -SDL_OpenAudioDevice(const char *device, int iscapture, - const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, - int allowed_changes) -{ - return open_audio_device(device, iscapture, desired, obtained, - allowed_changes, 2); -} - -SDL_AudioStatus -SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) -{ - SDL_AudioDevice *device = get_audio_device(devid); - SDL_AudioStatus status = SDL_AUDIO_STOPPED; - if (device && SDL_AtomicGet(&device->enabled)) { - if (SDL_AtomicGet(&device->paused)) { - status = SDL_AUDIO_PAUSED; - } else { - status = SDL_AUDIO_PLAYING; - } - } - return status; -} - - -SDL_AudioStatus -SDL_GetAudioStatus(void) -{ - return SDL_GetAudioDeviceStatus(1); -} - -void -SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) -{ - SDL_AudioDevice *device = get_audio_device(devid); - if (device) { - current_audio.impl.LockDevice(device); - SDL_AtomicSet(&device->paused, pause_on ? 1 : 0); - current_audio.impl.UnlockDevice(device); - } -} - -void -SDL_PauseAudio(int pause_on) -{ - SDL_PauseAudioDevice(1, pause_on); -} - - -void -SDL_LockAudioDevice(SDL_AudioDeviceID devid) -{ - /* Obtain a lock on the mixing buffers */ - SDL_AudioDevice *device = get_audio_device(devid); - if (device) { - current_audio.impl.LockDevice(device); - } -} - -void -SDL_LockAudio(void) -{ - SDL_LockAudioDevice(1); -} - -void -SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) -{ - /* Obtain a lock on the mixing buffers */ - SDL_AudioDevice *device = get_audio_device(devid); - if (device) { - current_audio.impl.UnlockDevice(device); - } -} - -void -SDL_UnlockAudio(void) -{ - SDL_UnlockAudioDevice(1); -} - -void -SDL_CloseAudioDevice(SDL_AudioDeviceID devid) -{ - close_audio_device(get_audio_device(devid)); -} - -void -SDL_CloseAudio(void) -{ - SDL_CloseAudioDevice(1); -} - -void -SDL_AudioQuit(void) -{ - SDL_AudioDeviceID i; - - if (!current_audio.name) { /* not initialized?! */ - return; - } - - for (i = 0; i < SDL_arraysize(open_devices); i++) { - close_audio_device(open_devices[i]); - } - - free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); - free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); - - /* Free the driver data */ - current_audio.impl.Deinitialize(); - - SDL_DestroyMutex(current_audio.detectionLock); - - SDL_zero(current_audio); - SDL_zero(open_devices); - -#ifdef HAVE_LIBSAMPLERATE_H - UnloadLibSampleRate(); -#endif - - SDL_FreeResampleFilter(); -} - -#define NUM_FORMATS 10 -static int format_idx; -static int format_idx_sub; -static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = { - {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, - {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, - {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, -}; - -SDL_AudioFormat -SDL_FirstAudioFormat(SDL_AudioFormat format) -{ - for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) { - if (format_list[format_idx][0] == format) { - break; - } - } - format_idx_sub = 0; - return SDL_NextAudioFormat(); -} - -SDL_AudioFormat -SDL_NextAudioFormat(void) -{ - if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) { - return 0; - } - return format_list[format_idx][format_idx_sub++]; -} - -void -SDL_CalculateAudioSpec(SDL_AudioSpec * spec) -{ - switch (spec->format) { - case AUDIO_U8: - spec->silence = 0x80; - break; - default: - spec->silence = 0x00; - break; - } - spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8; - spec->size *= spec->channels; - spec->size *= spec->samples; -} - - -/* - * Moved here from SDL_mixer.c, since it relies on internals of an opened - * audio device (and is deprecated, by the way!). - */ -void -SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume) -{ - /* Mix the user-level audio format */ - SDL_AudioDevice *device = get_audio_device(1); - if (device != NULL) { - SDL_MixAudioFormat(dst, src, device->callbackspec.format, len, volume); - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audio_c.h b/Source/3rdParty/SDL2/src/audio/SDL_audio_c.h deleted file mode 100644 index d47ebb1..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audio_c.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_audio_c_h_ -#define SDL_audio_c_h_ - -#include "../SDL_internal.h" - -#ifndef DEBUG_CONVERT -#define DEBUG_CONVERT 0 -#endif - -#if DEBUG_CONVERT -#define LOG_DEBUG_CONVERT(from, to) fprintf(stderr, "Converting %s to %s.\n", from, to); -#else -#define LOG_DEBUG_CONVERT(from, to) -#endif - -/* Functions and variables exported from SDL_audio.c for SDL_sysaudio.c */ - -#ifdef HAVE_LIBSAMPLERATE_H -#include "samplerate.h" -extern SDL_bool SRC_available; -extern int SRC_converter; -extern SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error); -extern int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data); -extern int (*SRC_src_reset)(SRC_STATE *state); -extern SRC_STATE* (*SRC_src_delete)(SRC_STATE *state); -extern const char* (*SRC_src_strerror)(int error); -#endif - -/* Functions to get a list of "close" audio formats */ -extern SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format); -extern SDL_AudioFormat SDL_NextAudioFormat(void); - -/* Function to calculate the size and silence for a SDL_AudioSpec */ -extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec); - -/* Choose the audio filter functions below */ -extern void SDL_ChooseAudioConverters(void); - -/* These pointers get set during SDL_ChooseAudioConverters() to various SIMD implementations. */ -extern SDL_AudioFilter SDL_Convert_S8_to_F32; -extern SDL_AudioFilter SDL_Convert_U8_to_F32; -extern SDL_AudioFilter SDL_Convert_S16_to_F32; -extern SDL_AudioFilter SDL_Convert_U16_to_F32; -extern SDL_AudioFilter SDL_Convert_S32_to_F32; -extern SDL_AudioFilter SDL_Convert_F32_to_S8; -extern SDL_AudioFilter SDL_Convert_F32_to_U8; -extern SDL_AudioFilter SDL_Convert_F32_to_S16; -extern SDL_AudioFilter SDL_Convert_F32_to_U16; -extern SDL_AudioFilter SDL_Convert_F32_to_S32; - -/* You need to call SDL_PrepareResampleFilter() before using the internal resampler. - SDL_AudioQuit() calls SDL_FreeResamplerFilter(), you should never call it yourself. */ -extern int SDL_PrepareResampleFilter(void); -extern void SDL_FreeResampleFilter(void); - -#endif /* SDL_audio_c_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audiocvt.c b/Source/3rdParty/SDL2/src/audio/SDL_audiocvt.c deleted file mode 100644 index ee0ba32..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audiocvt.c +++ /dev/null @@ -1,1673 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* Functions for audio drivers to perform runtime conversion of audio format */ - -/* FIXME: Channel weights when converting from more channels to fewer may need to be adjusted, see https://msdn.microsoft.com/en-us/library/windows/desktop/ff819070(v=vs.85).aspx -*/ - -#include "SDL.h" -#include "SDL_audio.h" -#include "SDL_audio_c.h" - -#include "SDL_loadso.h" -#include "SDL_assert.h" -#include "../SDL_dataqueue.h" -#include "SDL_cpuinfo.h" - -#define DEBUG_AUDIOSTREAM 0 - -#ifdef __SSE3__ -#define HAVE_SSE3_INTRINSICS 1 -#endif - -#if HAVE_SSE3_INTRINSICS -/* Convert from stereo to mono. Average left and right. */ -static void SDLCALL -SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i = cvt->len_cvt / 8; - - LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)"); - SDL_assert(format == AUDIO_F32SYS); - - /* We can only do this if dst is aligned to 16 bytes; since src is the - same pointer and it moves by 2, it can't be forcibly aligned. */ - if ((((size_t) dst) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 divby2 = _mm_set1_ps(0.5f); - while (i >= 4) { /* 4 * float32 */ - _mm_store_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_load_ps(src+4)), divby2)); - i -= 4; src += 8; dst += 4; - } - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (src[0] + src[1]) * 0.5f; - dst++; i--; src += 2; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} -#endif - -/* Convert from stereo to mono. Average left and right. */ -static void SDLCALL -SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("stereo", "mono"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / 8; i; --i, src += 2) { - *(dst++) = (src[0] + src[1]) * 0.5f; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */ -static void SDLCALL -SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - /* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */ - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 2) { - const float front_center_distributed = src[2] * 0.5f; - dst[0] = (src[0] + front_center_distributed + src[4]) / 2.5f; /* left */ - dst[1] = (src[1] + front_center_distributed + src[5]) / 2.5f; /* right */ - } - - cvt->len_cvt /= 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Convert from quad to stereo. Average left and right. */ -static void SDLCALL -SDL_ConvertQuadToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("quad", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 4); i; --i, src += 4, dst += 2) { - dst[0] = (src[0] + src[2]) * 0.5f; /* left */ - dst[1] = (src[1] + src[3]) * 0.5f; /* right */ - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Convert from 7.1 to 5.1. Distribute sides across front and back. */ -static void SDLCALL -SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("7.1", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 6) { - const float surround_left_distributed = src[6] * 0.5f; - const float surround_right_distributed = src[7] * 0.5f; - dst[0] = (src[0] + surround_left_distributed) / 1.5f; /* FL */ - dst[1] = (src[1] + surround_right_distributed) / 1.5f; /* FR */ - dst[2] = src[2] / 1.5f; /* CC */ - dst[3] = src[3] / 1.5f; /* LFE */ - dst[4] = (src[4] + surround_left_distributed) / 1.5f; /* BL */ - dst[5] = (src[5] + surround_right_distributed) / 1.5f; /* BR */ - } - - cvt->len_cvt /= 8; - cvt->len_cvt *= 6; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Convert from 5.1 to quad. Distribute center across front, discard LFE. */ -static void SDLCALL -SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float *dst = (float *) cvt->buf; - const float *src = dst; - int i; - - LOG_DEBUG_CONVERT("5.1", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - /* SDL's 4.0 layout: FL+FR+BL+BR */ - /* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */ - for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 4) { - const float front_center_distributed = src[2] * 0.5f; - dst[0] = (src[0] + front_center_distributed) / 1.5f; /* FL */ - dst[1] = (src[1] + front_center_distributed) / 1.5f; /* FR */ - dst[2] = src[4] / 1.5f; /* BL */ - dst[3] = src[5] / 1.5f; /* BR */ - } - - cvt->len_cvt /= 6; - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Upmix mono to stereo (by duplication) */ -static void SDLCALL -SDL_ConvertMonoToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) (cvt->buf + cvt->len_cvt); - float *dst = (float *) (cvt->buf + cvt->len_cvt * 2); - int i; - - LOG_DEBUG_CONVERT("mono", "stereo"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / sizeof (float); i; --i) { - src--; - dst -= 2; - dst[0] = dst[1] = *src; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Upmix stereo to a pseudo-5.1 stream */ -static void SDLCALL -SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - int i; - float lf, rf, ce; - const float *src = (const float *) (cvt->buf + cvt->len_cvt); - float *dst = (float *) (cvt->buf + cvt->len_cvt * 3); - - LOG_DEBUG_CONVERT("stereo", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof(float) * 2); i; --i) { - dst -= 6; - src -= 2; - lf = src[0]; - rf = src[1]; - ce = (lf + rf) * 0.5f; - /* !!! FIXME: FL and FR may clip */ - dst[0] = lf + (lf - ce); /* FL */ - dst[1] = rf + (rf - ce); /* FR */ - dst[2] = ce; /* FC */ - dst[3] = 0; /* LFE (only meant for special LFE effects) */ - dst[4] = lf; /* BL */ - dst[5] = rf; /* BR */ - } - - cvt->len_cvt *= 3; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Upmix quad to a pseudo-5.1 stream */ -static void SDLCALL -SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - int i; - float lf, rf, lb, rb, ce; - const float *src = (const float *) (cvt->buf + cvt->len_cvt); - float *dst = (float *) (cvt->buf + cvt->len_cvt * 3 / 2); - - LOG_DEBUG_CONVERT("quad", "5.1"); - SDL_assert(format == AUDIO_F32SYS); - SDL_assert(cvt->len_cvt % (sizeof(float) * 4) == 0); - - for (i = cvt->len_cvt / (sizeof(float) * 4); i; --i) { - dst -= 6; - src -= 4; - lf = src[0]; - rf = src[1]; - lb = src[2]; - rb = src[3]; - ce = (lf + rf) * 0.5f; - /* !!! FIXME: FL and FR may clip */ - dst[0] = lf + (lf - ce); /* FL */ - dst[1] = rf + (rf - ce); /* FR */ - dst[2] = ce; /* FC */ - dst[3] = 0; /* LFE (only meant for special LFE effects) */ - dst[4] = lb; /* BL */ - dst[5] = rb; /* BR */ - } - - cvt->len_cvt = cvt->len_cvt * 3 / 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Upmix stereo to a pseudo-4.0 stream (by duplication) */ -static void SDLCALL -SDL_ConvertStereoToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) (cvt->buf + cvt->len_cvt); - float *dst = (float *) (cvt->buf + cvt->len_cvt * 2); - float lf, rf; - int i; - - LOG_DEBUG_CONVERT("stereo", "quad"); - SDL_assert(format == AUDIO_F32SYS); - - for (i = cvt->len_cvt / (sizeof(float) * 2); i; --i) { - dst -= 4; - src -= 2; - lf = src[0]; - rf = src[1]; - dst[0] = lf; /* FL */ - dst[1] = rf; /* FR */ - dst[2] = lf; /* BL */ - dst[3] = rf; /* BR */ - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - - -/* Upmix 5.1 to 7.1 */ -static void SDLCALL -SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format) -{ - float lf, rf, lb, rb, ls, rs; - int i; - const float *src = (const float *) (cvt->buf + cvt->len_cvt); - float *dst = (float *) (cvt->buf + cvt->len_cvt * 4 / 3); - - LOG_DEBUG_CONVERT("5.1", "7.1"); - SDL_assert(format == AUDIO_F32SYS); - SDL_assert(cvt->len_cvt % (sizeof(float) * 6) == 0); - - for (i = cvt->len_cvt / (sizeof(float) * 6); i; --i) { - dst -= 8; - src -= 6; - lf = src[0]; - rf = src[1]; - lb = src[4]; - rb = src[5]; - ls = (lf + lb) * 0.5f; - rs = (rf + rb) * 0.5f; - /* !!! FIXME: these four may clip */ - lf += lf - ls; - rf += rf - ls; - lb += lb - ls; - rb += rb - ls; - dst[3] = src[3]; /* LFE */ - dst[2] = src[2]; /* FC */ - dst[7] = rs; /* SR */ - dst[6] = ls; /* SL */ - dst[5] = rb; /* BR */ - dst[4] = lb; /* BL */ - dst[1] = rf; /* FR */ - dst[0] = lf; /* FL */ - } - - cvt->len_cvt = cvt->len_cvt * 4 / 3; - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index] (cvt, format); - } -} - -/* SDL's resampler uses a "bandlimited interpolation" algorithm: - https://ccrma.stanford.edu/~jos/resample/ */ - -#define RESAMPLER_ZERO_CROSSINGS 5 -#define RESAMPLER_BITS_PER_SAMPLE 16 -#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) -#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) - -/* This is a "modified" bessel function, so you can't use POSIX j0() */ -static double -bessel(const double x) -{ - const double xdiv2 = x / 2.0; - double i0 = 1.0f; - double f = 1.0f; - int i = 1; - - while (SDL_TRUE) { - const double diff = SDL_pow(xdiv2, i * 2) / SDL_pow(f, 2); - if (diff < 1.0e-21f) { - break; - } - i0 += diff; - i++; - f *= (double) i; - } - - return i0; -} - -/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */ -static void -kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta) -{ - const int lenm1 = tablelen - 1; - const int lenm1div2 = lenm1 / 2; - int i; - - table[0] = 1.0f; - for (i = 1; i < tablelen; i++) { - const double kaiser = bessel(beta * SDL_sqrt(1.0 - SDL_pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel(beta); - table[tablelen - i] = (float) kaiser; - } - - for (i = 1; i < tablelen; i++) { - const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI); - table[i] *= SDL_sinf(x) / x; - diffs[i - 1] = table[i] - table[i - 1]; - } - diffs[lenm1] = 0.0f; -} - - -static SDL_SpinLock ResampleFilterSpinlock = 0; -static float *ResamplerFilter = NULL; -static float *ResamplerFilterDifference = NULL; - -int -SDL_PrepareResampleFilter(void) -{ - SDL_AtomicLock(&ResampleFilterSpinlock); - if (!ResamplerFilter) { - /* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */ - const double dB = 80.0; - const double beta = 0.1102 * (dB - 8.7); - const size_t alloclen = RESAMPLER_FILTER_SIZE * sizeof (float); - - ResamplerFilter = (float *) SDL_malloc(alloclen); - if (!ResamplerFilter) { - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return SDL_OutOfMemory(); - } - - ResamplerFilterDifference = (float *) SDL_malloc(alloclen); - if (!ResamplerFilterDifference) { - SDL_free(ResamplerFilter); - ResamplerFilter = NULL; - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return SDL_OutOfMemory(); - } - kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta); - } - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return 0; -} - -void -SDL_FreeResampleFilter(void) -{ - SDL_free(ResamplerFilter); - SDL_free(ResamplerFilterDifference); - ResamplerFilter = NULL; - ResamplerFilterDifference = NULL; -} - -static int -ResamplerPadding(const int inrate, const int outrate) -{ - if (inrate == outrate) { - return 0; - } else if (inrate > outrate) { - return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate))); - } - return RESAMPLER_SAMPLES_PER_ZERO_CROSSING; -} - -/* lpadding and rpadding are expected to be buffers of (ResamplePadding(inrate, outrate) * chans * sizeof (float)) bytes. */ -static int -SDL_ResampleAudio(const int chans, const int inrate, const int outrate, - const float *lpadding, const float *rpadding, - const float *inbuf, const int inbuflen, - float *outbuf, const int outbuflen) -{ - const double finrate = (double) inrate; - const double outtimeincr = 1.0 / ((float) outrate); - const double ratio = ((float) outrate) / ((float) inrate); - const int paddinglen = ResamplerPadding(inrate, outrate); - const int framelen = chans * (int)sizeof (float); - const int inframes = inbuflen / framelen; - const int wantedoutframes = (int) ((inbuflen / framelen) * ratio); /* outbuflen isn't total to write, it's total available. */ - const int maxoutframes = outbuflen / framelen; - const int outframes = SDL_min(wantedoutframes, maxoutframes); - float *dst = outbuf; - double outtime = 0.0; - int i, j, chan; - - for (i = 0; i < outframes; i++) { - const int srcindex = (int) (outtime * inrate); - const double intime = ((double) srcindex) / finrate; - const double innexttime = ((double) (srcindex + 1)) / finrate; - const double interpolation1 = 1.0 - ((innexttime - outtime) / (innexttime - intime)); - const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); - const double interpolation2 = 1.0 - interpolation1; - const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); - - for (chan = 0; chan < chans; chan++) { - float outsample = 0.0f; - - /* do this twice to calculate the sample, once for the "left wing" and then same for the right. */ - /* !!! FIXME: do both wings in one loop */ - for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { - const int srcframe = srcindex - j; - /* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */ - const float insample = (srcframe < 0) ? lpadding[((paddinglen + srcframe) * chans) + chan] : inbuf[(srcframe * chans) + chan]; - outsample += (float)(insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); - } - - for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { - const int srcframe = srcindex + 1 + j; - /* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */ - const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan]; - outsample += (float)(insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); - } - *(dst++) = outsample; - } - - outtime += outtimeincr; - } - - return outframes * chans * sizeof (float); -} - -int -SDL_ConvertAudio(SDL_AudioCVT * cvt) -{ - /* !!! FIXME: (cvt) should be const; stack-copy it here. */ - /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */ - - /* Make sure there's data to convert */ - if (cvt->buf == NULL) { - return SDL_SetError("No buffer allocated for conversion"); - } - - /* Return okay if no conversion is necessary */ - cvt->len_cvt = cvt->len; - if (cvt->filters[0] == NULL) { - return 0; - } - - /* Set up the conversion and go! */ - cvt->filter_index = 0; - cvt->filters[0] (cvt, cvt->src_format); - return 0; -} - -static void SDLCALL -SDL_Convert_Byteswap(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ -#if DEBUG_CONVERT - printf("Converting byte order\n"); -#endif - - switch (SDL_AUDIO_BITSIZE(format)) { - #define CASESWAP(b) \ - case b: { \ - Uint##b *ptr = (Uint##b *) cvt->buf; \ - int i; \ - for (i = cvt->len_cvt / sizeof (*ptr); i; --i, ++ptr) { \ - *ptr = SDL_Swap##b(*ptr); \ - } \ - break; \ - } - - CASESWAP(16); - CASESWAP(32); - CASESWAP(64); - - #undef CASESWAP - - default: SDL_assert(!"unhandled byteswap datatype!"); break; - } - - if (cvt->filters[++cvt->filter_index]) { - /* flip endian flag for data. */ - if (format & SDL_AUDIO_MASK_ENDIAN) { - format &= ~SDL_AUDIO_MASK_ENDIAN; - } else { - format |= SDL_AUDIO_MASK_ENDIAN; - } - cvt->filters[cvt->filter_index](cvt, format); - } -} - -static int -SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, const SDL_AudioFilter filter) -{ - if (cvt->filter_index >= SDL_AUDIOCVT_MAX_FILTERS) { - return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS); - } - if (filter == NULL) { - return SDL_SetError("Audio filter pointer is NULL"); - } - cvt->filters[cvt->filter_index++] = filter; - cvt->filters[cvt->filter_index] = NULL; /* Moving terminator */ - return 0; -} - -static int -SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt) -{ - int retval = 0; /* 0 == no conversion necessary. */ - - if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { - return -1; - } - retval = 1; /* added a converter. */ - } - - if (!SDL_AUDIO_ISFLOAT(src_fmt)) { - const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt); - const Uint16 dst_bitsize = 32; - SDL_AudioFilter filter = NULL; - - switch (src_fmt & ~SDL_AUDIO_MASK_ENDIAN) { - case AUDIO_S8: filter = SDL_Convert_S8_to_F32; break; - case AUDIO_U8: filter = SDL_Convert_U8_to_F32; break; - case AUDIO_S16: filter = SDL_Convert_S16_to_F32; break; - case AUDIO_U16: filter = SDL_Convert_U16_to_F32; break; - case AUDIO_S32: filter = SDL_Convert_S32_to_F32; break; - default: SDL_assert(!"Unexpected audio format!"); break; - } - - if (!filter) { - return SDL_SetError("No conversion from source format to float available"); - } - - if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { - return -1; - } - if (src_bitsize < dst_bitsize) { - const int mult = (dst_bitsize / src_bitsize); - cvt->len_mult *= mult; - cvt->len_ratio *= mult; - } else if (src_bitsize > dst_bitsize) { - cvt->len_ratio /= (src_bitsize / dst_bitsize); - } - - retval = 1; /* added a converter. */ - } - - return retval; -} - -static int -SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt) -{ - int retval = 0; /* 0 == no conversion necessary. */ - - if (!SDL_AUDIO_ISFLOAT(dst_fmt)) { - const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt); - const Uint16 src_bitsize = 32; - SDL_AudioFilter filter = NULL; - switch (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN) { - case AUDIO_S8: filter = SDL_Convert_F32_to_S8; break; - case AUDIO_U8: filter = SDL_Convert_F32_to_U8; break; - case AUDIO_S16: filter = SDL_Convert_F32_to_S16; break; - case AUDIO_U16: filter = SDL_Convert_F32_to_U16; break; - case AUDIO_S32: filter = SDL_Convert_F32_to_S32; break; - default: SDL_assert(!"Unexpected audio format!"); break; - } - - if (!filter) { - return SDL_SetError("No conversion from float to destination format available"); - } - - if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { - return -1; - } - if (src_bitsize < dst_bitsize) { - const int mult = (dst_bitsize / src_bitsize); - cvt->len_mult *= mult; - cvt->len_ratio *= mult; - } else if (src_bitsize > dst_bitsize) { - cvt->len_ratio /= (src_bitsize / dst_bitsize); - } - retval = 1; /* added a converter. */ - } - - if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { - return -1; - } - retval = 1; /* added a converter. */ - } - - return retval; -} - -static void -SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format) -{ - /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator). - !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates, - !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */ - const int inrate = (int) (size_t) cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1]; - const int outrate = (int) (size_t) cvt->filters[SDL_AUDIOCVT_MAX_FILTERS]; - const float *src = (const float *) cvt->buf; - const int srclen = cvt->len_cvt; - /*float *dst = (float *) cvt->buf; - const int dstlen = (cvt->len * cvt->len_mult);*/ - /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ - float *dst = (float *) (cvt->buf + srclen); - const int dstlen = (cvt->len * cvt->len_mult) - srclen; - const int paddingsamples = (ResamplerPadding(inrate, outrate) * chans); - float *padding; - - SDL_assert(format == AUDIO_F32SYS); - - /* we keep no streaming state here, so pad with silence on both ends. */ - padding = (float *) SDL_calloc(paddingsamples ? paddingsamples : 1, sizeof (float)); - if (!padding) { - SDL_OutOfMemory(); - return; - } - - cvt->len_cvt = SDL_ResampleAudio(chans, inrate, outrate, padding, padding, src, srclen, dst, dstlen); - - SDL_free(padding); - - SDL_memmove(cvt->buf, dst, cvt->len_cvt); /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, format); - } -} - -/* !!! FIXME: We only have this macro salsa because SDL_AudioCVT doesn't - !!! FIXME: store channel info, so we have to have function entry - !!! FIXME: points for each supported channel count and multiple - !!! FIXME: vs arbitrary. When we rev the ABI, clean this up. */ -#define RESAMPLER_FUNCS(chans) \ - static void SDLCALL \ - SDL_ResampleCVT_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) { \ - SDL_ResampleCVT(cvt, chans, format); \ - } -RESAMPLER_FUNCS(1) -RESAMPLER_FUNCS(2) -RESAMPLER_FUNCS(4) -RESAMPLER_FUNCS(6) -RESAMPLER_FUNCS(8) -#undef RESAMPLER_FUNCS - -static SDL_AudioFilter -ChooseCVTResampler(const int dst_channels) -{ - switch (dst_channels) { - case 1: return SDL_ResampleCVT_c1; - case 2: return SDL_ResampleCVT_c2; - case 4: return SDL_ResampleCVT_c4; - case 6: return SDL_ResampleCVT_c6; - case 8: return SDL_ResampleCVT_c8; - default: break; - } - - return NULL; -} - -static int -SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels, - const int src_rate, const int dst_rate) -{ - SDL_AudioFilter filter; - - if (src_rate == dst_rate) { - return 0; /* no conversion necessary. */ - } - - filter = ChooseCVTResampler(dst_channels); - if (filter == NULL) { - return SDL_SetError("No conversion available for these rates"); - } - - if (SDL_PrepareResampleFilter() < 0) { - return -1; - } - - /* Update (cvt) with filter details... */ - if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { - return -1; - } - - /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator). - !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates, - !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */ - if (cvt->filter_index >= (SDL_AUDIOCVT_MAX_FILTERS-2)) { - return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS-2); - } - cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1] = (SDL_AudioFilter) (size_t) src_rate; - cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter) (size_t) dst_rate; - - if (src_rate < dst_rate) { - const double mult = ((double) dst_rate) / ((double) src_rate); - cvt->len_mult *= (int) SDL_ceil(mult); - cvt->len_ratio *= mult; - } else { - cvt->len_ratio /= ((double) src_rate) / ((double) dst_rate); - } - - /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ - /* the buffer is big enough to hold the destination now, but - we need it large enough to hold a separate scratch buffer. */ - cvt->len_mult *= 2; - - return 1; /* added a converter. */ -} - -static SDL_bool -SDL_SupportedAudioFormat(const SDL_AudioFormat fmt) -{ - switch (fmt) { - case AUDIO_U8: - case AUDIO_S8: - case AUDIO_U16LSB: - case AUDIO_S16LSB: - case AUDIO_U16MSB: - case AUDIO_S16MSB: - case AUDIO_S32LSB: - case AUDIO_S32MSB: - case AUDIO_F32LSB: - case AUDIO_F32MSB: - return SDL_TRUE; /* supported. */ - - default: - break; - } - - return SDL_FALSE; /* unsupported. */ -} - -static SDL_bool -SDL_SupportedChannelCount(const int channels) -{ - switch (channels) { - case 1: /* mono */ - case 2: /* stereo */ - case 4: /* quad */ - case 6: /* 5.1 */ - case 8: /* 7.1 */ - return SDL_TRUE; /* supported. */ - - default: - break; - } - - return SDL_FALSE; /* unsupported. */ -} - - -/* Creates a set of audio filters to convert from one format to another. - Returns 0 if no conversion is needed, 1 if the audio filter is set up, - or -1 if an error like invalid parameter, unsupported format, etc. occurred. -*/ - -int -SDL_BuildAudioCVT(SDL_AudioCVT * cvt, - SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate, - SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate) -{ - /* Sanity check target pointer */ - if (cvt == NULL) { - return SDL_InvalidParamError("cvt"); - } - - /* Make sure we zero out the audio conversion before error checking */ - SDL_zerop(cvt); - - if (!SDL_SupportedAudioFormat(src_fmt)) { - return SDL_SetError("Invalid source format"); - } else if (!SDL_SupportedAudioFormat(dst_fmt)) { - return SDL_SetError("Invalid destination format"); - } else if (!SDL_SupportedChannelCount(src_channels)) { - return SDL_SetError("Invalid source channels"); - } else if (!SDL_SupportedChannelCount(dst_channels)) { - return SDL_SetError("Invalid destination channels"); - } else if (src_rate == 0) { - return SDL_SetError("Source rate is zero"); - } else if (dst_rate == 0) { - return SDL_SetError("Destination rate is zero"); - } - -#if DEBUG_CONVERT - printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n", - src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate); -#endif - - /* Start off with no conversion necessary */ - cvt->src_format = src_fmt; - cvt->dst_format = dst_fmt; - cvt->needed = 0; - cvt->filter_index = 0; - SDL_zero(cvt->filters); - cvt->len_mult = 1; - cvt->len_ratio = 1.0; - cvt->rate_incr = ((double) dst_rate) / ((double) src_rate); - - /* Make sure we've chosen audio conversion functions (MMX, scalar, etc.) */ - SDL_ChooseAudioConverters(); - - /* Type conversion goes like this now: - - byteswap to CPU native format first if necessary. - - convert to native Float32 if necessary. - - resample and change channel count if necessary. - - convert back to native format. - - byteswap back to foreign format if necessary. - - The expectation is we can process data faster in float32 - (possibly with SIMD), and making several passes over the same - buffer is likely to be CPU cache-friendly, avoiding the - biggest performance hit in modern times. Previously we had - (script-generated) custom converters for every data type and - it was a bloat on SDL compile times and final library size. */ - - /* see if we can skip float conversion entirely. */ - if (src_rate == dst_rate && src_channels == dst_channels) { - if (src_fmt == dst_fmt) { - return 0; - } - - /* just a byteswap needed? */ - if ((src_fmt & ~SDL_AUDIO_MASK_ENDIAN) == (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { - return -1; - } - cvt->needed = 1; - return 1; - } - } - - /* Convert data types, if necessary. Updates (cvt). */ - if (SDL_BuildAudioTypeCVTToFloat(cvt, src_fmt) < 0) { - return -1; /* shouldn't happen, but just in case... */ - } - - /* Channel conversion */ - if (src_channels < dst_channels) { - /* Upmixing */ - /* Mono -> Stereo [-> ...] */ - if ((src_channels == 1) && (dst_channels > 1)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertMonoToStereo) < 0) { - return -1; - } - cvt->len_mult *= 2; - src_channels = 2; - cvt->len_ratio *= 2; - } - /* [Mono ->] Stereo -> 5.1 [-> 7.1] */ - if ((src_channels == 2) && (dst_channels >= 6)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertStereoTo51) < 0) { - return -1; - } - src_channels = 6; - cvt->len_mult *= 3; - cvt->len_ratio *= 3; - } - /* Quad -> 5.1 [-> 7.1] */ - if ((src_channels == 4) && (dst_channels >= 6)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertQuadTo51) < 0) { - return -1; - } - src_channels = 6; - cvt->len_mult = (cvt->len_mult * 3 + 1) / 2; - cvt->len_ratio *= 1.5; - } - /* [[Mono ->] Stereo ->] 5.1 -> 7.1 */ - if ((src_channels == 6) && (dst_channels == 8)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51To71) < 0) { - return -1; - } - src_channels = 8; - cvt->len_mult = (cvt->len_mult * 4 + 2) / 3; - /* Should be numerically exact with every valid input to this - function */ - cvt->len_ratio = cvt->len_ratio * 4 / 3; - } - /* [Mono ->] Stereo -> Quad */ - if ((src_channels == 2) && (dst_channels == 4)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertStereoToQuad) < 0) { - return -1; - } - src_channels = 4; - cvt->len_mult *= 2; - cvt->len_ratio *= 2; - } - } else if (src_channels > dst_channels) { - /* Downmixing */ - /* 7.1 -> 5.1 [-> Stereo [-> Mono]] */ - /* 7.1 -> 5.1 [-> Quad] */ - if ((src_channels == 8) && (dst_channels <= 6)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert71To51) < 0) { - return -1; - } - src_channels = 6; - cvt->len_ratio *= 0.75; - } - /* [7.1 ->] 5.1 -> Stereo [-> Mono] */ - if ((src_channels == 6) && (dst_channels <= 2)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51ToStereo) < 0) { - return -1; - } - src_channels = 2; - cvt->len_ratio /= 3; - } - /* 5.1 -> Quad */ - if ((src_channels == 6) && (dst_channels == 4)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51ToQuad) < 0) { - return -1; - } - src_channels = 4; - cvt->len_ratio = cvt->len_ratio * 2 / 3; - } - /* Quad -> Stereo [-> Mono] */ - if ((src_channels == 4) && (dst_channels <= 2)) { - if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertQuadToStereo) < 0) { - return -1; - } - src_channels = 2; - cvt->len_ratio /= 2; - } - /* [... ->] Stereo -> Mono */ - if ((src_channels == 2) && (dst_channels == 1)) { - SDL_AudioFilter filter = NULL; - - #if HAVE_SSE3_INTRINSICS - if (SDL_HasSSE3()) { - filter = SDL_ConvertStereoToMono_SSE3; - } - #endif - - if (!filter) { - filter = SDL_ConvertStereoToMono; - } - - if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { - return -1; - } - - src_channels = 1; - cvt->len_ratio /= 2; - } - } - - if (src_channels != dst_channels) { - /* All combinations of supported channel counts should have been - handled by now, but let's be defensive */ - return SDL_SetError("Invalid channel combination"); - } - - /* Do rate conversion, if necessary. Updates (cvt). */ - if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) { - return -1; /* shouldn't happen, but just in case... */ - } - - /* Move to final data type. */ - if (SDL_BuildAudioTypeCVTFromFloat(cvt, dst_fmt) < 0) { - return -1; /* shouldn't happen, but just in case... */ - } - - cvt->needed = (cvt->filter_index != 0); - return (cvt->needed); -} - -typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *inbuf, const int inbuflen, void *outbuf, const int outbuflen); -typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream); -typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream); - -struct _SDL_AudioStream -{ - SDL_AudioCVT cvt_before_resampling; - SDL_AudioCVT cvt_after_resampling; - SDL_DataQueue *queue; - SDL_bool first_run; - Uint8 *staging_buffer; - int staging_buffer_size; - int staging_buffer_filled; - Uint8 *work_buffer_base; /* maybe unaligned pointer from SDL_realloc(). */ - int work_buffer_len; - int src_sample_frame_size; - SDL_AudioFormat src_format; - Uint8 src_channels; - int src_rate; - int dst_sample_frame_size; - SDL_AudioFormat dst_format; - Uint8 dst_channels; - int dst_rate; - double rate_incr; - Uint8 pre_resample_channels; - int packetlen; - int resampler_padding_samples; - float *resampler_padding; - void *resampler_state; - SDL_ResampleAudioStreamFunc resampler_func; - SDL_ResetAudioStreamResamplerFunc reset_resampler_func; - SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func; -}; - -static Uint8 * -EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen) -{ - Uint8 *ptr; - size_t offset; - - if (stream->work_buffer_len >= newlen) { - ptr = stream->work_buffer_base; - } else { - ptr = (Uint8 *) SDL_realloc(stream->work_buffer_base, newlen + 32); - if (!ptr) { - SDL_OutOfMemory(); - return NULL; - } - /* Make sure we're aligned to 16 bytes for SIMD code. */ - stream->work_buffer_base = ptr; - stream->work_buffer_len = newlen; - } - - offset = ((size_t) ptr) & 15; - return offset ? ptr + (16 - offset) : ptr; -} - -#ifdef HAVE_LIBSAMPLERATE_H -static int -SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen) -{ - const float *inbuf = (const float *) _inbuf; - float *outbuf = (float *) _outbuf; - const int framelen = sizeof(float) * stream->pre_resample_channels; - SRC_STATE *state = (SRC_STATE *)stream->resampler_state; - SRC_DATA data; - int result; - - SDL_assert(inbuf != ((const float *) outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */ - - data.data_in = (float *)inbuf; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */ - data.input_frames = inbuflen / framelen; - data.input_frames_used = 0; - - data.data_out = outbuf; - data.output_frames = outbuflen / framelen; - - data.end_of_input = 0; - data.src_ratio = stream->rate_incr; - - result = SRC_src_process(state, &data); - if (result != 0) { - SDL_SetError("src_process() failed: %s", SRC_src_strerror(result)); - return 0; - } - - /* If this fails, we need to store them off somewhere */ - SDL_assert(data.input_frames_used == data.input_frames); - - return data.output_frames_gen * (sizeof(float) * stream->pre_resample_channels); -} - -static void -SDL_ResetAudioStreamResampler_SRC(SDL_AudioStream *stream) -{ - SRC_src_reset((SRC_STATE *)stream->resampler_state); -} - -static void -SDL_CleanupAudioStreamResampler_SRC(SDL_AudioStream *stream) -{ - SRC_STATE *state = (SRC_STATE *)stream->resampler_state; - if (state) { - SRC_src_delete(state); - } - - stream->resampler_state = NULL; - stream->resampler_func = NULL; - stream->reset_resampler_func = NULL; - stream->cleanup_resampler_func = NULL; -} - -static SDL_bool -SetupLibSampleRateResampling(SDL_AudioStream *stream) -{ - int result = 0; - SRC_STATE *state = NULL; - - if (SRC_available) { - state = SRC_src_new(SRC_converter, stream->pre_resample_channels, &result); - if (!state) { - SDL_SetError("src_new() failed: %s", SRC_src_strerror(result)); - } - } - - if (!state) { - SDL_CleanupAudioStreamResampler_SRC(stream); - return SDL_FALSE; - } - - stream->resampler_state = state; - stream->resampler_func = SDL_ResampleAudioStream_SRC; - stream->reset_resampler_func = SDL_ResetAudioStreamResampler_SRC; - stream->cleanup_resampler_func = SDL_CleanupAudioStreamResampler_SRC; - - return SDL_TRUE; -} -#endif /* HAVE_LIBSAMPLERATE_H */ - - -static int -SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen) -{ - const Uint8 *inbufend = ((const Uint8 *) _inbuf) + inbuflen; - const float *inbuf = (const float *) _inbuf; - float *outbuf = (float *) _outbuf; - const int chans = (int) stream->pre_resample_channels; - const int inrate = stream->src_rate; - const int outrate = stream->dst_rate; - const int paddingsamples = stream->resampler_padding_samples; - const int paddingbytes = paddingsamples * sizeof (float); - float *lpadding = (float *) stream->resampler_state; - const float *rpadding = (const float *) inbufend; /* we set this up so there are valid padding samples at the end of the input buffer. */ - const int cpy = SDL_min(inbuflen, paddingbytes); - int retval; - - SDL_assert(inbuf != ((const float *) outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */ - - retval = SDL_ResampleAudio(chans, inrate, outrate, lpadding, rpadding, inbuf, inbuflen, outbuf, outbuflen); - - /* update our left padding with end of current input, for next run. */ - SDL_memcpy((lpadding + paddingsamples) - (cpy / sizeof (float)), inbufend - cpy, cpy); - return retval; -} - -static void -SDL_ResetAudioStreamResampler(SDL_AudioStream *stream) -{ - /* set all the padding to silence. */ - const int len = stream->resampler_padding_samples; - SDL_memset(stream->resampler_state, '\0', len * sizeof (float)); -} - -static void -SDL_CleanupAudioStreamResampler(SDL_AudioStream *stream) -{ - SDL_free(stream->resampler_state); -} - -SDL_AudioStream * -SDL_NewAudioStream(const SDL_AudioFormat src_format, - const Uint8 src_channels, - const int src_rate, - const SDL_AudioFormat dst_format, - const Uint8 dst_channels, - const int dst_rate) -{ - const int packetlen = 4096; /* !!! FIXME: good enough for now. */ - Uint8 pre_resample_channels; - SDL_AudioStream *retval; - - retval = (SDL_AudioStream *) SDL_calloc(1, sizeof (SDL_AudioStream)); - if (!retval) { - return NULL; - } - - /* If increasing channels, do it after resampling, since we'd just - do more work to resample duplicate channels. If we're decreasing, do - it first so we resample the interpolated data instead of interpolating - the resampled data (!!! FIXME: decide if that works in practice, though!). */ - pre_resample_channels = SDL_min(src_channels, dst_channels); - - retval->first_run = SDL_TRUE; - retval->src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_format) / 8) * src_channels; - retval->src_format = src_format; - retval->src_channels = src_channels; - retval->src_rate = src_rate; - retval->dst_sample_frame_size = (SDL_AUDIO_BITSIZE(dst_format) / 8) * dst_channels; - retval->dst_format = dst_format; - retval->dst_channels = dst_channels; - retval->dst_rate = dst_rate; - retval->pre_resample_channels = pre_resample_channels; - retval->packetlen = packetlen; - retval->rate_incr = ((double) dst_rate) / ((double) src_rate); - retval->resampler_padding_samples = ResamplerPadding(retval->src_rate, retval->dst_rate) * pre_resample_channels; - retval->resampler_padding = (float *) SDL_calloc(retval->resampler_padding_samples ? retval->resampler_padding_samples : 1, sizeof (float)); - - if (retval->resampler_padding == NULL) { - SDL_FreeAudioStream(retval); - SDL_OutOfMemory(); - return NULL; - } - - retval->staging_buffer_size = ((retval->resampler_padding_samples / retval->pre_resample_channels) * retval->src_sample_frame_size); - if (retval->staging_buffer_size > 0) { - retval->staging_buffer = (Uint8 *) SDL_malloc(retval->staging_buffer_size); - if (retval->staging_buffer == NULL) { - SDL_FreeAudioStream(retval); - SDL_OutOfMemory(); - return NULL; - } - } - - /* Not resampling? It's an easy conversion (and maybe not even that!) */ - if (src_rate == dst_rate) { - retval->cvt_before_resampling.needed = SDL_FALSE; - if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, src_format, src_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) { - SDL_FreeAudioStream(retval); - return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ - } - } else { - /* Don't resample at first. Just get us to Float32 format. */ - /* !!! FIXME: convert to int32 on devices without hardware float. */ - if (SDL_BuildAudioCVT(&retval->cvt_before_resampling, src_format, src_channels, src_rate, AUDIO_F32SYS, pre_resample_channels, src_rate) < 0) { - SDL_FreeAudioStream(retval); - return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ - } - -#ifdef HAVE_LIBSAMPLERATE_H - SetupLibSampleRateResampling(retval); -#endif - - if (!retval->resampler_func) { - retval->resampler_state = SDL_calloc(retval->resampler_padding_samples, sizeof (float)); - if (!retval->resampler_state) { - SDL_FreeAudioStream(retval); - SDL_OutOfMemory(); - return NULL; - } - - if (SDL_PrepareResampleFilter() < 0) { - SDL_free(retval->resampler_state); - retval->resampler_state = NULL; - SDL_FreeAudioStream(retval); - return NULL; - } - - retval->resampler_func = SDL_ResampleAudioStream; - retval->reset_resampler_func = SDL_ResetAudioStreamResampler; - retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler; - } - - /* Convert us to the final format after resampling. */ - if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, AUDIO_F32SYS, pre_resample_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) { - SDL_FreeAudioStream(retval); - return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ - } - } - - retval->queue = SDL_NewDataQueue(packetlen, packetlen * 2); - if (!retval->queue) { - SDL_FreeAudioStream(retval); - return NULL; /* SDL_NewDataQueue should have called SDL_SetError. */ - } - - return retval; -} - -static int -SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len, int *maxputbytes) -{ - int buflen = len; - int workbuflen; - Uint8 *workbuf; - Uint8 *resamplebuf = NULL; - int resamplebuflen = 0; - int neededpaddingbytes; - int paddingbytes; - - /* !!! FIXME: several converters can take advantage of SIMD, but only - !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize() - !!! FIXME: guarantees the buffer will align, but the - !!! FIXME: converters will iterate over the data backwards if - !!! FIXME: the output grows, and this means we won't align if buflen - !!! FIXME: isn't a multiple of 16. In these cases, we should chop off - !!! FIXME: a few samples at the end and convert them separately. */ - - /* no padding prepended on first run. */ - neededpaddingbytes = stream->resampler_padding_samples * sizeof (float); - paddingbytes = stream->first_run ? 0 : neededpaddingbytes; - stream->first_run = SDL_FALSE; - - /* Make sure the work buffer can hold all the data we need at once... */ - workbuflen = buflen; - if (stream->cvt_before_resampling.needed) { - workbuflen *= stream->cvt_before_resampling.len_mult; - } - - if (stream->dst_rate != stream->src_rate) { - /* resamples can't happen in place, so make space for second buf. */ - const int framesize = stream->pre_resample_channels * sizeof (float); - const int frames = workbuflen / framesize; - resamplebuflen = ((int) SDL_ceil(frames * stream->rate_incr)) * framesize; - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: will resample %d bytes to %d (ratio=%.6f)\n", workbuflen, resamplebuflen, stream->rate_incr); - #endif - workbuflen += resamplebuflen; - } - - if (stream->cvt_after_resampling.needed) { - /* !!! FIXME: buffer might be big enough already? */ - workbuflen *= stream->cvt_after_resampling.len_mult; - } - - workbuflen += neededpaddingbytes; - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: Putting %d bytes of preconverted audio, need %d byte work buffer\n", buflen, workbuflen); - #endif - - workbuf = EnsureStreamBufferSize(stream, workbuflen); - if (!workbuf) { - return -1; /* probably out of memory. */ - } - - resamplebuf = workbuf; /* default if not resampling. */ - - SDL_memcpy(workbuf + paddingbytes, buf, buflen); - - if (stream->cvt_before_resampling.needed) { - stream->cvt_before_resampling.buf = workbuf + paddingbytes; - stream->cvt_before_resampling.len = buflen; - if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) { - return -1; /* uhoh! */ - } - buflen = stream->cvt_before_resampling.len_cvt; - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: After initial conversion we have %d bytes\n", buflen); - #endif - } - - if (stream->dst_rate != stream->src_rate) { - /* save off some samples at the end; they are used for padding now so - the resampler is coherent and then used at the start of the next - put operation. Prepend last put operation's padding, too. */ - - /* prepend prior put's padding. :P */ - if (paddingbytes) { - SDL_memcpy(workbuf, stream->resampler_padding, paddingbytes); - buflen += paddingbytes; - } - - /* save off the data at the end for the next run. */ - SDL_memcpy(stream->resampler_padding, workbuf + (buflen - neededpaddingbytes), neededpaddingbytes); - - resamplebuf = workbuf + buflen; /* skip to second piece of workbuf. */ - SDL_assert(buflen >= neededpaddingbytes); - if (buflen > neededpaddingbytes) { - buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen); - } else { - buflen = 0; - } - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: After resampling we have %d bytes\n", buflen); - #endif - } - - if (stream->cvt_after_resampling.needed && (buflen > 0)) { - stream->cvt_after_resampling.buf = resamplebuf; - stream->cvt_after_resampling.len = buflen; - if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) { - return -1; /* uhoh! */ - } - buflen = stream->cvt_after_resampling.len_cvt; - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: After final conversion we have %d bytes\n", buflen); - #endif - } - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: Final output is %d bytes\n", buflen); - #endif - - if (maxputbytes) { - const int maxbytes = *maxputbytes; - if (buflen > maxbytes) - buflen = maxbytes; - *maxputbytes -= buflen; - } - - /* resamplebuf holds the final output, even if we didn't resample. */ - return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0; -} - -int -SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) -{ - /* !!! FIXME: several converters can take advantage of SIMD, but only - !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize() - !!! FIXME: guarantees the buffer will align, but the - !!! FIXME: converters will iterate over the data backwards if - !!! FIXME: the output grows, and this means we won't align if buflen - !!! FIXME: isn't a multiple of 16. In these cases, we should chop off - !!! FIXME: a few samples at the end and convert them separately. */ - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen); - #endif - - if (!stream) { - return SDL_InvalidParamError("stream"); - } else if (!buf) { - return SDL_InvalidParamError("buf"); - } else if (len == 0) { - return 0; /* nothing to do. */ - } else if ((len % stream->src_sample_frame_size) != 0) { - return SDL_SetError("Can't add partial sample frames"); - } - - if (!stream->cvt_before_resampling.needed && - (stream->dst_rate == stream->src_rate) && - !stream->cvt_after_resampling.needed) { - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: no conversion needed at all, queueing %d bytes.\n", len); - #endif - return SDL_WriteToDataQueue(stream->queue, buf, len); - } - - while (len > 0) { - int amount; - - /* If we don't have a staging buffer or we're given enough data that - we don't need to store it for later, skip the staging process. - */ - if (!stream->staging_buffer_filled && len >= stream->staging_buffer_size) { - return SDL_AudioStreamPutInternal(stream, buf, len, NULL); - } - - /* If there's not enough data to fill the staging buffer, just save it */ - if ((stream->staging_buffer_filled + len) < stream->staging_buffer_size) { - SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, len); - stream->staging_buffer_filled += len; - return 0; - } - - /* Fill the staging buffer, process it, and continue */ - amount = (stream->staging_buffer_size - stream->staging_buffer_filled); - SDL_assert(amount > 0); - SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, amount); - stream->staging_buffer_filled = 0; - if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, NULL) < 0) { - return -1; - } - buf = (void *)((Uint8 *)buf + amount); - len -= amount; - } - return 0; -} - -int SDL_AudioStreamFlush(SDL_AudioStream *stream) -{ - if (!stream) { - return SDL_InvalidParamError("stream"); - } - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: flushing! staging_buffer_filled=%d bytes\n", stream->staging_buffer_filled); - #endif - - /* shouldn't use a staging buffer if we're not resampling. */ - SDL_assert((stream->dst_rate != stream->src_rate) || (stream->staging_buffer_filled == 0)); - - if (stream->staging_buffer_filled > 0) { - /* push the staging buffer + silence. We need to flush out not just - the staging buffer, but the piece that the stream was saving off - for right-side resampler padding. */ - const SDL_bool first_run = stream->first_run; - const int filled = stream->staging_buffer_filled; - int actual_input_frames = filled / stream->src_sample_frame_size; - if (!first_run) - actual_input_frames += stream->resampler_padding_samples / stream->pre_resample_channels; - - if (actual_input_frames > 0) { /* don't bother if nothing to flush. */ - /* This is how many bytes we're expecting without silence appended. */ - int flush_remaining = ((int) SDL_ceil(actual_input_frames * stream->rate_incr)) * stream->dst_sample_frame_size; - - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: flushing with padding to get max %d bytes!\n", flush_remaining); - #endif - - SDL_memset(stream->staging_buffer + filled, '\0', stream->staging_buffer_size - filled); - if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) { - return -1; - } - - /* we have flushed out (or initially filled) the pending right-side - resampler padding, but we need to push more silence to guarantee - the staging buffer is fully flushed out, too. */ - SDL_memset(stream->staging_buffer, '\0', filled); - if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) { - return -1; - } - } - } - - stream->staging_buffer_filled = 0; - stream->first_run = SDL_TRUE; - - return 0; -} - -/* get converted/resampled data from the stream */ -int -SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len) -{ - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: want to get %d converted bytes\n", len); - #endif - - if (!stream) { - return SDL_InvalidParamError("stream"); - } else if (!buf) { - return SDL_InvalidParamError("buf"); - } else if (len <= 0) { - return 0; /* nothing to do. */ - } else if ((len % stream->dst_sample_frame_size) != 0) { - return SDL_SetError("Can't request partial sample frames"); - } - - return (int) SDL_ReadFromDataQueue(stream->queue, buf, len); -} - -/* number of converted/resampled bytes available */ -int -SDL_AudioStreamAvailable(SDL_AudioStream *stream) -{ - return stream ? (int) SDL_CountDataQueue(stream->queue) : 0; -} - -void -SDL_AudioStreamClear(SDL_AudioStream *stream) -{ - if (!stream) { - SDL_InvalidParamError("stream"); - } else { - SDL_ClearDataQueue(stream->queue, stream->packetlen * 2); - if (stream->reset_resampler_func) { - stream->reset_resampler_func(stream); - } - stream->first_run = SDL_TRUE; - stream->staging_buffer_filled = 0; - } -} - -/* dispose of a stream */ -void -SDL_FreeAudioStream(SDL_AudioStream *stream) -{ - if (stream) { - if (stream->cleanup_resampler_func) { - stream->cleanup_resampler_func(stream); - } - SDL_FreeDataQueue(stream->queue); - SDL_free(stream->staging_buffer); - SDL_free(stream->work_buffer_base); - SDL_free(stream->resampler_padding); - SDL_free(stream); - } -} - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audiodev.c b/Source/3rdParty/SDL2/src/audio/SDL_audiodev.c deleted file mode 100644 index d0b94a0..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audiodev.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* Get the name of the audio device we use for output */ - -#if SDL_AUDIO_DRIVER_NETBSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO - -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> /* For close() */ - -#include "SDL_stdinc.h" -#include "SDL_audiodev_c.h" - -#ifndef _PATH_DEV_DSP -#if defined(__NETBSD__) || defined(__OPENBSD__) -#define _PATH_DEV_DSP "/dev/audio" -#else -#define _PATH_DEV_DSP "/dev/dsp" -#endif -#endif -#ifndef _PATH_DEV_DSP24 -#define _PATH_DEV_DSP24 "/dev/sound/dsp" -#endif -#ifndef _PATH_DEV_AUDIO -#define _PATH_DEV_AUDIO "/dev/audio" -#endif - -static void -test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd)) -{ - struct stat sb; - if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { - const int audio_fd = open(fname, flags, 0); - if (audio_fd >= 0) { - const int okay = test(audio_fd); - close(audio_fd); - if (okay) { - static size_t dummyhandle = 0; - dummyhandle++; - SDL_assert(dummyhandle != 0); - SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle); - } - } - } -} - -static int -test_stub(int fd) -{ - return 1; -} - -static void -SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) -{ - const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; - const char *audiodev; - char audiopath[1024]; - - if (test == NULL) - test = test_stub; - - /* Figure out what our audio device is */ - if (((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) && - ((audiodev = SDL_getenv("AUDIODEV")) == NULL)) { - if (classic) { - audiodev = _PATH_DEV_AUDIO; - } else { - struct stat sb; - - /* Added support for /dev/sound/\* in Linux 2.4 */ - if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) - && ((stat(_PATH_DEV_DSP24, &sb) == 0) - && S_ISCHR(sb.st_mode))) { - audiodev = _PATH_DEV_DSP24; - } else { - audiodev = _PATH_DEV_DSP; - } - } - } - test_device(iscapture, audiodev, flags, test); - - if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) { - int instance = 0; - while (instance <= 64) { - SDL_snprintf(audiopath, SDL_arraysize(audiopath), - "%s%d", audiodev, instance); - instance++; - test_device(iscapture, audiopath, flags, test); - } - } -} - -void -SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) -{ - SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test); - SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test); -} - -#endif /* Audio driver selection */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audiodev_c.h b/Source/3rdParty/SDL2/src/audio/SDL_audiodev_c.h deleted file mode 100644 index 2d3b0ea..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audiodev_c.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_audiodev_c_h_ -#define SDL_audiodev_c_h_ - -#include "SDL.h" -#include "../SDL_internal.h" -#include "SDL_sysaudio.h" - -/* Open the audio device for playback, and don't block if busy */ -/* #define USE_BLOCKING_WRITES */ - -#ifdef USE_BLOCKING_WRITES -#define OPEN_FLAGS_OUTPUT O_WRONLY -#define OPEN_FLAGS_INPUT O_RDONLY -#else -#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK) -#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK) -#endif - -extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)); - -#endif /* SDL_audiodev_c_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_audiotypecvt.c b/Source/3rdParty/SDL2/src/audio/SDL_audiotypecvt.c deleted file mode 100644 index 5f8cc22..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_audiotypecvt.c +++ /dev/null @@ -1,1431 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../SDL_internal.h" -#include "SDL_audio.h" -#include "SDL_audio_c.h" -#include "SDL_cpuinfo.h" -#include "SDL_assert.h" - -/* !!! FIXME: disabled until we fix https://bugzilla.libsdl.org/show_bug.cgi?id=4186 */ -#if 0 /*def __ARM_NEON__*/ -#define HAVE_NEON_INTRINSICS 1 -#endif - -#ifdef __SSE2__ -#define HAVE_SSE2_INTRINSICS 1 -#endif - -#if defined(__x86_64__) && HAVE_SSE2_INTRINSICS -#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* x86_64 guarantees SSE2. */ -#elif __MACOSX__ && HAVE_SSE2_INTRINSICS -#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* Mac OS X/Intel guarantees SSE2. */ -#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && HAVE_NEON_INTRINSICS -#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* ARMv8+ promise NEON. */ -#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && HAVE_NEON_INTRINSICS -#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* All Apple ARMv7 chips promise NEON support. */ -#endif - -/* Set to zero if platform is guaranteed to use a SIMD codepath here. */ -#ifndef NEED_SCALAR_CONVERTER_FALLBACKS -#define NEED_SCALAR_CONVERTER_FALLBACKS 1 -#endif - -/* Function pointers set to a CPU-specific implementation. */ -SDL_AudioFilter SDL_Convert_S8_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_U8_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_S16_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_U16_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_S32_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_S8 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_U8 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_S16 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_U16 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_S32 = NULL; - - -#define DIVBY128 0.0078125f -#define DIVBY32768 0.000030517578125f -#define DIVBY8388607 0.00000011920930376163766f - - -#if NEED_SCALAR_CONVERTER_FALLBACKS -static void SDLCALL -SDL_Convert_S8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint8 *src = ((const Sint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32"); - - for (i = cvt->len_cvt; i; --i, --src, --dst) { - *dst = ((float) *src) * DIVBY128; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32"); - - for (i = cvt->len_cvt; i; --i, --src, --dst) { - *dst = (((float) *src) * DIVBY128) - 1.0f; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint16 *src = ((const Sint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32"); - - for (i = cvt->len_cvt / sizeof (Sint16); i; --i, --src, --dst) { - *dst = ((float) *src) * DIVBY32768; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32"); - - for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) { - *dst = (((float) *src) * DIVBY32768) - 1.0f; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S32_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint32 *src = (const Sint32 *) cvt->buf; - float *dst = (float *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32"); - - for (i = cvt->len_cvt / sizeof (Sint32); i; --i, ++src, ++dst) { - *dst = ((float) (*src>>8)) * DIVBY8388607; - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint8 *dst = (Sint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8"); - - for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 127; - } else if (sample <= -1.0f) { - *dst = -128; - } else { - *dst = (Sint8)(sample * 127.0f); - } - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint8 *dst = (Uint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8"); - - for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 255; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint8)((sample + 1.0f) * 127.0f); - } - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint16 *dst = (Sint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16"); - - for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 32767; - } else if (sample <= -1.0f) { - *dst = -32768; - } else { - *dst = (Sint16)(sample * 32767.0f); - } - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint16 *dst = (Uint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16"); - - for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint32 *dst = (Sint32 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32"); - - for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 2147483647; - } else if (sample <= -1.0f) { - *dst = (Sint32) -2147483648LL; - } else { - *dst = ((Sint32)(sample * 8388607.0f)) << 8; - } - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); - } -} -#endif - - -#if HAVE_SSE2_INTRINSICS -static void SDLCALL -SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint8 *src = ((const Sint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt; i && (((size_t) (dst-15)) & 15); --i, --src, --dst) { - *dst = ((float) *src) * DIVBY128; - } - - src -= 15; dst -= 15; /* adjust to read SSE blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128i *mmsrc = (const __m128i *) src; - const __m128i zero = _mm_setzero_si128(); - const __m128 divby128 = _mm_set1_ps(DIVBY128); - while (i >= 16) { /* 16 * 8-bit */ - const __m128i bytes = _mm_load_si128(mmsrc); /* get 16 sint8 into an XMM register. */ - /* treat as int16, shift left to clear every other sint16, then back right with sign-extend. Now sint16. */ - const __m128i shorts1 = _mm_srai_epi16(_mm_slli_epi16(bytes, 8), 8); - /* right-shift-sign-extend gets us sint16 with the other set of values. */ - const __m128i shorts2 = _mm_srai_epi16(bytes, 8); - /* unpack against zero to make these int32, shift to make them sign-extend, convert to float, multiply. Whew! */ - const __m128 floats1 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpacklo_epi16(shorts1, zero), 16), 16)), divby128); - const __m128 floats2 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpacklo_epi16(shorts2, zero), 16), 16)), divby128); - const __m128 floats3 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpackhi_epi16(shorts1, zero), 16), 16)), divby128); - const __m128 floats4 = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_slli_epi32(_mm_unpackhi_epi16(shorts2, zero), 16), 16)), divby128); - /* Interleave back into correct order, store. */ - _mm_store_ps(dst, _mm_unpacklo_ps(floats1, floats2)); - _mm_store_ps(dst+4, _mm_unpackhi_ps(floats1, floats2)); - _mm_store_ps(dst+8, _mm_unpacklo_ps(floats3, floats4)); - _mm_store_ps(dst+12, _mm_unpackhi_ps(floats3, floats4)); - i -= 16; mmsrc--; dst -= 16; - } - - src = (const Sint8 *) mmsrc; - } - - src += 15; dst += 15; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) *src) * DIVBY128; - i--; src--; dst--; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt; i && (((size_t) (dst-15)) & 15); --i, --src, --dst) { - *dst = (((float) *src) * DIVBY128) - 1.0f; - } - - src -= 15; dst -= 15; /* adjust to read SSE blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128i *mmsrc = (const __m128i *) src; - const __m128i zero = _mm_setzero_si128(); - const __m128 divby128 = _mm_set1_ps(DIVBY128); - const __m128 minus1 = _mm_set1_ps(-1.0f); - while (i >= 16) { /* 16 * 8-bit */ - const __m128i bytes = _mm_load_si128(mmsrc); /* get 16 uint8 into an XMM register. */ - /* treat as int16, shift left to clear every other sint16, then back right with zero-extend. Now uint16. */ - const __m128i shorts1 = _mm_srli_epi16(_mm_slli_epi16(bytes, 8), 8); - /* right-shift-zero-extend gets us uint16 with the other set of values. */ - const __m128i shorts2 = _mm_srli_epi16(bytes, 8); - /* unpack against zero to make these int32, convert to float, multiply, add. Whew! */ - /* Note that AVX2 can do floating point multiply+add in one instruction, fwiw. SSE2 cannot. */ - const __m128 floats1 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(shorts1, zero)), divby128), minus1); - const __m128 floats2 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(shorts2, zero)), divby128), minus1); - const __m128 floats3 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(shorts1, zero)), divby128), minus1); - const __m128 floats4 = _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(shorts2, zero)), divby128), minus1); - /* Interleave back into correct order, store. */ - _mm_store_ps(dst, _mm_unpacklo_ps(floats1, floats2)); - _mm_store_ps(dst+4, _mm_unpackhi_ps(floats1, floats2)); - _mm_store_ps(dst+8, _mm_unpacklo_ps(floats3, floats4)); - _mm_store_ps(dst+12, _mm_unpackhi_ps(floats3, floats4)); - i -= 16; mmsrc--; dst -= 16; - } - - src = (const Uint8 *) mmsrc; - } - - src += 15; dst += 15; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float) *src) * DIVBY128) - 1.0f; - i--; src--; dst--; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint16 *src = ((const Sint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof (Sint16); i && (((size_t) (dst-7)) & 15); --i, --src, --dst) { - *dst = ((float) *src) * DIVBY32768; - } - - src -= 7; dst -= 7; /* adjust to read SSE blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 divby32768 = _mm_set1_ps(DIVBY32768); - while (i >= 8) { /* 8 * 16-bit */ - const __m128i ints = _mm_load_si128((__m128i const *) src); /* get 8 sint16 into an XMM register. */ - /* treat as int32, shift left to clear every other sint16, then back right with sign-extend. Now sint32. */ - const __m128i a = _mm_srai_epi32(_mm_slli_epi32(ints, 16), 16); - /* right-shift-sign-extend gets us sint32 with the other set of values. */ - const __m128i b = _mm_srai_epi32(ints, 16); - /* Interleave these back into the right order, convert to float, multiply, store. */ - _mm_store_ps(dst, _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi32(a, b)), divby32768)); - _mm_store_ps(dst+4, _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi32(a, b)), divby32768)); - i -= 8; src -= 8; dst -= 8; - } - } - - src += 7; dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) *src) * DIVBY32768; - i--; src--; dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof (Sint16); i && (((size_t) (dst-7)) & 15); --i, --src, --dst) { - *dst = (((float) *src) * DIVBY32768) - 1.0f; - } - - src -= 7; dst -= 7; /* adjust to read SSE blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 divby32768 = _mm_set1_ps(DIVBY32768); - const __m128 minus1 = _mm_set1_ps(1.0f); - while (i >= 8) { /* 8 * 16-bit */ - const __m128i ints = _mm_load_si128((__m128i const *) src); /* get 8 sint16 into an XMM register. */ - /* treat as int32, shift left to clear every other sint16, then back right with zero-extend. Now sint32. */ - const __m128i a = _mm_srli_epi32(_mm_slli_epi32(ints, 16), 16); - /* right-shift-sign-extend gets us sint32 with the other set of values. */ - const __m128i b = _mm_srli_epi32(ints, 16); - /* Interleave these back into the right order, convert to float, multiply, store. */ - _mm_store_ps(dst, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi32(a, b)), divby32768), minus1)); - _mm_store_ps(dst+4, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi32(a, b)), divby32768), minus1)); - i -= 8; src -= 8; dst -= 8; - } - } - - src += 7; dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float) *src) * DIVBY32768) - 1.0f; - i--; src--; dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint32 *src = (const Sint32 *) cvt->buf; - float *dst = (float *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (Sint32); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - *dst = ((float) (*src>>8)) * DIVBY8388607; - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - SDL_assert(!i || ((((size_t) src) & 15) == 0)); - - { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 divby8388607 = _mm_set1_ps(DIVBY8388607); - const __m128i *mmsrc = (const __m128i *) src; - while (i >= 4) { /* 4 * sint32 */ - /* shift out lowest bits so int fits in a float32. Small precision loss, but much faster. */ - _mm_store_ps(dst, _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128(mmsrc), 8)), divby8388607)); - i -= 4; mmsrc++; dst += 4; - } - src = (const Sint32 *) mmsrc; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) (*src>>8)) * DIVBY8388607; - i--; src++; dst++; - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint8 *dst = (Sint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 127; - } else if (sample <= -1.0f) { - *dst = -128; - } else { - *dst = (Sint8)(sample * 127.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - const __m128 mulby127 = _mm_set1_ps(127.0f); - __m128i *mmdst = (__m128i *) dst; - while (i >= 16) { /* 16 * float32 */ - const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+4)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+8)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+12)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - _mm_store_si128(mmdst, _mm_packs_epi16(_mm_packs_epi32(ints1, ints2), _mm_packs_epi32(ints3, ints4))); /* pack down, store out. */ - i -= 16; src += 16; mmdst++; - } - dst = (Sint8 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 127; - } else if (sample <= -1.0f) { - *dst = -128; - } else { - *dst = (Sint8)(sample * 127.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint8 *dst = (Uint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 255; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint8)((sample + 1.0f) * 127.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - const __m128 mulby127 = _mm_set1_ps(127.0f); - __m128i *mmdst = (__m128i *) dst; - while (i >= 16) { /* 16 * float32 */ - const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+4)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+8)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_add_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+12)), one), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - _mm_store_si128(mmdst, _mm_packus_epi16(_mm_packs_epi32(ints1, ints2), _mm_packs_epi32(ints3, ints4))); /* pack down, store out. */ - i -= 16; src += 16; mmdst++; - } - dst = (Uint8 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 255; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint8)((sample + 1.0f) * 127.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint16 *dst = (Sint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 32767; - } else if (sample <= -1.0f) { - *dst = -32768; - } else { - *dst = (Sint16)(sample * 32767.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - const __m128 mulby32767 = _mm_set1_ps(32767.0f); - __m128i *mmdst = (__m128i *) dst; - while (i >= 8) { /* 8 * float32 */ - const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - _mm_store_si128(mmdst, _mm_packs_epi32(ints1, ints2)); /* pack to sint16, store out. */ - i -= 8; src += 8; mmdst++; - } - dst = (Sint16 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 32767; - } else if (sample <= -1.0f) { - *dst = -32768; - } else { - *dst = (Sint16)(sample * 32767.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint16 *dst = (Uint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - /* This calculates differently than the scalar path because SSE2 can't - pack int32 data down to unsigned int16. _mm_packs_epi32 does signed - saturation, so that would corrupt our data. _mm_packus_epi32 exists, - but not before SSE 4.1. So we convert from float to sint16, packing - that down with legit signed saturation, and then xor the top bit - against 1. This results in the correct unsigned 16-bit value, even - though it looks like dark magic. */ - const __m128 mulby32767 = _mm_set1_ps(32767.0f); - const __m128i topbit = _mm_set1_epi16(-32768); - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - __m128i *mmdst = (__m128i *) dst; - while (i >= 8) { /* 8 * float32 */ - const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src+4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - _mm_store_si128(mmdst, _mm_xor_si128(_mm_packs_epi32(ints1, ints2), topbit)); /* pack to sint16, xor top bit, store out. */ - i -= 8; src += 8; mmdst++; - } - dst = (Uint16 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint32 *dst = (Sint32 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 2147483647; - } else if (sample <= -1.0f) { - *dst = (Sint32) -2147483648LL; - } else { - *dst = ((Sint32)(sample * 8388607.0f)) << 8; - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - SDL_assert(!i || ((((size_t) src) & 15) == 0)); - - { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - const __m128 mulby8388607 = _mm_set1_ps(8388607.0f); - __m128i *mmdst = (__m128i *) dst; - while (i >= 4) { /* 4 * float32 */ - _mm_store_si128(mmdst, _mm_slli_epi32(_mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby8388607)), 8)); /* load 4 floats, clamp, convert to sint32 */ - i -= 4; src += 4; mmdst++; - } - dst = (Sint32 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 2147483647; - } else if (sample <= -1.0f) { - *dst = (Sint32) -2147483648LL; - } else { - *dst = ((Sint32)(sample * 8388607.0f)) << 8; - } - i--; src++; dst++; - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); - } -} -#endif - - -#if HAVE_NEON_INTRINSICS -static void SDLCALL -SDL_Convert_S8_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint8 *src = ((const Sint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt; i && (((size_t) (dst-15)) & 15); --i, --src, --dst) { - *dst = ((float) *src) * DIVBY128; - } - - src -= 15; dst -= 15; /* adjust to read NEON blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const int8_t *mmsrc = (const int8_t *) src; - const float32x4_t divby128 = vdupq_n_f32(DIVBY128); - while (i >= 16) { /* 16 * 8-bit */ - const int8x16_t bytes = vld1q_s8(mmsrc); /* get 16 sint8 into a NEON register. */ - const int16x8_t int16hi = vmovl_s8(vget_high_s8(bytes)); /* convert top 8 bytes to 8 int16 */ - const int16x8_t int16lo = vmovl_s8(vget_low_s8(bytes)); /* convert bottom 8 bytes to 8 int16 */ - /* split int16 to two int32, then convert to float, then multiply to normalize, store. */ - vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(int16hi))), divby128)); - vst1q_f32(dst+4, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(int16hi))), divby128)); - vst1q_f32(dst+8, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(int16lo))), divby128)); - vst1q_f32(dst+12, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(int16lo))), divby128)); - i -= 16; mmsrc -= 16; dst -= 16; - } - - src = (const Sint8 *) mmsrc; - } - - src += 15; dst += 15; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) *src) * DIVBY128; - i--; src--; dst--; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U8_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt; i && (((size_t) (dst-15)) & 15); --i, --src, --dst) { - *dst = (((float) *src) * DIVBY128) - 1.0f; - } - - src -= 15; dst -= 15; /* adjust to read NEON blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const uint8_t *mmsrc = (const uint8_t *) src; - const float32x4_t divby128 = vdupq_n_f32(DIVBY128); - const float32x4_t one = vdupq_n_f32(1.0f); - while (i >= 16) { /* 16 * 8-bit */ - const uint8x16_t bytes = vld1q_u8(mmsrc); /* get 16 uint8 into a NEON register. */ - const uint16x8_t uint16hi = vmovl_u8(vget_high_u8(bytes)); /* convert top 8 bytes to 8 uint16 */ - const uint16x8_t uint16lo = vmovl_u8(vget_low_u8(bytes)); /* convert bottom 8 bytes to 8 uint16 */ - /* split uint16 to two uint32, then convert to float, then multiply to normalize, subtract to adjust for sign, store. */ - vst1q_f32(dst, vmlsq_f32(vcvtq_f32_u32(vmovl_u16(vget_high_u16(uint16hi))), divby128, one)); - vst1q_f32(dst+4, vmlsq_f32(vcvtq_f32_u32(vmovl_u16(vget_low_u16(uint16hi))), divby128, one)); - vst1q_f32(dst+8, vmlsq_f32(vcvtq_f32_u32(vmovl_u16(vget_high_u16(uint16lo))), divby128, one)); - vst1q_f32(dst+12, vmlsq_f32(vcvtq_f32_u32(vmovl_u16(vget_low_u16(uint16lo))), divby128, one)); - i -= 16; mmsrc -= 16; dst -= 16; - } - - src = (const Uint8 *) mmsrc; - } - - src += 15; dst += 15; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float) *src) * DIVBY128) - 1.0f; - i--; src--; dst--; - } - - cvt->len_cvt *= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint16 *src = ((const Sint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof (Sint16); i && (((size_t) (dst-7)) & 15); --i, --src, --dst) { - *dst = ((float) *src) * DIVBY32768; - } - - src -= 7; dst -= 7; /* adjust to read NEON blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t divby32768 = vdupq_n_f32(DIVBY32768); - while (i >= 8) { /* 8 * 16-bit */ - const int16x8_t ints = vld1q_s16((int16_t const *) src); /* get 8 sint16 into a NEON register. */ - /* split int16 to two int32, then convert to float, then multiply to normalize, store. */ - vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(ints))), divby32768)); - vst1q_f32(dst+4, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(ints))), divby32768)); - i -= 8; src -= 8; dst -= 8; - } - } - - src += 7; dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) *src) * DIVBY32768; - i--; src--; dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_U16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *) (cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof (Sint16); i && (((size_t) (dst-7)) & 15); --i, --src, --dst) { - *dst = (((float) *src) * DIVBY32768) - 1.0f; - } - - src -= 7; dst -= 7; /* adjust to read NEON blocks from the start. */ - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t divby32768 = vdupq_n_f32(DIVBY32768); - const float32x4_t one = vdupq_n_f32(1.0f); - while (i >= 8) { /* 8 * 16-bit */ - const uint16x8_t uints = vld1q_u16((uint16_t const *) src); /* get 8 uint16 into a NEON register. */ - /* split uint16 to two int32, then convert to float, then multiply to normalize, subtract for sign, store. */ - vst1q_f32(dst, vmlsq_f32(one, vcvtq_f32_u32(vmovl_u16(vget_low_u16(uints))), divby32768)); - vst1q_f32(dst+4, vmlsq_f32(one, vcvtq_f32_u32(vmovl_u16(vget_high_u16(uints))), divby32768)); - i -= 8; src -= 8; dst -= 8; - } - } - - src += 7; dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float) *src) * DIVBY32768) - 1.0f; - i--; src--; dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_S32_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Sint32 *src = (const Sint32 *) cvt->buf; - float *dst = (float *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (Sint32); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - *dst = ((float) (*src>>8)) * DIVBY8388607; - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - SDL_assert(!i || ((((size_t) src) & 15) == 0)); - - { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t divby8388607 = vdupq_n_f32(DIVBY8388607); - const int32_t *mmsrc = (const int32_t *) src; - while (i >= 4) { /* 4 * sint32 */ - /* shift out lowest bits so int fits in a float32. Small precision loss, but much faster. */ - vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vshrq_n_s32(vld1q_s32(mmsrc), 8)), divby8388607)); - i -= 4; mmsrc += 4; dst += 4; - } - src = (const Sint32 *) mmsrc; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = ((float) (*src>>8)) * DIVBY8388607; - i--; src++; dst++; - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S8_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint8 *dst = (Sint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 127; - } else if (sample <= -1.0f) { - *dst = -128; - } else { - *dst = (Sint8)(sample * 127.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby127 = vdupq_n_f32(127.0f); - int8_t *mmdst = (int8_t *) dst; - while (i >= 16) { /* 16 * float32 */ - const int32x4_t ints1 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const int32x4_t ints2 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+4)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const int32x4_t ints3 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+8)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const int32x4_t ints4 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+12)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ - const int8x8_t i8lo = vmovn_s16(vcombine_s16(vmovn_s32(ints1), vmovn_s32(ints2))); /* narrow to sint16, combine, narrow to sint8 */ - const int8x8_t i8hi = vmovn_s16(vcombine_s16(vmovn_s32(ints3), vmovn_s32(ints4))); /* narrow to sint16, combine, narrow to sint8 */ - vst1q_s8(mmdst, vcombine_s8(i8lo, i8hi)); /* combine to int8x16_t, store out */ - i -= 16; src += 16; mmdst += 16; - } - dst = (Sint8 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 127; - } else if (sample <= -1.0f) { - *dst = -128; - } else { - *dst = (Sint8)(sample * 127.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U8_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint8 *dst = (Uint8 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 255; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint8)((sample + 1.0f) * 127.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby127 = vdupq_n_f32(127.0f); - uint8_t *mmdst = (uint8_t *) dst; - while (i >= 16) { /* 16 * float32 */ - const uint32x4_t uints1 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ - const uint32x4_t uints2 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+4)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ - const uint32x4_t uints3 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+8)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ - const uint32x4_t uints4 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+12)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ - const uint8x8_t ui8lo = vmovn_u16(vcombine_u16(vmovn_u32(uints1), vmovn_u32(uints2))); /* narrow to uint16, combine, narrow to uint8 */ - const uint8x8_t ui8hi = vmovn_u16(vcombine_u16(vmovn_u32(uints3), vmovn_u32(uints4))); /* narrow to uint16, combine, narrow to uint8 */ - vst1q_u8(mmdst, vcombine_u8(ui8lo, ui8hi)); /* combine to uint8x16_t, store out */ - i -= 16; src += 16; mmdst += 16; - } - - dst = (Uint8 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 255; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint8)((sample + 1.0f) * 127.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 4; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U8); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S16_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint16 *dst = (Sint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 32767; - } else if (sample <= -1.0f) { - *dst = -32768; - } else { - *dst = (Sint16)(sample * 32767.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby32767 = vdupq_n_f32(32767.0f); - int16_t *mmdst = (int16_t *) dst; - while (i >= 8) { /* 8 * float32 */ - const int32x4_t ints1 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - const int32x4_t ints2 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - vst1q_s16(mmdst, vcombine_s16(vmovn_s32(ints1), vmovn_s32(ints2))); /* narrow to sint16, combine, store out. */ - i -= 8; src += 8; mmdst += 8; - } - dst = (Sint16 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 32767; - } else if (sample <= -1.0f) { - *dst = -32768; - } else { - *dst = (Sint16)(sample * 32767.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_U16_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Uint16 *dst = (Uint16 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - - /* Make sure src is aligned too. */ - if ((((size_t) src) & 15) == 0) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby32767 = vdupq_n_f32(32767.0f); - uint16_t *mmdst = (uint16_t *) dst; - while (i >= 8) { /* 8 * float32 */ - const uint32x4_t uints1 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ - const uint32x4_t uints2 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src+4)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ - vst1q_u16(mmdst, vcombine_u16(vmovn_u32(uints1), vmovn_u32(uints2))); /* narrow to uint16, combine, store out. */ - i -= 8; src += 8; mmdst += 8; - } - dst = (Uint16 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - i--; src++; dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - -static void SDLCALL -SDL_Convert_F32_to_S32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *) cvt->buf; - Sint32 *dst = (Sint32 *) cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof (float); i && (((size_t) dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 2147483647; - } else if (sample <= -1.0f) { - *dst = -2147483648; - } else { - *dst = ((Sint32)(sample * 8388607.0f)) << 8; - } - } - - SDL_assert(!i || ((((size_t) dst) & 15) == 0)); - SDL_assert(!i || ((((size_t) src) & 15) == 0)); - - { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby8388607 = vdupq_n_f32(8388607.0f); - int32_t *mmdst = (int32_t *) dst; - while (i >= 4) { /* 4 * float32 */ - vst1q_s32(mmdst, vshlq_n_s32(vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby8388607)), 8)); - i -= 4; src += 4; mmdst += 4; - } - dst = (Sint32 *) mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 2147483647; - } else if (sample <= -1.0f) { - *dst = -2147483648; - } else { - *dst = ((Sint32)(sample * 8388607.0f)) << 8; - } - i--; src++; dst++; - } - - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); - } -} -#endif - - - -void SDL_ChooseAudioConverters(void) -{ - static SDL_bool converters_chosen = SDL_FALSE; - - if (converters_chosen) { - return; - } - -#define SET_CONVERTER_FUNCS(fntype) \ - SDL_Convert_S8_to_F32 = SDL_Convert_S8_to_F32_##fntype; \ - SDL_Convert_U8_to_F32 = SDL_Convert_U8_to_F32_##fntype; \ - SDL_Convert_S16_to_F32 = SDL_Convert_S16_to_F32_##fntype; \ - SDL_Convert_U16_to_F32 = SDL_Convert_U16_to_F32_##fntype; \ - SDL_Convert_S32_to_F32 = SDL_Convert_S32_to_F32_##fntype; \ - SDL_Convert_F32_to_S8 = SDL_Convert_F32_to_S8_##fntype; \ - SDL_Convert_F32_to_U8 = SDL_Convert_F32_to_U8_##fntype; \ - SDL_Convert_F32_to_S16 = SDL_Convert_F32_to_S16_##fntype; \ - SDL_Convert_F32_to_U16 = SDL_Convert_F32_to_U16_##fntype; \ - SDL_Convert_F32_to_S32 = SDL_Convert_F32_to_S32_##fntype; \ - converters_chosen = SDL_TRUE - -#if HAVE_SSE2_INTRINSICS - if (SDL_HasSSE2()) { - SET_CONVERTER_FUNCS(SSE2); - return; - } -#endif - -#if HAVE_NEON_INTRINSICS - if (SDL_HasNEON()) { - SET_CONVERTER_FUNCS(NEON); - return; - } -#endif - -#if NEED_SCALAR_CONVERTER_FALLBACKS - SET_CONVERTER_FUNCS(Scalar); -#endif - -#undef SET_CONVERTER_FUNCS - - SDL_assert(converters_chosen == SDL_TRUE); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_mixer.c b/Source/3rdParty/SDL2/src/audio/SDL_mixer.c deleted file mode 100644 index d416a94..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_mixer.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* This provides the default mixing callback for the SDL audio routines */ - -#include "SDL_cpuinfo.h" -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "SDL_sysaudio.h" - -/* This table is used to add two sound values together and pin - * the value to avoid overflow. (used with permission from ARDI) - * Changed to use 0xFE instead of 0xFF for better sound quality. - */ -static const Uint8 mix8[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, - 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, - 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, - 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, - 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, - 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, - 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, - 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, - 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, - 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, - 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, - 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE -}; - -/* The volume ranges from 0 - 128 */ -#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME) -#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128) - - -void -SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format, - Uint32 len, int volume) -{ - if (volume == 0) { - return; - } - - switch (format) { - - case AUDIO_U8: - { -#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES) - SDL_MixAudio_m68k_U8((char *) dst, (char *) src, - (unsigned long) len, (long) volume, - (char *) mix8); -#else - Uint8 src_sample; - - while (len--) { - src_sample = *src; - ADJUST_VOLUME_U8(src_sample, volume); - *dst = mix8[*dst + src_sample]; - ++dst; - ++src; - } -#endif - } - break; - - case AUDIO_S8: - { - Sint8 *dst8, *src8; - Sint8 src_sample; - int dst_sample; - const int max_audioval = ((1 << (8 - 1)) - 1); - const int min_audioval = -(1 << (8 - 1)); - - src8 = (Sint8 *) src; - dst8 = (Sint8 *) dst; - while (len--) { - src_sample = *src8; - ADJUST_VOLUME(src_sample, volume); - dst_sample = *dst8 + src_sample; - if (dst_sample > max_audioval) { - *dst8 = max_audioval; - } else if (dst_sample < min_audioval) { - *dst8 = min_audioval; - } else { - *dst8 = dst_sample; - } - ++dst8; - ++src8; - } - } - break; - - case AUDIO_S16LSB: - { - Sint16 src1, src2; - int dst_sample; - const int max_audioval = ((1 << (16 - 1)) - 1); - const int min_audioval = -(1 << (16 - 1)); - - len /= 2; - while (len--) { - src1 = ((src[1]) << 8 | src[0]); - ADJUST_VOLUME(src1, volume); - src2 = ((dst[1]) << 8 | dst[0]); - src += 2; - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - dst[0] = dst_sample & 0xFF; - dst_sample >>= 8; - dst[1] = dst_sample & 0xFF; - dst += 2; - } - } - break; - - case AUDIO_S16MSB: - { -#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES) - SDL_MixAudio_m68k_S16MSB((short *) dst, (short *) src, - (unsigned long) len, (long) volume); -#else - Sint16 src1, src2; - int dst_sample; - const int max_audioval = ((1 << (16 - 1)) - 1); - const int min_audioval = -(1 << (16 - 1)); - - len /= 2; - while (len--) { - src1 = ((src[0]) << 8 | src[1]); - ADJUST_VOLUME(src1, volume); - src2 = ((dst[0]) << 8 | dst[1]); - src += 2; - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - dst[1] = dst_sample & 0xFF; - dst_sample >>= 8; - dst[0] = dst_sample & 0xFF; - dst += 2; - } -#endif - } - break; - - case AUDIO_U16LSB: - { - Uint16 src1, src2; - int dst_sample; - const int max_audioval = 0xFFFF; - - len /= 2; - while (len--) { - src1 = ((src[1]) << 8 | src[0]); - ADJUST_VOLUME(src1, volume); - src2 = ((dst[1]) << 8 | dst[0]); - src += 2; - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } - dst[0] = dst_sample & 0xFF; - dst_sample >>= 8; - dst[1] = dst_sample & 0xFF; - dst += 2; - } - } - break; - - case AUDIO_U16MSB: - { - Uint16 src1, src2; - int dst_sample; - const int max_audioval = 0xFFFF; - - len /= 2; - while (len--) { - src1 = ((src[0]) << 8 | src[1]); - ADJUST_VOLUME(src1, volume); - src2 = ((dst[0]) << 8 | dst[1]); - src += 2; - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } - dst[1] = dst_sample & 0xFF; - dst_sample >>= 8; - dst[0] = dst_sample & 0xFF; - dst += 2; - } - } - break; - - case AUDIO_S32LSB: - { - const Uint32 *src32 = (Uint32 *) src; - Uint32 *dst32 = (Uint32 *) dst; - Sint64 src1, src2; - Sint64 dst_sample; - const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1); - const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1)); - - len /= 4; - while (len--) { - src1 = (Sint64) ((Sint32) SDL_SwapLE32(*src32)); - src32++; - ADJUST_VOLUME(src1, volume); - src2 = (Sint64) ((Sint32) SDL_SwapLE32(*dst32)); - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample)); - } - } - break; - - case AUDIO_S32MSB: - { - const Uint32 *src32 = (Uint32 *) src; - Uint32 *dst32 = (Uint32 *) dst; - Sint64 src1, src2; - Sint64 dst_sample; - const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1); - const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1)); - - len /= 4; - while (len--) { - src1 = (Sint64) ((Sint32) SDL_SwapBE32(*src32)); - src32++; - ADJUST_VOLUME(src1, volume); - src2 = (Sint64) ((Sint32) SDL_SwapBE32(*dst32)); - dst_sample = src1 + src2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample)); - } - } - break; - - case AUDIO_F32LSB: - { - const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME); - const float fvolume = (float) volume; - const float *src32 = (float *) src; - float *dst32 = (float *) dst; - float src1, src2; - double dst_sample; - /* !!! FIXME: are these right? */ - const double max_audioval = 3.402823466e+38F; - const double min_audioval = -3.402823466e+38F; - - len /= 4; - while (len--) { - src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume); - src2 = SDL_SwapFloatLE(*dst32); - src32++; - - dst_sample = ((double) src1) + ((double) src2); - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - *(dst32++) = SDL_SwapFloatLE((float) dst_sample); - } - } - break; - - case AUDIO_F32MSB: - { - const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME); - const float fvolume = (float) volume; - const float *src32 = (float *) src; - float *dst32 = (float *) dst; - float src1, src2; - double dst_sample; - /* !!! FIXME: are these right? */ - const double max_audioval = 3.402823466e+38F; - const double min_audioval = -3.402823466e+38F; - - len /= 4; - while (len--) { - src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume); - src2 = SDL_SwapFloatBE(*dst32); - src32++; - - dst_sample = ((double) src1) + ((double) src2); - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - *(dst32++) = SDL_SwapFloatBE((float) dst_sample); - } - } - break; - - default: /* If this happens... FIXME! */ - SDL_SetError("SDL_MixAudioFormat(): unknown audio format"); - return; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_sysaudio.h b/Source/3rdParty/SDL2/src/audio/SDL_sysaudio.h deleted file mode 100644 index 579dea5..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_sysaudio.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -#ifndef SDL_sysaudio_h_ -#define SDL_sysaudio_h_ - -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "../SDL_dataqueue.h" -#include "./SDL_audio_c.h" - -/* !!! FIXME: These are wordy and unlocalized... */ -#define DEFAULT_OUTPUT_DEVNAME "System audio output device" -#define DEFAULT_INPUT_DEVNAME "System audio capture device" - -/* The SDL audio driver */ -typedef struct SDL_AudioDevice SDL_AudioDevice; -#define _THIS SDL_AudioDevice *_this - -/* Audio targets should call this as devices are added to the system (such as - a USB headset being plugged in), and should also be called for - for every device found during DetectDevices(). */ -extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle); - -/* Audio targets should call this as devices are removed, so SDL can update - its list of available devices. */ -extern void SDL_RemoveAudioDevice(const int iscapture, void *handle); - -/* Audio targets should call this if an opened audio device is lost while - being used. This can happen due to i/o errors, or a device being unplugged, - etc. If the device is totally gone, please also call SDL_RemoveAudioDevice() - as appropriate so SDL's list of devices is accurate. */ -extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device); - -/* This is the size of a packet when using SDL_QueueAudio(). We allocate - these as necessary and pool them, under the assumption that we'll - eventually end up with a handful that keep recycling, meeting whatever - the app needs. We keep packing data tightly as more arrives to avoid - wasting space, and if we get a giant block of data, we'll split them - into multiple packets behind the scenes. My expectation is that most - apps will have 2-3 of these in the pool. 8k should cover most needs, but - if this is crippling for some embedded system, we can #ifdef this. - The system preallocates enough packets for 2 callbacks' worth of data. */ -#define SDL_AUDIOBUFFERQUEUE_PACKETLEN (8 * 1024) - -typedef struct SDL_AudioDriverImpl -{ - void (*DetectDevices) (void); - int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture); - void (*ThreadInit) (_THIS); /* Called by audio thread at start */ - void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */ - void (*BeginLoopIteration)(_THIS); /* Called by audio thread at top of loop */ - void (*WaitDevice) (_THIS); - void (*PlayDevice) (_THIS); - int (*GetPendingBytes) (_THIS); - Uint8 *(*GetDeviceBuf) (_THIS); - int (*CaptureFromDevice) (_THIS, void *buffer, int buflen); - void (*FlushCapture) (_THIS); - void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */ - void (*CloseDevice) (_THIS); - void (*LockDevice) (_THIS); - void (*UnlockDevice) (_THIS); - void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */ - void (*Deinitialize) (void); - - /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */ - - /* Some flags to push duplicate code into the core and reduce #ifdefs. */ - /* !!! FIXME: these should be SDL_bool */ - int ProvidesOwnCallbackThread; - int SkipMixerLock; - int HasCaptureSupport; - int OnlyHasDefaultOutputDevice; - int OnlyHasDefaultCaptureDevice; - int AllowsArbitraryDeviceNames; -} SDL_AudioDriverImpl; - - -typedef struct SDL_AudioDeviceItem -{ - void *handle; - char *name; - char *original_name; - int dupenum; - struct SDL_AudioDeviceItem *next; -} SDL_AudioDeviceItem; - - -typedef struct SDL_AudioDriver -{ - /* * * */ - /* The name of this audio driver */ - const char *name; - - /* * * */ - /* The description of this audio driver */ - const char *desc; - - SDL_AudioDriverImpl impl; - - /* A mutex for device detection */ - SDL_mutex *detectionLock; - SDL_bool captureDevicesRemoved; - SDL_bool outputDevicesRemoved; - int outputDeviceCount; - int inputDeviceCount; - SDL_AudioDeviceItem *outputDevices; - SDL_AudioDeviceItem *inputDevices; -} SDL_AudioDriver; - - -/* Define the SDL audio driver structure */ -struct SDL_AudioDevice -{ - /* * * */ - /* Data common to all devices */ - SDL_AudioDeviceID id; - - /* The device's current audio specification */ - SDL_AudioSpec spec; - - /* The callback's expected audio specification (converted vs device's spec). */ - SDL_AudioSpec callbackspec; - - /* Stream that converts and resamples. NULL if not needed. */ - SDL_AudioStream *stream; - - /* Current state flags */ - SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */ - SDL_atomic_t enabled; /* true if device is functioning and connected. */ - SDL_atomic_t paused; - SDL_bool iscapture; - - /* Scratch buffer used in the bridge between SDL and the user callback. */ - Uint8 *work_buffer; - - /* Size, in bytes, of work_buffer. */ - Uint32 work_buffer_len; - - /* A mutex for locking the mixing buffers */ - SDL_mutex *mixer_lock; - - /* A thread to feed the audio device */ - SDL_Thread *thread; - SDL_threadID threadid; - - /* Queued buffers (if app not using callback). */ - SDL_DataQueue *buffer_queue; - - /* * * */ - /* Data private to this driver */ - struct SDL_PrivateAudioData *hidden; - - void *handle; -}; -#undef _THIS - -typedef struct AudioBootStrap -{ - const char *name; - const char *desc; - int (*init) (SDL_AudioDriverImpl * impl); - int demand_only; /* 1==request explicitly, or it won't be available. */ -} AudioBootStrap; - -/* Not all of these are available in a given build. Use #ifdefs, etc. */ -extern AudioBootStrap PULSEAUDIO_bootstrap; -extern AudioBootStrap ALSA_bootstrap; -extern AudioBootStrap JACK_bootstrap; -extern AudioBootStrap SNDIO_bootstrap; -extern AudioBootStrap NETBSDAUDIO_bootstrap; -extern AudioBootStrap DSP_bootstrap; -extern AudioBootStrap QSAAUDIO_bootstrap; -extern AudioBootStrap SUNAUDIO_bootstrap; -extern AudioBootStrap ARTS_bootstrap; -extern AudioBootStrap ESD_bootstrap; -extern AudioBootStrap NACLAUDIO_bootstrap; -extern AudioBootStrap NAS_bootstrap; -extern AudioBootStrap WASAPI_bootstrap; -extern AudioBootStrap DSOUND_bootstrap; -extern AudioBootStrap WINMM_bootstrap; -extern AudioBootStrap PAUDIO_bootstrap; -extern AudioBootStrap HAIKUAUDIO_bootstrap; -extern AudioBootStrap COREAUDIO_bootstrap; -extern AudioBootStrap DISKAUDIO_bootstrap; -extern AudioBootStrap DUMMYAUDIO_bootstrap; -extern AudioBootStrap FUSIONSOUND_bootstrap; -extern AudioBootStrap ANDROIDAUDIO_bootstrap; -extern AudioBootStrap PSPAUDIO_bootstrap; -extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; - -#endif /* SDL_sysaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_wave.c b/Source/3rdParty/SDL2/src/audio/SDL_wave.c deleted file mode 100644 index 2c76a8c..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_wave.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* Microsoft WAVE file loading routines */ - -#include "SDL_audio.h" -#include "SDL_wave.h" - - -static int ReadChunk(SDL_RWops * src, Chunk * chunk); - -struct MS_ADPCM_decodestate -{ - Uint8 hPredictor; - Uint16 iDelta; - Sint16 iSamp1; - Sint16 iSamp2; -}; -static struct MS_ADPCM_decoder -{ - WaveFMT wavefmt; - Uint16 wSamplesPerBlock; - Uint16 wNumCoef; - Sint16 aCoeff[7][2]; - /* * * */ - struct MS_ADPCM_decodestate state[2]; -} MS_ADPCM_state; - -static int -InitMS_ADPCM(WaveFMT * format) -{ - Uint8 *rogue_feel; - int i; - - /* Set the rogue pointer to the MS_ADPCM specific data */ - MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding); - MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels); - MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency); - MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate); - MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign); - MS_ADPCM_state.wavefmt.bitspersample = - SDL_SwapLE16(format->bitspersample); - rogue_feel = (Uint8 *) format + sizeof(*format); - if (sizeof(*format) == 16) { - /* const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]); */ - rogue_feel += sizeof(Uint16); - } - MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]); - rogue_feel += sizeof(Uint16); - MS_ADPCM_state.wNumCoef = ((rogue_feel[1] << 8) | rogue_feel[0]); - rogue_feel += sizeof(Uint16); - if (MS_ADPCM_state.wNumCoef != 7) { - SDL_SetError("Unknown set of MS_ADPCM coefficients"); - return (-1); - } - for (i = 0; i < MS_ADPCM_state.wNumCoef; ++i) { - MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1] << 8) | rogue_feel[0]); - rogue_feel += sizeof(Uint16); - MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1] << 8) | rogue_feel[0]); - rogue_feel += sizeof(Uint16); - } - return (0); -} - -static Sint32 -MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state, - Uint8 nybble, Sint16 * coeff) -{ - const Sint32 max_audioval = ((1 << (16 - 1)) - 1); - const Sint32 min_audioval = -(1 << (16 - 1)); - const Sint32 adaptive[] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 768, 614, 512, 409, 307, 230, 230, 230 - }; - Sint32 new_sample, delta; - - new_sample = ((state->iSamp1 * coeff[0]) + - (state->iSamp2 * coeff[1])) / 256; - if (nybble & 0x08) { - new_sample += state->iDelta * (nybble - 0x10); - } else { - new_sample += state->iDelta * nybble; - } - if (new_sample < min_audioval) { - new_sample = min_audioval; - } else if (new_sample > max_audioval) { - new_sample = max_audioval; - } - delta = ((Sint32) state->iDelta * adaptive[nybble]) / 256; - if (delta < 16) { - delta = 16; - } - state->iDelta = (Uint16) delta; - state->iSamp2 = state->iSamp1; - state->iSamp1 = (Sint16) new_sample; - return (new_sample); -} - -static int -MS_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len) -{ - struct MS_ADPCM_decodestate *state[2]; - Uint8 *freeable, *encoded, *decoded; - Sint32 encoded_len, samplesleft; - Sint8 nybble; - Uint8 stereo; - Sint16 *coeff[2]; - Sint32 new_sample; - - /* Allocate the proper sized output buffer */ - encoded_len = *audio_len; - encoded = *audio_buf; - freeable = *audio_buf; - *audio_len = (encoded_len / MS_ADPCM_state.wavefmt.blockalign) * - MS_ADPCM_state.wSamplesPerBlock * - MS_ADPCM_state.wavefmt.channels * sizeof(Sint16); - *audio_buf = (Uint8 *) SDL_malloc(*audio_len); - if (*audio_buf == NULL) { - return SDL_OutOfMemory(); - } - decoded = *audio_buf; - - /* Get ready... Go! */ - stereo = (MS_ADPCM_state.wavefmt.channels == 2); - state[0] = &MS_ADPCM_state.state[0]; - state[1] = &MS_ADPCM_state.state[stereo]; - while (encoded_len >= MS_ADPCM_state.wavefmt.blockalign) { - /* Grab the initial information for this block */ - state[0]->hPredictor = *encoded++; - if (stereo) { - state[1]->hPredictor = *encoded++; - } - state[0]->iDelta = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - if (stereo) { - state[1]->iDelta = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - } - state[0]->iSamp1 = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - if (stereo) { - state[1]->iSamp1 = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - } - state[0]->iSamp2 = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - if (stereo) { - state[1]->iSamp2 = ((encoded[1] << 8) | encoded[0]); - encoded += sizeof(Sint16); - } - coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor]; - coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor]; - - /* Store the two initial samples we start with */ - decoded[0] = state[0]->iSamp2 & 0xFF; - decoded[1] = state[0]->iSamp2 >> 8; - decoded += 2; - if (stereo) { - decoded[0] = state[1]->iSamp2 & 0xFF; - decoded[1] = state[1]->iSamp2 >> 8; - decoded += 2; - } - decoded[0] = state[0]->iSamp1 & 0xFF; - decoded[1] = state[0]->iSamp1 >> 8; - decoded += 2; - if (stereo) { - decoded[0] = state[1]->iSamp1 & 0xFF; - decoded[1] = state[1]->iSamp1 >> 8; - decoded += 2; - } - - /* Decode and store the other samples in this block */ - samplesleft = (MS_ADPCM_state.wSamplesPerBlock - 2) * - MS_ADPCM_state.wavefmt.channels; - while (samplesleft > 0) { - nybble = (*encoded) >> 4; - new_sample = MS_ADPCM_nibble(state[0], nybble, coeff[0]); - decoded[0] = new_sample & 0xFF; - new_sample >>= 8; - decoded[1] = new_sample & 0xFF; - decoded += 2; - - nybble = (*encoded) & 0x0F; - new_sample = MS_ADPCM_nibble(state[1], nybble, coeff[1]); - decoded[0] = new_sample & 0xFF; - new_sample >>= 8; - decoded[1] = new_sample & 0xFF; - decoded += 2; - - ++encoded; - samplesleft -= 2; - } - encoded_len -= MS_ADPCM_state.wavefmt.blockalign; - } - SDL_free(freeable); - return (0); -} - -struct IMA_ADPCM_decodestate -{ - Sint32 sample; - Sint8 index; -}; -static struct IMA_ADPCM_decoder -{ - WaveFMT wavefmt; - Uint16 wSamplesPerBlock; - /* * * */ - struct IMA_ADPCM_decodestate state[2]; -} IMA_ADPCM_state; - -static int -InitIMA_ADPCM(WaveFMT * format) -{ - Uint8 *rogue_feel; - - /* Set the rogue pointer to the IMA_ADPCM specific data */ - IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding); - IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels); - IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency); - IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate); - IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign); - IMA_ADPCM_state.wavefmt.bitspersample = - SDL_SwapLE16(format->bitspersample); - rogue_feel = (Uint8 *) format + sizeof(*format); - if (sizeof(*format) == 16) { - /* const Uint16 extra_info = ((rogue_feel[1] << 8) | rogue_feel[0]); */ - rogue_feel += sizeof(Uint16); - } - IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1] << 8) | rogue_feel[0]); - return (0); -} - -static Sint32 -IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state, Uint8 nybble) -{ - const Sint32 max_audioval = ((1 << (16 - 1)) - 1); - const Sint32 min_audioval = -(1 << (16 - 1)); - const int index_table[16] = { - -1, -1, -1, -1, - 2, 4, 6, 8, - -1, -1, -1, -1, - 2, 4, 6, 8 - }; - const Sint32 step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, - 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, - 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, - 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, - 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, - 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, - 22385, 24623, 27086, 29794, 32767 - }; - Sint32 delta, step; - - /* Compute difference and new sample value */ - if (state->index > 88) { - state->index = 88; - } else if (state->index < 0) { - state->index = 0; - } - /* explicit cast to avoid gcc warning about using 'char' as array index */ - step = step_table[(int)state->index]; - delta = step >> 3; - if (nybble & 0x04) - delta += step; - if (nybble & 0x02) - delta += (step >> 1); - if (nybble & 0x01) - delta += (step >> 2); - if (nybble & 0x08) - delta = -delta; - state->sample += delta; - - /* Update index value */ - state->index += index_table[nybble]; - - /* Clamp output sample */ - if (state->sample > max_audioval) { - state->sample = max_audioval; - } else if (state->sample < min_audioval) { - state->sample = min_audioval; - } - return (state->sample); -} - -/* Fill the decode buffer with a channel block of data (8 samples) */ -static void -Fill_IMA_ADPCM_block(Uint8 * decoded, Uint8 * encoded, - int channel, int numchannels, - struct IMA_ADPCM_decodestate *state) -{ - int i; - Sint8 nybble; - Sint32 new_sample; - - decoded += (channel * 2); - for (i = 0; i < 4; ++i) { - nybble = (*encoded) & 0x0F; - new_sample = IMA_ADPCM_nibble(state, nybble); - decoded[0] = new_sample & 0xFF; - new_sample >>= 8; - decoded[1] = new_sample & 0xFF; - decoded += 2 * numchannels; - - nybble = (*encoded) >> 4; - new_sample = IMA_ADPCM_nibble(state, nybble); - decoded[0] = new_sample & 0xFF; - new_sample >>= 8; - decoded[1] = new_sample & 0xFF; - decoded += 2 * numchannels; - - ++encoded; - } -} - -static int -IMA_ADPCM_decode(Uint8 ** audio_buf, Uint32 * audio_len) -{ - struct IMA_ADPCM_decodestate *state; - Uint8 *freeable, *encoded, *decoded; - Sint32 encoded_len, samplesleft; - unsigned int c, channels; - - /* Check to make sure we have enough variables in the state array */ - channels = IMA_ADPCM_state.wavefmt.channels; - if (channels > SDL_arraysize(IMA_ADPCM_state.state)) { - SDL_SetError("IMA ADPCM decoder can only handle %u channels", - (unsigned int)SDL_arraysize(IMA_ADPCM_state.state)); - return (-1); - } - state = IMA_ADPCM_state.state; - - /* Allocate the proper sized output buffer */ - encoded_len = *audio_len; - encoded = *audio_buf; - freeable = *audio_buf; - *audio_len = (encoded_len / IMA_ADPCM_state.wavefmt.blockalign) * - IMA_ADPCM_state.wSamplesPerBlock * - IMA_ADPCM_state.wavefmt.channels * sizeof(Sint16); - *audio_buf = (Uint8 *) SDL_malloc(*audio_len); - if (*audio_buf == NULL) { - return SDL_OutOfMemory(); - } - decoded = *audio_buf; - - /* Get ready... Go! */ - while (encoded_len >= IMA_ADPCM_state.wavefmt.blockalign) { - /* Grab the initial information for this block */ - for (c = 0; c < channels; ++c) { - /* Fill the state information for this block */ - state[c].sample = ((encoded[1] << 8) | encoded[0]); - encoded += 2; - if (state[c].sample & 0x8000) { - state[c].sample -= 0x10000; - } - state[c].index = *encoded++; - /* Reserved byte in buffer header, should be 0 */ - if (*encoded++ != 0) { - /* Uh oh, corrupt data? Buggy code? */ ; - } - - /* Store the initial sample we start with */ - decoded[0] = (Uint8) (state[c].sample & 0xFF); - decoded[1] = (Uint8) (state[c].sample >> 8); - decoded += 2; - } - - /* Decode and store the other samples in this block */ - samplesleft = (IMA_ADPCM_state.wSamplesPerBlock - 1) * channels; - while (samplesleft > 0) { - for (c = 0; c < channels; ++c) { - Fill_IMA_ADPCM_block(decoded, encoded, - c, channels, &state[c]); - encoded += 4; - samplesleft -= 8; - } - decoded += (channels * 8 * 2); - } - encoded_len -= IMA_ADPCM_state.wavefmt.blockalign; - } - SDL_free(freeable); - return (0); -} - - -static int -ConvertSint24ToSint32(Uint8 ** audio_buf, Uint32 * audio_len) -{ - const double DIVBY8388608 = 0.00000011920928955078125; - const Uint32 original_len = *audio_len; - const Uint32 samples = original_len / 3; - const Uint32 expanded_len = samples * sizeof (Uint32); - Uint8 *ptr = (Uint8 *) SDL_realloc(*audio_buf, expanded_len); - const Uint8 *src; - Uint32 *dst; - Uint32 i; - - if (!ptr) { - return SDL_OutOfMemory(); - } - - *audio_buf = ptr; - *audio_len = expanded_len; - - /* work from end to start, since we're expanding in-place. */ - src = (ptr + original_len) - 3; - dst = ((Uint32 *) (ptr + expanded_len)) - 1; - for (i = 0; i < samples; i++) { - /* There's probably a faster way to do all this. */ - const Sint32 converted = ((Sint32) ( (((Uint32) src[2]) << 24) | - (((Uint32) src[1]) << 16) | - (((Uint32) src[0]) << 8) )) >> 8; - const double scaled = (((double) converted) * DIVBY8388608); - src -= 3; - *(dst--) = (Sint32) (scaled * 2147483647.0); - } - - return 0; -} - - -/* GUIDs that are used by WAVE_FORMAT_EXTENSIBLE */ -static const Uint8 extensible_pcm_guid[16] = { 1, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 }; -static const Uint8 extensible_ieee_guid[16] = { 3, 0, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 }; - -SDL_AudioSpec * -SDL_LoadWAV_RW(SDL_RWops * src, int freesrc, - SDL_AudioSpec * spec, Uint8 ** audio_buf, Uint32 * audio_len) -{ - int was_error; - Chunk chunk; - int lenread; - int IEEE_float_encoded, MS_ADPCM_encoded, IMA_ADPCM_encoded; - int samplesize; - - /* WAV magic header */ - Uint32 RIFFchunk; - Uint32 wavelen = 0; - Uint32 WAVEmagic; - Uint32 headerDiff = 0; - - /* FMT chunk */ - WaveFMT *format = NULL; - WaveExtensibleFMT *ext = NULL; - - SDL_zero(chunk); - - /* Make sure we are passed a valid data source */ - was_error = 0; - if (src == NULL) { - was_error = 1; - goto done; - } - - /* Check the magic header */ - RIFFchunk = SDL_ReadLE32(src); - wavelen = SDL_ReadLE32(src); - if (wavelen == WAVE) { /* The RIFFchunk has already been read */ - WAVEmagic = wavelen; - wavelen = RIFFchunk; - RIFFchunk = RIFF; - } else { - WAVEmagic = SDL_ReadLE32(src); - } - if ((RIFFchunk != RIFF) || (WAVEmagic != WAVE)) { - SDL_SetError("Unrecognized file type (not WAVE)"); - was_error = 1; - goto done; - } - headerDiff += sizeof(Uint32); /* for WAVE */ - - /* Read the audio data format chunk */ - chunk.data = NULL; - do { - SDL_free(chunk.data); - chunk.data = NULL; - lenread = ReadChunk(src, &chunk); - if (lenread < 0) { - was_error = 1; - goto done; - } - /* 2 Uint32's for chunk header+len, plus the lenread */ - headerDiff += lenread + 2 * sizeof(Uint32); - } while ((chunk.magic == FACT) || (chunk.magic == LIST) || (chunk.magic == BEXT) || (chunk.magic == JUNK)); - - /* Decode the audio data format */ - format = (WaveFMT *) chunk.data; - if (chunk.magic != FMT) { - SDL_SetError("Complex WAVE files not supported"); - was_error = 1; - goto done; - } - IEEE_float_encoded = MS_ADPCM_encoded = IMA_ADPCM_encoded = 0; - switch (SDL_SwapLE16(format->encoding)) { - case PCM_CODE: - /* We can understand this */ - break; - case IEEE_FLOAT_CODE: - IEEE_float_encoded = 1; - /* We can understand this */ - break; - case MS_ADPCM_CODE: - /* Try to understand this */ - if (InitMS_ADPCM(format) < 0) { - was_error = 1; - goto done; - } - MS_ADPCM_encoded = 1; - break; - case IMA_ADPCM_CODE: - /* Try to understand this */ - if (InitIMA_ADPCM(format) < 0) { - was_error = 1; - goto done; - } - IMA_ADPCM_encoded = 1; - break; - case EXTENSIBLE_CODE: - /* note that this ignores channel masks, smaller valid bit counts - inside a larger container, and most subtypes. This is just enough - to get things that didn't really _need_ WAVE_FORMAT_EXTENSIBLE - to be useful working when they use this format flag. */ - ext = (WaveExtensibleFMT *) format; - if (SDL_SwapLE16(ext->size) < 22) { - SDL_SetError("bogus extended .wav header"); - was_error = 1; - goto done; - } - if (SDL_memcmp(ext->subformat, extensible_pcm_guid, 16) == 0) { - break; /* cool. */ - } else if (SDL_memcmp(ext->subformat, extensible_ieee_guid, 16) == 0) { - IEEE_float_encoded = 1; - break; - } - break; - case MP3_CODE: - SDL_SetError("MPEG Layer 3 data not supported"); - was_error = 1; - goto done; - default: - SDL_SetError("Unknown WAVE data format: 0x%.4x", - SDL_SwapLE16(format->encoding)); - was_error = 1; - goto done; - } - SDL_zerop(spec); - spec->freq = SDL_SwapLE32(format->frequency); - - if (IEEE_float_encoded) { - if ((SDL_SwapLE16(format->bitspersample)) != 32) { - was_error = 1; - } else { - spec->format = AUDIO_F32; - } - } else { - switch (SDL_SwapLE16(format->bitspersample)) { - case 4: - if (MS_ADPCM_encoded || IMA_ADPCM_encoded) { - spec->format = AUDIO_S16; - } else { - was_error = 1; - } - break; - case 8: - spec->format = AUDIO_U8; - break; - case 16: - spec->format = AUDIO_S16; - break; - case 24: /* convert this. */ - spec->format = AUDIO_S32; - break; - case 32: - spec->format = AUDIO_S32; - break; - default: - was_error = 1; - break; - } - } - - if (was_error) { - SDL_SetError("Unknown %d-bit PCM data format", - SDL_SwapLE16(format->bitspersample)); - goto done; - } - spec->channels = (Uint8) SDL_SwapLE16(format->channels); - spec->samples = 4096; /* Good default buffer size */ - - /* Read the audio data chunk */ - *audio_buf = NULL; - do { - SDL_free(*audio_buf); - *audio_buf = NULL; - lenread = ReadChunk(src, &chunk); - if (lenread < 0) { - was_error = 1; - goto done; - } - *audio_len = lenread; - *audio_buf = chunk.data; - if (chunk.magic != DATA) - headerDiff += lenread + 2 * sizeof(Uint32); - } while (chunk.magic != DATA); - headerDiff += 2 * sizeof(Uint32); /* for the data chunk and len */ - - if (MS_ADPCM_encoded) { - if (MS_ADPCM_decode(audio_buf, audio_len) < 0) { - was_error = 1; - goto done; - } - } - if (IMA_ADPCM_encoded) { - if (IMA_ADPCM_decode(audio_buf, audio_len) < 0) { - was_error = 1; - goto done; - } - } - - if (SDL_SwapLE16(format->bitspersample) == 24) { - if (ConvertSint24ToSint32(audio_buf, audio_len) < 0) { - was_error = 1; - goto done; - } - } - - /* Don't return a buffer that isn't a multiple of samplesize */ - samplesize = ((SDL_AUDIO_BITSIZE(spec->format)) / 8) * spec->channels; - *audio_len &= ~(samplesize - 1); - - done: - SDL_free(format); - if (src) { - if (freesrc) { - SDL_RWclose(src); - } else { - /* seek to the end of the file (given by the RIFF chunk) */ - SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR); - } - } - if (was_error) { - spec = NULL; - } - return (spec); -} - -/* Since the WAV memory is allocated in the shared library, it must also - be freed here. (Necessary under Win32, VC++) - */ -void -SDL_FreeWAV(Uint8 * audio_buf) -{ - SDL_free(audio_buf); -} - -static int -ReadChunk(SDL_RWops * src, Chunk * chunk) -{ - chunk->magic = SDL_ReadLE32(src); - chunk->length = SDL_ReadLE32(src); - chunk->data = (Uint8 *) SDL_malloc(chunk->length); - if (chunk->data == NULL) { - return SDL_OutOfMemory(); - } - if (SDL_RWread(src, chunk->data, chunk->length, 1) != 1) { - SDL_free(chunk->data); - chunk->data = NULL; - return SDL_Error(SDL_EFREAD); - } - return (chunk->length); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/SDL_wave.h b/Source/3rdParty/SDL2/src/audio/SDL_wave.h deleted file mode 100644 index 5c60f75..0000000 --- a/Source/3rdParty/SDL2/src/audio/SDL_wave.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* WAVE files are little-endian */ - -/*******************************************/ -/* Define values for Microsoft WAVE format */ -/*******************************************/ -#define RIFF 0x46464952 /* "RIFF" */ -#define WAVE 0x45564157 /* "WAVE" */ -#define FACT 0x74636166 /* "fact" */ -#define LIST 0x5453494c /* "LIST" */ -#define BEXT 0x74786562 /* "bext" */ -#define JUNK 0x4B4E554A /* "JUNK" */ -#define FMT 0x20746D66 /* "fmt " */ -#define DATA 0x61746164 /* "data" */ -#define PCM_CODE 0x0001 -#define MS_ADPCM_CODE 0x0002 -#define IEEE_FLOAT_CODE 0x0003 -#define IMA_ADPCM_CODE 0x0011 -#define MP3_CODE 0x0055 -#define EXTENSIBLE_CODE 0xFFFE -#define WAVE_MONO 1 -#define WAVE_STEREO 2 - -/* Normally, these three chunks come consecutively in a WAVE file */ -typedef struct WaveFMT -{ -/* Not saved in the chunk we read: - Uint32 FMTchunk; - Uint32 fmtlen; -*/ - Uint16 encoding; - Uint16 channels; /* 1 = mono, 2 = stereo */ - Uint32 frequency; /* One of 11025, 22050, or 44100 Hz */ - Uint32 byterate; /* Average bytes per second */ - Uint16 blockalign; /* Bytes per sample block */ - Uint16 bitspersample; /* One of 8, 12, 16, or 4 for ADPCM */ -} WaveFMT; - -/* The general chunk found in the WAVE file */ -typedef struct Chunk -{ - Uint32 magic; - Uint32 length; - Uint8 *data; -} Chunk; - -typedef struct WaveExtensibleFMT -{ - WaveFMT format; - Uint16 size; - Uint16 validbits; - Uint32 channelmask; - Uint8 subformat[16]; /* a GUID. */ -} WaveExtensibleFMT; - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.c b/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.c deleted file mode 100644 index eff192b..0000000 --- a/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.c +++ /dev/null @@ -1,990 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_ALSA - -#ifndef SDL_ALSA_NON_BLOCKING -#define SDL_ALSA_NON_BLOCKING 0 -#endif - -/* Allow access to a raw mixing buffer */ - -#include <sys/types.h> -#include <signal.h> /* For kill() */ -#include <string.h> - -#include "SDL_assert.h" -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_alsa_audio.h" - -#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC -#include "SDL_loadso.h" -#endif - -static int (*ALSA_snd_pcm_open) - (snd_pcm_t **, const char *, snd_pcm_stream_t, int); -static int (*ALSA_snd_pcm_close) (snd_pcm_t * pcm); -static snd_pcm_sframes_t (*ALSA_snd_pcm_writei) - (snd_pcm_t *, const void *, snd_pcm_uframes_t); -static snd_pcm_sframes_t (*ALSA_snd_pcm_readi) - (snd_pcm_t *, void *, snd_pcm_uframes_t); -static int (*ALSA_snd_pcm_recover) (snd_pcm_t *, int, int); -static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *); -static int (*ALSA_snd_pcm_drain) (snd_pcm_t *); -static const char *(*ALSA_snd_strerror) (int); -static size_t(*ALSA_snd_pcm_hw_params_sizeof) (void); -static size_t(*ALSA_snd_pcm_sw_params_sizeof) (void); -static void (*ALSA_snd_pcm_hw_params_copy) - (snd_pcm_hw_params_t *, const snd_pcm_hw_params_t *); -static int (*ALSA_snd_pcm_hw_params_any) (snd_pcm_t *, snd_pcm_hw_params_t *); -static int (*ALSA_snd_pcm_hw_params_set_access) - (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_access_t); -static int (*ALSA_snd_pcm_hw_params_set_format) - (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t); -static int (*ALSA_snd_pcm_hw_params_set_channels) - (snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int); -static int (*ALSA_snd_pcm_hw_params_get_channels) - (const snd_pcm_hw_params_t *, unsigned int *); -static int (*ALSA_snd_pcm_hw_params_set_rate_near) - (snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); -static int (*ALSA_snd_pcm_hw_params_set_period_size_near) - (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); -static int (*ALSA_snd_pcm_hw_params_get_period_size) - (const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); -static int (*ALSA_snd_pcm_hw_params_set_periods_near) - (snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); -static int (*ALSA_snd_pcm_hw_params_get_periods) - (const snd_pcm_hw_params_t *, unsigned int *, int *); -static int (*ALSA_snd_pcm_hw_params_set_buffer_size_near) - (snd_pcm_t *pcm, snd_pcm_hw_params_t *, snd_pcm_uframes_t *); -static int (*ALSA_snd_pcm_hw_params_get_buffer_size) - (const snd_pcm_hw_params_t *, snd_pcm_uframes_t *); -static int (*ALSA_snd_pcm_hw_params) (snd_pcm_t *, snd_pcm_hw_params_t *); -static int (*ALSA_snd_pcm_sw_params_current) (snd_pcm_t *, - snd_pcm_sw_params_t *); -static int (*ALSA_snd_pcm_sw_params_set_start_threshold) - (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t); -static int (*ALSA_snd_pcm_sw_params) (snd_pcm_t *, snd_pcm_sw_params_t *); -static int (*ALSA_snd_pcm_nonblock) (snd_pcm_t *, int); -static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int); -static int (*ALSA_snd_pcm_sw_params_set_avail_min) - (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t); -static int (*ALSA_snd_pcm_reset)(snd_pcm_t *); -static int (*ALSA_snd_device_name_hint) (int, const char *, void ***); -static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *); -static int (*ALSA_snd_device_name_free_hint) (void **); -static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *); -#ifdef SND_CHMAP_API_VERSION -static snd_pcm_chmap_t* (*ALSA_snd_pcm_get_chmap) (snd_pcm_t *); -static int (*ALSA_snd_pcm_chmap_print) (const snd_pcm_chmap_t *map, size_t maxlen, char *buf); -#endif - -#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC -#define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof -#define snd_pcm_sw_params_sizeof ALSA_snd_pcm_sw_params_sizeof - -static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC; -static void *alsa_handle = NULL; - -static int -load_alsa_sym(const char *fn, void **addr) -{ - *addr = SDL_LoadFunction(alsa_handle, fn); - if (*addr == NULL) { - /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ - return 0; - } - - return 1; -} - -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_ALSA_SYM(x) \ - if (!load_alsa_sym(#x, (void **) (char *) &ALSA_##x)) return -1 -#else -#define SDL_ALSA_SYM(x) ALSA_##x = x -#endif - -static int -load_alsa_syms(void) -{ - SDL_ALSA_SYM(snd_pcm_open); - SDL_ALSA_SYM(snd_pcm_close); - SDL_ALSA_SYM(snd_pcm_writei); - SDL_ALSA_SYM(snd_pcm_readi); - SDL_ALSA_SYM(snd_pcm_recover); - SDL_ALSA_SYM(snd_pcm_prepare); - SDL_ALSA_SYM(snd_pcm_drain); - SDL_ALSA_SYM(snd_strerror); - SDL_ALSA_SYM(snd_pcm_hw_params_sizeof); - SDL_ALSA_SYM(snd_pcm_sw_params_sizeof); - SDL_ALSA_SYM(snd_pcm_hw_params_copy); - SDL_ALSA_SYM(snd_pcm_hw_params_any); - SDL_ALSA_SYM(snd_pcm_hw_params_set_access); - SDL_ALSA_SYM(snd_pcm_hw_params_set_format); - SDL_ALSA_SYM(snd_pcm_hw_params_set_channels); - SDL_ALSA_SYM(snd_pcm_hw_params_get_channels); - SDL_ALSA_SYM(snd_pcm_hw_params_set_rate_near); - SDL_ALSA_SYM(snd_pcm_hw_params_set_period_size_near); - SDL_ALSA_SYM(snd_pcm_hw_params_get_period_size); - SDL_ALSA_SYM(snd_pcm_hw_params_set_periods_near); - SDL_ALSA_SYM(snd_pcm_hw_params_get_periods); - SDL_ALSA_SYM(snd_pcm_hw_params_set_buffer_size_near); - SDL_ALSA_SYM(snd_pcm_hw_params_get_buffer_size); - SDL_ALSA_SYM(snd_pcm_hw_params); - SDL_ALSA_SYM(snd_pcm_sw_params_current); - SDL_ALSA_SYM(snd_pcm_sw_params_set_start_threshold); - SDL_ALSA_SYM(snd_pcm_sw_params); - SDL_ALSA_SYM(snd_pcm_nonblock); - SDL_ALSA_SYM(snd_pcm_wait); - SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min); - SDL_ALSA_SYM(snd_pcm_reset); - SDL_ALSA_SYM(snd_device_name_hint); - SDL_ALSA_SYM(snd_device_name_get_hint); - SDL_ALSA_SYM(snd_device_name_free_hint); - SDL_ALSA_SYM(snd_pcm_avail); -#ifdef SND_CHMAP_API_VERSION - SDL_ALSA_SYM(snd_pcm_get_chmap); - SDL_ALSA_SYM(snd_pcm_chmap_print); -#endif - - return 0; -} - -#undef SDL_ALSA_SYM - -#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC - -static void -UnloadALSALibrary(void) -{ - if (alsa_handle != NULL) { - SDL_UnloadObject(alsa_handle); - alsa_handle = NULL; - } -} - -static int -LoadALSALibrary(void) -{ - int retval = 0; - if (alsa_handle == NULL) { - alsa_handle = SDL_LoadObject(alsa_library); - if (alsa_handle == NULL) { - retval = -1; - /* Don't call SDL_SetError(): SDL_LoadObject already did. */ - } else { - retval = load_alsa_syms(); - if (retval < 0) { - UnloadALSALibrary(); - } - } - } - return retval; -} - -#else - -static void -UnloadALSALibrary(void) -{ -} - -static int -LoadALSALibrary(void) -{ - load_alsa_syms(); - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ - -static const char * -get_audio_device(void *handle, const int channels) -{ - const char *device; - - if (handle != NULL) { - return (const char *) handle; - } - - /* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */ - device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ - if (device != NULL) { - return device; - } - - if (channels == 6) { - return "plug:surround51"; - } else if (channels == 4) { - return "plug:surround40"; - } - - return "default"; -} - - -/* This function waits until it is possible to write a full sound buffer */ -static void -ALSA_WaitDevice(_THIS) -{ -#if SDL_ALSA_NON_BLOCKING - const snd_pcm_sframes_t needed = (snd_pcm_sframes_t) this->spec.samples; - while (SDL_AtomicGet(&this->enabled)) { - const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(this->hidden->pcm_handle); - if ((rc < 0) && (rc != -EAGAIN)) { - /* Hmm, not much we can do - abort */ - fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n", - ALSA_snd_strerror(rc)); - SDL_OpenedAudioDeviceDisconnected(this); - return; - } else if (rc < needed) { - const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / this->spec.freq; - SDL_Delay(SDL_max(delay, 10)); - } else { - break; /* ready to go! */ - } - } -#endif -} - - -/* !!! FIXME: is there a channel swizzler in alsalib instead? */ -/* - * http://bugzilla.libsdl.org/show_bug.cgi?id=110 - * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE - * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR" - */ -#define SWIZ6(T, buf, numframes) \ - T *ptr = (T *) buf; \ - Uint32 i; \ - for (i = 0; i < numframes; i++, ptr += 6) { \ - T tmp; \ - tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \ - tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \ - } - -static void -swizzle_alsa_channels_6_64bit(void *buffer, Uint32 bufferlen) -{ - SWIZ6(Uint64, buffer, bufferlen); -} - -static void -swizzle_alsa_channels_6_32bit(void *buffer, Uint32 bufferlen) -{ - SWIZ6(Uint32, buffer, bufferlen); -} - -static void -swizzle_alsa_channels_6_16bit(void *buffer, Uint32 bufferlen) -{ - SWIZ6(Uint16, buffer, bufferlen); -} - -static void -swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen) -{ - SWIZ6(Uint8, buffer, bufferlen); -} - -#undef SWIZ6 - - -/* - * Called right before feeding this->hidden->mixbuf to the hardware. Swizzle - * channels from Windows/Mac order to the format alsalib will want. - */ -static void -swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen) -{ - if (this->spec.channels == 6) { - switch (SDL_AUDIO_BITSIZE(this->spec.format)) { - case 8: swizzle_alsa_channels_6_8bit(buffer, bufferlen); break; - case 16: swizzle_alsa_channels_6_16bit(buffer, bufferlen); break; - case 32: swizzle_alsa_channels_6_32bit(buffer, bufferlen); break; - case 64: swizzle_alsa_channels_6_64bit(buffer, bufferlen); break; - default: SDL_assert(!"unhandled bitsize"); break; - } - } - - /* !!! FIXME: update this for 7.1 if needed, later. */ -} - -#ifdef SND_CHMAP_API_VERSION -/* Some devices have the right channel map, no swizzling necessary */ -static void -no_swizzle(_THIS, void *buffer, Uint32 bufferlen) -{ - return; -} -#endif /* SND_CHMAP_API_VERSION */ - - -static void -ALSA_PlayDevice(_THIS) -{ - const Uint8 *sample_buf = (const Uint8 *) this->hidden->mixbuf; - const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * - this->spec.channels; - snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t) this->spec.samples); - - this->hidden->swizzle_func(this, this->hidden->mixbuf, frames_left); - - while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) { - int status = ALSA_snd_pcm_writei(this->hidden->pcm_handle, - sample_buf, frames_left); - - if (status < 0) { - if (status == -EAGAIN) { - /* Apparently snd_pcm_recover() doesn't handle this case - - does it assume snd_pcm_wait() above? */ - SDL_Delay(1); - continue; - } - status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0); - if (status < 0) { - /* Hmm, not much we can do - abort */ - fprintf(stderr, "ALSA write failed (unrecoverable): %s\n", - ALSA_snd_strerror(status)); - SDL_OpenedAudioDeviceDisconnected(this); - return; - } - continue; - } - else if (status == 0) { - /* No frames were written (no available space in pcm device). - Allow other threads to catch up. */ - Uint32 delay = (frames_left / 2 * 1000) / this->spec.freq; - SDL_Delay(delay); - } - - sample_buf += status * frame_size; - frames_left -= status; - } -} - -static Uint8 * -ALSA_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static int -ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - Uint8 *sample_buf = (Uint8 *) buffer; - const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * - this->spec.channels; - const int total_frames = buflen / frame_size; - snd_pcm_uframes_t frames_left = total_frames; - snd_pcm_uframes_t wait_time = frame_size / 2; - - SDL_assert((buflen % frame_size) == 0); - - while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) { - int status; - - status = ALSA_snd_pcm_readi(this->hidden->pcm_handle, - sample_buf, frames_left); - - if (status == -EAGAIN) { - ALSA_snd_pcm_wait(this->hidden->pcm_handle, wait_time); - status = 0; - } - else if (status < 0) { - /*printf("ALSA: capture error %d\n", status);*/ - status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0); - if (status < 0) { - /* Hmm, not much we can do - abort */ - fprintf(stderr, "ALSA read failed (unrecoverable): %s\n", - ALSA_snd_strerror(status)); - return -1; - } - continue; - } - - /*printf("ALSA: captured %d bytes\n", status * frame_size);*/ - sample_buf += status * frame_size; - frames_left -= status; - } - - this->hidden->swizzle_func(this, buffer, total_frames - frames_left); - - return (total_frames - frames_left) * frame_size; -} - -static void -ALSA_FlushCapture(_THIS) -{ - ALSA_snd_pcm_reset(this->hidden->pcm_handle); -} - -static void -ALSA_CloseDevice(_THIS) -{ - if (this->hidden->pcm_handle) { - /* Wait for the submitted audio to drain - ALSA_snd_pcm_drop() can hang, so don't use that. - */ - Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; - SDL_Delay(delay); - - ALSA_snd_pcm_close(this->hidden->pcm_handle); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params) -{ - int status; - snd_pcm_hw_params_t *hwparams; - snd_pcm_uframes_t bufsize; - snd_pcm_uframes_t persize; - - /* Copy the hardware parameters for this setup */ - snd_pcm_hw_params_alloca(&hwparams); - ALSA_snd_pcm_hw_params_copy(hwparams, params); - - /* Prioritize matching the period size to the requested buffer size */ - persize = this->spec.samples; - status = ALSA_snd_pcm_hw_params_set_period_size_near( - this->hidden->pcm_handle, hwparams, &persize, NULL); - if ( status < 0 ) { - return(-1); - } - - /* Next try to restrict the parameters to having only two periods */ - bufsize = this->spec.samples * 2; - status = ALSA_snd_pcm_hw_params_set_buffer_size_near( - this->hidden->pcm_handle, hwparams, &bufsize); - if ( status < 0 ) { - return(-1); - } - - /* "set" the hardware with the desired parameters */ - status = ALSA_snd_pcm_hw_params(this->hidden->pcm_handle, hwparams); - if ( status < 0 ) { - return(-1); - } - - this->spec.samples = persize; - - /* This is useful for debugging */ - if ( SDL_getenv("SDL_AUDIO_ALSA_DEBUG") ) { - unsigned int periods = 0; - - ALSA_snd_pcm_hw_params_get_periods(hwparams, &periods, NULL); - - fprintf(stderr, - "ALSA: period size = %ld, periods = %u, buffer size = %lu\n", - persize, periods, bufsize); - } - - return(0); -} - -static int -ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - int status = 0; - snd_pcm_t *pcm_handle = NULL; - snd_pcm_hw_params_t *hwparams = NULL; - snd_pcm_sw_params_t *swparams = NULL; - snd_pcm_format_t format = 0; - SDL_AudioFormat test_format = 0; - unsigned int rate = 0; - unsigned int channels = 0; -#ifdef SND_CHMAP_API_VERSION - snd_pcm_chmap_t *chmap; - char chmap_str[64]; -#endif - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - /* Name of device should depend on # channels in spec */ - status = ALSA_snd_pcm_open(&pcm_handle, - get_audio_device(handle, this->spec.channels), - iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, - SND_PCM_NONBLOCK); - - if (status < 0) { - return SDL_SetError("ALSA: Couldn't open audio device: %s", - ALSA_snd_strerror(status)); - } - - this->hidden->pcm_handle = pcm_handle; - - /* Figure out what the hardware is capable of */ - snd_pcm_hw_params_alloca(&hwparams); - status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't get hardware config: %s", - ALSA_snd_strerror(status)); - } - - /* SDL only uses interleaved sample output */ - status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams, - SND_PCM_ACCESS_RW_INTERLEAVED); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't set interleaved access: %s", - ALSA_snd_strerror(status)); - } - - /* Try for a closest match on audio format */ - status = -1; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - test_format && (status < 0);) { - status = 0; /* if we can't support a format, it'll become -1. */ - switch (test_format) { - case AUDIO_U8: - format = SND_PCM_FORMAT_U8; - break; - case AUDIO_S8: - format = SND_PCM_FORMAT_S8; - break; - case AUDIO_S16LSB: - format = SND_PCM_FORMAT_S16_LE; - break; - case AUDIO_S16MSB: - format = SND_PCM_FORMAT_S16_BE; - break; - case AUDIO_U16LSB: - format = SND_PCM_FORMAT_U16_LE; - break; - case AUDIO_U16MSB: - format = SND_PCM_FORMAT_U16_BE; - break; - case AUDIO_S32LSB: - format = SND_PCM_FORMAT_S32_LE; - break; - case AUDIO_S32MSB: - format = SND_PCM_FORMAT_S32_BE; - break; - case AUDIO_F32LSB: - format = SND_PCM_FORMAT_FLOAT_LE; - break; - case AUDIO_F32MSB: - format = SND_PCM_FORMAT_FLOAT_BE; - break; - default: - status = -1; - break; - } - if (status >= 0) { - status = ALSA_snd_pcm_hw_params_set_format(pcm_handle, - hwparams, format); - } - if (status < 0) { - test_format = SDL_NextAudioFormat(); - } - } - if (status < 0) { - return SDL_SetError("ALSA: Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - /* Validate number of channels and determine if swizzling is necessary - * Assume original swizzling, until proven otherwise. - */ - this->hidden->swizzle_func = swizzle_alsa_channels; -#ifdef SND_CHMAP_API_VERSION - chmap = ALSA_snd_pcm_get_chmap(pcm_handle); - if (chmap) { - ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str); - if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 || - SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) { - this->hidden->swizzle_func = no_swizzle; - } - free(chmap); - } -#endif /* SND_CHMAP_API_VERSION */ - - /* Set the number of channels */ - status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams, - this->spec.channels); - channels = this->spec.channels; - if (status < 0) { - status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't set audio channels"); - } - this->spec.channels = channels; - } - - /* Set the audio rate */ - rate = this->spec.freq; - status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, - &rate, NULL); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't set audio frequency: %s", - ALSA_snd_strerror(status)); - } - this->spec.freq = rate; - - /* Set the buffer size, in samples */ - status = ALSA_set_buffer_size(this, hwparams); - if (status < 0) { - return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status)); - } - - /* Set the software parameters */ - snd_pcm_sw_params_alloca(&swparams); - status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't get software config: %s", - ALSA_snd_strerror(status)); - } - status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples); - if (status < 0) { - return SDL_SetError("Couldn't set minimum available samples: %s", - ALSA_snd_strerror(status)); - } - status = - ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1); - if (status < 0) { - return SDL_SetError("ALSA: Couldn't set start threshold: %s", - ALSA_snd_strerror(status)); - } - status = ALSA_snd_pcm_sw_params(pcm_handle, swparams); - if (status < 0) { - return SDL_SetError("Couldn't set software audio parameters: %s", - ALSA_snd_strerror(status)); - } - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate mixing buffer */ - if (!iscapture) { - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); - } - - #if !SDL_ALSA_NON_BLOCKING - if (!iscapture) { - ALSA_snd_pcm_nonblock(pcm_handle, 0); - } - #endif - - /* We're ready to rock and roll. :-) */ - return 0; -} - -typedef struct ALSA_Device -{ - char *name; - SDL_bool iscapture; - struct ALSA_Device *next; -} ALSA_Device; - -static void -add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen) -{ - ALSA_Device *dev = SDL_malloc(sizeof (ALSA_Device)); - char *desc; - char *handle = NULL; - char *ptr; - - if (!dev) { - return; - } - - /* Not all alsa devices are enumerable via snd_device_name_get_hint - (i.e. bluetooth devices). Therefore if hint is passed in to this - function as NULL, assume name contains desc. - Make sure not to free the storage associated with desc in this case */ - if (hint) { - desc = ALSA_snd_device_name_get_hint(hint, "DESC"); - if (!desc) { - SDL_free(dev); - return; - } - } else { - desc = (char *) name; - } - - SDL_assert(name != NULL); - - /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output". - just chop the extra lines off, this seems to get a reasonable device - name without extra details. */ - if ((ptr = strchr(desc, '\n')) != NULL) { - *ptr = '\0'; - } - - /*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/ - - handle = SDL_strdup(name); - if (!handle) { - if (hint) { - free(desc); - } - SDL_free(dev); - return; - } - - SDL_AddAudioDevice(iscapture, desc, handle); - if (hint) - free(desc); - dev->name = handle; - dev->iscapture = iscapture; - dev->next = *pSeen; - *pSeen = dev; -} - - -static SDL_atomic_t ALSA_hotplug_shutdown; -static SDL_Thread *ALSA_hotplug_thread; - -static int SDLCALL -ALSA_HotplugThread(void *arg) -{ - SDL_sem *first_run_semaphore = (SDL_sem *) arg; - ALSA_Device *devices = NULL; - ALSA_Device *next; - ALSA_Device *dev; - Uint32 ticks; - - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); - - while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) { - void **hints = NULL; - ALSA_Device *unseen; - ALSA_Device *seen; - ALSA_Device *prev; - - if (ALSA_snd_device_name_hint(-1, "pcm", &hints) != -1) { - int i, j; - const char *match = NULL; - int bestmatch = 0xFFFF; - size_t match_len = 0; - int defaultdev = -1; - static const char * const prefixes[] = { - "hw:", "sysdefault:", "default:", NULL - }; - - unseen = devices; - seen = NULL; - /* Apparently there are several different ways that ALSA lists - actual hardware. It could be prefixed with "hw:" or "default:" - or "sysdefault:" and maybe others. Go through the list and see - if we can find a preferred prefix for the system. */ - for (i = 0; hints[i]; i++) { - char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); - if (!name) { - continue; - } - - /* full name, not a prefix */ - if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) { - defaultdev = i; - } - - for (j = 0; prefixes[j]; j++) { - const char *prefix = prefixes[j]; - const size_t prefixlen = SDL_strlen(prefix); - if (SDL_strncmp(name, prefix, prefixlen) == 0) { - if (j < bestmatch) { - bestmatch = j; - match = prefix; - match_len = prefixlen; - } - } - } - - free(name); - } - - /* look through the list of device names to find matches */ - for (i = 0; hints[i]; i++) { - char *name; - - /* if we didn't find a device name prefix we like at all... */ - if ((!match) && (defaultdev != i)) { - continue; /* ...skip anything that isn't the default device. */ - } - - name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); - if (!name) { - continue; - } - - /* only want physical hardware interfaces */ - if (!match || (SDL_strncmp(name, match, match_len) == 0)) { - char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID"); - const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0); - const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0); - SDL_bool have_output = SDL_FALSE; - SDL_bool have_input = SDL_FALSE; - - free(ioid); - - if (!isoutput && !isinput) { - free(name); - continue; - } - - prev = NULL; - for (dev = unseen; dev; dev = next) { - next = dev->next; - if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) { - if (prev) { - prev->next = next; - } else { - unseen = next; - } - dev->next = seen; - seen = dev; - if (isinput) have_input = SDL_TRUE; - if (isoutput) have_output = SDL_TRUE; - } else { - prev = dev; - } - } - - if (isinput && !have_input) { - add_device(SDL_TRUE, name, hints[i], &seen); - } - if (isoutput && !have_output) { - add_device(SDL_FALSE, name, hints[i], &seen); - } - } - - free(name); - } - - ALSA_snd_device_name_free_hint(hints); - - devices = seen; /* now we have a known-good list of attached devices. */ - - /* report anything still in unseen as removed. */ - for (dev = unseen; dev; dev = next) { - /*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ - next = dev->next; - SDL_RemoveAudioDevice(dev->iscapture, dev->name); - SDL_free(dev->name); - SDL_free(dev); - } - } - - /* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */ - if (first_run_semaphore) { - SDL_SemPost(first_run_semaphore); - first_run_semaphore = NULL; /* let other thread clean it up. */ - } - - /* Block awhile before checking again, unless we're told to stop. */ - ticks = SDL_GetTicks() + 5000; - while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) { - SDL_Delay(100); - } - } - - /* Shutting down! Clean up any data we've gathered. */ - for (dev = devices; dev; dev = next) { - /*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ - next = dev->next; - SDL_free(dev->name); - SDL_free(dev); - } - - return 0; -} - -static void -ALSA_DetectDevices(void) -{ - /* Start the device detection thread here, wait for an initial iteration to complete. */ - SDL_sem *semaphore = SDL_CreateSemaphore(0); - if (!semaphore) { - return; /* oh well. */ - } - - SDL_AtomicSet(&ALSA_hotplug_shutdown, 0); - - ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore); - if (ALSA_hotplug_thread) { - SDL_SemWait(semaphore); /* wait for the first iteration to finish. */ - } - - SDL_DestroySemaphore(semaphore); -} - -static void -ALSA_Deinitialize(void) -{ - if (ALSA_hotplug_thread != NULL) { - SDL_AtomicSet(&ALSA_hotplug_shutdown, 1); - SDL_WaitThread(ALSA_hotplug_thread, NULL); - ALSA_hotplug_thread = NULL; - } - - UnloadALSALibrary(); -} - -static int -ALSA_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadALSALibrary() < 0) { - return 0; - } - - /* Set the function pointers */ - impl->DetectDevices = ALSA_DetectDevices; - impl->OpenDevice = ALSA_OpenDevice; - impl->WaitDevice = ALSA_WaitDevice; - impl->GetDeviceBuf = ALSA_GetDeviceBuf; - impl->PlayDevice = ALSA_PlayDevice; - impl->CloseDevice = ALSA_CloseDevice; - impl->Deinitialize = ALSA_Deinitialize; - impl->CaptureFromDevice = ALSA_CaptureFromDevice; - impl->FlushCapture = ALSA_FlushCapture; - - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap ALSA_bootstrap = { - "alsa", "ALSA PCM audio", ALSA_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_ALSA */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.h b/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.h deleted file mode 100644 index f620500..0000000 --- a/Source/3rdParty/SDL2/src/audio/alsa/SDL_alsa_audio.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_ALSA_audio_h_ -#define SDL_ALSA_audio_h_ - -#include <alsa/asoundlib.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The audio device handle */ - snd_pcm_t *pcm_handle; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* swizzle function */ - void (*swizzle_func)(_THIS, void *buffer, Uint32 bufferlen); -}; - -#endif /* SDL_ALSA_audio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.c b/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.c deleted file mode 100644 index 77a5f0d..0000000 --- a/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_ANDROID - -/* Output audio to Android */ - -#include "SDL_assert.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_androidaudio.h" - -#include "../../core/android/SDL_android.h" - -#include <android/log.h> - -static SDL_AudioDevice* audioDevice = NULL; -static SDL_AudioDevice* captureDevice = NULL; - -static int -ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - SDL_AudioFormat test_format; - - SDL_assert((captureDevice == NULL) || !iscapture); - SDL_assert((audioDevice == NULL) || iscapture); - - if (iscapture) { - captureDevice = this; - } else { - audioDevice = this; - } - - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - - test_format = SDL_FirstAudioFormat(this->spec.format); - while (test_format != 0) { /* no "UNKNOWN" constant */ - if ((test_format == AUDIO_U8) || - (test_format == AUDIO_S16) || - (test_format == AUDIO_F32)) { - this->spec.format = test_format; - break; - } - test_format = SDL_NextAudioFormat(); - } - - if (test_format == 0) { - /* Didn't find a compatible format :( */ - return SDL_SetError("No compatible audio format!"); - } - - if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) { - return -1; - } - - SDL_CalculateAudioSpec(&this->spec); - - return 0; -} - -static void -ANDROIDAUDIO_PlayDevice(_THIS) -{ - Android_JNI_WriteAudioBuffer(); -} - -static Uint8 * -ANDROIDAUDIO_GetDeviceBuf(_THIS) -{ - return Android_JNI_GetAudioBuffer(); -} - -static int -ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - return Android_JNI_CaptureAudioBuffer(buffer, buflen); -} - -static void -ANDROIDAUDIO_FlushCapture(_THIS) -{ - Android_JNI_FlushCapturedAudio(); -} - -static void -ANDROIDAUDIO_CloseDevice(_THIS) -{ - /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread - so it's safe to terminate the Java side buffer and AudioTrack - */ - Android_JNI_CloseAudioDevice(this->iscapture); - if (this->iscapture) { - SDL_assert(captureDevice == this); - captureDevice = NULL; - } else { - SDL_assert(audioDevice == this); - audioDevice = NULL; - } - SDL_free(this->hidden); -} - -static int -ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = ANDROIDAUDIO_OpenDevice; - impl->PlayDevice = ANDROIDAUDIO_PlayDevice; - impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf; - impl->CloseDevice = ANDROIDAUDIO_CloseDevice; - impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice; - impl->FlushCapture = ANDROIDAUDIO_FlushCapture; - - /* and the capabilities */ - impl->HasCaptureSupport = SDL_TRUE; - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap ANDROIDAUDIO_bootstrap = { - "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0 -}; - -/* Pause (block) all non already paused audio devices by taking their mixer lock */ -void ANDROIDAUDIO_PauseDevices(void) -{ - /* TODO: Handle multiple devices? */ - struct SDL_PrivateAudioData *private; - if(audioDevice != NULL && audioDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (SDL_AtomicGet(&audioDevice->paused)) { - /* The device is already paused, leave it alone */ - private->resume = SDL_FALSE; - } - else { - SDL_LockMutex(audioDevice->mixer_lock); - SDL_AtomicSet(&audioDevice->paused, 1); - private->resume = SDL_TRUE; - } - } - - if(captureDevice != NULL && captureDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) captureDevice->hidden; - if (SDL_AtomicGet(&captureDevice->paused)) { - /* The device is already paused, leave it alone */ - private->resume = SDL_FALSE; - } - else { - SDL_LockMutex(captureDevice->mixer_lock); - SDL_AtomicSet(&captureDevice->paused, 1); - private->resume = SDL_TRUE; - } - } -} - -/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ -void ANDROIDAUDIO_ResumeDevices(void) -{ - /* TODO: Handle multiple devices? */ - struct SDL_PrivateAudioData *private; - if(audioDevice != NULL && audioDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (private->resume) { - SDL_AtomicSet(&audioDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(audioDevice->mixer_lock); - } - } - - if(captureDevice != NULL && captureDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) captureDevice->hidden; - if (private->resume) { - SDL_AtomicSet(&captureDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(captureDevice->mixer_lock); - } - } -} - -#else - -void ANDROIDAUDIO_ResumeDevices(void) {} -void ANDROIDAUDIO_PauseDevices(void) {} - -#endif /* SDL_AUDIO_DRIVER_ANDROID */ - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.h b/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.h deleted file mode 100644 index c732ac6..0000000 --- a/Source/3rdParty/SDL2/src/audio/android/SDL_androidaudio.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_androidaudio_h_ -#define SDL_androidaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* Resume device if it was paused automatically */ - int resume; -}; - -void ANDROIDAUDIO_ResumeDevices(void); -void ANDROIDAUDIO_PauseDevices(void); - -#endif /* SDL_androidaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.c b/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.c deleted file mode 100644 index 47bad4b..0000000 --- a/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_ARTS - -/* Allow access to a raw mixing buffer */ - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif -#include <unistd.h> -#include <errno.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_artsaudio.h" - -#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC -#include "SDL_name.h" -#include "SDL_loadso.h" -#else -#define SDL_NAME(X) X -#endif - -#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC - -static const char *arts_library = SDL_AUDIO_DRIVER_ARTS_DYNAMIC; -static void *arts_handle = NULL; - -/* !!! FIXME: I hate this SDL_NAME clutter...it makes everything so messy! */ -static int (*SDL_NAME(arts_init)) (void); -static void (*SDL_NAME(arts_free)) (void); -static arts_stream_t(*SDL_NAME(arts_play_stream)) (int rate, int bits, - int channels, - const char *name); -static int (*SDL_NAME(arts_stream_set)) (arts_stream_t s, - arts_parameter_t param, int value); -static int (*SDL_NAME(arts_stream_get)) (arts_stream_t s, - arts_parameter_t param); -static int (*SDL_NAME(arts_write)) (arts_stream_t s, const void *buffer, - int count); -static void (*SDL_NAME(arts_close_stream)) (arts_stream_t s); -static int (*SDL_NAME(arts_suspend))(void); -static int (*SDL_NAME(arts_suspended)) (void); -static const char *(*SDL_NAME(arts_error_text)) (int errorcode); - -#define SDL_ARTS_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) } -static struct -{ - const char *name; - void **func; -} arts_functions[] = { -/* *INDENT-OFF* */ - SDL_ARTS_SYM(arts_init), - SDL_ARTS_SYM(arts_free), - SDL_ARTS_SYM(arts_play_stream), - SDL_ARTS_SYM(arts_stream_set), - SDL_ARTS_SYM(arts_stream_get), - SDL_ARTS_SYM(arts_write), - SDL_ARTS_SYM(arts_close_stream), - SDL_ARTS_SYM(arts_suspend), - SDL_ARTS_SYM(arts_suspended), - SDL_ARTS_SYM(arts_error_text), -/* *INDENT-ON* */ -}; - -#undef SDL_ARTS_SYM - -static void -UnloadARTSLibrary() -{ - if (arts_handle != NULL) { - SDL_UnloadObject(arts_handle); - arts_handle = NULL; - } -} - -static int -LoadARTSLibrary(void) -{ - int i, retval = -1; - - if (arts_handle == NULL) { - arts_handle = SDL_LoadObject(arts_library); - if (arts_handle != NULL) { - retval = 0; - for (i = 0; i < SDL_arraysize(arts_functions); ++i) { - *arts_functions[i].func = - SDL_LoadFunction(arts_handle, arts_functions[i].name); - if (!*arts_functions[i].func) { - retval = -1; - UnloadARTSLibrary(); - break; - } - } - } - } - - return retval; -} - -#else - -static void -UnloadARTSLibrary() -{ - return; -} - -static int -LoadARTSLibrary(void) -{ - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ - -/* This function waits until it is possible to write a full sound buffer */ -static void -ARTS_WaitDevice(_THIS) -{ - Sint32 ticks; - - /* Check to see if the thread-parent process is still alive */ - { - static int cnt = 0; - /* Note that this only works with thread implementations - that use a different process id for each thread. - */ - /* Check every 10 loops */ - if (this->hidden->parent && (((++cnt) % 10) == 0)) { - if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { - SDL_OpenedAudioDeviceDisconnected(this); - } - } - } - - /* Use timer for general audio synchronization */ - ticks = - ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) - FUDGE_TICKS; - if (ticks > 0) { - SDL_Delay(ticks); - } -} - -static void -ARTS_PlayDevice(_THIS) -{ - /* Write the audio data */ - int written = SDL_NAME(arts_write) (this->hidden->stream, - this->hidden->mixbuf, - this->hidden->mixlen); - - /* If timer synchronization is enabled, set the next write frame */ - if (this->hidden->frame_ticks) { - this->hidden->next_frame += this->hidden->frame_ticks; - } - - /* If we couldn't write, assume fatal error for now */ - if (written < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif -} - -static Uint8 * -ARTS_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - - -static void -ARTS_CloseDevice(_THIS) -{ - if (this->hidden->stream) { - SDL_NAME(arts_close_stream) (this->hidden->stream); - } - SDL_NAME(arts_free) (); - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -ARTS_Suspend(void) -{ - const Uint32 abortms = SDL_GetTicks() + 3000; /* give up after 3 secs */ - while ( (!SDL_NAME(arts_suspended)()) && !SDL_TICKS_PASSED(SDL_GetTicks(), abortms) ) { - if ( SDL_NAME(arts_suspend)() ) { - break; - } - } - return SDL_NAME(arts_suspended)(); -} - -static int -ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - int rc = 0; - int bits = 0, frag_spec = 0; - SDL_AudioFormat test_format = 0, format = 0; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - switch (test_format) { - case AUDIO_U8: - bits = 8; - format = 1; - break; - case AUDIO_S16LSB: - bits = 16; - format = 1; - break; - default: - format = 0; - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); - } - } - if (format == 0) { - return SDL_SetError("Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - if ((rc = SDL_NAME(arts_init) ()) != 0) { - return SDL_SetError("Unable to initialize ARTS: %s", - SDL_NAME(arts_error_text) (rc)); - } - - if (!ARTS_Suspend()) { - return SDL_SetError("ARTS can not open audio device"); - } - - this->hidden->stream = SDL_NAME(arts_play_stream) (this->spec.freq, - bits, - this->spec.channels, - "SDL"); - - /* Play nothing so we have at least one write (server bug workaround). */ - SDL_NAME(arts_write) (this->hidden->stream, "", 0); - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Determine the power of two of the fragment size */ - for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec); - if ((0x01 << frag_spec) != this->spec.size) { - return SDL_SetError("Fragment size must be a power of two"); - } - frag_spec |= 0x00020000; /* two fragments, for low latency */ - -#ifdef ARTS_P_PACKET_SETTINGS - SDL_NAME(arts_stream_set) (this->hidden->stream, - ARTS_P_PACKET_SETTINGS, frag_spec); -#else - SDL_NAME(arts_stream_set) (this->hidden->stream, ARTS_P_PACKET_SIZE, - frag_spec & 0xffff); - SDL_NAME(arts_stream_set) (this->hidden->stream, ARTS_P_PACKET_COUNT, - frag_spec >> 16); -#endif - this->spec.size = SDL_NAME(arts_stream_get) (this->hidden->stream, - ARTS_P_PACKET_SIZE); - - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - - /* Get the parent process id (we're the parent of the audio thread) */ - this->hidden->parent = getpid(); - - /* We're ready to rock and roll. :-) */ - return 0; -} - - -static void -ARTS_Deinitialize(void) -{ - UnloadARTSLibrary(); -} - - -static int -ARTS_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadARTSLibrary() < 0) { - return 0; - } else { - if (SDL_NAME(arts_init) () != 0) { - UnloadARTSLibrary(); - SDL_SetError("ARTS: arts_init failed (no audio server?)"); - return 0; - } - - /* Play a stream so aRts doesn't crash */ - if (ARTS_Suspend()) { - arts_stream_t stream; - stream = SDL_NAME(arts_play_stream) (44100, 16, 2, "SDL"); - SDL_NAME(arts_write) (stream, "", 0); - SDL_NAME(arts_close_stream) (stream); - } - - SDL_NAME(arts_free) (); - } - - /* Set the function pointers */ - impl->OpenDevice = ARTS_OpenDevice; - impl->PlayDevice = ARTS_PlayDevice; - impl->WaitDevice = ARTS_WaitDevice; - impl->GetDeviceBuf = ARTS_GetDeviceBuf; - impl->CloseDevice = ARTS_CloseDevice; - impl->Deinitialize = ARTS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap ARTS_bootstrap = { - "arts", "Analog RealTime Synthesizer", ARTS_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_ARTS */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.h b/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.h deleted file mode 100644 index 7743654..0000000 --- a/Source/3rdParty/SDL2/src/audio/arts/SDL_artsaudio.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_artsaudio_h_ -#define SDL_artsaudio_h_ - -#include <artsc.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The stream descriptor for the audio device */ - arts_stream_t stream; - - /* The parent process id, to detect when application quits */ - pid_t parent; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Support for audio timing using a timer, in addition to SDL_IOReady() */ - float frame_ticks; - float next_frame; -}; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -#endif /* SDL_artsaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.h b/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.h deleted file mode 100644 index dcce3f7..0000000 --- a/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_coreaudio_h_ -#define SDL_coreaudio_h_ - -#include "../SDL_sysaudio.h" - -#if !defined(__IPHONEOS__) -#define MACOSX_COREAUDIO 1 -#endif - -#if MACOSX_COREAUDIO -#include <CoreAudio/CoreAudio.h> -#include <CoreServices/CoreServices.h> -#else -#import <AVFoundation/AVFoundation.h> -#import <UIKit/UIApplication.h> -#endif - -#include <AudioToolbox/AudioToolbox.h> -#include <AudioUnit/AudioUnit.h> - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - AudioQueueRef audioQueue; - int numAudioBuffers; - AudioQueueBufferRef *audioBuffer; - void *buffer; - UInt32 bufferSize; - AudioStreamBasicDescription strdesc; - SDL_bool refill; - SDL_AudioStream *capturestream; -#if MACOSX_COREAUDIO - AudioDeviceID deviceID; -#else - SDL_bool interrupted; - CFTypeRef interruption_listener; -#endif -}; - -#endif /* SDL_coreaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.m b/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.m deleted file mode 100644 index 59242f9..0000000 --- a/Source/3rdParty/SDL2/src/audio/coreaudio/SDL_coreaudio.m +++ /dev/null @@ -1,861 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_COREAUDIO - -/* !!! FIXME: clean out some of the macro salsa in here. */ - -#include "SDL_audio.h" -#include "SDL_hints.h" -#include "SDL_timer.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_coreaudio.h" -#include "SDL_assert.h" -#include "../../thread/SDL_systhread.h" - -#define DEBUG_COREAUDIO 0 - -#define CHECK_RESULT(msg) \ - if (result != noErr) { \ - SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \ - return 0; \ - } - -#if MACOSX_COREAUDIO -static const AudioObjectPropertyAddress devlist_address = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster -}; - -typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data); - -typedef struct AudioDeviceList -{ - AudioDeviceID devid; - SDL_bool alive; - struct AudioDeviceList *next; -} AudioDeviceList; - -static AudioDeviceList *output_devs = NULL; -static AudioDeviceList *capture_devs = NULL; - -static SDL_bool -add_to_internal_dev_list(const int iscapture, AudioDeviceID devId) -{ - AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList)); - if (item == NULL) { - return SDL_FALSE; - } - item->devid = devId; - item->alive = SDL_TRUE; - item->next = iscapture ? capture_devs : output_devs; - if (iscapture) { - capture_devs = item; - } else { - output_devs = item; - } - - return SDL_TRUE; -} - -static void -addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data) -{ - if (add_to_internal_dev_list(iscapture, devId)) { - SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); - } -} - -static void -build_device_list(int iscapture, addDevFn addfn, void *addfndata) -{ - OSStatus result = noErr; - UInt32 size = 0; - AudioDeviceID *devs = NULL; - UInt32 i = 0; - UInt32 max = 0; - - result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, - &devlist_address, 0, NULL, &size); - if (result != kAudioHardwareNoError) - return; - - devs = (AudioDeviceID *) alloca(size); - if (devs == NULL) - return; - - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, - &devlist_address, 0, NULL, &size, devs); - if (result != kAudioHardwareNoError) - return; - - max = size / sizeof (AudioDeviceID); - for (i = 0; i < max; i++) { - CFStringRef cfstr = NULL; - char *ptr = NULL; - AudioDeviceID dev = devs[i]; - AudioBufferList *buflist = NULL; - int usable = 0; - CFIndex len = 0; - const AudioObjectPropertyAddress addr = { - kAudioDevicePropertyStreamConfiguration, - iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; - - const AudioObjectPropertyAddress nameaddr = { - kAudioObjectPropertyName, - iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; - - result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size); - if (result != noErr) - continue; - - buflist = (AudioBufferList *) SDL_malloc(size); - if (buflist == NULL) - continue; - - result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, - &size, buflist); - - if (result == noErr) { - UInt32 j; - for (j = 0; j < buflist->mNumberBuffers; j++) { - if (buflist->mBuffers[j].mNumberChannels > 0) { - usable = 1; - break; - } - } - } - - SDL_free(buflist); - - if (!usable) - continue; - - - size = sizeof (CFStringRef); - result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr); - if (result != kAudioHardwareNoError) - continue; - - len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), - kCFStringEncodingUTF8); - - ptr = (char *) SDL_malloc(len + 1); - usable = ((ptr != NULL) && - (CFStringGetCString - (cfstr, ptr, len + 1, kCFStringEncodingUTF8))); - - CFRelease(cfstr); - - if (usable) { - len = strlen(ptr); - /* Some devices have whitespace at the end...trim it. */ - while ((len > 0) && (ptr[len - 1] == ' ')) { - len--; - } - usable = (len > 0); - } - - if (usable) { - ptr[len] = '\0'; - -#if DEBUG_COREAUDIO - printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", - ((iscapture) ? "capture" : "output"), - (int) i, ptr, (int) dev); -#endif - addfn(ptr, iscapture, dev, addfndata); - } - SDL_free(ptr); /* addfn() would have copied the string. */ - } -} - -static void -free_audio_device_list(AudioDeviceList **list) -{ - AudioDeviceList *item = *list; - while (item) { - AudioDeviceList *next = item->next; - SDL_free(item); - item = next; - } - *list = NULL; -} - -static void -COREAUDIO_DetectDevices(void) -{ - build_device_list(SDL_TRUE, addToDevList, NULL); - build_device_list(SDL_FALSE, addToDevList, NULL); -} - -static void -build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data) -{ - AudioDeviceList **list = (AudioDeviceList **) data; - AudioDeviceList *item; - for (item = *list; item != NULL; item = item->next) { - if (item->devid == devId) { - item->alive = SDL_TRUE; - return; - } - } - - add_to_internal_dev_list(iscapture, devId); /* new device, add it. */ - SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); -} - -static void -reprocess_device_list(const int iscapture, AudioDeviceList **list) -{ - AudioDeviceList *item; - AudioDeviceList *prev = NULL; - for (item = *list; item != NULL; item = item->next) { - item->alive = SDL_FALSE; - } - - build_device_list(iscapture, build_device_change_list, list); - - /* free items in the list that aren't still alive. */ - item = *list; - while (item != NULL) { - AudioDeviceList *next = item->next; - if (item->alive) { - prev = item; - } else { - SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid)); - if (prev) { - prev->next = item->next; - } else { - *list = item->next; - } - SDL_free(item); - } - item = next; - } -} - -/* this is called when the system's list of available audio devices changes. */ -static OSStatus -device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) -{ - reprocess_device_list(SDL_TRUE, &capture_devs); - reprocess_device_list(SDL_FALSE, &output_devs); - return 0; -} -#endif - - -static int open_playback_devices = 0; -static int open_capture_devices = 0; - -#if !MACOSX_COREAUDIO - -static void interruption_begin(_THIS) -{ - if (this != NULL && this->hidden->audioQueue != NULL) { - this->hidden->interrupted = SDL_TRUE; - AudioQueuePause(this->hidden->audioQueue); - } -} - -static void interruption_end(_THIS) -{ - if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL - && this->hidden->interrupted - && AudioQueueStart(this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) { - this->hidden->interrupted = SDL_FALSE; - } -} - -@interface SDLInterruptionListener : NSObject - -@property (nonatomic, assign) SDL_AudioDevice *device; - -@end - -@implementation SDLInterruptionListener - -- (void)audioSessionInterruption:(NSNotification *)note -{ - @synchronized (self) { - NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; - if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { - interruption_begin(self.device); - } else { - interruption_end(self.device); - } - } -} - -- (void)applicationBecameActive:(NSNotification *)note -{ - @synchronized (self) { - interruption_end(self.device); - } -} - -@end - -static BOOL update_audio_session(_THIS, SDL_bool open) -{ - @autoreleasepool { - AVAudioSession *session = [AVAudioSession sharedInstance]; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - /* Set category to ambient by default so that other music continues playing. */ - NSString *category = AVAudioSessionCategoryAmbient; - NSError *err = nil; - - if (open_playback_devices && open_capture_devices) { - category = AVAudioSessionCategoryPlayAndRecord; - } else if (open_capture_devices) { - category = AVAudioSessionCategoryRecord; - } else { - const char *hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY); - if (hint) { - if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) { - category = AVAudioSessionCategoryAmbient; - } else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) { - category = AVAudioSessionCategorySoloAmbient; - } else if (SDL_strcasecmp(hint, "AVAudioSessionCategoryPlayback") == 0 || - SDL_strcasecmp(hint, "playback") == 0) { - category = AVAudioSessionCategoryPlayback; - } - } - } - - if (![session setCategory:category error:&err]) { - NSString *desc = err.description; - SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String); - return NO; - } - - if (open && (open_playback_devices + open_capture_devices) == 1) { - if (![session setActive:YES error:&err]) { - NSString *desc = err.description; - SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String); - return NO; - } - } else if (!open_playback_devices && !open_capture_devices) { - [session setActive:NO error:nil]; - } - - if (open) { - SDLInterruptionListener *listener = [SDLInterruptionListener new]; - listener.device = this; - - [center addObserver:listener - selector:@selector(audioSessionInterruption:) - name:AVAudioSessionInterruptionNotification - object:session]; - - /* An interruption end notification is not guaranteed to be sent if - we were previously interrupted... resuming if needed when the app - becomes active seems to be the way to go. */ - [center addObserver:listener - selector:@selector(applicationBecameActive:) - name:UIApplicationDidBecomeActiveNotification - object:session]; - - [center addObserver:listener - selector:@selector(applicationBecameActive:) - name:UIApplicationWillEnterForegroundNotification - object:session]; - - this->hidden->interruption_listener = CFBridgingRetain(listener); - } else { - if (this->hidden->interruption_listener != NULL) { - SDLInterruptionListener *listener = nil; - listener = (SDLInterruptionListener *) CFBridgingRelease(this->hidden->interruption_listener); - [center removeObserver:listener]; - @synchronized (listener) { - listener.device = NULL; - } - } - } - } - - return YES; -} -#endif - - -/* The AudioQueue callback */ -static void -outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; - SDL_assert(inBuffer->mAudioDataBytesCapacity == this->hidden->bufferSize); - SDL_memcpy(inBuffer->mAudioData, this->hidden->buffer, this->hidden->bufferSize); - SDL_memset(this->hidden->buffer, '\0', this->hidden->bufferSize); /* zero out in case we have to fill again without new data. */ - inBuffer->mAudioDataByteSize = this->hidden->bufferSize; - AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); - this->hidden->refill = SDL_TRUE; -} - -static Uint8 * -COREAUDIO_GetDeviceBuf(_THIS) -{ - return this->hidden->buffer; -} - -static void -COREAUDIO_WaitDevice(_THIS) -{ - while (SDL_AtomicGet(&this->enabled) && !this->hidden->refill) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1); - } - this->hidden->refill = SDL_FALSE; -} - -static void -inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, - const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, - const AudioStreamPacketDescription *inPacketDescs ) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; - if (SDL_AtomicGet(&this->enabled)) { - SDL_AudioStream *stream = this->hidden->capturestream; - if (SDL_AudioStreamPut(stream, inBuffer->mAudioData, inBuffer->mAudioDataByteSize) == -1) { - /* yikes, out of memory or something. I guess drop the buffer. Our WASAPI target kills the device in this case, though */ - } - AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); - this->hidden->refill = SDL_TRUE; - } -} - -static int -COREAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - SDL_AudioStream *stream = this->hidden->capturestream; - while (SDL_AtomicGet(&this->enabled)) { - const int avail = SDL_AudioStreamAvailable(stream); - if (avail > 0) { - const int cpy = SDL_min(buflen, avail); - SDL_AudioStreamGet(stream, buffer, cpy); - return cpy; - } - - /* wait for more data, try again. */ - while (SDL_AtomicGet(&this->enabled) && !this->hidden->refill) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1); - } - this->hidden->refill = SDL_FALSE; - } - - return 0; /* not enabled, giving up. */ -} - -static void -COREAUDIO_FlushCapture(_THIS) -{ - while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 1) == kCFRunLoopRunHandledSource) { - /* spin. */ - } - this->hidden->refill = SDL_FALSE; - SDL_AudioStreamClear(this->hidden->capturestream); -} - - -#if MACOSX_COREAUDIO -static const AudioObjectPropertyAddress alive_address = -{ - kAudioDevicePropertyDeviceIsAlive, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster -}; - -static OSStatus -device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) data; - SDL_bool dead = SDL_FALSE; - UInt32 isAlive = 1; - UInt32 size = sizeof (isAlive); - OSStatus error; - - if (!SDL_AtomicGet(&this->enabled)) { - return 0; /* already known to be dead. */ - } - - error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address, - 0, NULL, &size, &isAlive); - - if (error == kAudioHardwareBadDeviceError) { - dead = SDL_TRUE; /* device was unplugged. */ - } else if ((error == kAudioHardwareNoError) && (!isAlive)) { - dead = SDL_TRUE; /* device died in some other way. */ - } - - if (dead) { - SDL_OpenedAudioDeviceDisconnected(this); - } - - return 0; -} -#endif - -static void -COREAUDIO_CloseDevice(_THIS) -{ - const SDL_bool iscapture = this->iscapture; - -/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ -/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ -#if MACOSX_COREAUDIO - /* Fire a callback if the device stops being "alive" (disconnected, etc). */ - AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); -#endif - -#if !MACOSX_COREAUDIO - update_audio_session(this, SDL_FALSE); -#endif - - if (this->hidden->audioQueue) { - AudioQueueDispose(this->hidden->audioQueue, 1); - } - - if (this->hidden->capturestream) { - SDL_FreeAudioStream(this->hidden->capturestream); - } - - /* AudioQueueDispose() frees the actual buffer objects. */ - SDL_free(this->hidden->audioBuffer); - SDL_free(this->hidden->buffer); - SDL_free(this->hidden); - - if (iscapture) { - open_capture_devices--; - } else { - open_playback_devices--; - } -} - -#if MACOSX_COREAUDIO -static int -prepare_device(_THIS, void *handle, int iscapture) -{ - AudioDeviceID devid = (AudioDeviceID) ((size_t) handle); - OSStatus result = noErr; - UInt32 size = 0; - UInt32 alive = 0; - pid_t pid = 0; - - AudioObjectPropertyAddress addr = { - 0, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - if (handle == NULL) { - size = sizeof (AudioDeviceID); - addr.mSelector = - ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : - kAudioHardwarePropertyDefaultOutputDevice); - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, &devid); - CHECK_RESULT("AudioHardwareGetProperty (default device)"); - } - - addr.mSelector = kAudioDevicePropertyDeviceIsAlive; - addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : - kAudioDevicePropertyScopeOutput; - - size = sizeof (alive); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); - CHECK_RESULT - ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); - - if (!alive) { - SDL_SetError("CoreAudio: requested device exists, but isn't alive."); - return 0; - } - - addr.mSelector = kAudioDevicePropertyHogMode; - size = sizeof (pid); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); - - /* some devices don't support this property, so errors are fine here. */ - if ((result == noErr) && (pid != -1)) { - SDL_SetError("CoreAudio: requested device is being hogged."); - return 0; - } - - this->hidden->deviceID = devid; - return 1; -} -#endif - - -/* this all happens in the audio thread, since it needs a separate runloop. */ -static int -prepare_audioqueue(_THIS) -{ - const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc; - const int iscapture = this->iscapture; - OSStatus result; - int i; - - SDL_assert(CFRunLoopGetCurrent() != NULL); - - if (iscapture) { - result = AudioQueueNewInput(strdesc, inputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); - CHECK_RESULT("AudioQueueNewInput"); - } else { - result = AudioQueueNewOutput(strdesc, outputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); - CHECK_RESULT("AudioQueueNewOutput"); - } - -#if MACOSX_COREAUDIO -{ - const AudioObjectPropertyAddress prop = { - kAudioDevicePropertyDeviceUID, - iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; - CFStringRef devuid; - UInt32 devuidsize = sizeof (devuid); - result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); - CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)"); - result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); - CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); - - /* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ - /* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ - /* Fire a callback if the device stops being "alive" (disconnected, etc). */ - AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); -} -#endif - - /* Make sure we can feed the device a minimum amount of time */ - double MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0; -#if defined(__IPHONEOS__) - if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { - /* Older iOS hardware, use 40 ms as a minimum time */ - MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0; - } -#endif - const double msecs = (this->spec.samples / ((double) this->spec.freq)) * 1000.0; - int numAudioBuffers = 2; - if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) { /* use more buffers if we have a VERY small sample set. */ - numAudioBuffers = ((int)SDL_ceil(MINIMUM_AUDIO_BUFFER_TIME_MS / msecs) * 2); - } - - this->hidden->numAudioBuffers = numAudioBuffers; - this->hidden->audioBuffer = SDL_calloc(1, sizeof (AudioQueueBufferRef) * numAudioBuffers); - if (this->hidden->audioBuffer == NULL) { - SDL_OutOfMemory(); - return 0; - } - -#if DEBUG_COREAUDIO - printf("COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers); -#endif - - for (i = 0; i < numAudioBuffers; i++) { - result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[i]); - CHECK_RESULT("AudioQueueAllocateBuffer"); - SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity); - this->hidden->audioBuffer[i]->mAudioDataByteSize = this->hidden->audioBuffer[i]->mAudioDataBytesCapacity; - result = AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i], 0, NULL); - CHECK_RESULT("AudioQueueEnqueueBuffer"); - } - - result = AudioQueueStart(this->hidden->audioQueue, NULL); - CHECK_RESULT("AudioQueueStart"); - - /* We're running! */ - return 1; -} - -static void -COREAUDIO_ThreadInit(_THIS) -{ - const int rc = prepare_audioqueue(this); - if (!rc) { - /* !!! FIXME: do this in RunAudio, and maybe block OpenDevice until ThreadInit finishes, too, to report an opening error */ - SDL_OpenedAudioDeviceDisconnected(this); /* oh well. */ - } -} - -static void -COREAUDIO_PrepareToClose(_THIS) -{ - /* run long enough to queue some silence, so we know our actual audio - has been played */ - CFRunLoopRunInMode(kCFRunLoopDefaultMode, (((this->spec.samples * 1000) / this->spec.freq) * 2) / 1000.0f, 0); - AudioQueueStop(this->hidden->audioQueue, 1); -} - -static int -COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - AudioStreamBasicDescription *strdesc; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - int valid_datatype = 0; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - strdesc = &this->hidden->strdesc; - - if (iscapture) { - open_capture_devices++; - } else { - open_playback_devices++; - } - -#if !MACOSX_COREAUDIO - if (!update_audio_session(this, SDL_TRUE)) { - return -1; - } - - /* Stop CoreAudio from doing expensive audio rate conversion */ - @autoreleasepool { - AVAudioSession* session = [AVAudioSession sharedInstance]; - [session setPreferredSampleRate:this->spec.freq error:nil]; - this->spec.freq = (int)session.sampleRate; - } -#endif - - /* Setup a AudioStreamBasicDescription with the requested format */ - SDL_zerop(strdesc); - strdesc->mFormatID = kAudioFormatLinearPCM; - strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked; - strdesc->mChannelsPerFrame = this->spec.channels; - strdesc->mSampleRate = this->spec.freq; - strdesc->mFramesPerPacket = 1; - - while ((!valid_datatype) && (test_format)) { - this->spec.format = test_format; - /* Just a list of valid SDL formats, so people don't pass junk here. */ - switch (test_format) { - case AUDIO_U8: - case AUDIO_S8: - case AUDIO_U16LSB: - case AUDIO_S16LSB: - case AUDIO_U16MSB: - case AUDIO_S16MSB: - case AUDIO_S32LSB: - case AUDIO_S32MSB: - case AUDIO_F32LSB: - case AUDIO_F32MSB: - valid_datatype = 1; - strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format); - if (SDL_AUDIO_ISBIGENDIAN(this->spec.format)) - strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; - - if (SDL_AUDIO_ISFLOAT(this->spec.format)) - strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat; - else if (SDL_AUDIO_ISSIGNED(this->spec.format)) - strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; - break; - } - } - - if (!valid_datatype) { /* shouldn't happen, but just in case... */ - return SDL_SetError("Unsupported audio format"); - } - - strdesc->mBytesPerFrame = strdesc->mBitsPerChannel * strdesc->mChannelsPerFrame / 8; - strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket; - -#if MACOSX_COREAUDIO - if (!prepare_device(this, handle, iscapture)) { - return -1; - } -#endif - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - if (iscapture) { - this->hidden->capturestream = SDL_NewAudioStream(this->spec.format, this->spec.channels, this->spec.freq, this->spec.format, this->spec.channels, this->spec.freq); - if (!this->hidden->capturestream) { - return -1; /* already set SDL_Error */ - } - } else { - this->hidden->bufferSize = this->spec.size; - this->hidden->buffer = SDL_malloc(this->hidden->bufferSize); - if (this->hidden->buffer == NULL) { - return SDL_OutOfMemory(); - } - } - - return 0; -} - -static void -COREAUDIO_Deinitialize(void) -{ -#if MACOSX_COREAUDIO - AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); - free_audio_device_list(&capture_devs); - free_audio_device_list(&output_devs); -#endif -} - -static int -COREAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = COREAUDIO_OpenDevice; - impl->CloseDevice = COREAUDIO_CloseDevice; - impl->Deinitialize = COREAUDIO_Deinitialize; - impl->ThreadInit = COREAUDIO_ThreadInit; - impl->WaitDevice = COREAUDIO_WaitDevice; - impl->GetDeviceBuf = COREAUDIO_GetDeviceBuf; - impl->PrepareToClose = COREAUDIO_PrepareToClose; - impl->CaptureFromDevice = COREAUDIO_CaptureFromDevice; - impl->FlushCapture = COREAUDIO_FlushCapture; - -#if MACOSX_COREAUDIO - impl->DetectDevices = COREAUDIO_DetectDevices; - AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); -#else - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; -#endif - - impl->HasCaptureSupport = 1; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap COREAUDIO_bootstrap = { - "coreaudio", "CoreAudio", COREAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_COREAUDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.c b/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.c deleted file mode 100644 index a943ba2..0000000 --- a/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_DSOUND - -/* Allow access to a raw mixing buffer */ - -#include "SDL_assert.h" -#include "SDL_timer.h" -#include "SDL_loadso.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_directsound.h" - -#ifndef WAVE_FORMAT_IEEE_FLOAT -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 -#endif - -/* DirectX function pointers for audio */ -static void* DSoundDLL = NULL; -typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); -typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); -typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN); -typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID); -static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL; -static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL; -static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL; -static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL; - -static void -DSOUND_Unload(void) -{ - pDirectSoundCreate8 = NULL; - pDirectSoundEnumerateW = NULL; - pDirectSoundCaptureCreate8 = NULL; - pDirectSoundCaptureEnumerateW = NULL; - - if (DSoundDLL != NULL) { - SDL_UnloadObject(DSoundDLL); - DSoundDLL = NULL; - } -} - - -static int -DSOUND_Load(void) -{ - int loaded = 0; - - DSOUND_Unload(); - - DSoundDLL = SDL_LoadObject("DSOUND.DLL"); - if (DSoundDLL == NULL) { - SDL_SetError("DirectSound: failed to load DSOUND.DLL"); - } else { - /* Now make sure we have DirectX 8 or better... */ - #define DSOUNDLOAD(f) { \ - p##f = (fn##f) SDL_LoadFunction(DSoundDLL, #f); \ - if (!p##f) loaded = 0; \ - } - loaded = 1; /* will reset if necessary. */ - DSOUNDLOAD(DirectSoundCreate8); - DSOUNDLOAD(DirectSoundEnumerateW); - DSOUNDLOAD(DirectSoundCaptureCreate8); - DSOUNDLOAD(DirectSoundCaptureEnumerateW); - #undef DSOUNDLOAD - - if (!loaded) { - SDL_SetError("DirectSound: System doesn't appear to have DX8."); - } - } - - if (!loaded) { - DSOUND_Unload(); - } - - return loaded; -} - -static int -SetDSerror(const char *function, int code) -{ - static const char *error; - static char errbuf[1024]; - - errbuf[0] = 0; - switch (code) { - case E_NOINTERFACE: - error = "Unsupported interface -- Is DirectX 8.0 or later installed?"; - break; - case DSERR_ALLOCATED: - error = "Audio device in use"; - break; - case DSERR_BADFORMAT: - error = "Unsupported audio format"; - break; - case DSERR_BUFFERLOST: - error = "Mixing buffer was lost"; - break; - case DSERR_CONTROLUNAVAIL: - error = "Control requested is not available"; - break; - case DSERR_INVALIDCALL: - error = "Invalid call for the current state"; - break; - case DSERR_INVALIDPARAM: - error = "Invalid parameter"; - break; - case DSERR_NODRIVER: - error = "No audio device found"; - break; - case DSERR_OUTOFMEMORY: - error = "Out of memory"; - break; - case DSERR_PRIOLEVELNEEDED: - error = "Caller doesn't have priority"; - break; - case DSERR_UNSUPPORTED: - error = "Function not supported"; - break; - default: - SDL_snprintf(errbuf, SDL_arraysize(errbuf), - "%s: Unknown DirectSound error: 0x%x", function, code); - break; - } - if (!errbuf[0]) { - SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, - error); - } - return SDL_SetError("%s", errbuf); -} - -static void -DSOUND_FreeDeviceHandle(void *handle) -{ - SDL_free(handle); -} - -static BOOL CALLBACK -FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) -{ - const int iscapture = (int) ((size_t) data); - if (guid != NULL) { /* skip default device */ - char *str = WIN_LookupAudioDeviceName(desc, guid); - if (str != NULL) { - LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID)); - SDL_memcpy(cpyguid, guid, sizeof (GUID)); - SDL_AddAudioDevice(iscapture, str, cpyguid); - SDL_free(str); /* addfn() makes a copy of this string. */ - } - } - return TRUE; /* keep enumerating. */ -} - -static void -DSOUND_DetectDevices(void) -{ - pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1)); - pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0)); -} - - -static void -DSOUND_WaitDevice(_THIS) -{ - DWORD status = 0; - DWORD cursor = 0; - DWORD junk = 0; - HRESULT result = DS_OK; - - /* Semi-busy wait, since we have no way of getting play notification - on a primary mixing buffer located in hardware (DirectX 5.0) - */ - result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, - &junk, &cursor); - if (result != DS_OK) { - if (result == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(this->hidden->mixbuf); - } -#ifdef DEBUG_SOUND - SetDSerror("DirectSound GetCurrentPosition", result); -#endif - return; - } - - while ((cursor / this->spec.size) == this->hidden->lastchunk) { - /* FIXME: find out how much time is left and sleep that long */ - SDL_Delay(1); - - /* Try to restore a lost sound buffer */ - IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status); - if ((status & DSBSTATUS_BUFFERLOST)) { - IDirectSoundBuffer_Restore(this->hidden->mixbuf); - IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status); - if ((status & DSBSTATUS_BUFFERLOST)) { - break; - } - } - if (!(status & DSBSTATUS_PLAYING)) { - result = IDirectSoundBuffer_Play(this->hidden->mixbuf, 0, 0, - DSBPLAY_LOOPING); - if (result == DS_OK) { - continue; - } -#ifdef DEBUG_SOUND - SetDSerror("DirectSound Play", result); -#endif - return; - } - - /* Find out where we are playing */ - result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, - &junk, &cursor); - if (result != DS_OK) { - SetDSerror("DirectSound GetCurrentPosition", result); - return; - } - } -} - -static void -DSOUND_PlayDevice(_THIS) -{ - /* Unlock the buffer, allowing it to play */ - if (this->hidden->locked_buf) { - IDirectSoundBuffer_Unlock(this->hidden->mixbuf, - this->hidden->locked_buf, - this->spec.size, NULL, 0); - } -} - -static Uint8 * -DSOUND_GetDeviceBuf(_THIS) -{ - DWORD cursor = 0; - DWORD junk = 0; - HRESULT result = DS_OK; - DWORD rawlen = 0; - - /* Figure out which blocks to fill next */ - this->hidden->locked_buf = NULL; - result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, - &junk, &cursor); - if (result == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(this->hidden->mixbuf); - result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, - &junk, &cursor); - } - if (result != DS_OK) { - SetDSerror("DirectSound GetCurrentPosition", result); - return (NULL); - } - cursor /= this->spec.size; -#ifdef DEBUG_SOUND - /* Detect audio dropouts */ - { - DWORD spot = cursor; - if (spot < this->hidden->lastchunk) { - spot += this->hidden->num_buffers; - } - if (spot > this->hidden->lastchunk + 1) { - fprintf(stderr, "Audio dropout, missed %d fragments\n", - (spot - (this->hidden->lastchunk + 1))); - } - } -#endif - this->hidden->lastchunk = cursor; - cursor = (cursor + 1) % this->hidden->num_buffers; - cursor *= this->spec.size; - - /* Lock the audio buffer */ - result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, - this->spec.size, - (LPVOID *) & this->hidden->locked_buf, - &rawlen, NULL, &junk, 0); - if (result == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(this->hidden->mixbuf); - result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, - this->spec.size, - (LPVOID *) & this-> - hidden->locked_buf, &rawlen, NULL, - &junk, 0); - } - if (result != DS_OK) { - SetDSerror("DirectSound Lock", result); - return (NULL); - } - return (this->hidden->locked_buf); -} - -static int -DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - struct SDL_PrivateAudioData *h = this->hidden; - DWORD junk, cursor, ptr1len, ptr2len; - VOID *ptr1, *ptr2; - - SDL_assert(buflen == this->spec.size); - - while (SDL_TRUE) { - if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */ - SDL_memset(buffer, this->spec.silence, buflen); - return buflen; - } - - if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) { - return -1; - } - if ((cursor / this->spec.size) == h->lastchunk) { - SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ - } else { - break; - } - } - - if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) { - return -1; - } - - SDL_assert(ptr1len == this->spec.size); - SDL_assert(ptr2 == NULL); - SDL_assert(ptr2len == 0); - - SDL_memcpy(buffer, ptr1, ptr1len); - - if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) { - return -1; - } - - h->lastchunk = (h->lastchunk + 1) % h->num_buffers; - - return ptr1len; -} - -static void -DSOUND_FlushCapture(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - DWORD junk, cursor; - if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) { - h->lastchunk = cursor / this->spec.size; - } -} - -static void -DSOUND_CloseDevice(_THIS) -{ - if (this->hidden->mixbuf != NULL) { - IDirectSoundBuffer_Stop(this->hidden->mixbuf); - IDirectSoundBuffer_Release(this->hidden->mixbuf); - } - if (this->hidden->sound != NULL) { - IDirectSound_Release(this->hidden->sound); - } - if (this->hidden->capturebuf != NULL) { - IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf); - IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf); - } - if (this->hidden->capture != NULL) { - IDirectSoundCapture_Release(this->hidden->capture); - } - SDL_free(this->hidden); -} - -/* This function tries to create a secondary audio buffer, and returns the - number of audio chunks available in the created buffer. This is for - playback devices, not capture. -*/ -static int -CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) -{ - LPDIRECTSOUND sndObj = this->hidden->sound; - LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf; - HRESULT result = DS_OK; - DSBUFFERDESC format; - LPVOID pvAudioPtr1, pvAudioPtr2; - DWORD dwAudioBytes1, dwAudioBytes2; - - /* Try to create the secondary buffer */ - SDL_zero(format); - format.dwSize = sizeof(format); - format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; - format.dwFlags |= DSBCAPS_GLOBALFOCUS; - format.dwBufferBytes = bufsize; - format.lpwfxFormat = wfmt; - result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); - if (result != DS_OK) { - return SetDSerror("DirectSound CreateSoundBuffer", result); - } - IDirectSoundBuffer_SetFormat(*sndbuf, wfmt); - - /* Silence the initial audio buffer */ - result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, - (LPVOID *) & pvAudioPtr1, &dwAudioBytes1, - (LPVOID *) & pvAudioPtr2, &dwAudioBytes2, - DSBLOCK_ENTIREBUFFER); - if (result == DS_OK) { - SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1); - IDirectSoundBuffer_Unlock(*sndbuf, - (LPVOID) pvAudioPtr1, dwAudioBytes1, - (LPVOID) pvAudioPtr2, dwAudioBytes2); - } - - /* We're ready to go */ - return 0; -} - -/* This function tries to create a capture buffer, and returns the - number of audio chunks available in the created buffer. This is for - capture devices, not playback. -*/ -static int -CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) -{ - LPDIRECTSOUNDCAPTURE capture = this->hidden->capture; - LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf; - DSCBUFFERDESC format; - HRESULT result; - - SDL_zero(format); - format.dwSize = sizeof (format); - format.dwFlags = DSCBCAPS_WAVEMAPPED; - format.dwBufferBytes = bufsize; - format.lpwfxFormat = wfmt; - - result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL); - if (result != DS_OK) { - return SetDSerror("DirectSound CreateCaptureBuffer", result); - } - - result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING); - if (result != DS_OK) { - IDirectSoundCaptureBuffer_Release(*capturebuf); - return SetDSerror("DirectSound Start", result); - } - -#if 0 - /* presumably this starts at zero, but just in case... */ - result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor); - if (result != DS_OK) { - IDirectSoundCaptureBuffer_Stop(*capturebuf); - IDirectSoundCaptureBuffer_Release(*capturebuf); - return SetDSerror("DirectSound GetCurrentPosition", result); - } - - this->hidden->lastchunk = cursor / this->spec.size; -#endif - - return 0; -} - -static int -DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - const DWORD numchunks = 8; - HRESULT result; - SDL_bool valid_format = SDL_FALSE; - SDL_bool tried_format = SDL_FALSE; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - LPGUID guid = (LPGUID) handle; - DWORD bufsize; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - if (iscapture) { - result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL); - if (result != DS_OK) { - return SetDSerror("DirectSoundCaptureCreate8", result); - } - } else { - result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL); - if (result != DS_OK) { - return SetDSerror("DirectSoundCreate8", result); - } - result = IDirectSound_SetCooperativeLevel(this->hidden->sound, - GetDesktopWindow(), - DSSCL_NORMAL); - if (result != DS_OK) { - return SetDSerror("DirectSound SetCooperativeLevel", result); - } - } - - while ((!valid_format) && (test_format)) { - switch (test_format) { - case AUDIO_U8: - case AUDIO_S16: - case AUDIO_S32: - case AUDIO_F32: - tried_format = SDL_TRUE; - - this->spec.format = test_format; - - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&this->spec); - - bufsize = numchunks * this->spec.size; - if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) { - SDL_SetError("Sound buffer size must be between %d and %d", - (int) ((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks), - (int) (DSBSIZE_MAX / numchunks)); - } else { - int rc; - WAVEFORMATEX wfmt; - SDL_zero(wfmt); - if (SDL_AUDIO_ISFLOAT(this->spec.format)) { - wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - } else { - wfmt.wFormatTag = WAVE_FORMAT_PCM; - } - - wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); - wfmt.nChannels = this->spec.channels; - wfmt.nSamplesPerSec = this->spec.freq; - wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8); - wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign; - - rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt); - if (rc == 0) { - this->hidden->num_buffers = numchunks; - valid_format = SDL_TRUE; - } - } - break; - } - test_format = SDL_NextAudioFormat(); - } - - if (!valid_format) { - if (tried_format) { - return -1; /* CreateSecondary() should have called SDL_SetError(). */ - } - return SDL_SetError("DirectSound: Unsupported audio format"); - } - - /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */ - - return 0; /* good to go. */ -} - - -static void -DSOUND_Deinitialize(void) -{ - DSOUND_Unload(); -} - - -static int -DSOUND_Init(SDL_AudioDriverImpl * impl) -{ - if (!DSOUND_Load()) { - return 0; - } - - /* Set the function pointers */ - impl->DetectDevices = DSOUND_DetectDevices; - impl->OpenDevice = DSOUND_OpenDevice; - impl->PlayDevice = DSOUND_PlayDevice; - impl->WaitDevice = DSOUND_WaitDevice; - impl->GetDeviceBuf = DSOUND_GetDeviceBuf; - impl->CaptureFromDevice = DSOUND_CaptureFromDevice; - impl->FlushCapture = DSOUND_FlushCapture; - impl->CloseDevice = DSOUND_CloseDevice; - impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle; - impl->Deinitialize = DSOUND_Deinitialize; - - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap DSOUND_bootstrap = { - "directsound", "DirectSound", DSOUND_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_DSOUND */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.h b/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.h deleted file mode 100644 index acb7b6a..0000000 --- a/Source/3rdParty/SDL2/src/audio/directsound/SDL_directsound.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_directsound_h_ -#define SDL_directsound_h_ - -#include "../../core/windows/SDL_directx.h" - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -/* The DirectSound objects */ -struct SDL_PrivateAudioData -{ - LPDIRECTSOUND sound; - LPDIRECTSOUNDBUFFER mixbuf; - LPDIRECTSOUNDCAPTURE capture; - LPDIRECTSOUNDCAPTUREBUFFER capturebuf; - int num_buffers; - DWORD lastchunk; - Uint8 *locked_buf; -}; - -#endif /* SDL_directsound_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.c b/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.c deleted file mode 100644 index 2250375..0000000 --- a/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_DISK - -/* Output raw audio data to a file. */ - -#if HAVE_STDIO_H -#include <stdio.h> -#endif - -#include "SDL_rwops.h" -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_diskaudio.h" -#include "SDL_log.h" - -/* !!! FIXME: these should be SDL hints, not environment variables. */ -/* environment variables and defaults. */ -#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" -#define DISKDEFAULT_OUTFILE "sdlaudio.raw" -#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN" -#define DISKDEFAULT_INFILE "sdlaudio-in.raw" -#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY" - -/* This function waits until it is possible to write a full sound buffer */ -static void -DISKAUDIO_WaitDevice(_THIS) -{ - SDL_Delay(this->hidden->io_delay); -} - -static void -DISKAUDIO_PlayDevice(_THIS) -{ - const size_t written = SDL_RWwrite(this->hidden->io, - this->hidden->mixbuf, - 1, this->spec.size); - - /* If we couldn't write, assume fatal error for now */ - if (written != this->spec.size) { - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif -} - -static Uint8 * -DISKAUDIO_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static int -DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - struct SDL_PrivateAudioData *h = this->hidden; - const int origbuflen = buflen; - - SDL_Delay(h->io_delay); - - if (h->io) { - const size_t br = SDL_RWread(h->io, buffer, 1, buflen); - buflen -= (int) br; - buffer = ((Uint8 *) buffer) + br; - if (buflen > 0) { /* EOF (or error, but whatever). */ - SDL_RWclose(h->io); - h->io = NULL; - } - } - - /* if we ran out of file, just write silence. */ - SDL_memset(buffer, this->spec.silence, buflen); - - return origbuflen; -} - -static void -DISKAUDIO_FlushCapture(_THIS) -{ - /* no op...we don't advance the file pointer or anything. */ -} - - -static void -DISKAUDIO_CloseDevice(_THIS) -{ - if (this->hidden->io != NULL) { - SDL_RWclose(this->hidden->io); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - - -static const char * -get_filename(const int iscapture, const char *devname) -{ - if (devname == NULL) { - devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); - if (devname == NULL) { - devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; - } - } - return devname; -} - -static int -DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - /* handle != NULL means "user specified the placeholder name on the fake detected device list" */ - const char *fname = get_filename(iscapture, handle ? NULL : devname); - const char *envr = SDL_getenv(DISKENVR_IODELAY); - - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - if (envr != NULL) { - this->hidden->io_delay = SDL_atoi(envr); - } else { - this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq); - } - - /* Open the audio device */ - this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); - if (this->hidden->io == NULL) { - return -1; - } - - /* Allocate mixing buffer */ - if (!iscapture) { - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - } - - SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, - "You are using the SDL disk i/o audio driver!\n"); - SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, - " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", - fname); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static void -DISKAUDIO_DetectDevices(void) -{ - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1); - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2); -} - -static int -DISKAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = DISKAUDIO_OpenDevice; - impl->WaitDevice = DISKAUDIO_WaitDevice; - impl->PlayDevice = DISKAUDIO_PlayDevice; - impl->GetDeviceBuf = DISKAUDIO_GetDeviceBuf; - impl->CaptureFromDevice = DISKAUDIO_CaptureFromDevice; - impl->FlushCapture = DISKAUDIO_FlushCapture; - - impl->CloseDevice = DISKAUDIO_CloseDevice; - impl->DetectDevices = DISKAUDIO_DetectDevices; - - impl->AllowsArbitraryDeviceNames = 1; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap DISKAUDIO_bootstrap = { - "disk", "direct-to-disk audio", DISKAUDIO_Init, 1 -}; - -#endif /* SDL_AUDIO_DRIVER_DISK */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.h b/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.h deleted file mode 100644 index 7e73ebe..0000000 --- a/Source/3rdParty/SDL2/src/audio/disk/SDL_diskaudio.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_diskaudio_h_ -#define SDL_diskaudio_h_ - -#include "SDL_rwops.h" -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - SDL_RWops *io; - Uint32 io_delay; - Uint8 *mixbuf; -}; - -#endif /* SDL_diskaudio_h_ */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.c b/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.c deleted file mode 100644 index 77653be..0000000 --- a/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_OSS - -/* Allow access to a raw mixing buffer */ - -#include <stdio.h> /* For perror() */ -#include <string.h> /* For strerror() */ -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/stat.h> - -#if SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H -/* This is installed on some systems */ -#include <soundcard.h> -#else -/* This is recommended by OSS */ -#include <sys/soundcard.h> -#endif - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" -#include "SDL_dspaudio.h" - - -static void -DSP_DetectDevices(void) -{ - SDL_EnumUnixAudioDevices(0, NULL); -} - - -static void -DSP_CloseDevice(_THIS) -{ - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - - -static int -DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); - int format; - int value; - int frag_spec; - SDL_AudioFormat test_format; - - /* We don't care what the devname is...we'll try to open anything. */ - /* ...but default to first name in the list... */ - if (devname == NULL) { - devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { - return SDL_SetError("No such audio device"); - } - } - - /* Make sure fragment size stays a power of 2, or OSS fails. */ - /* I don't know which of these are actually legal values, though... */ - if (this->spec.channels > 8) - this->spec.channels = 8; - else if (this->spec.channels > 4) - this->spec.channels = 4; - else if (this->spec.channels > 2) - this->spec.channels = 2; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - this->hidden->audio_fd = open(devname, flags, 0); - if (this->hidden->audio_fd < 0) { - return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); - } - - /* Make the file descriptor use blocking i/o with fcntl() */ - { - long ctlflags; - ctlflags = fcntl(this->hidden->audio_fd, F_GETFL); - ctlflags &= ~O_NONBLOCK; - if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) { - return SDL_SetError("Couldn't set audio blocking mode"); - } - } - - /* Get a list of supported hardware formats */ - if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { - perror("SNDCTL_DSP_GETFMTS"); - return SDL_SetError("Couldn't get audio format list"); - } - - /* Try for a closest match on audio format */ - format = 0; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - switch (test_format) { - case AUDIO_U8: - if (value & AFMT_U8) { - format = AFMT_U8; - } - break; - case AUDIO_S16LSB: - if (value & AFMT_S16_LE) { - format = AFMT_S16_LE; - } - break; - case AUDIO_S16MSB: - if (value & AFMT_S16_BE) { - format = AFMT_S16_BE; - } - break; -#if 0 -/* - * These formats are not used by any real life systems so they are not - * needed here. - */ - case AUDIO_S8: - if (value & AFMT_S8) { - format = AFMT_S8; - } - break; - case AUDIO_U16LSB: - if (value & AFMT_U16_LE) { - format = AFMT_U16_LE; - } - break; - case AUDIO_U16MSB: - if (value & AFMT_U16_BE) { - format = AFMT_U16_BE; - } - break; -#endif - default: - format = 0; - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); - } - } - if (format == 0) { - return SDL_SetError("Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - /* Set the audio format */ - value = format; - if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || - (value != format)) { - perror("SNDCTL_DSP_SETFMT"); - return SDL_SetError("Couldn't set audio format"); - } - - /* Set the number of channels of output */ - value = this->spec.channels; - if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { - perror("SNDCTL_DSP_CHANNELS"); - return SDL_SetError("Cannot set the number of channels"); - } - this->spec.channels = value; - - /* Set the DSP frequency */ - value = this->spec.freq; - if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { - perror("SNDCTL_DSP_SPEED"); - return SDL_SetError("Couldn't set audio frequency"); - } - this->spec.freq = value; - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Determine the power of two of the fragment size */ - for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec); - if ((0x01U << frag_spec) != this->spec.size) { - return SDL_SetError("Fragment size must be a power of two"); - } - frag_spec |= 0x00020000; /* two fragments, for low latency */ - - /* Set the audio buffering parameters */ -#ifdef DEBUG_AUDIO - fprintf(stderr, "Requesting %d fragments of size %d\n", - (frag_spec >> 16), 1 << (frag_spec & 0xFFFF)); -#endif - if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) { - perror("SNDCTL_DSP_SETFRAGMENT"); - } -#ifdef DEBUG_AUDIO - { - audio_buf_info info; - ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info); - fprintf(stderr, "fragments = %d\n", info.fragments); - fprintf(stderr, "fragstotal = %d\n", info.fragstotal); - fprintf(stderr, "fragsize = %d\n", info.fragsize); - fprintf(stderr, "bytes = %d\n", info.bytes); - } -#endif - - /* Allocate mixing buffer */ - if (!iscapture) { - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - } - - /* We're ready to rock and roll. :-) */ - return 0; -} - - -static void -DSP_PlayDevice(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) { - perror("Audio write"); - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen); -#endif -} - -static Uint8 * -DSP_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static int -DSP_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - return (int) read(this->hidden->audio_fd, buffer, buflen); -} - -static void -DSP_FlushCapture(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - audio_buf_info info; - if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) { - while (info.bytes > 0) { - char buf[512]; - const size_t len = SDL_min(sizeof (buf), info.bytes); - const ssize_t br = read(h->audio_fd, buf, len); - if (br <= 0) { - break; - } - info.bytes -= br; - } - } -} - -static int -DSP_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->DetectDevices = DSP_DetectDevices; - impl->OpenDevice = DSP_OpenDevice; - impl->PlayDevice = DSP_PlayDevice; - impl->GetDeviceBuf = DSP_GetDeviceBuf; - impl->CloseDevice = DSP_CloseDevice; - impl->CaptureFromDevice = DSP_CaptureFromDevice; - impl->FlushCapture = DSP_FlushCapture; - - impl->AllowsArbitraryDeviceNames = 1; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap DSP_bootstrap = { - "dsp", "OSS /dev/dsp standard audio", DSP_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_OSS */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.h b/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.h deleted file mode 100644 index 6bd86d7..0000000 --- a/Source/3rdParty/SDL2/src/audio/dsp/SDL_dspaudio.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_dspaudio_h_ -#define SDL_dspaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; -}; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -#endif /* SDL_dspaudio_h_ */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.c b/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.c deleted file mode 100644 index f91dea3..0000000 --- a/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -/* Output audio to nowhere... */ - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_dummyaudio.h" - -static int -DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - return 0; /* always succeeds. */ -} - -static int -DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - /* Delay to make this sort of simulate real audio input. */ - SDL_Delay((this->spec.samples * 1000) / this->spec.freq); - - /* always return a full buffer of silence. */ - SDL_memset(buffer, this->spec.silence, buflen); - return buflen; -} - -static int -DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = DUMMYAUDIO_OpenDevice; - impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice; - - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap DUMMYAUDIO_bootstrap = { - "dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1 -}; - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.h b/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.h deleted file mode 100644 index 18241ee..0000000 --- a/Source/3rdParty/SDL2/src/audio/dummy/SDL_dummyaudio.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_dummyaudio_h_ -#define SDL_dummyaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - Uint8 *mixbuf; - Uint32 mixlen; - Uint32 write_delay; - Uint32 initial_calls; -}; - -#endif /* SDL_dummyaudio_h_ */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c b/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c deleted file mode 100644 index e519f08..0000000 --- a/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_EMSCRIPTEN - -#include "SDL_audio.h" -#include "SDL_log.h" -#include "../SDL_audio_c.h" -#include "SDL_emscriptenaudio.h" -#include "SDL_assert.h" - -#include <emscripten/emscripten.h> - -static void -FeedAudioDevice(_THIS, const void *buf, const int buflen) -{ - const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels; - EM_ASM_ARGS({ - var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; - for (var c = 0; c < numChannels; ++c) { - var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); - if (channelData.length != $1) { - throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; - } - - for (var j = 0; j < $1; ++j) { - channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; /* !!! FIXME: why are these shifts here? */ - } - } - }, buf, buflen / framelen); -} - -static void -HandleAudioProcess(_THIS) -{ - SDL_AudioCallback callback = this->callbackspec.callback; - const int stream_len = this->callbackspec.size; - - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { - if (this->stream) { - SDL_AudioStreamClear(this->stream); - } - return; - } - - if (this->stream == NULL) { /* no conversion necessary. */ - SDL_assert(this->spec.size == stream_len); - callback(this->callbackspec.userdata, this->work_buffer, stream_len); - } else { /* streaming/converting */ - int got; - while (SDL_AudioStreamAvailable(this->stream) < ((int) this->spec.size)) { - callback(this->callbackspec.userdata, this->work_buffer, stream_len); - if (SDL_AudioStreamPut(this->stream, this->work_buffer, stream_len) == -1) { - SDL_AudioStreamClear(this->stream); - SDL_AtomicSet(&this->enabled, 0); - break; - } - } - - got = SDL_AudioStreamGet(this->stream, this->work_buffer, this->spec.size); - SDL_assert((got < 0) || (got == this->spec.size)); - if (got != this->spec.size) { - SDL_memset(this->work_buffer, this->spec.silence, this->spec.size); - } - } - - FeedAudioDevice(this, this->work_buffer, this->spec.size); -} - -static void -HandleCaptureProcess(_THIS) -{ - SDL_AudioCallback callback = this->callbackspec.callback; - const int stream_len = this->callbackspec.size; - - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { - SDL_AudioStreamClear(this->stream); - return; - } - - EM_ASM_ARGS({ - var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; - for (var c = 0; c < numChannels; ++c) { - var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); - if (channelData.length != $1) { - throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; - } - - if (numChannels == 1) { /* fastpath this a little for the common (mono) case. */ - for (var j = 0; j < $1; ++j) { - setValue($0 + (j * 4), channelData[j], 'float'); - } - } else { - for (var j = 0; j < $1; ++j) { - setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); - } - } - } - }, this->work_buffer, (this->spec.size / sizeof (float)) / this->spec.channels); - - /* okay, we've got an interleaved float32 array in C now. */ - - if (this->stream == NULL) { /* no conversion necessary. */ - SDL_assert(this->spec.size == stream_len); - callback(this->callbackspec.userdata, this->work_buffer, stream_len); - } else { /* streaming/converting */ - if (SDL_AudioStreamPut(this->stream, this->work_buffer, this->spec.size) == -1) { - SDL_AtomicSet(&this->enabled, 0); - } - - while (SDL_AudioStreamAvailable(this->stream) >= stream_len) { - const int got = SDL_AudioStreamGet(this->stream, this->work_buffer, stream_len); - SDL_assert((got < 0) || (got == stream_len)); - if (got != stream_len) { - SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len); - } - callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */ - } - } -} - - -static void -EMSCRIPTENAUDIO_CloseDevice(_THIS) -{ - EM_ASM_({ - if ($0) { - if (SDL2.capture.silenceTimer !== undefined) { - clearTimeout(SDL2.capture.silenceTimer); - } - if (SDL2.capture.stream !== undefined) { - var tracks = SDL2.capture.stream.getAudioTracks(); - for (var i = 0; i < tracks.length; i++) { - SDL2.capture.stream.removeTrack(tracks[i]); - } - SDL2.capture.stream = undefined; - } - if (SDL2.capture.scriptProcessorNode !== undefined) { - SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; - SDL2.capture.scriptProcessorNode.disconnect(); - SDL2.capture.scriptProcessorNode = undefined; - } - if (SDL2.capture.mediaStreamNode !== undefined) { - SDL2.capture.mediaStreamNode.disconnect(); - SDL2.capture.mediaStreamNode = undefined; - } - if (SDL2.capture.silenceBuffer !== undefined) { - SDL2.capture.silenceBuffer = undefined - } - SDL2.capture = undefined; - } else { - if (SDL2.audio.scriptProcessorNode != undefined) { - SDL2.audio.scriptProcessorNode.disconnect(); - SDL2.audio.scriptProcessorNode = undefined; - } - SDL2.audio = undefined; - } - if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { - SDL2.audioContext.close(); - SDL2.audioContext = undefined; - } - }, this->iscapture); - -#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */ - SDL_free(this->hidden); -#endif -} - -static int -EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - SDL_bool valid_format = SDL_FALSE; - SDL_AudioFormat test_format; - int result; - - /* based on parts of library_sdl.js */ - - /* create context (TODO: this puts stuff in the global namespace...)*/ - result = EM_ASM_INT({ - if(typeof(SDL2) === 'undefined') { - SDL2 = {}; - } - if (!$0) { - SDL2.audio = {}; - } else { - SDL2.capture = {}; - } - - if (!SDL2.audioContext) { - if (typeof(AudioContext) !== 'undefined') { - SDL2.audioContext = new AudioContext(); - } else if (typeof(webkitAudioContext) !== 'undefined') { - SDL2.audioContext = new webkitAudioContext(); - } - } - return SDL2.audioContext === undefined ? -1 : 0; - }, iscapture); - if (result < 0) { - return SDL_SetError("Web Audio API is not available!"); - } - - test_format = SDL_FirstAudioFormat(this->spec.format); - while ((!valid_format) && (test_format)) { - switch (test_format) { - case AUDIO_F32: /* web audio only supports floats */ - this->spec.format = test_format; - - valid_format = SDL_TRUE; - break; - } - test_format = SDL_NextAudioFormat(); - } - - if (!valid_format) { - /* Didn't find a compatible format :( */ - return SDL_SetError("No compatible audio format!"); - } - - /* Initialize all variables that we clean on shutdown */ -#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); -#endif - - /* limit to native freq */ - this->spec.freq = EM_ASM_INT_V({ return SDL2.audioContext.sampleRate; }); - - SDL_CalculateAudioSpec(&this->spec); - - if (iscapture) { - /* The idea is to take the capture media stream, hook it up to an - audio graph where we can pass it through a ScriptProcessorNode - to access the raw PCM samples and push them to the SDL app's - callback. From there, we "process" the audio data into silence - and forget about it. */ - - /* This should, strictly speaking, use MediaRecorder for capture, but - this API is cleaner to use and better supported, and fires a - callback whenever there's enough data to fire down into the app. - The downside is that we are spending CPU time silencing a buffer - that the audiocontext uselessly mixes into any output. On the - upside, both of those things are not only run in native code in - the browser, they're probably SIMD code, too. MediaRecorder - feels like it's a pretty inefficient tapdance in similar ways, - to be honest. */ - - EM_ASM_({ - var have_microphone = function(stream) { - //console.log('SDL audio capture: we have a microphone! Replacing silence callback.'); - if (SDL2.capture.silenceTimer !== undefined) { - clearTimeout(SDL2.capture.silenceTimer); - SDL2.capture.silenceTimer = undefined; - } - SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); - SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); - SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { - if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } - audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); - SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; - Runtime.dynCall('vi', $2, [$3]); - }; - SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); - SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); - SDL2.capture.stream = stream; - }; - - var no_microphone = function(error) { - //console.log('SDL audio capture: we DO NOT have a microphone! (' + error.name + ')...leaving silence callback running.'); - }; - - /* we write silence to the audio callback until the microphone is available (user approves use, etc). */ - SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); - SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); - var silence_callback = function() { - SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; - Runtime.dynCall('vi', $2, [$3]); - }; - - SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); - - if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { - navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); - } else if (navigator.webkitGetUserMedia !== undefined) { - navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); - } - }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this); - } else { - /* setup a ScriptProcessorNode */ - EM_ASM_ARGS({ - SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); - SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { - if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } - SDL2.audio.currentOutputBuffer = e['outputBuffer']; - Runtime.dynCall('vi', $2, [$3]); - }; - SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); - }, this->spec.channels, this->spec.samples, HandleAudioProcess, this); - } - - return 0; -} - -static int -EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - int available; - int capture_available; - - /* Set the function pointers */ - impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice; - impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice; - - impl->OnlyHasDefaultOutputDevice = 1; - - /* no threads here */ - impl->SkipMixerLock = 1; - impl->ProvidesOwnCallbackThread = 1; - - /* check availability */ - available = EM_ASM_INT_V({ - if (typeof(AudioContext) !== 'undefined') { - return 1; - } else if (typeof(webkitAudioContext) !== 'undefined') { - return 1; - } - return 0; - }); - - if (!available) { - SDL_SetError("No audio context available"); - } - - capture_available = available && EM_ASM_INT_V({ - if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { - return 1; - } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { - return 1; - } - return 0; - }); - - impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE; - impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE; - - return available; -} - -AudioBootStrap EMSCRIPTENAUDIO_bootstrap = { - "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h b/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h deleted file mode 100644 index 3c95668..0000000 --- a/Source/3rdParty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_emscriptenaudio_h_ -#define SDL_emscriptenaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - int unused; -}; - -#endif /* SDL_emscriptenaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.c b/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.c deleted file mode 100644 index 802ea78..0000000 --- a/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_ESD - -/* Allow access to an ESD network stream mixing buffer */ - -#include <sys/types.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <esd.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_esdaudio.h" - -#ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC -#include "SDL_name.h" -#include "SDL_loadso.h" -#else -#define SDL_NAME(X) X -#endif - -#ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC - -static const char *esd_library = SDL_AUDIO_DRIVER_ESD_DYNAMIC; -static void *esd_handle = NULL; - -static int (*SDL_NAME(esd_open_sound)) (const char *host); -static int (*SDL_NAME(esd_close)) (int esd); -static int (*SDL_NAME(esd_play_stream)) (esd_format_t format, int rate, - const char *host, const char *name); - -#define SDL_ESD_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) } -static struct -{ - const char *name; - void **func; -} const esd_functions[] = { - SDL_ESD_SYM(esd_open_sound), - SDL_ESD_SYM(esd_close), SDL_ESD_SYM(esd_play_stream), -}; - -#undef SDL_ESD_SYM - -static void -UnloadESDLibrary() -{ - if (esd_handle != NULL) { - SDL_UnloadObject(esd_handle); - esd_handle = NULL; - } -} - -static int -LoadESDLibrary(void) -{ - int i, retval = -1; - - if (esd_handle == NULL) { - esd_handle = SDL_LoadObject(esd_library); - if (esd_handle) { - retval = 0; - for (i = 0; i < SDL_arraysize(esd_functions); ++i) { - *esd_functions[i].func = - SDL_LoadFunction(esd_handle, esd_functions[i].name); - if (!*esd_functions[i].func) { - retval = -1; - UnloadESDLibrary(); - break; - } - } - } - } - return retval; -} - -#else - -static void -UnloadESDLibrary() -{ - return; -} - -static int -LoadESDLibrary(void) -{ - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_ESD_DYNAMIC */ - - -/* This function waits until it is possible to write a full sound buffer */ -static void -ESD_WaitDevice(_THIS) -{ - Sint32 ticks; - - /* Check to see if the thread-parent process is still alive */ - { - static int cnt = 0; - /* Note that this only works with thread implementations - that use a different process id for each thread. - */ - /* Check every 10 loops */ - if (this->hidden->parent && (((++cnt) % 10) == 0)) { - if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { - SDL_OpenedAudioDeviceDisconnected(this); - } - } - } - - /* Use timer for general audio synchronization */ - ticks = ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) - FUDGE_TICKS; - if (ticks > 0) { - SDL_Delay(ticks); - } -} - -static void -ESD_PlayDevice(_THIS) -{ - int written = 0; - - /* Write the audio data, checking for EAGAIN on broken audio drivers */ - do { - written = write(this->hidden->audio_fd, - this->hidden->mixbuf, this->hidden->mixlen); - if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { - SDL_Delay(1); /* Let a little CPU time go by */ - } - } while ((written < 0) && - ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); - - /* Set the next write frame */ - this->hidden->next_frame += this->hidden->frame_ticks; - - /* If we couldn't write, assume fatal error for now */ - if (written < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } -} - -static Uint8 * -ESD_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static void -ESD_CloseDevice(_THIS) -{ - if (this->hidden->audio_fd >= 0) { - SDL_NAME(esd_close) (this->hidden->audio_fd); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -/* Try to get the name of the program */ -static char * -get_progname(void) -{ - char *progname = NULL; -#ifdef __LINUX__ - FILE *fp; - static char temp[BUFSIZ]; - - SDL_snprintf(temp, SDL_arraysize(temp), "/proc/%d/cmdline", getpid()); - fp = fopen(temp, "r"); - if (fp != NULL) { - if (fgets(temp, sizeof(temp) - 1, fp)) { - progname = SDL_strrchr(temp, '/'); - if (progname == NULL) { - progname = temp; - } else { - progname = progname + 1; - } - } - fclose(fp); - } -#endif - return (progname); -} - - -static int -ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - esd_format_t format = (ESD_STREAM | ESD_PLAY); - SDL_AudioFormat test_format = 0; - int found = 0; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - this->hidden->audio_fd = -1; - - /* Convert audio spec to the ESD audio format */ - /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !found && test_format; test_format = SDL_NextAudioFormat()) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - found = 1; - switch (test_format) { - case AUDIO_U8: - format |= ESD_BITS8; - break; - case AUDIO_S16SYS: - format |= ESD_BITS16; - break; - default: - found = 0; - break; - } - } - - if (!found) { - return SDL_SetError("Couldn't find any hardware audio formats"); - } - - if (this->spec.channels == 1) { - format |= ESD_MONO; - } else { - format |= ESD_STEREO; - } -#if 0 - this->spec.samples = ESD_BUF_SIZE; /* Darn, no way to change this yet */ -#endif - - /* Open a connection to the ESD audio server */ - this->hidden->audio_fd = - SDL_NAME(esd_play_stream) (format, this->spec.freq, NULL, - get_progname()); - - if (this->hidden->audio_fd < 0) { - return SDL_SetError("Couldn't open ESD connection"); - } - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - this->hidden->frame_ticks = - (float) (this->spec.samples * 1000) / this->spec.freq; - this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks; - - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - - /* Get the parent process id (we're the parent of the audio thread) */ - this->hidden->parent = getpid(); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static void -ESD_Deinitialize(void) -{ - UnloadESDLibrary(); -} - -static int -ESD_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadESDLibrary() < 0) { - return 0; - } else { - int connection = 0; - - /* Don't start ESD if it's not running */ - SDL_setenv("ESD_NO_SPAWN", "1", 0); - - connection = SDL_NAME(esd_open_sound) (NULL); - if (connection < 0) { - UnloadESDLibrary(); - SDL_SetError("ESD: esd_open_sound failed (no audio server?)"); - return 0; - } - SDL_NAME(esd_close) (connection); - } - - /* Set the function pointers */ - impl->OpenDevice = ESD_OpenDevice; - impl->PlayDevice = ESD_PlayDevice; - impl->WaitDevice = ESD_WaitDevice; - impl->GetDeviceBuf = ESD_GetDeviceBuf; - impl->CloseDevice = ESD_CloseDevice; - impl->Deinitialize = ESD_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap ESD_bootstrap = { - "esd", "Enlightened Sound Daemon", ESD_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_ESD */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.h b/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.h deleted file mode 100644 index 9b5c25a..0000000 --- a/Source/3rdParty/SDL2/src/audio/esd/SDL_esdaudio.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_esdaudio_h_ -#define SDL_esdaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - /* The parent process id, to detect when application quits */ - pid_t parent; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Support for audio timing using a timer */ - float frame_ticks; - float next_frame; -}; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -#endif /* SDL_esdaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.c b/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.c deleted file mode 100644 index 36fa5c5..0000000 --- a/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_FUSIONSOUND - -/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */ - -/* Allow access to a raw mixing buffer */ - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif -#include <unistd.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_fsaudio.h" - -#include <fusionsound/fusionsound_version.h> - -/* #define SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "libfusionsound.so" */ - -#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC -#include "SDL_name.h" -#include "SDL_loadso.h" -#else -#define SDL_NAME(X) X -#endif - -#if (FUSIONSOUND_MAJOR_VERSION == 1) && (FUSIONSOUND_MINOR_VERSION < 1) -typedef DFBResult DirectResult; -#endif - -/* Buffers to use - more than 2 gives a lot of latency */ -#define FUSION_BUFFERS (2) - -#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC - -static const char *fs_library = SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC; -static void *fs_handle = NULL; - -static DirectResult (*SDL_NAME(FusionSoundInit)) (int *argc, char *(*argv[])); -static DirectResult (*SDL_NAME(FusionSoundCreate)) (IFusionSound ** - ret_interface); - -#define SDL_FS_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) } -static struct -{ - const char *name; - void **func; -} fs_functions[] = { -/* *INDENT-OFF* */ - SDL_FS_SYM(FusionSoundInit), - SDL_FS_SYM(FusionSoundCreate), -/* *INDENT-ON* */ -}; - -#undef SDL_FS_SYM - -static void -UnloadFusionSoundLibrary() -{ - if (fs_handle != NULL) { - SDL_UnloadObject(fs_handle); - fs_handle = NULL; - } -} - -static int -LoadFusionSoundLibrary(void) -{ - int i, retval = -1; - - if (fs_handle == NULL) { - fs_handle = SDL_LoadObject(fs_library); - if (fs_handle != NULL) { - retval = 0; - for (i = 0; i < SDL_arraysize(fs_functions); ++i) { - *fs_functions[i].func = - SDL_LoadFunction(fs_handle, fs_functions[i].name); - if (!*fs_functions[i].func) { - retval = -1; - UnloadFusionSoundLibrary(); - break; - } - } - } - } - - return retval; -} - -#else - -static void -UnloadFusionSoundLibrary() -{ - return; -} - -static int -LoadFusionSoundLibrary(void) -{ - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ - -/* This function waits until it is possible to write a full sound buffer */ -static void -SDL_FS_WaitDevice(_THIS) -{ - this->hidden->stream->Wait(this->hidden->stream, - this->hidden->mixsamples); -} - -static void -SDL_FS_PlayDevice(_THIS) -{ - DirectResult ret; - - ret = this->hidden->stream->Write(this->hidden->stream, - this->hidden->mixbuf, - this->hidden->mixsamples); - /* If we couldn't write, assume fatal error for now */ - if (ret) { - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); -#endif -} - - -static Uint8 * -SDL_FS_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - - -static void -SDL_FS_CloseDevice(_THIS) -{ - if (this->hidden->stream) { - this->hidden->stream->Release(this->hidden->stream); - } - if (this->hidden->fs) { - this->hidden->fs->Release(this->hidden->fs); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - - -static int -SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - int bytes; - SDL_AudioFormat test_format = 0, format = 0; - FSSampleFormat fs_format; - FSStreamDescription desc; - DirectResult ret; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - switch (test_format) { - case AUDIO_U8: - fs_format = FSSF_U8; - bytes = 1; - format = 1; - break; - case AUDIO_S16SYS: - fs_format = FSSF_S16; - bytes = 2; - format = 1; - break; - case AUDIO_S32SYS: - fs_format = FSSF_S32; - bytes = 4; - format = 1; - break; - case AUDIO_F32SYS: - fs_format = FSSF_FLOAT; - bytes = 4; - format = 1; - break; - default: - format = 0; - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); - } - } - - if (format == 0) { - return SDL_SetError("Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - /* Retrieve the main sound interface. */ - ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs); - if (ret) { - return SDL_SetError("Unable to initialize FusionSound: %d", ret); - } - - this->hidden->mixsamples = this->spec.size / bytes / this->spec.channels; - - /* Fill stream description. */ - desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE | - FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT | FSSDF_PREBUFFER; - desc.samplerate = this->spec.freq; - desc.buffersize = this->spec.size * FUSION_BUFFERS; - desc.channels = this->spec.channels; - desc.prebuffer = 10; - desc.sampleformat = fs_format; - - ret = - this->hidden->fs->CreateStream(this->hidden->fs, &desc, - &this->hidden->stream); - if (ret) { - return SDL_SetError("Unable to create FusionSoundStream: %d", ret); - } - - /* See what we got */ - desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE | - FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT; - ret = this->hidden->stream->GetDescription(this->hidden->stream, &desc); - - this->spec.freq = desc.samplerate; - this->spec.size = - desc.buffersize / FUSION_BUFFERS * bytes * desc.channels; - this->spec.channels = desc.channels; - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - - /* We're ready to rock and roll. :-) */ - return 0; -} - - -static void -SDL_FS_Deinitialize(void) -{ - UnloadFusionSoundLibrary(); -} - - -static int -SDL_FS_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadFusionSoundLibrary() < 0) { - return 0; - } else { - DirectResult ret; - - ret = SDL_NAME(FusionSoundInit) (NULL, NULL); - if (ret) { - UnloadFusionSoundLibrary(); - SDL_SetError - ("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)", - ret); - return 0; - } - } - - /* Set the function pointers */ - impl->OpenDevice = SDL_FS_OpenDevice; - impl->PlayDevice = SDL_FS_PlayDevice; - impl->WaitDevice = SDL_FS_WaitDevice; - impl->GetDeviceBuf = SDL_FS_GetDeviceBuf; - impl->CloseDevice = SDL_FS_CloseDevice; - impl->Deinitialize = SDL_FS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap FUSIONSOUND_bootstrap = { - "fusionsound", "FusionSound", SDL_FS_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.h b/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.h deleted file mode 100644 index 27e45ce..0000000 --- a/Source/3rdParty/SDL2/src/audio/fusionsound/SDL_fsaudio.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_fsaudio_h_ -#define SDL_fsaudio_h_ - -#include <fusionsound/fusionsound.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* Interface */ - IFusionSound *fs; - - /* The stream interface for the audio device */ - IFusionSoundStream *stream; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - int mixsamples; - -}; - -#endif /* SDL_fsaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.cc b/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.cc deleted file mode 100644 index 52946a5..0000000 --- a/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_HAIKU - -/* Allow access to the audio stream on Haiku */ - -#include <SoundPlayer.h> -#include <signal.h> - -#include "../../main/haiku/SDL_BeApp.h" - -extern "C" -{ - -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_haikuaudio.h" -#include "SDL_assert.h" - -} - - -/* !!! FIXME: have the callback call the higher level to avoid code dupe. */ -/* The Haiku callback for handling the audio buffer */ -static void -FillSound(void *device, void *stream, size_t len, - const media_raw_audio_format & format) -{ - SDL_AudioDevice *audio = (SDL_AudioDevice *) device; - SDL_AudioCallback callback = audio->callbackspec.callback; - - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&audio->enabled) || SDL_AtomicGet(&audio->paused)) { - if (audio->stream) { - SDL_AudioStreamClear(audio->stream); - } - SDL_memset(stream, audio->spec.silence, len); - return; - } - - SDL_assert(audio->spec.size == len); - - if (audio->stream == NULL) { /* no conversion necessary. */ - SDL_LockMutex(audio->mixer_lock); - callback(audio->callbackspec.userdata, (Uint8 *) stream, len); - SDL_UnlockMutex(audio->mixer_lock); - } else { /* streaming/converting */ - const int stream_len = audio->callbackspec.size; - const int ilen = (int) len; - while (SDL_AudioStreamAvailable(audio->stream) < ilen) { - callback(audio->callbackspec.userdata, audio->work_buffer, stream_len); - if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) { - SDL_AudioStreamClear(audio->stream); - SDL_AtomicSet(&audio->enabled, 0); - break; - } - } - - const int got = SDL_AudioStreamGet(audio->stream, stream, ilen); - SDL_assert((got < 0) || (got == ilen)); - if (got != ilen) { - SDL_memset(stream, audio->spec.silence, len); - } - } -} - -static void -HAIKUAUDIO_CloseDevice(_THIS) -{ - if (_this->hidden->audio_obj) { - _this->hidden->audio_obj->Stop(); - delete _this->hidden->audio_obj; - } - delete _this->hidden; -} - - -static const int sig_list[] = { - SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0 -}; - -static inline void -MaskSignals(sigset_t * omask) -{ - sigset_t mask; - int i; - - sigemptyset(&mask); - for (i = 0; sig_list[i]; ++i) { - sigaddset(&mask, sig_list[i]); - } - sigprocmask(SIG_BLOCK, &mask, omask); -} - -static inline void -UnmaskSignals(sigset_t * omask) -{ - sigprocmask(SIG_SETMASK, omask, NULL); -} - - -static int -HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - int valid_datatype = 0; - media_raw_audio_format format; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format); - - /* Initialize all variables that we clean on shutdown */ - _this->hidden = new SDL_PrivateAudioData; - if (_this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(_this->hidden); - - /* Parse the audio format and fill the Be raw audio format */ - SDL_zero(format); - format.byte_order = B_MEDIA_LITTLE_ENDIAN; - format.frame_rate = (float) _this->spec.freq; - format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */ - while ((!valid_datatype) && (test_format)) { - valid_datatype = 1; - _this->spec.format = test_format; - switch (test_format) { - case AUDIO_S8: - format.format = media_raw_audio_format::B_AUDIO_CHAR; - break; - - case AUDIO_U8: - format.format = media_raw_audio_format::B_AUDIO_UCHAR; - break; - - case AUDIO_S16LSB: - format.format = media_raw_audio_format::B_AUDIO_SHORT; - break; - - case AUDIO_S16MSB: - format.format = media_raw_audio_format::B_AUDIO_SHORT; - format.byte_order = B_MEDIA_BIG_ENDIAN; - break; - - case AUDIO_S32LSB: - format.format = media_raw_audio_format::B_AUDIO_INT; - break; - - case AUDIO_S32MSB: - format.format = media_raw_audio_format::B_AUDIO_INT; - format.byte_order = B_MEDIA_BIG_ENDIAN; - break; - - case AUDIO_F32LSB: - format.format = media_raw_audio_format::B_AUDIO_FLOAT; - break; - - case AUDIO_F32MSB: - format.format = media_raw_audio_format::B_AUDIO_FLOAT; - format.byte_order = B_MEDIA_BIG_ENDIAN; - break; - - default: - valid_datatype = 0; - test_format = SDL_NextAudioFormat(); - break; - } - } - - if (!valid_datatype) { /* shouldn't happen, but just in case... */ - return SDL_SetError("Unsupported audio format"); - } - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); - - format.buffer_size = _this->spec.size; - - /* Subscribe to the audio stream (creates a new thread) */ - sigset_t omask; - MaskSignals(&omask); - _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio", - FillSound, NULL, _this); - UnmaskSignals(&omask); - - if (_this->hidden->audio_obj->Start() == B_NO_ERROR) { - _this->hidden->audio_obj->SetHasData(true); - } else { - return SDL_SetError("Unable to start Be audio"); - } - - /* We're running! */ - return 0; -} - -static void -HAIKUAUDIO_Deinitialize(void) -{ - SDL_QuitBeApp(); -} - -static int -HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Initialize the Be Application, if it's not already started */ - if (SDL_InitBeApp() < 0) { - return 0; - } - - /* Set the function pointers */ - impl->OpenDevice = HAIKUAUDIO_OpenDevice; - impl->CloseDevice = HAIKUAUDIO_CloseDevice; - impl->Deinitialize = HAIKUAUDIO_Deinitialize; - impl->ProvidesOwnCallbackThread = 1; - impl->OnlyHasDefaultOutputDevice = 1; - - return 1; /* this audio target is available. */ -} - -extern "C" -{ - extern AudioBootStrap HAIKUAUDIO_bootstrap; -} -AudioBootStrap HAIKUAUDIO_bootstrap = { - "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_HAIKU */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.h b/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.h deleted file mode 100644 index f63ccdb..0000000 --- a/Source/3rdParty/SDL2/src/audio/haiku/SDL_haikuaudio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_haikuaudio_h_ -#define SDL_haikuaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *_this - -struct SDL_PrivateAudioData -{ - BSoundPlayer *audio_obj; -}; - -#endif /* SDL_haikuaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.c b/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.c deleted file mode 100644 index 76ff431..0000000 --- a/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_JACK - -#include "SDL_assert.h" -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_jackaudio.h" -#include "SDL_loadso.h" -#include "../../thread/SDL_systhread.h" - - -static jack_client_t * (*JACK_jack_client_open) (const char *, jack_options_t, jack_status_t *, ...); -static int (*JACK_jack_client_close) (jack_client_t *); -static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback, void *); -static int (*JACK_jack_activate) (jack_client_t *); -static int (*JACK_jack_deactivate) (jack_client_t *); -static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t); -static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *); -static void (*JACK_jack_free) (void *); -static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long); -static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *); -static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *); -static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long); -static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *); -static const char * (*JACK_jack_port_name) (const jack_port_t *); -static const char * (*JACK_jack_port_type) (const jack_port_t *); -static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *); -static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *); - -static int load_jack_syms(void); - - -#ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC - -static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC; -static void *jack_handle = NULL; - -/* !!! FIXME: this is copy/pasted in several places now */ -static int -load_jack_sym(const char *fn, void **addr) -{ - *addr = SDL_LoadFunction(jack_handle, fn); - if (*addr == NULL) { - /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ - return 0; - } - - return 1; -} - -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_JACK_SYM(x) \ - if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1 - -static void -UnloadJackLibrary(void) -{ - if (jack_handle != NULL) { - SDL_UnloadObject(jack_handle); - jack_handle = NULL; - } -} - -static int -LoadJackLibrary(void) -{ - int retval = 0; - if (jack_handle == NULL) { - jack_handle = SDL_LoadObject(jack_library); - if (jack_handle == NULL) { - retval = -1; - /* Don't call SDL_SetError(): SDL_LoadObject already did. */ - } else { - retval = load_jack_syms(); - if (retval < 0) { - UnloadJackLibrary(); - } - } - } - return retval; -} - -#else - -#define SDL_JACK_SYM(x) JACK_##x = x - -static void -UnloadJackLibrary(void) -{ -} - -static int -LoadJackLibrary(void) -{ - load_jack_syms(); - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_JACK_DYNAMIC */ - - -static int -load_jack_syms(void) -{ - SDL_JACK_SYM(jack_client_open); - SDL_JACK_SYM(jack_client_close); - SDL_JACK_SYM(jack_on_shutdown); - SDL_JACK_SYM(jack_activate); - SDL_JACK_SYM(jack_deactivate); - SDL_JACK_SYM(jack_port_get_buffer); - SDL_JACK_SYM(jack_port_unregister); - SDL_JACK_SYM(jack_free); - SDL_JACK_SYM(jack_get_ports); - SDL_JACK_SYM(jack_get_sample_rate); - SDL_JACK_SYM(jack_get_buffer_size); - SDL_JACK_SYM(jack_port_register); - SDL_JACK_SYM(jack_port_by_name); - SDL_JACK_SYM(jack_port_name); - SDL_JACK_SYM(jack_port_type); - SDL_JACK_SYM(jack_connect); - SDL_JACK_SYM(jack_set_process_callback); - return 0; -} - - -static void -jackShutdownCallback(void *arg) /* JACK went away; device is lost. */ -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; - SDL_OpenedAudioDeviceDisconnected(this); - SDL_SemPost(this->hidden->iosem); /* unblock the SDL thread. */ -} - -// !!! FIXME: implement and register these! -//typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg) -//typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg) - -static int -jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; - jack_port_t **ports = this->hidden->sdlports; - const int total_channels = this->spec.channels; - const int total_frames = this->spec.samples; - int channelsi; - - if (!SDL_AtomicGet(&this->enabled)) { - /* silence the buffer to avoid repeats and corruption. */ - SDL_memset(this->hidden->iobuffer, '\0', this->spec.size); - } - - for (channelsi = 0; channelsi < total_channels; channelsi++) { - float *dst = (float *) JACK_jack_port_get_buffer(ports[channelsi], nframes); - if (dst) { - const float *src = ((float *) this->hidden->iobuffer) + channelsi; - int framesi; - for (framesi = 0; framesi < total_frames; framesi++) { - *(dst++) = *src; - src += total_channels; - } - } - } - - SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */ - return 0; /* success */ -} - - -/* This function waits until it is possible to write a full sound buffer */ -static void -JACK_WaitDevice(_THIS) -{ - if (SDL_AtomicGet(&this->enabled)) { - if (SDL_SemWait(this->hidden->iosem) == -1) { - SDL_OpenedAudioDeviceDisconnected(this); - } - } -} - -static Uint8 * -JACK_GetDeviceBuf(_THIS) -{ - return (Uint8 *) this->hidden->iobuffer; -} - - -static int -jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; - if (SDL_AtomicGet(&this->enabled)) { - jack_port_t **ports = this->hidden->sdlports; - const int total_channels = this->spec.channels; - const int total_frames = this->spec.samples; - int channelsi; - - for (channelsi = 0; channelsi < total_channels; channelsi++) { - const float *src = (const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes); - if (src) { - float *dst = ((float *) this->hidden->iobuffer) + channelsi; - int framesi; - for (framesi = 0; framesi < total_frames; framesi++) { - *dst = *(src++); - dst += total_channels; - } - } - } - } - - SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */ - return 0; /* success */ -} - -static int -JACK_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */ - - /* Wait for JACK to fill the iobuffer */ - if (SDL_SemWait(this->hidden->iosem) == -1) { - return -1; - } - - SDL_memcpy(buffer, this->hidden->iobuffer, buflen); - return buflen; -} - -static void -JACK_FlushCapture(_THIS) -{ - SDL_SemWait(this->hidden->iosem); -} - - -static void -JACK_CloseDevice(_THIS) -{ - if (this->hidden->client) { - JACK_jack_deactivate(this->hidden->client); - - if (this->hidden->sdlports) { - const int channels = this->spec.channels; - int i; - for (i = 0; i < channels; i++) { - JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[i]); - } - SDL_free(this->hidden->sdlports); - } - - JACK_jack_client_close(this->hidden->client); - } - - if (this->hidden->iosem) { - SDL_DestroySemaphore(this->hidden->iosem); - } - - SDL_free(this->hidden->iobuffer); -} - -static int -JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - /* Note that JACK uses "output" for capture devices (they output audio - data to us) and "input" for playback (we input audio data to them). - Likewise, SDL's playback port will be "output" (we write data out) - and capture will be "input" (we read data in). */ - const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput; - const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput; - const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback; - const char *sdlportstr = iscapture ? "input" : "output"; - const char **devports = NULL; - int *audio_ports; - jack_client_t *client = NULL; - jack_status_t status; - int channels = 0; - int ports = 0; - int i; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - - /* !!! FIXME: we _still_ need an API to specify an app name */ - client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL); - this->hidden->client = client; - if (client == NULL) { - return SDL_SetError("Can't open JACK client"); - } - - devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags); - if (!devports || !devports[0]) { - return SDL_SetError("No physical JACK ports available"); - } - - while (devports[++ports]) { - /* spin to count devports */ - } - - /* Filter out non-audio ports */ - audio_ports = SDL_calloc(ports, sizeof *audio_ports); - for (i = 0; i < ports; i++) { - const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]); - const char *type = JACK_jack_port_type(dport); - const int len = SDL_strlen(type); - /* See if type ends with "audio" */ - if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) { - audio_ports[channels++] = i; - } - } - if (channels == 0) { - return SDL_SetError("No physical JACK ports available"); - } - - - /* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */ - - /* Jack pretty much demands what it wants. */ - this->spec.format = AUDIO_F32SYS; - this->spec.freq = JACK_jack_get_sample_rate(client); - this->spec.channels = channels; - this->spec.samples = JACK_jack_get_buffer_size(client); - - SDL_CalculateAudioSpec(&this->spec); - - this->hidden->iosem = SDL_CreateSemaphore(0); - if (!this->hidden->iosem) { - return -1; /* error was set by SDL_CreateSemaphore */ - } - - this->hidden->iobuffer = (float *) SDL_calloc(1, this->spec.size); - if (!this->hidden->iobuffer) { - return SDL_OutOfMemory(); - } - - /* Build SDL's ports, which we will connect to the device ports. */ - this->hidden->sdlports = (jack_port_t **) SDL_calloc(channels, sizeof (jack_port_t *)); - if (this->hidden->sdlports == NULL) { - return SDL_OutOfMemory(); - } - - for (i = 0; i < channels; i++) { - char portname[32]; - SDL_snprintf(portname, sizeof (portname), "sdl_jack_%s_%d", sdlportstr, i); - this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0); - if (this->hidden->sdlports[i] == NULL) { - return SDL_SetError("jack_port_register failed"); - } - } - - if (JACK_jack_set_process_callback(client, callback, this) != 0) { - return SDL_SetError("JACK: Couldn't set process callback"); - } - - JACK_jack_on_shutdown(client, jackShutdownCallback, this); - - if (JACK_jack_activate(client) != 0) { - return SDL_SetError("Failed to activate JACK client"); - } - - /* once activated, we can connect all the ports. */ - for (i = 0; i < channels; i++) { - const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]); - const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport; - const char *dstport = iscapture ? sdlport : devports[audio_ports[i]]; - if (JACK_jack_connect(client, srcport, dstport) != 0) { - return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport); - } - } - - /* don't need these anymore. */ - JACK_jack_free(devports); - SDL_free(audio_ports); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static void -JACK_Deinitialize(void) -{ - UnloadJackLibrary(); -} - -static int -JACK_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadJackLibrary() < 0) { - return 0; - } else { - /* Make sure a JACK server is running and available. */ - jack_status_t status; - jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL); - if (client == NULL) { - UnloadJackLibrary(); - return 0; - } - JACK_jack_client_close(client); - } - - /* Set the function pointers */ - impl->OpenDevice = JACK_OpenDevice; - impl->WaitDevice = JACK_WaitDevice; - impl->GetDeviceBuf = JACK_GetDeviceBuf; - impl->CloseDevice = JACK_CloseDevice; - impl->Deinitialize = JACK_Deinitialize; - impl->CaptureFromDevice = JACK_CaptureFromDevice; - impl->FlushCapture = JACK_FlushCapture; - impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap JACK_bootstrap = { - "jack", "JACK Audio Connection Kit", JACK_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_JACK */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.h b/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.h deleted file mode 100644 index 5bc04bd..0000000 --- a/Source/3rdParty/SDL2/src/audio/jack/SDL_jackaudio.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#ifndef SDL_jackaudio_h_ -#define SDL_jackaudio_h_ - -#include <jack/jack.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - jack_client_t *client; - SDL_sem *iosem; - float *iobuffer; - jack_port_t **sdlports; -}; - -#endif /* SDL_jackaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.c b/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.c deleted file mode 100644 index 3e3afc0..0000000 --- a/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_NACL - -#include "SDL_naclaudio.h" - -#include "SDL_audio.h" -#include "SDL_mutex.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" - -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi_simple/ps.h" -#include "ppapi_simple/ps_interface.h" -#include "ppapi_simple/ps_event.h" - -/* The tag name used by NACL audio */ -#define NACLAUDIO_DRIVER_NAME "nacl" - -#define SAMPLE_FRAME_COUNT 4096 - -/* Audio driver functions */ -static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data); - -/* FIXME: Make use of latency if needed */ -static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta latency, void* data) { - const int len = (int) buffer_size; - SDL_AudioDevice* _this = (SDL_AudioDevice*) data; - SDL_AudioCallback callback = _this->callbackspec.callback; - - SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */ - - /* Only do something if audio is enabled */ - if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) { - if (_this->stream) { - SDL_AudioStreamClear(_this->stream); - } - SDL_memset(stream, _this->spec.silence, len); - return; - } - - SDL_assert(_this->spec.size == len); - - if (_this->stream == NULL) { /* no conversion necessary. */ - SDL_LockMutex(_this->mixer_lock); - callback(_this->callbackspec.userdata, stream, len); - SDL_UnlockMutex(_this->mixer_lock); - } else { /* streaming/converting */ - const int stream_len = _this->callbackspec.size; - while (SDL_AudioStreamAvailable(_this->stream) < len) { - callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); - if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) { - SDL_AudioStreamClear(_this->stream); - SDL_AtomicSet(&_this->enabled, 0); - break; - } - } - - const int got = SDL_AudioStreamGet(_this->stream, stream, len); - SDL_assert((got < 0) || (got == len)); - if (got != len) { - SDL_memset(stream, _this->spec.silence, len); - } - } - - SDL_UnlockMutex(private->mutex); -} - -static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) { - const PPB_Core *core = PSInterfaceCore(); - const PPB_Audio *ppb_audio = PSInterfaceAudio(); - SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden; - - ppb_audio->StopPlayback(hidden->audio); - SDL_DestroyMutex(hidden->mutex); - core->ReleaseResource(hidden->audio); -} - -static int -NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { - PP_Instance instance = PSGetInstanceId(); - const PPB_Audio *ppb_audio = PSInterfaceAudio(); - const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig(); - - private = (SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *private)); - if (private == NULL) { - return SDL_OutOfMemory(); - } - - private->mutex = SDL_CreateMutex(); - _this->spec.freq = 44100; - _this->spec.format = AUDIO_S16LSB; - _this->spec.channels = 2; - _this->spec.samples = ppb_audiocfg->RecommendSampleFrameCount( - instance, - PP_AUDIOSAMPLERATE_44100, - SAMPLE_FRAME_COUNT); - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&_this->spec); - - private->audio = ppb_audio->Create( - instance, - ppb_audiocfg->CreateStereo16Bit(instance, PP_AUDIOSAMPLERATE_44100, _this->spec.samples), - nacl_audio_callback, - _this); - - /* Start audio playback while we are still on the main thread. */ - ppb_audio->StartPlayback(private->audio); - - return 0; -} - -static int -NACLAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - if (PSGetInstanceId() == 0) { - return 0; - } - - /* Set the function pointers */ - impl->OpenDevice = NACLAUDIO_OpenDevice; - impl->CloseDevice = NACLAUDIO_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; - impl->ProvidesOwnCallbackThread = 1; - /* - * impl->WaitDevice = NACLAUDIO_WaitDevice; - * impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf; - * impl->PlayDevice = NACLAUDIO_PlayDevice; - * impl->Deinitialize = NACLAUDIO_Deinitialize; - */ - - return 1; -} - -AudioBootStrap NACLAUDIO_bootstrap = { - NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver", - NACLAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_NACL */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.h b/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.h deleted file mode 100644 index 5ec842b..0000000 --- a/Source/3rdParty/SDL2/src/audio/nacl/SDL_naclaudio.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#ifndef SDL_naclaudio_h_ -#define SDL_naclaudio_h_ - -#include "SDL_audio.h" -#include "../SDL_sysaudio.h" -#include "SDL_mutex.h" - -#include "ppapi/c/ppb_audio.h" - -#define _THIS SDL_AudioDevice *_this -#define private _this->hidden - -typedef struct SDL_PrivateAudioData { - SDL_mutex* mutex; - PP_Resource audio; -} SDL_PrivateAudioData; - -#endif /* SDL_naclaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.c b/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.c deleted file mode 100644 index 5a02a3b..0000000 --- a/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_NAS - -/* Allow access to a raw mixing buffer */ - -#include <signal.h> -#include <unistd.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "SDL_loadso.h" -#include "../SDL_audio_c.h" -#include "SDL_nasaudio.h" - -static void (*NAS_AuCloseServer) (AuServer *); -static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *); -static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *); -static void (*NAS_AuHandleEvents) (AuServer *); -static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *); -static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *); -static void (*NAS_AuSetElements) - (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *); -static void (*NAS_AuWriteElement) - (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *); -static AuUint32 (*NAS_AuReadElement) - (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *); -static AuServer *(*NAS_AuOpenServer) - (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **); -static AuEventHandlerRec *(*NAS_AuRegisterEventHandler) - (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer); - - -#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC - -static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC; -static void *nas_handle = NULL; - -static int -load_nas_sym(const char *fn, void **addr) -{ - *addr = SDL_LoadFunction(nas_handle, fn); - if (*addr == NULL) { - return 0; - } - return 1; -} - -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_NAS_SYM(x) \ - if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1 -#else -#define SDL_NAS_SYM(x) NAS_##x = x -#endif - -static int -load_nas_syms(void) -{ - SDL_NAS_SYM(AuCloseServer); - SDL_NAS_SYM(AuNextEvent); - SDL_NAS_SYM(AuDispatchEvent); - SDL_NAS_SYM(AuHandleEvents); - SDL_NAS_SYM(AuCreateFlow); - SDL_NAS_SYM(AuStartFlow); - SDL_NAS_SYM(AuSetElements); - SDL_NAS_SYM(AuWriteElement); - SDL_NAS_SYM(AuReadElement); - SDL_NAS_SYM(AuOpenServer); - SDL_NAS_SYM(AuRegisterEventHandler); - return 0; -} - -#undef SDL_NAS_SYM - -#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC - -static void -UnloadNASLibrary(void) -{ - if (nas_handle != NULL) { - SDL_UnloadObject(nas_handle); - nas_handle = NULL; - } -} - -static int -LoadNASLibrary(void) -{ - int retval = 0; - if (nas_handle == NULL) { - nas_handle = SDL_LoadObject(nas_library); - if (nas_handle == NULL) { - /* Copy error string so we can use it in a new SDL_SetError(). */ - const char *origerr = SDL_GetError(); - const size_t len = SDL_strlen(origerr) + 1; - char *err = (char *) alloca(len); - SDL_strlcpy(err, origerr, len); - retval = -1; - SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s", - nas_library, err); - } else { - retval = load_nas_syms(); - if (retval < 0) { - UnloadNASLibrary(); - } - } - } - return retval; -} - -#else - -static void -UnloadNASLibrary(void) -{ -} - -static int -LoadNASLibrary(void) -{ - load_nas_syms(); - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */ - -/* This function waits until it is possible to write a full sound buffer */ -static void -NAS_WaitDevice(_THIS) -{ - while (this->hidden->buf_free < this->hidden->mixlen) { - AuEvent ev; - NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev); - NAS_AuDispatchEvent(this->hidden->aud, &ev); - } -} - -static void -NAS_PlayDevice(_THIS) -{ - while (this->hidden->mixlen > this->hidden->buf_free) { - /* - * We think the buffer is full? Yikes! Ask the server for events, - * in the hope that some of them is LowWater events telling us more - * of the buffer is free now than what we think. - */ - AuEvent ev; - NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev); - NAS_AuDispatchEvent(this->hidden->aud, &ev); - } - this->hidden->buf_free -= this->hidden->mixlen; - - /* Write the audio data */ - NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0, - this->hidden->mixlen, this->hidden->mixbuf, AuFalse, - NULL); - - this->hidden->written += this->hidden->mixlen; - -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); -#endif -} - -static Uint8 * -NAS_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static int -NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - struct SDL_PrivateAudioData *h = this->hidden; - int retval; - - while (SDL_TRUE) { - /* just keep the event queue moving and the server chattering. */ - NAS_AuHandleEvents(h->aud); - - retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL); - /*printf("read %d capture bytes\n", (int) retval);*/ - if (retval == 0) { - SDL_Delay(10); /* don't burn the CPU if we're waiting for data. */ - } else { - break; - } - } - - return retval; -} - -static void -NAS_FlushCapture(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - AuUint32 total = 0; - AuUint32 br; - Uint8 buf[512]; - - do { - /* just keep the event queue moving and the server chattering. */ - NAS_AuHandleEvents(h->aud); - br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL); - /*printf("flushed %d capture bytes\n", (int) br);*/ - total += br; - } while ((br == sizeof (buf)) && (total < this->spec.size)); -} - -static void -NAS_CloseDevice(_THIS) -{ - if (this->hidden->aud) { - NAS_AuCloseServer(this->hidden->aud); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static unsigned char -sdlformat_to_auformat(unsigned int fmt) -{ - switch (fmt) { - case AUDIO_U8: - return AuFormatLinearUnsigned8; - case AUDIO_S8: - return AuFormatLinearSigned8; - case AUDIO_U16LSB: - return AuFormatLinearUnsigned16LSB; - case AUDIO_U16MSB: - return AuFormatLinearUnsigned16MSB; - case AUDIO_S16LSB: - return AuFormatLinearSigned16LSB; - case AUDIO_S16MSB: - return AuFormatLinearSigned16MSB; - } - return AuNone; -} - -static AuBool -event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data; - struct SDL_PrivateAudioData *h = this->hidden; - if (this->iscapture) { - return AuTrue; /* we don't (currently) care about any of this for capture devices */ - } - - switch (ev->type) { - case AuEventTypeElementNotify: - { - AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; - - switch (event->kind) { - case AuElementNotifyKindLowWater: - if (h->buf_free >= 0) { - h->really += event->num_bytes; - gettimeofday(&h->last_tv, 0); - h->buf_free += event->num_bytes; - } else { - h->buf_free = event->num_bytes; - } - break; - case AuElementNotifyKindState: - switch (event->cur_state) { - case AuStatePause: - if (event->reason != AuReasonUser) { - if (h->buf_free >= 0) { - h->really += event->num_bytes; - gettimeofday(&h->last_tv, 0); - h->buf_free += event->num_bytes; - } else { - h->buf_free = event->num_bytes; - } - } - break; - } - } - } - } - return AuTrue; -} - -static AuDeviceID -find_device(_THIS) -{ - /* These "Au" things are all macros, not functions... */ - struct SDL_PrivateAudioData *h = this->hidden; - const unsigned int devicekind = this->iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput; - const int numdevs = AuServerNumDevices(h->aud); - const int nch = this->spec.channels; - int i; - - /* Try to find exact match on channels first... */ - for (i = 0; i < numdevs; i++) { - const AuDeviceAttributes *dev = AuServerDevice(h->aud, i); - if ((AuDeviceKind(dev) == devicekind) && (AuDeviceNumTracks(dev) == nch)) { - return AuDeviceIdentifier(dev); - } - } - - /* Take anything, then... */ - for (i = 0; i < numdevs; i++) { - const AuDeviceAttributes *dev = AuServerDevice(h->aud, i); - if (AuDeviceKind(dev) == devicekind) { - this->spec.channels = AuDeviceNumTracks(dev); - return AuDeviceIdentifier(dev); - } - } - return AuNone; -} - -static int -NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - AuElement elms[3]; - int buffer_size; - SDL_AudioFormat test_format, format; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Try for a closest match on audio format */ - format = 0; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { - format = sdlformat_to_auformat(test_format); - if (format == AuNone) { - test_format = SDL_NextAudioFormat(); - } - } - if (format == 0) { - return SDL_SetError("NAS: Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); - if (this->hidden->aud == 0) { - return SDL_SetError("NAS: Couldn't open connection to NAS server"); - } - - this->hidden->dev = find_device(this); - if ((this->hidden->dev == AuNone) - || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) { - return SDL_SetError("NAS: Couldn't find a fitting device on NAS server"); - } - - buffer_size = this->spec.freq; - if (buffer_size < 4096) - buffer_size = 4096; - - if (buffer_size > 32768) - buffer_size = 32768; /* So that the buffer won't get unmanageably big. */ - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - if (iscapture) { - AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev, - AuUnlimitedSamples, 0, NULL); - AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format, - this->spec.channels, AuTrue, buffer_size, - buffer_size, 0, NULL); - } else { - AuMakeElementImportClient(elms, this->spec.freq, format, - this->spec.channels, AuTrue, buffer_size, - buffer_size / 4, 0, NULL); - AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq, - AuUnlimitedSamples, 0, NULL); - } - - NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, - 2, elms, NULL); - - NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0, - this->hidden->flow, event_handler, - (AuPointer) this); - - NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL); - - /* Allocate mixing buffer */ - if (!iscapture) { - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - } - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static void -NAS_Deinitialize(void) -{ - UnloadNASLibrary(); -} - -static int -NAS_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadNASLibrary() < 0) { - return 0; - } else { - AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); - if (aud == NULL) { - SDL_SetError("NAS: AuOpenServer() failed (no audio server?)"); - return 0; - } - NAS_AuCloseServer(aud); - } - - /* Set the function pointers */ - impl->OpenDevice = NAS_OpenDevice; - impl->PlayDevice = NAS_PlayDevice; - impl->WaitDevice = NAS_WaitDevice; - impl->GetDeviceBuf = NAS_GetDeviceBuf; - impl->CaptureFromDevice = NAS_CaptureFromDevice; - impl->FlushCapture = NAS_FlushCapture; - impl->CloseDevice = NAS_CloseDevice; - impl->Deinitialize = NAS_Deinitialize; - - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap NAS_bootstrap = { - "nas", "Network Audio System", NAS_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_NAS */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.h b/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.h deleted file mode 100644 index b1a51d1..0000000 --- a/Source/3rdParty/SDL2/src/audio/nas/SDL_nasaudio.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_nasaudio_h_ -#define SDL_nasaudio_h_ - -#ifdef __sgi -#include <nas/audiolib.h> -#else -#include <audio/audiolib.h> -#endif -#include <sys/time.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - AuServer *aud; - AuFlowID flow; - AuDeviceID dev; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - int written; - int really; - int bps; - struct timeval last_tv; - int buf_free; -}; -#endif /* SDL_nasaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.c b/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.c deleted file mode 100644 index 0dc0b25..0000000 --- a/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_NETBSD - -/* - * Driver for native NetBSD audio(4). - * vedge@vedge.com.ar. - */ - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/audioio.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../../core/unix/SDL_poll.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" -#include "SDL_netbsdaudio.h" - -/* Use timer for synchronization */ -/* #define USE_TIMER_SYNC */ - -/* #define DEBUG_AUDIO */ -/* #define DEBUG_AUDIO_STREAM */ - - -static void -NETBSDAUDIO_DetectDevices(void) -{ - SDL_EnumUnixAudioDevices(0, NULL); -} - - -static void -NETBSDAUDIO_Status(_THIS) -{ -#ifdef DEBUG_AUDIO - /* *INDENT-OFF* */ - audio_info_t info; - const audio_prinfo *prinfo; - - if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - fprintf(stderr, "AUDIO_GETINFO failed.\n"); - return; - } - - prinfo = this->iscapture ? &info.play : &info.record; - - fprintf(stderr, "\n" - "[%s info]\n" - "buffer size : %d bytes\n" - "sample rate : %i Hz\n" - "channels : %i\n" - "precision : %i-bit\n" - "encoding : 0x%x\n" - "seek : %i\n" - "sample count : %i\n" - "EOF count : %i\n" - "paused : %s\n" - "error occured : %s\n" - "waiting : %s\n" - "active : %s\n" - "", - this->iscapture ? "record" : "play", - prinfo->buffer_size, - prinfo->sample_rate, - prinfo->channels, - prinfo->precision, - prinfo->encoding, - prinfo->seek, - prinfo->samples, - prinfo->eof, - prinfo->pause ? "yes" : "no", - prinfo->error ? "yes" : "no", - prinfo->waiting ? "yes" : "no", - prinfo->active ? "yes" : "no"); - - fprintf(stderr, "\n" - "[audio info]\n" - "monitor_gain : %i\n" - "hw block size : %d bytes\n" - "hi watermark : %i\n" - "lo watermark : %i\n" - "audio mode : %s\n" - "", - info.monitor_gain, - info.blocksize, - info.hiwat, info.lowat, - (info.mode == AUMODE_PLAY) ? "PLAY" - : (info.mode = AUMODE_RECORD) ? "RECORD" - : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?")); - /* *INDENT-ON* */ -#endif /* DEBUG_AUDIO */ -} - - -/* This function waits until it is possible to write a full sound buffer */ -static void -NETBSDAUDIO_WaitDevice(_THIS) -{ -#ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */ - /* See if we need to use timed audio synchronization */ - if (this->hidden->frame_ticks) { - /* Use timer for general audio synchronization */ - Sint32 ticks; - - ticks = ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) - FUDGE_TICKS; - if (ticks > 0) { - SDL_Delay(ticks); - } - } else { - /* Use SDL_IOReady() for audio synchronization */ -#ifdef DEBUG_AUDIO - fprintf(stderr, "Waiting for audio to get ready\n"); -#endif - if (SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, 10 * 1000) - <= 0) { - const char *message = - "Audio timeout - buggy audio driver? (disabled)"; - /* In general we should never print to the screen, - but in this case we have no other way of letting - the user know what happened. - */ - fprintf(stderr, "SDL: %s\n", message); - SDL_OpenedAudioDeviceDisconnected(this); - /* Don't try to close - may hang */ - this->hidden->audio_fd = -1; -#ifdef DEBUG_AUDIO - fprintf(stderr, "Done disabling audio\n"); -#endif - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Ready!\n"); -#endif - } -#endif /* !USE_BLOCKING_WRITES */ -} - -static void -NETBSDAUDIO_PlayDevice(_THIS) -{ - int written, p = 0; - - /* Write the audio data, checking for EAGAIN on broken audio drivers */ - do { - written = write(this->hidden->audio_fd, - &this->hidden->mixbuf[p], this->hidden->mixlen - p); - - if (written > 0) - p += written; - if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) { - /* Non recoverable error has occurred. It should be reported!!! */ - perror("audio"); - break; - } - -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif - - if (p < this->hidden->mixlen - || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) { - SDL_Delay(1); /* Let a little CPU time go by */ - } - } while (p < this->hidden->mixlen); - - /* If timer synchronization is enabled, set the next write frame */ - if (this->hidden->frame_ticks) { - this->hidden->next_frame += this->hidden->frame_ticks; - } - - /* If we couldn't write, assume fatal error for now */ - if (written < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } -} - -static Uint8 * -NETBSDAUDIO_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - - -static int -NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen) -{ - Uint8 *buffer = (Uint8 *) _buffer; - int br, p = 0; - - /* Capture the audio data, checking for EAGAIN on broken audio drivers */ - do { - br = read(this->hidden->audio_fd, buffer + p, buflen - p); - if (br > 0) - p += br; - if (br == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) { - /* Non recoverable error has occurred. It should be reported!!! */ - perror("audio"); - return p ? p : -1; - } - -#ifdef DEBUG_AUDIO - fprintf(stderr, "Captured %d bytes of audio data\n", br); -#endif - - if (p < buflen - || ((br < 0) && ((errno == 0) || (errno == EAGAIN)))) { - SDL_Delay(1); /* Let a little CPU time go by */ - } - } while (p < buflen); -} - -static void -NETBSDAUDIO_FlushCapture(_THIS) -{ - audio_info_t info; - size_t remain; - Uint8 buf[512]; - - if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - return; /* oh well. */ - } - - remain = (size_t) (info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8)); - while (remain > 0) { - const size_t len = SDL_min(sizeof (buf), remain); - const int br = read(this->hidden->audio_fd, buf, len); - if (br <= 0) { - return; /* oh well. */ - } - remain -= br; - } -} - -static void -NETBSDAUDIO_CloseDevice(_THIS) -{ - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; - SDL_AudioFormat format = 0; - audio_info_t info; - audio_prinfo *prinfo = iscapture ? &info.play : &info.record; - - /* We don't care what the devname is...we'll try to open anything. */ - /* ...but default to first name in the list... */ - if (devname == NULL) { - devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { - return SDL_SetError("No such audio device"); - } - } - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - this->hidden->audio_fd = open(devname, flags, 0); - if (this->hidden->audio_fd < 0) { - return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); - } - - AUDIO_INITINFO(&info); - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Set to play mode */ - info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY; - if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) { - return SDL_SetError("Couldn't put device into play mode"); - } - - AUDIO_INITINFO(&info); - for (format = SDL_FirstAudioFormat(this->spec.format); - format; format = SDL_NextAudioFormat()) { - switch (format) { - case AUDIO_U8: - prinfo->encoding = AUDIO_ENCODING_ULINEAR; - prinfo->precision = 8; - break; - case AUDIO_S8: - prinfo->encoding = AUDIO_ENCODING_SLINEAR; - prinfo->precision = 8; - break; - case AUDIO_S16LSB: - prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE; - prinfo->precision = 16; - break; - case AUDIO_S16MSB: - prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE; - prinfo->precision = 16; - break; - case AUDIO_U16LSB: - prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE; - prinfo->precision = 16; - break; - case AUDIO_U16MSB: - prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE; - prinfo->precision = 16; - break; - default: - continue; - } - - if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) { - break; - } - } - - if (!format) { - return SDL_SetError("No supported encoding for 0x%x", this->spec.format); - } - - this->spec.format = format; - - AUDIO_INITINFO(&info); - prinfo->channels = this->spec.channels; - if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) { - this->spec.channels = 1; - } - AUDIO_INITINFO(&info); - prinfo->sample_rate = this->spec.freq; - info.blocksize = this->spec.size; - info.hiwat = 5; - info.lowat = 3; - (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info); - (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info); - this->spec.freq = prinfo->sample_rate; - - if (!iscapture) { - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - } - - NETBSDAUDIO_Status(this); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static int -NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->DetectDevices = NETBSDAUDIO_DetectDevices; - impl->OpenDevice = NETBSDAUDIO_OpenDevice; - impl->PlayDevice = NETBSDAUDIO_PlayDevice; - impl->WaitDevice = NETBSDAUDIO_WaitDevice; - impl->GetDeviceBuf = NETBSDAUDIO_GetDeviceBuf; - impl->CloseDevice = NETBSDAUDIO_CloseDevice; - impl->CaptureFromDevice = NETBSDAUDIO_CaptureFromDevice; - impl->FlushCapture = NETBSDAUDIO_FlushCapture; - - impl->HasCaptureSupport = SDL_TRUE; - impl->AllowsArbitraryDeviceNames = 1; - - return 1; /* this audio target is available. */ -} - - -AudioBootStrap NETBSDAUDIO_bootstrap = { - "netbsd", "NetBSD audio", NETBSDAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_NETBSD */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.h b/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.h deleted file mode 100644 index 1c46068..0000000 --- a/Source/3rdParty/SDL2/src/audio/netbsd/SDL_netbsdaudio.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_netbsdaudio_h_ -#define SDL_netbsdaudio_h_ - -#include "../SDL_sysaudio.h" - -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Support for audio timing using a timer, in addition to SDL_IOReady() */ - float frame_ticks; - float next_frame; -}; - -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -#endif /* SDL_netbsdaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.c b/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.c deleted file mode 100644 index 1e8c124..0000000 --- a/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_PAUDIO - -/* Allow access to a raw mixing buffer */ - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" -#include "../SDL_audio_c.h" -#include "../../core/unix/SDL_poll.h" -#include "SDL_paudio.h" - -/* #define DEBUG_AUDIO */ - -/* A conflict within AIX 4.3.3 <sys/> headers and probably others as well. - * I guess nobody ever uses audio... Shame over AIX header files. */ -#include <sys/machine.h> -#undef BIG_ENDIAN -#include <sys/audio.h> - -/* Open the audio device for playback, and don't block if busy */ -/* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ -#define OPEN_FLAGS O_WRONLY - -/* Get the name of the audio device we use for output */ - -#ifndef _PATH_DEV_DSP -#define _PATH_DEV_DSP "/dev/%caud%c/%c" -#endif - -static char devsettings[][3] = { - {'p', '0', '1'}, {'p', '0', '2'}, {'p', '0', '3'}, {'p', '0', '4'}, - {'p', '1', '1'}, {'p', '1', '2'}, {'p', '1', '3'}, {'p', '1', '4'}, - {'p', '2', '1'}, {'p', '2', '2'}, {'p', '2', '3'}, {'p', '2', '4'}, - {'p', '3', '1'}, {'p', '3', '2'}, {'p', '3', '3'}, {'p', '3', '4'}, - {'b', '0', '1'}, {'b', '0', '2'}, {'b', '0', '3'}, {'b', '0', '4'}, - {'b', '1', '1'}, {'b', '1', '2'}, {'b', '1', '3'}, {'b', '1', '4'}, - {'b', '2', '1'}, {'b', '2', '2'}, {'b', '2', '3'}, {'b', '2', '4'}, - {'b', '3', '1'}, {'b', '3', '2'}, {'b', '3', '3'}, {'b', '3', '4'}, - {'\0', '\0', '\0'} -}; - -static int -OpenUserDefinedDevice(char *path, int maxlen, int flags) -{ - const char *audiodev; - int fd; - - /* Figure out what our audio device is */ - if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) { - audiodev = SDL_getenv("AUDIODEV"); - } - if (audiodev == NULL) { - return -1; - } - fd = open(audiodev, flags, 0); - if (path != NULL) { - SDL_strlcpy(path, audiodev, maxlen); - path[maxlen - 1] = '\0'; - } - return fd; -} - -static int -OpenAudioPath(char *path, int maxlen, int flags, int classic) -{ - struct stat sb; - int cycle = 0; - int fd = OpenUserDefinedDevice(path, maxlen, flags); - - if (fd != -1) { - return fd; - } - - /* !!! FIXME: do we really need a table here? */ - while (devsettings[cycle][0] != '\0') { - char audiopath[1024]; - SDL_snprintf(audiopath, SDL_arraysize(audiopath), - _PATH_DEV_DSP, - devsettings[cycle][0], - devsettings[cycle][1], devsettings[cycle][2]); - - if (stat(audiopath, &sb) == 0) { - fd = open(audiopath, flags, 0); - if (fd >= 0) { - if (path != NULL) { - SDL_strlcpy(path, audiopath, maxlen); - } - return fd; - } - } - } - return -1; -} - -/* This function waits until it is possible to write a full sound buffer */ -static void -PAUDIO_WaitDevice(_THIS) -{ - fd_set fdset; - - /* See if we need to use timed audio synchronization */ - if (this->hidden->frame_ticks) { - /* Use timer for general audio synchronization */ - Sint32 ticks; - - ticks = ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) - FUDGE_TICKS; - if (ticks > 0) { - SDL_Delay(ticks); - } - } else { - int timeoutMS; - audio_buffer paud_bufinfo; - - if (ioctl(this->hidden->audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Couldn't get audio buffer information\n"); -#endif - timeoutMS = 10 * 1000; - } else { - timeoutMS = paud_bufinfo.write_buf_time; -#ifdef DEBUG_AUDIO - fprintf(stderr, "Waiting for write_buf_time=%d ms\n", timeoutMS); -#endif - } - -#ifdef DEBUG_AUDIO - fprintf(stderr, "Waiting for audio to get ready\n"); -#endif - if (SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, timeoutMS) <= 0) { - /* - * In general we should never print to the screen, - * but in this case we have no other way of letting - * the user know what happened. - */ - fprintf(stderr, "SDL: %s - Audio timeout - buggy audio driver? (disabled)\n", strerror(errno)); - SDL_OpenedAudioDeviceDisconnected(this); - /* Don't try to close - may hang */ - this->hidden->audio_fd = -1; -#ifdef DEBUG_AUDIO - fprintf(stderr, "Done disabling audio\n"); -#endif - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Ready!\n"); -#endif - } -} - -static void -PAUDIO_PlayDevice(_THIS) -{ - int written = 0; - const Uint8 *mixbuf = this->hidden->mixbuf; - const size_t mixlen = this->hidden->mixlen; - - /* Write the audio data, checking for EAGAIN on broken audio drivers */ - do { - written = write(this->hidden->audio_fd, mixbuf, mixlen); - if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { - SDL_Delay(1); /* Let a little CPU time go by */ - } - } while ((written < 0) && - ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); - - /* If timer synchronization is enabled, set the next write frame */ - if (this->hidden->frame_ticks) { - this->hidden->next_frame += this->hidden->frame_ticks; - } - - /* If we couldn't write, assume fatal error for now */ - if (written < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif -} - -static Uint8 * -PAUDIO_GetDeviceBuf(_THIS) -{ - return this->hidden->mixbuf; -} - -static void -PAUDIO_CloseDevice(_THIS) -{ - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - const char *workaround = SDL_getenv("SDL_DSP_NOSELECT"); - char audiodev[1024]; - const char *err = NULL; - int format; - int bytes_per_sample; - SDL_AudioFormat test_format; - audio_init paud_init; - audio_buffer paud_bufinfo; - audio_control paud_control; - audio_change paud_change; - int fd = -1; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); - this->hidden->audio_fd = fd; - if (fd < 0) { - return SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); - } - - /* - * We can't set the buffer size - just ask the device for the maximum - * that we can have. - */ - if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { - return SDL_SetError("Couldn't get audio buffer information"); - } - - if (this->spec.channels > 1) - this->spec.channels = 2; - else - this->spec.channels = 1; - - /* - * Fields in the audio_init structure: - * - * Ignored by us: - * - * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? - * paud.slot_number; * slot number of the adapter - * paud.device_id; * adapter identification number - * - * Input: - * - * paud.srate; * the sampling rate in Hz - * paud.bits_per_sample; * 8, 16, 32, ... - * paud.bsize; * block size for this rate - * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX - * paud.channels; * 1=mono, 2=stereo - * paud.flags; * FIXED - fixed length data - * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) - * * TWOS_COMPLEMENT - 2's complement data - * * SIGNED - signed? comment seems wrong in sys/audio.h - * * BIG_ENDIAN - * paud.operation; * PLAY, RECORD - * - * Output: - * - * paud.flags; * PITCH - pitch is supported - * * INPUT - input is supported - * * OUTPUT - output is supported - * * MONITOR - monitor is supported - * * VOLUME - volume is supported - * * VOLUME_DELAY - volume delay is supported - * * BALANCE - balance is supported - * * BALANCE_DELAY - balance delay is supported - * * TREBLE - treble control is supported - * * BASS - bass control is supported - * * BESTFIT_PROVIDED - best fit returned - * * LOAD_CODE - DSP load needed - * paud.rc; * NO_PLAY - DSP code can't do play requests - * * NO_RECORD - DSP code can't do record requests - * * INVALID_REQUEST - request was invalid - * * CONFLICT - conflict with open's flags - * * OVERLOADED - out of DSP MIPS or memory - * paud.position_resolution; * smallest increment for position - */ - - paud_init.srate = this->spec.freq; - paud_init.mode = PCM; - paud_init.operation = PLAY; - paud_init.channels = this->spec.channels; - - /* Try for a closest match on audio format */ - format = 0; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - switch (test_format) { - case AUDIO_U8: - bytes_per_sample = 1; - paud_init.bits_per_sample = 8; - paud_init.flags = TWOS_COMPLEMENT | FIXED; - format = 1; - break; - case AUDIO_S8: - bytes_per_sample = 1; - paud_init.bits_per_sample = 8; - paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; - break; - case AUDIO_S16LSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; - break; - case AUDIO_S16MSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; - break; - case AUDIO_U16LSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = TWOS_COMPLEMENT | FIXED; - format = 1; - break; - case AUDIO_U16MSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED; - format = 1; - break; - default: - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); - } - } - if (format == 0) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Couldn't find any hardware audio formats\n"); -#endif - return SDL_SetError("Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - /* - * We know the buffer size and the max number of subsequent writes - * that can be pending. If more than one can pend, allow the application - * to do something like double buffering between our write buffer and - * the device's own buffer that we are filling with write() anyway. - * - * We calculate this->spec.samples like this because - * SDL_CalculateAudioSpec() will give put paud_bufinfo.write_buf_cap - * (or paud_bufinfo.write_buf_cap/2) into this->spec.size in return. - */ - if (paud_bufinfo.request_buf_cap == 1) { - this->spec.samples = paud_bufinfo.write_buf_cap - / bytes_per_sample / this->spec.channels; - } else { - this->spec.samples = paud_bufinfo.write_buf_cap - / bytes_per_sample / this->spec.channels / 2; - } - paud_init.bsize = bytes_per_sample * this->spec.channels; - - SDL_CalculateAudioSpec(&this->spec); - - /* - * The AIX paud device init can't modify the values of the audio_init - * structure that we pass to it. So we don't need any recalculation - * of this stuff and no reinit call as in linux dsp code. - * - * /dev/paud supports all of the encoding formats, so we don't need - * to do anything like reopening the device, either. - */ - if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) { - switch (paud_init.rc) { - case 1: - err = "Couldn't set audio format: DSP can't do play requests"; - break; - case 2: - err = "Couldn't set audio format: DSP can't do record requests"; - break; - case 4: - err = "Couldn't set audio format: request was invalid"; - break; - case 5: - err = "Couldn't set audio format: conflict with open's flags"; - break; - case 6: - err = "Couldn't set audio format: out of DSP MIPS or memory"; - break; - default: - err = "Couldn't set audio format: not documented in sys/audio.h"; - break; - } - } - - if (err != NULL) { - return SDL_SetError("Paudio: %s", err); - } - - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - - /* - * Set some paramters: full volume, first speaker that we can find. - * Ignore the other settings for now. - */ - paud_change.input = AUDIO_IGNORE; /* the new input source */ - paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ - paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ - paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ - paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ - paud_change.balance = 0x3fffffff; /* the new balance */ - paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ - paud_change.treble = AUDIO_IGNORE; /* the new treble state */ - paud_change.bass = AUDIO_IGNORE; /* the new bass state */ - paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ - - paud_control.ioctl_request = AUDIO_CHANGE; - paud_control.request_info = (char *) &paud_change; - if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Can't change audio display settings\n"); -#endif - } - - /* - * Tell the device to expect data. Actual start will wait for - * the first write() call. - */ - paud_control.ioctl_request = AUDIO_START; - paud_control.position = 0; - if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Can't start audio play\n"); -#endif - return SDL_SetError("Can't start audio play"); - } - - /* Check to see if we need to use SDL_IOReady() workaround */ - if (workaround != NULL) { - this->hidden->frame_ticks = (float) (this->spec.samples * 1000) / - this->spec.freq; - this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks; - } - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static int -PAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* !!! FIXME: not right for device enum? */ - int fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); - if (fd < 0) { - SDL_SetError("PAUDIO: Couldn't open audio device"); - return 0; - } - close(fd); - - /* Set the function pointers */ - impl->OpenDevice = PAUDIO_OpenDevice; - impl->PlayDevice = PAUDIO_PlayDevice; - impl->PlayDevice = PAUDIO_WaitDevice; - impl->GetDeviceBuf = PAUDIO_GetDeviceBuf; - impl->CloseDevice = PAUDIO_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: add device enum! */ - - return 1; /* this audio target is available. */ -} - -AudioBootStrap PAUDIO_bootstrap = { - "paud", "AIX Paudio", PAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_PAUDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.h b/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.h deleted file mode 100644 index c295ae4..0000000 --- a/Source/3rdParty/SDL2/src/audio/paudio/SDL_paudio.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_paudio_h_ -#define SDL_paudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Support for audio timing using a timer, in addition to SDL_IOReady() */ - float frame_ticks; - float next_frame; -}; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -#endif /* SDL_paudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.c b/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.c deleted file mode 100644 index 3e7b8e1..0000000 --- a/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_PSP - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <malloc.h> - -#include "SDL_audio.h" -#include "SDL_error.h" -#include "SDL_timer.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_pspaudio.h" - -#include <pspaudio.h> -#include <pspthreadman.h> - -/* The tag name used by PSP audio */ -#define PSPAUDIO_DRIVER_NAME "psp" - -static int -PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - int format, mixlen, i; - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - switch (this->spec.format & 0xff) { - case 8: - case 16: - this->spec.format = AUDIO_S16LSB; - break; - default: - return SDL_SetError("Unsupported audio format"); - } - - /* The sample count must be a multiple of 64. */ - this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples); - this->spec.freq = 44100; - - /* Update the fragment size as size in bytes. */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate the mixing buffer. Its size and starting address must - be a multiple of 64 bytes. Our sample count is already a multiple of - 64, so spec->size should be a multiple of 64 as well. */ - mixlen = this->spec.size * NUM_BUFFERS; - this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen); - if (this->hidden->rawbuf == NULL) { - return SDL_SetError("Couldn't allocate mixing buffer"); - } - - /* Setup the hardware channel. */ - if (this->spec.channels == 1) { - format = PSP_AUDIO_FORMAT_MONO; - } else { - this->spec.channels = 2; - format = PSP_AUDIO_FORMAT_STEREO; - } - this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format); - if (this->hidden->channel < 0) { - free(this->hidden->rawbuf); - this->hidden->rawbuf = NULL; - return SDL_SetError("Couldn't reserve hardware channel"); - } - - memset(this->hidden->rawbuf, 0, mixlen); - for (i = 0; i < NUM_BUFFERS; i++) { - this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size]; - } - - this->hidden->next_buffer = 0; - return 0; -} - -static void PSPAUDIO_PlayDevice(_THIS) -{ - Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; - - if (this->spec.channels == 1) { - sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf); - } else { - sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf); - } - - this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; -} - -/* This function waits until it is possible to write a full sound buffer */ -static void PSPAUDIO_WaitDevice(_THIS) -{ - /* Because we block when sending audio, there's no need for this function to do anything. */ -} -static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS) -{ - return this->hidden->mixbufs[this->hidden->next_buffer]; -} - -static void PSPAUDIO_CloseDevice(_THIS) -{ - if (this->hidden->channel >= 0) { - sceAudioChRelease(this->hidden->channel); - } - free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */ - SDL_free(this->hidden); -} - -static void PSPAUDIO_ThreadInit(_THIS) -{ - /* Increase the priority of this audio thread by 1 to put it - ahead of other SDL threads. */ - SceUID thid; - SceKernelThreadInfo status; - thid = sceKernelGetThreadId(); - status.size = sizeof(SceKernelThreadInfo); - if (sceKernelReferThreadStatus(thid, &status) == 0) { - sceKernelChangeThreadPriority(thid, status.currentPriority - 1); - } -} - - -static int -PSPAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = PSPAUDIO_OpenDevice; - impl->PlayDevice = PSPAUDIO_PlayDevice; - impl->WaitDevice = PSPAUDIO_WaitDevice; - impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf; - impl->CloseDevice = PSPAUDIO_CloseDevice; - impl->ThreadInit = PSPAUDIO_ThreadInit; - - /* PSP audio device */ - impl->OnlyHasDefaultOutputDevice = 1; -/* - impl->HasCaptureSupport = 1; - - impl->OnlyHasDefaultCaptureDevice = 1; -*/ - /* - impl->DetectDevices = DSOUND_DetectDevices; - impl->Deinitialize = DSOUND_Deinitialize; - */ - return 1; /* this audio target is available. */ -} - -AudioBootStrap PSPAUDIO_bootstrap = { - "psp", "PSP audio driver", PSPAUDIO_Init, 0 -}; - - /* SDL_AUDI */ - -#endif /* SDL_AUDIO_DRIVER_PSP */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.h b/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.h deleted file mode 100644 index 3f0cdc1..0000000 --- a/Source/3rdParty/SDL2/src/audio/psp/SDL_pspaudio.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_pspaudio_h_ -#define SDL_pspaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -#define NUM_BUFFERS 2 - -struct SDL_PrivateAudioData { - /* The hardware output channel. */ - int channel; - /* The raw allocated mixing buffer. */ - Uint8 *rawbuf; - /* Individual mixing buffers. */ - Uint8 *mixbufs[NUM_BUFFERS]; - /* Index of the next available mixing buffer. */ - int next_buffer; -}; - -#endif /* SDL_pspaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.c b/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.c deleted file mode 100644 index 053a1c3..0000000 --- a/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - The PulseAudio target for SDL 1.3 is based on the 1.3 arts target, with - the appropriate parts replaced with the 1.2 PulseAudio target code. This - was the cleanest way to move it to 1.3. The 1.2 target was written by - Stéphan Kochen: stephan .a.t. kochen.nl -*/ -#include "../../SDL_internal.h" -#include "SDL_assert.h" - -#if SDL_AUDIO_DRIVER_PULSEAUDIO - -/* Allow access to a raw mixing buffer */ - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif -#include <unistd.h> -#include <sys/types.h> -#include <pulse/pulseaudio.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_pulseaudio.h" -#include "SDL_loadso.h" -#include "../../thread/SDL_systhread.h" - -#if (PA_API_VERSION < 12) -/** Return non-zero if the passed state is one of the connected states */ -static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x) { - return - x == PA_CONTEXT_CONNECTING || - x == PA_CONTEXT_AUTHORIZING || - x == PA_CONTEXT_SETTING_NAME || - x == PA_CONTEXT_READY; -} -/** Return non-zero if the passed state is one of the connected states */ -static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x) { - return - x == PA_STREAM_CREATING || - x == PA_STREAM_READY; -} -#endif /* pulseaudio <= 0.9.10 */ - - -static const char *(*PULSEAUDIO_pa_get_library_version) (void); -static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) ( - pa_channel_map *, unsigned, pa_channel_map_def_t); -static const char * (*PULSEAUDIO_pa_strerror) (int); -static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void); -static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *); -static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *); -static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *); -static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int); -static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *); - -static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) ( - pa_operation *); -static void (*PULSEAUDIO_pa_operation_cancel) (pa_operation *); -static void (*PULSEAUDIO_pa_operation_unref) (pa_operation *); - -static pa_context * (*PULSEAUDIO_pa_context_new) (pa_mainloop_api *, - const char *); -static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *, - pa_context_flags_t, const pa_spawn_api *); -static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *); -static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *); -static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *); -static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *); -static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *); -static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *); -static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *); -static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *); -static void (*PULSEAUDIO_pa_context_unref) (pa_context *); - -static pa_stream * (*PULSEAUDIO_pa_stream_new) (pa_context *, const char *, - const pa_sample_spec *, const pa_channel_map *); -static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *, - const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *); -static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *, - const pa_buffer_attr *, pa_stream_flags_t); -static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *); -static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *); -static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *); -static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t, - pa_free_cb_t, int64_t, pa_seek_mode_t); -static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *, - pa_stream_success_cb_t, void *); -static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *); -static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *); -static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *, - pa_stream_success_cb_t, void *); -static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *); -static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *); - -static int load_pulseaudio_syms(void); - - -#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC - -static const char *pulseaudio_library = SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC; -static void *pulseaudio_handle = NULL; - -static int -load_pulseaudio_sym(const char *fn, void **addr) -{ - *addr = SDL_LoadFunction(pulseaudio_handle, fn); - if (*addr == NULL) { - /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ - return 0; - } - - return 1; -} - -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_PULSEAUDIO_SYM(x) \ - if (!load_pulseaudio_sym(#x, (void **) (char *) &PULSEAUDIO_##x)) return -1 - -static void -UnloadPulseAudioLibrary(void) -{ - if (pulseaudio_handle != NULL) { - SDL_UnloadObject(pulseaudio_handle); - pulseaudio_handle = NULL; - } -} - -static int -LoadPulseAudioLibrary(void) -{ - int retval = 0; - if (pulseaudio_handle == NULL) { - pulseaudio_handle = SDL_LoadObject(pulseaudio_library); - if (pulseaudio_handle == NULL) { - retval = -1; - /* Don't call SDL_SetError(): SDL_LoadObject already did. */ - } else { - retval = load_pulseaudio_syms(); - if (retval < 0) { - UnloadPulseAudioLibrary(); - } - } - } - return retval; -} - -#else - -#define SDL_PULSEAUDIO_SYM(x) PULSEAUDIO_##x = x - -static void -UnloadPulseAudioLibrary(void) -{ -} - -static int -LoadPulseAudioLibrary(void) -{ - load_pulseaudio_syms(); - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */ - - -static int -load_pulseaudio_syms(void) -{ - SDL_PULSEAUDIO_SYM(pa_get_library_version); - SDL_PULSEAUDIO_SYM(pa_mainloop_new); - SDL_PULSEAUDIO_SYM(pa_mainloop_get_api); - SDL_PULSEAUDIO_SYM(pa_mainloop_iterate); - SDL_PULSEAUDIO_SYM(pa_mainloop_run); - SDL_PULSEAUDIO_SYM(pa_mainloop_quit); - SDL_PULSEAUDIO_SYM(pa_mainloop_free); - SDL_PULSEAUDIO_SYM(pa_operation_get_state); - SDL_PULSEAUDIO_SYM(pa_operation_cancel); - SDL_PULSEAUDIO_SYM(pa_operation_unref); - SDL_PULSEAUDIO_SYM(pa_context_new); - SDL_PULSEAUDIO_SYM(pa_context_connect); - SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list); - SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list); - SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index); - SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index); - SDL_PULSEAUDIO_SYM(pa_context_get_state); - SDL_PULSEAUDIO_SYM(pa_context_subscribe); - SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback); - SDL_PULSEAUDIO_SYM(pa_context_disconnect); - SDL_PULSEAUDIO_SYM(pa_context_unref); - SDL_PULSEAUDIO_SYM(pa_stream_new); - SDL_PULSEAUDIO_SYM(pa_stream_connect_playback); - SDL_PULSEAUDIO_SYM(pa_stream_connect_record); - SDL_PULSEAUDIO_SYM(pa_stream_get_state); - SDL_PULSEAUDIO_SYM(pa_stream_writable_size); - SDL_PULSEAUDIO_SYM(pa_stream_readable_size); - SDL_PULSEAUDIO_SYM(pa_stream_write); - SDL_PULSEAUDIO_SYM(pa_stream_drain); - SDL_PULSEAUDIO_SYM(pa_stream_disconnect); - SDL_PULSEAUDIO_SYM(pa_stream_peek); - SDL_PULSEAUDIO_SYM(pa_stream_drop); - SDL_PULSEAUDIO_SYM(pa_stream_flush); - SDL_PULSEAUDIO_SYM(pa_stream_unref); - SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto); - SDL_PULSEAUDIO_SYM(pa_strerror); - return 0; -} - -static SDL_INLINE int -squashVersion(const int major, const int minor, const int patch) -{ - return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF); -} - -/* Workaround for older pulse: pa_context_new() must have non-NULL appname */ -static const char * -getAppName(void) -{ - const char *verstr = PULSEAUDIO_pa_get_library_version(); - if (verstr != NULL) { - int maj, min, patch; - if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) { - if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) { - return NULL; /* 0.9.15+ handles NULL correctly. */ - } - } - } - return "SDL Application"; /* oh well. */ -} - -static void -WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o) -{ - /* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */ - if (mainloop && o) { - SDL_bool okay = SDL_TRUE; - while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) { - okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0); - } - PULSEAUDIO_pa_operation_unref(o); - } -} - -static void -DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context) -{ - if (context) { - PULSEAUDIO_pa_context_disconnect(context); - PULSEAUDIO_pa_context_unref(context); - } - if (mainloop != NULL) { - PULSEAUDIO_pa_mainloop_free(mainloop); - } -} - -static int -ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context) -{ - pa_mainloop *mainloop = NULL; - pa_context *context = NULL; - pa_mainloop_api *mainloop_api = NULL; - int state = 0; - - *_mainloop = NULL; - *_context = NULL; - - /* Set up a new main loop */ - if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) { - return SDL_SetError("pa_mainloop_new() failed"); - } - - *_mainloop = mainloop; - - mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop); - SDL_assert(mainloop_api); /* this never fails, right? */ - - context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName()); - if (!context) { - return SDL_SetError("pa_context_new() failed"); - } - *_context = context; - - /* Connect to the PulseAudio server */ - if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) { - return SDL_SetError("Could not setup connection to PulseAudio"); - } - - do { - if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) { - return SDL_SetError("pa_mainloop_iterate() failed"); - } - state = PULSEAUDIO_pa_context_get_state(context); - if (!PA_CONTEXT_IS_GOOD(state)) { - return SDL_SetError("Could not connect to PulseAudio"); - } - } while (state != PA_CONTEXT_READY); - - return 0; /* connected and ready! */ -} - -static int -ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context) -{ - const int retval = ConnectToPulseServer_Internal(_mainloop, _context); - if (retval < 0) { - DisconnectFromPulseServer(*_mainloop, *_context); - } - return retval; -} - - -/* This function waits until it is possible to write a full sound buffer */ -static void -PULSEAUDIO_WaitDevice(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - - while (SDL_AtomicGet(&this->enabled)) { - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - return; - } - if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) { - return; - } - } -} - -static void -PULSEAUDIO_PlayDevice(_THIS) -{ - /* Write the audio data */ - struct SDL_PrivateAudioData *h = this->hidden; - if (SDL_AtomicGet(&this->enabled)) { - if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } - } -} - -static Uint8 * -PULSEAUDIO_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - - -static int -PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - struct SDL_PrivateAudioData *h = this->hidden; - const void *data = NULL; - size_t nbytes = 0; - - while (SDL_AtomicGet(&this->enabled)) { - if (h->capturebuf != NULL) { - const int cpy = SDL_min(buflen, h->capturelen); - SDL_memcpy(buffer, h->capturebuf, cpy); - /*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/ - h->capturebuf += cpy; - h->capturelen -= cpy; - if (h->capturelen == 0) { - h->capturebuf = NULL; - PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */ - } - return cpy; /* new data, return it. */ - } - - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - return -1; /* uhoh, pulse failed! */ - } - - if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) { - continue; /* no data available yet. */ - } - - /* a new fragment is available! */ - PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); - SDL_assert(nbytes > 0); - if (data == NULL) { /* NULL==buffer had a hole. Ignore that. */ - PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */ - } else { - /* store this fragment's data, start feeding it to SDL. */ - /*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/ - h->capturebuf = (const Uint8 *) data; - h->capturelen = nbytes; - } - } - - return -1; /* not enabled? */ -} - -static void -PULSEAUDIO_FlushCapture(_THIS) -{ - struct SDL_PrivateAudioData *h = this->hidden; - const void *data = NULL; - size_t nbytes = 0; - - if (h->capturebuf != NULL) { - PULSEAUDIO_pa_stream_drop(h->stream); - h->capturebuf = NULL; - h->capturelen = 0; - } - - while (SDL_TRUE) { - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - return; /* uhoh, pulse failed! */ - } - - if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) { - break; /* no data available, so we're done. */ - } - - /* a new fragment is available! Just dump it. */ - PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); - PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */ - } -} - -static void -PULSEAUDIO_CloseDevice(_THIS) -{ - if (this->hidden->stream) { - if (this->hidden->capturebuf != NULL) { - PULSEAUDIO_pa_stream_drop(this->hidden->stream); - } - PULSEAUDIO_pa_stream_disconnect(this->hidden->stream); - PULSEAUDIO_pa_stream_unref(this->hidden->stream); - } - - DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context); - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden->device_name); - SDL_free(this->hidden); -} - -static void -SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) -{ - if (i) { - char **devname = (char **) data; - *devname = SDL_strdup(i->name); - } -} - -static void -SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data) -{ - if (i) { - char **devname = (char **) data; - *devname = SDL_strdup(i->name); - } -} - -static SDL_bool -FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle) -{ - const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1; - - if (handle == NULL) { /* NULL == default device. */ - return SDL_TRUE; - } - - if (iscapture) { - WaitForPulseOperation(h->mainloop, - PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx, - SourceDeviceNameCallback, &h->device_name)); - } else { - WaitForPulseOperation(h->mainloop, - PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, - SinkDeviceNameCallback, &h->device_name)); - } - - return (h->device_name != NULL); -} - -static int -PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - struct SDL_PrivateAudioData *h = NULL; - Uint16 test_format = 0; - pa_sample_spec paspec; - pa_buffer_attr paattr; - pa_channel_map pacmap; - pa_stream_flags_t flags = 0; - int state = 0; - int rc = 0; - - /* Initialize all variables that we clean on shutdown */ - h = this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - paspec.format = PA_SAMPLE_INVALID; - - /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - (paspec.format == PA_SAMPLE_INVALID) && test_format;) { -#ifdef DEBUG_AUDIO - fprintf(stderr, "Trying format 0x%4.4x\n", test_format); -#endif - switch (test_format) { - case AUDIO_U8: - paspec.format = PA_SAMPLE_U8; - break; - case AUDIO_S16LSB: - paspec.format = PA_SAMPLE_S16LE; - break; - case AUDIO_S16MSB: - paspec.format = PA_SAMPLE_S16BE; - break; - case AUDIO_S32LSB: - paspec.format = PA_SAMPLE_S32LE; - break; - case AUDIO_S32MSB: - paspec.format = PA_SAMPLE_S32BE; - break; - case AUDIO_F32LSB: - paspec.format = PA_SAMPLE_FLOAT32LE; - break; - case AUDIO_F32MSB: - paspec.format = PA_SAMPLE_FLOAT32BE; - break; - default: - paspec.format = PA_SAMPLE_INVALID; - break; - } - if (paspec.format == PA_SAMPLE_INVALID) { - test_format = SDL_NextAudioFormat(); - } - } - if (paspec.format == PA_SAMPLE_INVALID) { - return SDL_SetError("Couldn't find any hardware audio formats"); - } - this->spec.format = test_format; - - /* Calculate the final parameters for this audio specification */ -#ifdef PA_STREAM_ADJUST_LATENCY - this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */ -#endif - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate mixing buffer */ - if (!iscapture) { - h->mixlen = this->spec.size; - h->mixbuf = (Uint8 *) SDL_malloc(h->mixlen); - if (h->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(h->mixbuf, this->spec.silence, this->spec.size); - } - - paspec.channels = this->spec.channels; - paspec.rate = this->spec.freq; - - /* Reduced prebuffering compared to the defaults. */ -#ifdef PA_STREAM_ADJUST_LATENCY - /* 2x original requested bufsize */ - paattr.tlength = h->mixlen * 4; - paattr.prebuf = -1; - paattr.maxlength = -1; - /* -1 can lead to pa_stream_writable_size() >= mixlen never being true */ - paattr.minreq = h->mixlen; - flags = PA_STREAM_ADJUST_LATENCY; -#else - paattr.tlength = h->mixlen*2; - paattr.prebuf = h->mixlen*2; - paattr.maxlength = h->mixlen*2; - paattr.minreq = h->mixlen; -#endif - - if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) { - return SDL_SetError("Could not connect to PulseAudio server"); - } - - if (!FindDeviceName(h, iscapture, handle)) { - return SDL_SetError("Requested PulseAudio sink/source missing?"); - } - - /* The SDL ALSA output hints us that we use Windows' channel mapping */ - /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */ - PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels, - PA_CHANNEL_MAP_WAVEEX); - - h->stream = PULSEAUDIO_pa_stream_new( - h->context, - "Simple DirectMedia Layer", /* stream description */ - &paspec, /* sample format spec */ - &pacmap /* channel map */ - ); - - if (h->stream == NULL) { - return SDL_SetError("Could not set up PulseAudio stream"); - } - - /* now that we have multi-device support, don't move a stream from - a device that was unplugged to something else, unless we're default. */ - if (h->device_name != NULL) { - flags |= PA_STREAM_DONT_MOVE; - } - - if (iscapture) { - rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags); - } else { - rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL); - } - - if (rc < 0) { - return SDL_SetError("Could not connect PulseAudio stream"); - } - - do { - if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - return SDL_SetError("pa_mainloop_iterate() failed"); - } - state = PULSEAUDIO_pa_stream_get_state(h->stream); - if (!PA_STREAM_IS_GOOD(state)) { - return SDL_SetError("Could not connect PulseAudio stream"); - } - } while (state != PA_STREAM_READY); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static pa_mainloop *hotplug_mainloop = NULL; -static pa_context *hotplug_context = NULL; -static SDL_Thread *hotplug_thread = NULL; - -/* device handles are device index + 1, cast to void*, so we never pass a NULL. */ - -/* This is called when PulseAudio adds an output ("sink") device. */ -static void -SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) -{ - if (i) { - SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1)); - } -} - -/* This is called when PulseAudio adds a capture ("source") device. */ -static void -SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data) -{ - if (i) { - /* Skip "monitor" sources. These are just output from other sinks. */ - if (i->monitor_of_sink == PA_INVALID_INDEX) { - SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1)); - } - } -} - -/* This is called when PulseAudio has a device connected/removed/changed. */ -static void -HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data) -{ - const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW); - const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE); - - if (added || removed) { /* we only care about add/remove events. */ - const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK); - const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE); - - /* adds need sink details from the PulseAudio server. Another callback... */ - if (added && sink) { - PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, NULL); - } else if (added && source) { - PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, NULL); - } else if (removed && (sink || source)) { - /* removes we can handle just with the device index. */ - SDL_RemoveAudioDevice(source != 0, (void *) ((size_t) idx+1)); - } - } -} - -/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */ -static int SDLCALL -HotplugThread(void *data) -{ - pa_operation *o; - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); - PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL); - o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL); - PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */ - PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL); - return 0; -} - -static void -PULSEAUDIO_DetectDevices() -{ - WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, NULL)); - WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL)); - - /* ok, we have a sane list, let's set up hotplug notifications now... */ - hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL); -} - -static void -PULSEAUDIO_Deinitialize(void) -{ - if (hotplug_thread) { - PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0); - SDL_WaitThread(hotplug_thread, NULL); - hotplug_thread = NULL; - } - - DisconnectFromPulseServer(hotplug_mainloop, hotplug_context); - hotplug_mainloop = NULL; - hotplug_context = NULL; - - UnloadPulseAudioLibrary(); -} - -static int -PULSEAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadPulseAudioLibrary() < 0) { - return 0; - } - - if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) { - UnloadPulseAudioLibrary(); - return 0; - } - - /* Set the function pointers */ - impl->DetectDevices = PULSEAUDIO_DetectDevices; - impl->OpenDevice = PULSEAUDIO_OpenDevice; - impl->PlayDevice = PULSEAUDIO_PlayDevice; - impl->WaitDevice = PULSEAUDIO_WaitDevice; - impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf; - impl->CloseDevice = PULSEAUDIO_CloseDevice; - impl->Deinitialize = PULSEAUDIO_Deinitialize; - impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice; - impl->FlushCapture = PULSEAUDIO_FlushCapture; - - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap PULSEAUDIO_bootstrap = { - "pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.h b/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.h deleted file mode 100644 index 61da70b..0000000 --- a/Source/3rdParty/SDL2/src/audio/pulseaudio/SDL_pulseaudio.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_pulseaudio_h_ -#define SDL_pulseaudio_h_ - -#include <pulse/simple.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - char *device_name; - - /* pulseaudio structures */ - pa_mainloop *mainloop; - pa_context *context; - pa_stream *stream; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - const Uint8 *capturebuf; - int capturelen; -}; - -#endif /* SDL_pulseaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.c b/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.c deleted file mode 100644 index 957ac2d..0000000 --- a/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - * !!! FIXME: streamline this a little by removing all the - * !!! FIXME: if (capture) {} else {} sections that are identical - * !!! FIXME: except for one flag. - */ - -/* !!! FIXME: can this target support hotplugging? */ -/* !!! FIXME: ...does SDL2 even support QNX? */ - -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_QSA - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sched.h> -#include <sys/select.h> -#include <sys/neutrino.h> -#include <sys/asoundlib.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../../core/unix/SDL_poll.h" -#include "../SDL_audio_c.h" -#include "SDL_qsa_audio.h" - -/* default channel communication parameters */ -#define DEFAULT_CPARAMS_RATE 44100 -#define DEFAULT_CPARAMS_VOICES 1 - -#define DEFAULT_CPARAMS_FRAG_SIZE 4096 -#define DEFAULT_CPARAMS_FRAGS_MIN 1 -#define DEFAULT_CPARAMS_FRAGS_MAX 1 - -/* List of found devices */ -#define QSA_MAX_DEVICES 32 -#define QSA_MAX_NAME_LENGTH 81+16 /* Hardcoded in QSA, can't be changed */ - -typedef struct _QSA_Device -{ - char name[QSA_MAX_NAME_LENGTH]; /* Long audio device name for SDL */ - int cardno; - int deviceno; -} QSA_Device; - -QSA_Device qsa_playback_device[QSA_MAX_DEVICES]; -uint32_t qsa_playback_devices; - -QSA_Device qsa_capture_device[QSA_MAX_DEVICES]; -uint32_t qsa_capture_devices; - -static SDL_INLINE int -QSA_SetError(const char *fn, int status) -{ - return SDL_SetError("QSA: %s() failed: %s", fn, snd_strerror(status)); -} - -/* !!! FIXME: does this need to be here? Does the SDL version not work? */ -static void -QSA_ThreadInit(_THIS) -{ - /* Increase default 10 priority to 25 to avoid jerky sound */ - struct sched_param param; - if (SchedGet(0, 0, ¶m) != -1) { - param.sched_priority = param.sched_curpriority + 15; - SchedSet(0, 0, SCHED_NOCHANGE, ¶m); - } -} - -/* PCM channel parameters initialize function */ -static void -QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) -{ - SDL_zerop(cpars); - cpars->channel = SND_PCM_CHANNEL_PLAYBACK; - cpars->mode = SND_PCM_MODE_BLOCK; - cpars->start_mode = SND_PCM_START_DATA; - cpars->stop_mode = SND_PCM_STOP_STOP; - cpars->format.format = SND_PCM_SFMT_S16_LE; - cpars->format.interleave = 1; - cpars->format.rate = DEFAULT_CPARAMS_RATE; - cpars->format.voices = DEFAULT_CPARAMS_VOICES; - cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; - cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; - cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; -} - -/* This function waits until it is possible to write a full sound buffer */ -static void -QSA_WaitDevice(_THIS) -{ - int result; - - /* Setup timeout for playing one fragment equal to 2 seconds */ - /* If timeout occured than something wrong with hardware or driver */ - /* For example, Vortex 8820 audio driver stucks on second DAC because */ - /* it doesn't exist ! */ - result = SDL_IOReady(this->hidden->audio_fd, !this->hidden->iscapture, 2 * 1000); - switch (result) { - case -1: - SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); - break; - case 0: - SDL_SetError("QSA: timeout on buffer waiting occured"); - this->hidden->timeout_on_wait = 1; - break; - default: - this->hidden->timeout_on_wait = 0; - break; - } -} - -static void -QSA_PlayDevice(_THIS) -{ - snd_pcm_channel_status_t cstatus; - int written; - int status; - int towrite; - void *pcmbuffer; - - if (!SDL_AtomicGet(&this->enabled) || !this->hidden) { - return; - } - - towrite = this->spec.size; - pcmbuffer = this->hidden->pcm_buf; - - /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ - do { - written = - snd_pcm_plugin_write(this->hidden->audio_handle, pcmbuffer, - towrite); - if (written != towrite) { - /* Check if samples playback got stuck somewhere in hardware or in */ - /* the audio device driver */ - if ((errno == EAGAIN) && (written == 0)) { - if (this->hidden->timeout_on_wait != 0) { - SDL_SetError("QSA: buffer playback timeout"); - return; - } - } - - /* Check for errors or conditions */ - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - /* Let a little CPU time go by and try to write again */ - SDL_Delay(1); - - /* if we wrote some data */ - towrite -= written; - pcmbuffer += written * this->spec.channels; - continue; - } else { - if ((errno == EINVAL) || (errno == EIO)) { - SDL_zero(cstatus); - if (!this->hidden->iscapture) { - cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; - } else { - cstatus.channel = SND_PCM_CHANNEL_CAPTURE; - } - - status = - snd_pcm_plugin_status(this->hidden->audio_handle, - &cstatus); - if (status < 0) { - QSA_SetError("snd_pcm_plugin_status", status); - return; - } - - if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || - (cstatus.status == SND_PCM_STATUS_READY)) { - if (!this->hidden->iscapture) { - status = - snd_pcm_plugin_prepare(this->hidden-> - audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - status = - snd_pcm_plugin_prepare(this->hidden-> - audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - if (status < 0) { - QSA_SetError("snd_pcm_plugin_prepare", status); - return; - } - } - continue; - } else { - return; - } - } - } else { - /* we wrote all remaining data */ - towrite -= written; - pcmbuffer += written * this->spec.channels; - } - } while ((towrite > 0) && SDL_AtomicGet(&this->enabled)); - - /* If we couldn't write, assume fatal error for now */ - if (towrite != 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } -} - -static Uint8 * -QSA_GetDeviceBuf(_THIS) -{ - return this->hidden->pcm_buf; -} - -static void -QSA_CloseDevice(_THIS) -{ - if (this->hidden->audio_handle != NULL) { - if (!this->hidden->iscapture) { - /* Finish playing available samples */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - /* Cancel unread samples during capture */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - snd_pcm_close(this->hidden->audio_handle); - } - - SDL_free(this->hidden->pcm_buf); - SDL_free(this->hidden); -} - -static int -QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - const QSA_Device *device = (const QSA_Device *) handle; - int status = 0; - int format = 0; - SDL_AudioFormat test_format = 0; - int found = 0; - snd_pcm_channel_setup_t csetup; - snd_pcm_channel_params_t cparams; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = - (struct SDL_PrivateAudioData *) SDL_calloc(1, - (sizeof - (struct - SDL_PrivateAudioData))); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - - /* Initialize channel transfer parameters to default */ - QSA_InitAudioParams(&cparams); - - /* Initialize channel direction: capture or playback */ - this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; - - if (device != NULL) { - /* Open requested audio device */ - this->hidden->deviceno = device->deviceno; - this->hidden->cardno = device->cardno; - status = snd_pcm_open(&this->hidden->audio_handle, - device->cardno, device->deviceno, - iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); - } else { - /* Open system default audio device */ - status = snd_pcm_open_preferred(&this->hidden->audio_handle, - &this->hidden->cardno, - &this->hidden->deviceno, - iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK); - } - - /* Check if requested device is opened */ - if (status < 0) { - this->hidden->audio_handle = NULL; - return QSA_SetError("snd_pcm_open", status); - } - - /* Try for a closest match on audio format */ - format = 0; - /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */ - found = 0; - - for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) { - /* if match found set format to equivalent QSA format */ - switch (test_format) { - case AUDIO_U8: - { - format = SND_PCM_SFMT_U8; - found = 1; - } - break; - case AUDIO_S8: - { - format = SND_PCM_SFMT_S8; - found = 1; - } - break; - case AUDIO_S16LSB: - { - format = SND_PCM_SFMT_S16_LE; - found = 1; - } - break; - case AUDIO_S16MSB: - { - format = SND_PCM_SFMT_S16_BE; - found = 1; - } - break; - case AUDIO_U16LSB: - { - format = SND_PCM_SFMT_U16_LE; - found = 1; - } - break; - case AUDIO_U16MSB: - { - format = SND_PCM_SFMT_U16_BE; - found = 1; - } - break; - case AUDIO_S32LSB: - { - format = SND_PCM_SFMT_S32_LE; - found = 1; - } - break; - case AUDIO_S32MSB: - { - format = SND_PCM_SFMT_S32_BE; - found = 1; - } - break; - case AUDIO_F32LSB: - { - format = SND_PCM_SFMT_FLOAT_LE; - found = 1; - } - break; - case AUDIO_F32MSB: - { - format = SND_PCM_SFMT_FLOAT_BE; - found = 1; - } - break; - default: - { - break; - } - } - - if (!found) { - test_format = SDL_NextAudioFormat(); - } - } - - /* assumes test_format not 0 on success */ - if (test_format == 0) { - return SDL_SetError("QSA: Couldn't find any hardware audio formats"); - } - - this->spec.format = test_format; - - /* Set the audio format */ - cparams.format.format = format; - - /* Set mono/stereo/4ch/6ch/8ch audio */ - cparams.format.voices = this->spec.channels; - - /* Set rate */ - cparams.format.rate = this->spec.freq; - - /* Setup the transfer parameters according to cparams */ - status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams); - if (status < 0) { - return QSA_SetError("snd_pcm_plugin_params", status); - } - - /* Make sure channel is setup right one last time */ - SDL_zero(csetup); - if (!this->hidden->iscapture) { - csetup.channel = SND_PCM_CHANNEL_PLAYBACK; - } else { - csetup.channel = SND_PCM_CHANNEL_CAPTURE; - } - - /* Setup an audio channel */ - if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) { - return SDL_SetError("QSA: Unable to setup channel"); - } - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - this->hidden->pcm_len = this->spec.size; - - if (this->hidden->pcm_len == 0) { - this->hidden->pcm_len = - csetup.buf.block.frag_size * this->spec.channels * - (snd_pcm_format_width(format) / 8); - } - - /* - * Allocate memory to the audio buffer and initialize with silence - * (Note that buffer size must be a multiple of fragment size, so find - * closest multiple) - */ - this->hidden->pcm_buf = - (Uint8 *) SDL_malloc(this->hidden->pcm_len); - if (this->hidden->pcm_buf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->pcm_buf, this->spec.silence, - this->hidden->pcm_len); - - /* get the file descriptor */ - if (!this->hidden->iscapture) { - this->hidden->audio_fd = - snd_pcm_file_descriptor(this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - this->hidden->audio_fd = - snd_pcm_file_descriptor(this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - - if (this->hidden->audio_fd < 0) { - return QSA_SetError("snd_pcm_file_descriptor", status); - } - - /* Prepare an audio channel */ - if (!this->hidden->iscapture) { - /* Prepare audio playback */ - status = - snd_pcm_plugin_prepare(this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - /* Prepare audio capture */ - status = - snd_pcm_plugin_prepare(this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - - if (status < 0) { - return QSA_SetError("snd_pcm_plugin_prepare", status); - } - - /* We're really ready to rock and roll. :-) */ - return 0; -} - -static void -QSA_DetectDevices(void) -{ - uint32_t it; - uint32_t cards; - uint32_t devices; - int32_t status; - - /* Detect amount of available devices */ - /* this value can be changed in the runtime */ - cards = snd_cards(); - - /* If io-audio manager is not running we will get 0 as number */ - /* of available audio devices */ - if (cards == 0) { - /* We have no any available audio devices */ - return; - } - - /* !!! FIXME: code duplication */ - /* Find requested devices by type */ - { /* output devices */ - /* Playback devices enumeration requested */ - for (it = 0; it < cards; it++) { - devices = 0; - do { - status = - snd_card_get_longname(it, - qsa_playback_device - [qsa_playback_devices].name, - QSA_MAX_NAME_LENGTH); - if (status == EOK) { - snd_pcm_t *handle; - - /* Add device number to device name */ - sprintf(qsa_playback_device[qsa_playback_devices].name + - SDL_strlen(qsa_playback_device - [qsa_playback_devices].name), " d%d", - devices); - - /* Store associated card number id */ - qsa_playback_device[qsa_playback_devices].cardno = it; - - /* Check if this device id could play anything */ - status = - snd_pcm_open(&handle, it, devices, - SND_PCM_OPEN_PLAYBACK); - if (status == EOK) { - qsa_playback_device[qsa_playback_devices].deviceno = - devices; - status = snd_pcm_close(handle); - if (status == EOK) { - SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]); - qsa_playback_devices++; - } - } else { - /* Check if we got end of devices list */ - if (status == -ENOENT) { - break; - } - } - } else { - break; - } - - /* Check if we reached maximum devices count */ - if (qsa_playback_devices >= QSA_MAX_DEVICES) { - break; - } - devices++; - } while (1); - - /* Check if we reached maximum devices count */ - if (qsa_playback_devices >= QSA_MAX_DEVICES) { - break; - } - } - } - - { /* capture devices */ - /* Capture devices enumeration requested */ - for (it = 0; it < cards; it++) { - devices = 0; - do { - status = - snd_card_get_longname(it, - qsa_capture_device - [qsa_capture_devices].name, - QSA_MAX_NAME_LENGTH); - if (status == EOK) { - snd_pcm_t *handle; - - /* Add device number to device name */ - sprintf(qsa_capture_device[qsa_capture_devices].name + - SDL_strlen(qsa_capture_device - [qsa_capture_devices].name), " d%d", - devices); - - /* Store associated card number id */ - qsa_capture_device[qsa_capture_devices].cardno = it; - - /* Check if this device id could play anything */ - status = - snd_pcm_open(&handle, it, devices, - SND_PCM_OPEN_CAPTURE); - if (status == EOK) { - qsa_capture_device[qsa_capture_devices].deviceno = - devices; - status = snd_pcm_close(handle); - if (status == EOK) { - SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]); - qsa_capture_devices++; - } - } else { - /* Check if we got end of devices list */ - if (status == -ENOENT) { - break; - } - } - - /* Check if we reached maximum devices count */ - if (qsa_capture_devices >= QSA_MAX_DEVICES) { - break; - } - } else { - break; - } - devices++; - } while (1); - - /* Check if we reached maximum devices count */ - if (qsa_capture_devices >= QSA_MAX_DEVICES) { - break; - } - } - } -} - -static void -QSA_Deinitialize(void) -{ - /* Clear devices array on shutdown */ - /* !!! FIXME: we zero these on init...any reason to do it here? */ - SDL_zero(qsa_playback_device); - SDL_zero(qsa_capture_device); - qsa_playback_devices = 0; - qsa_capture_devices = 0; -} - -static int -QSA_Init(SDL_AudioDriverImpl * impl) -{ - /* Clear devices array */ - SDL_zero(qsa_playback_device); - SDL_zero(qsa_capture_device); - qsa_playback_devices = 0; - qsa_capture_devices = 0; - - /* Set function pointers */ - /* DeviceLock and DeviceUnlock functions are used default, */ - /* provided by SDL, which uses pthread_mutex for lock/unlock */ - impl->DetectDevices = QSA_DetectDevices; - impl->OpenDevice = QSA_OpenDevice; - impl->ThreadInit = QSA_ThreadInit; - impl->WaitDevice = QSA_WaitDevice; - impl->PlayDevice = QSA_PlayDevice; - impl->GetDeviceBuf = QSA_GetDeviceBuf; - impl->CloseDevice = QSA_CloseDevice; - impl->Deinitialize = QSA_Deinitialize; - impl->LockDevice = NULL; - impl->UnlockDevice = NULL; - - impl->ProvidesOwnCallbackThread = 0; - impl->SkipMixerLock = 0; - impl->HasCaptureSupport = 1; - impl->OnlyHasDefaultOutputDevice = 0; - impl->OnlyHasDefaultCaptureDevice = 0; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap QSAAUDIO_bootstrap = { - "qsa", "QNX QSA Audio", QSA_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_QSA */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.h b/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.h deleted file mode 100644 index a6300c1..0000000 --- a/Source/3rdParty/SDL2/src/audio/qsa/SDL_qsa_audio.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#ifndef __SDL_QSA_AUDIO_H__ -#define __SDL_QSA_AUDIO_H__ - -#include <sys/asoundlib.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice* this - -struct SDL_PrivateAudioData -{ - /* SDL capture state */ - SDL_bool iscapture; - - /* The audio device handle */ - int cardno; - int deviceno; - snd_pcm_t *audio_handle; - - /* The audio file descriptor */ - int audio_fd; - - /* Select timeout status */ - uint32_t timeout_on_wait; - - /* Raw mixing buffer */ - Uint8 *pcm_buf; - Uint32 pcm_len; -}; - -#endif /* __SDL_QSA_AUDIO_H__ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.c b/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.c deleted file mode 100644 index 4a49171..0000000 --- a/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_SNDIO - -/* OpenBSD sndio target */ - -#if HAVE_STDIO_H -#include <stdio.h> -#endif - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif - -#include <poll.h> -#include <unistd.h> - -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_sndioaudio.h" - -#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC -#include "SDL_loadso.h" -#endif - -#ifndef INFTIM -#define INFTIM -1 -#endif - -#ifndef SIO_DEVANY -#define SIO_DEVANY "default" -#endif - -static struct sio_hdl * (*SNDIO_sio_open)(const char *, unsigned int, int); -static void (*SNDIO_sio_close)(struct sio_hdl *); -static int (*SNDIO_sio_setpar)(struct sio_hdl *, struct sio_par *); -static int (*SNDIO_sio_getpar)(struct sio_hdl *, struct sio_par *); -static int (*SNDIO_sio_start)(struct sio_hdl *); -static int (*SNDIO_sio_stop)(struct sio_hdl *); -static size_t (*SNDIO_sio_read)(struct sio_hdl *, void *, size_t); -static size_t (*SNDIO_sio_write)(struct sio_hdl *, const void *, size_t); -static int (*SNDIO_sio_nfds)(struct sio_hdl *); -static int (*SNDIO_sio_pollfd)(struct sio_hdl *, struct pollfd *, int); -static int (*SNDIO_sio_revents)(struct sio_hdl *, struct pollfd *); -static int (*SNDIO_sio_eof)(struct sio_hdl *); -static void (*SNDIO_sio_initpar)(struct sio_par *); - -#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC -static const char *sndio_library = SDL_AUDIO_DRIVER_SNDIO_DYNAMIC; -static void *sndio_handle = NULL; - -static int -load_sndio_sym(const char *fn, void **addr) -{ - *addr = SDL_LoadFunction(sndio_handle, fn); - if (*addr == NULL) { - /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ - return 0; - } - - return 1; -} - -/* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_SNDIO_SYM(x) \ - if (!load_sndio_sym(#x, (void **) (char *) &SNDIO_##x)) return -1 -#else -#define SDL_SNDIO_SYM(x) SNDIO_##x = x -#endif - -static int -load_sndio_syms(void) -{ - SDL_SNDIO_SYM(sio_open); - SDL_SNDIO_SYM(sio_close); - SDL_SNDIO_SYM(sio_setpar); - SDL_SNDIO_SYM(sio_getpar); - SDL_SNDIO_SYM(sio_start); - SDL_SNDIO_SYM(sio_stop); - SDL_SNDIO_SYM(sio_read); - SDL_SNDIO_SYM(sio_write); - SDL_SNDIO_SYM(sio_nfds); - SDL_SNDIO_SYM(sio_pollfd); - SDL_SNDIO_SYM(sio_revents); - SDL_SNDIO_SYM(sio_eof); - SDL_SNDIO_SYM(sio_initpar); - return 0; -} - -#undef SDL_SNDIO_SYM - -#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC - -static void -UnloadSNDIOLibrary(void) -{ - if (sndio_handle != NULL) { - SDL_UnloadObject(sndio_handle); - sndio_handle = NULL; - } -} - -static int -LoadSNDIOLibrary(void) -{ - int retval = 0; - if (sndio_handle == NULL) { - sndio_handle = SDL_LoadObject(sndio_library); - if (sndio_handle == NULL) { - retval = -1; - /* Don't call SDL_SetError(): SDL_LoadObject already did. */ - } else { - retval = load_sndio_syms(); - if (retval < 0) { - UnloadSNDIOLibrary(); - } - } - } - return retval; -} - -#else - -static void -UnloadSNDIOLibrary(void) -{ -} - -static int -LoadSNDIOLibrary(void) -{ - load_sndio_syms(); - return 0; -} - -#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ - - - - -static void -SNDIO_WaitDevice(_THIS) -{ - /* no-op; SNDIO_sio_write() blocks if necessary. */ -} - -static void -SNDIO_PlayDevice(_THIS) -{ - const int written = SNDIO_sio_write(this->hidden->dev, - this->hidden->mixbuf, - this->hidden->mixlen); - - /* If we couldn't write, assume fatal error for now */ - if ( written == 0 ) { - SDL_OpenedAudioDeviceDisconnected(this); - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif -} - -static int -SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - size_t r; - int revents; - int nfds; - - /* Emulate a blocking read */ - r = SNDIO_sio_read(this->hidden->dev, buffer, buflen); - while (r == 0 && !SNDIO_sio_eof(this->hidden->dev)) { - if ((nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN)) <= 0 - || poll(this->hidden->pfd, nfds, INFTIM) < 0) { - return -1; - } - revents = SNDIO_sio_revents(this->hidden->dev, this->hidden->pfd); - if (revents & POLLIN) { - r = SNDIO_sio_read(this->hidden->dev, buffer, buflen); - } - if (revents & POLLHUP) { - break; - } - } - return (int) r; -} - -static void -SNDIO_FlushCapture(_THIS) -{ - char buf[512]; - - while (SNDIO_sio_read(this->hidden->dev, buf, sizeof(buf)) != 0) { - /* do nothing */; - } -} - -static Uint8 * -SNDIO_GetDeviceBuf(_THIS) -{ - return this->hidden->mixbuf; -} - -static void -SNDIO_CloseDevice(_THIS) -{ - if ( this->hidden->pfd != NULL ) { - SDL_free(this->hidden->pfd); - } - if ( this->hidden->dev != NULL ) { - SNDIO_sio_stop(this->hidden->dev); - SNDIO_sio_close(this->hidden->dev); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - struct sio_par par; - int status; - - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - this->hidden->mixlen = this->spec.size; - - /* Capture devices must be non-blocking for SNDIO_FlushCapture */ - if ((this->hidden->dev = - SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY, - iscapture ? SIO_REC : SIO_PLAY, iscapture)) == NULL) { - return SDL_SetError("sio_open() failed"); - } - - /* Allocate the pollfd array for capture devices */ - if (iscapture && (this->hidden->pfd = - SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev))) == NULL) { - return SDL_OutOfMemory(); - } - - SNDIO_sio_initpar(&par); - - par.rate = this->spec.freq; - par.pchan = this->spec.channels; - par.round = this->spec.samples; - par.appbufsz = par.round * 2; - - /* Try for a closest match on audio format */ - status = -1; - while (test_format && (status < 0)) { - if (!SDL_AUDIO_ISFLOAT(test_format)) { - par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0; - par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0; - par.bits = SDL_AUDIO_BITSIZE(test_format); - - if (SNDIO_sio_setpar(this->hidden->dev, &par) == 0) { - continue; - } - if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) { - return SDL_SetError("sio_getpar() failed"); - } - if (par.bps != SIO_BPS(par.bits)) { - continue; - } - if ((par.bits == 8 * par.bps) || (par.msb)) { - status = 0; - break; - } - } - test_format = SDL_NextAudioFormat(); - } - - if (status < 0) { - return SDL_SetError("sndio: Couldn't find any hardware audio formats"); - } - - if ((par.bps == 4) && (par.sig) && (par.le)) - this->spec.format = AUDIO_S32LSB; - else if ((par.bps == 4) && (par.sig) && (!par.le)) - this->spec.format = AUDIO_S32MSB; - else if ((par.bps == 2) && (par.sig) && (par.le)) - this->spec.format = AUDIO_S16LSB; - else if ((par.bps == 2) && (par.sig) && (!par.le)) - this->spec.format = AUDIO_S16MSB; - else if ((par.bps == 2) && (!par.sig) && (par.le)) - this->spec.format = AUDIO_U16LSB; - else if ((par.bps == 2) && (!par.sig) && (!par.le)) - this->spec.format = AUDIO_U16MSB; - else if ((par.bps == 1) && (par.sig)) - this->spec.format = AUDIO_S8; - else if ((par.bps == 1) && (!par.sig)) - this->spec.format = AUDIO_U8; - else { - return SDL_SetError("sndio: Got unsupported hardware audio format."); - } - - this->spec.freq = par.rate; - this->spec.channels = par.pchan; - this->spec.samples = par.round; - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); - - if (!SNDIO_sio_start(this->hidden->dev)) { - return SDL_SetError("sio_start() failed"); - } - - /* We're ready to rock and roll. :-) */ - return 0; -} - -static void -SNDIO_Deinitialize(void) -{ - UnloadSNDIOLibrary(); -} - -static int -SNDIO_Init(SDL_AudioDriverImpl * impl) -{ - if (LoadSNDIOLibrary() < 0) { - return 0; - } - - /* Set the function pointers */ - impl->OpenDevice = SNDIO_OpenDevice; - impl->WaitDevice = SNDIO_WaitDevice; - impl->PlayDevice = SNDIO_PlayDevice; - impl->GetDeviceBuf = SNDIO_GetDeviceBuf; - impl->CloseDevice = SNDIO_CloseDevice; - impl->CaptureFromDevice = SNDIO_CaptureFromDevice; - impl->FlushCapture = SNDIO_FlushCapture; - impl->Deinitialize = SNDIO_Deinitialize; - - impl->AllowsArbitraryDeviceNames = 1; - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap SNDIO_bootstrap = { - "sndio", "OpenBSD sndio", SNDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_SNDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.h b/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.h deleted file mode 100644 index 144bbc2..0000000 --- a/Source/3rdParty/SDL2/src/audio/sndio/SDL_sndioaudio.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_sndioaudio_h_ -#define SDL_sndioaudio_h_ - -#include <poll.h> -#include <sndio.h> - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The audio device handle */ - struct sio_hdl *dev; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Polling structures for non-blocking sndio devices */ - struct pollfd *pfd; -}; - -#endif /* SDL_sndioaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.c b/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.c deleted file mode 100644 index ddf94b3..0000000 --- a/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_SUNAUDIO - -/* Allow access to a raw mixing buffer */ - -#include <fcntl.h> -#include <errno.h> -#ifdef __NETBSD__ -#include <sys/ioctl.h> -#include <sys/audioio.h> -#endif -#ifdef __SVR4 -#include <sys/audioio.h> -#else -#include <sys/time.h> -#include <sys/types.h> -#endif -#include <unistd.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../../core/unix/SDL_poll.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" -#include "SDL_sunaudio.h" - -/* Open the audio device for playback, and don't block if busy */ - -#if defined(AUDIO_GETINFO) && !defined(AUDIO_GETBUFINFO) -#define AUDIO_GETBUFINFO AUDIO_GETINFO -#endif - -/* Audio driver functions */ -static Uint8 snd2au(int sample); - -/* Audio driver bootstrap functions */ -static void -SUNAUDIO_DetectDevices(void) -{ - SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL); -} - -#ifdef DEBUG_AUDIO -void -CheckUnderflow(_THIS) -{ -#ifdef AUDIO_GETBUFINFO - audio_info_t info; - int left; - - ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info); - left = (this->hidden->written - info.play.samples); - if (this->hidden->written && (left == 0)) { - fprintf(stderr, "audio underflow!\n"); - } -#endif -} -#endif - -static void -SUNAUDIO_WaitDevice(_THIS) -{ -#ifdef AUDIO_GETBUFINFO -#define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ - audio_info_t info; - Sint32 left; - - ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info); - left = (this->hidden->written - info.play.samples); - if (left > this->hidden->fragsize) { - Sint32 sleepy; - - sleepy = ((left - this->hidden->fragsize) / this->hidden->frequency); - sleepy -= SLEEP_FUDGE; - if (sleepy > 0) { - SDL_Delay(sleepy); - } - } -#else - SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, -1); -#endif -} - -static void -SUNAUDIO_PlayDevice(_THIS) -{ - /* Write the audio data */ - if (this->hidden->ulaw_only) { - /* Assuming that this->spec.freq >= 8000 Hz */ - int accum, incr, pos; - Uint8 *aubuf; - - accum = 0; - incr = this->spec.freq / 8; - aubuf = this->hidden->ulaw_buf; - switch (this->hidden->audio_fmt & 0xFF) { - case 8: - { - Uint8 *sndbuf; - - sndbuf = this->hidden->mixbuf; - for (pos = 0; pos < this->hidden->fragsize; ++pos) { - *aubuf = snd2au((0x80 - *sndbuf) * 64); - accum += incr; - while (accum > 0) { - accum -= 1000; - sndbuf += 1; - } - aubuf += 1; - } - } - break; - case 16: - { - Sint16 *sndbuf; - - sndbuf = (Sint16 *) this->hidden->mixbuf; - for (pos = 0; pos < this->hidden->fragsize; ++pos) { - *aubuf = snd2au(*sndbuf / 4); - accum += incr; - while (accum > 0) { - accum -= 1000; - sndbuf += 1; - } - aubuf += 1; - } - } - break; - } -#ifdef DEBUG_AUDIO - CheckUnderflow(this); -#endif - if (write(this->hidden->audio_fd, this->hidden->ulaw_buf, - this->hidden->fragsize) < 0) { - /* Assume fatal error, for now */ - SDL_OpenedAudioDeviceDisconnected(this); - } - this->hidden->written += this->hidden->fragsize; - } else { -#ifdef DEBUG_AUDIO - CheckUnderflow(this); -#endif - if (write(this->hidden->audio_fd, this->hidden->mixbuf, - this->spec.size) < 0) { - /* Assume fatal error, for now */ - SDL_OpenedAudioDeviceDisconnected(this); - } - this->hidden->written += this->hidden->fragsize; - } -} - -static Uint8 * -SUNAUDIO_GetDeviceBuf(_THIS) -{ - return (this->hidden->mixbuf); -} - -static void -SUNAUDIO_CloseDevice(_THIS) -{ - SDL_free(this->hidden->ulaw_buf); - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static int -SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ -#ifdef AUDIO_SETINFO - int enc; -#endif - int desired_freq = 0; - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); - SDL_AudioFormat format = 0; - audio_info_t info; - - /* We don't care what the devname is...we'll try to open anything. */ - /* ...but default to first name in the list... */ - if (devname == NULL) { - devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { - return SDL_SetError("No such audio device"); - } - } - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Open the audio device */ - this->hidden->audio_fd = open(devname, flags, 0); - if (this->hidden->audio_fd < 0) { - return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); - } - - desired_freq = this->spec.freq; - - /* Determine the audio parameters from the AudioSpec */ - switch (SDL_AUDIO_BITSIZE(this->spec.format)) { - - case 8: - { /* Unsigned 8 bit audio data */ - this->spec.format = AUDIO_U8; -#ifdef AUDIO_SETINFO - enc = AUDIO_ENCODING_LINEAR8; -#endif - } - break; - - case 16: - { /* Signed 16 bit audio data */ - this->spec.format = AUDIO_S16SYS; -#ifdef AUDIO_SETINFO - enc = AUDIO_ENCODING_LINEAR; -#endif - } - break; - - default: - { - /* !!! FIXME: fallback to conversion on unsupported types! */ - return SDL_SetError("Unsupported audio format"); - } - } - this->hidden->audio_fmt = this->spec.format; - - this->hidden->ulaw_only = 0; /* modern Suns do support linear audio */ -#ifdef AUDIO_SETINFO - for (;;) { - audio_info_t info; - AUDIO_INITINFO(&info); /* init all fields to "no change" */ - - /* Try to set the requested settings */ - info.play.sample_rate = this->spec.freq; - info.play.channels = this->spec.channels; - info.play.precision = (enc == AUDIO_ENCODING_ULAW) - ? 8 : this->spec.format & 0xff; - info.play.encoding = enc; - if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) { - - /* Check to be sure we got what we wanted */ - if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - return SDL_SetError("Error getting audio parameters: %s", - strerror(errno)); - } - if (info.play.encoding == enc - && info.play.precision == (this->spec.format & 0xff) - && info.play.channels == this->spec.channels) { - /* Yow! All seems to be well! */ - this->spec.freq = info.play.sample_rate; - break; - } - } - - switch (enc) { - case AUDIO_ENCODING_LINEAR8: - /* unsigned 8bit apparently not supported here */ - enc = AUDIO_ENCODING_LINEAR; - this->spec.format = AUDIO_S16SYS; - break; /* try again */ - - case AUDIO_ENCODING_LINEAR: - /* linear 16bit didn't work either, resort to -law */ - enc = AUDIO_ENCODING_ULAW; - this->spec.channels = 1; - this->spec.freq = 8000; - this->spec.format = AUDIO_U8; - this->hidden->ulaw_only = 1; - break; - - default: - /* oh well... */ - return SDL_SetError("Error setting audio parameters: %s", - strerror(errno)); - } - } -#endif /* AUDIO_SETINFO */ - this->hidden->written = 0; - - /* We can actually convert on-the-fly to U-Law */ - if (this->hidden->ulaw_only) { - this->spec.freq = desired_freq; - this->hidden->fragsize = (this->spec.samples * 1000) / - (this->spec.freq / 8); - this->hidden->frequency = 8; - this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize); - if (this->hidden->ulaw_buf == NULL) { - return SDL_OutOfMemory(); - } - this->spec.channels = 1; - } else { - this->hidden->fragsize = this->spec.samples; - this->hidden->frequency = this->spec.freq / 1000; - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Audio device %s U-Law only\n", - this->hidden->ulaw_only ? "is" : "is not"); - fprintf(stderr, "format=0x%x chan=%d freq=%d\n", - this->spec.format, this->spec.channels, this->spec.freq); -#endif - - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate mixing buffer */ - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); - - /* We're ready to rock and roll. :-) */ - return 0; -} - -/************************************************************************/ -/* This function (snd2au()) copyrighted: */ -/************************************************************************/ -/* Copyright 1989 by Rich Gopstein and Harris Corporation */ -/* */ -/* Permission to use, copy, modify, and distribute this software */ -/* and its documentation for any purpose and without fee is */ -/* hereby granted, provided that the above copyright notice */ -/* appears in all copies and that both that copyright notice and */ -/* this permission notice appear in supporting documentation, and */ -/* that the name of Rich Gopstein and Harris Corporation not be */ -/* used in advertising or publicity pertaining to distribution */ -/* of the software without specific, written prior permission. */ -/* Rich Gopstein and Harris Corporation make no representations */ -/* about the suitability of this software for any purpose. It */ -/* provided "as is" without express or implied warranty. */ -/************************************************************************/ - -static Uint8 -snd2au(int sample) -{ - - int mask; - - if (sample < 0) { - sample = -sample; - mask = 0x7f; - } else { - mask = 0xff; - } - - if (sample < 32) { - sample = 0xF0 | (15 - sample / 2); - } else if (sample < 96) { - sample = 0xE0 | (15 - (sample - 32) / 4); - } else if (sample < 224) { - sample = 0xD0 | (15 - (sample - 96) / 8); - } else if (sample < 480) { - sample = 0xC0 | (15 - (sample - 224) / 16); - } else if (sample < 992) { - sample = 0xB0 | (15 - (sample - 480) / 32); - } else if (sample < 2016) { - sample = 0xA0 | (15 - (sample - 992) / 64); - } else if (sample < 4064) { - sample = 0x90 | (15 - (sample - 2016) / 128); - } else if (sample < 8160) { - sample = 0x80 | (15 - (sample - 4064) / 256); - } else { - sample = 0x80; - } - return (mask & sample); -} - -static int -SUNAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->DetectDevices = SUNAUDIO_DetectDevices; - impl->OpenDevice = SUNAUDIO_OpenDevice; - impl->PlayDevice = SUNAUDIO_PlayDevice; - impl->WaitDevice = SUNAUDIO_WaitDevice; - impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf; - impl->CloseDevice = SUNAUDIO_CloseDevice; - - impl->AllowsArbitraryDeviceNames = 1; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap SUNAUDIO_bootstrap = { - "audio", "UNIX /dev/audio interface", SUNAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_SUNAUDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.h b/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.h deleted file mode 100644 index 2b7d57b..0000000 --- a/Source/3rdParty/SDL2/src/audio/sun/SDL_sunaudio.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_sunaudio_h_ -#define SDL_sunaudio_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - SDL_AudioFormat audio_fmt; /* The app audio format */ - Uint8 *mixbuf; /* The app mixing buffer */ - int ulaw_only; /* Flag -- does hardware only output U-law? */ - Uint8 *ulaw_buf; /* The U-law mixing buffer */ - Sint32 written; /* The number of samples written */ - int fragsize; /* The audio fragment size in samples */ - int frequency; /* The audio frequency in KHz */ -}; - -#endif /* SDL_sunaudio_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.c b/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.c deleted file mode 100644 index f517539..0000000 --- a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_WASAPI - -#include "../../core/windows/SDL_windows.h" -#include "SDL_audio.h" -#include "SDL_timer.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_assert.h" -#include "SDL_log.h" - -#define COBJMACROS -#include <mmdeviceapi.h> -#include <audioclient.h> - -#include "SDL_wasapi.h" - -/* This constant isn't available on MinGW-w64 */ -#ifndef AUDCLNT_STREAMFLAGS_RATEADJUST -#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000 -#endif - -/* these increment as default devices change. Opened default devices pick up changes in their threads. */ -SDL_atomic_t WASAPI_DefaultPlaybackGeneration; -SDL_atomic_t WASAPI_DefaultCaptureGeneration; - -/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ -typedef struct DevIdList -{ - WCHAR *str; - struct DevIdList *next; -} DevIdList; - -static DevIdList *deviceid_list = NULL; - -/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ -static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,{ 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } }; -static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } }; -static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; -static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; - -static SDL_bool -WStrEqual(const WCHAR *a, const WCHAR *b) -{ - while (*a) { - if (*a != *b) { - return SDL_FALSE; - } - a++; - b++; - } - return *b == 0; -} - -static size_t -WStrLen(const WCHAR *wstr) -{ - size_t retval = 0; - if (wstr) { - while (*(wstr++)) { - retval++; - } - } - return retval; -} - -static WCHAR * -WStrDupe(const WCHAR *wstr) -{ - const size_t len = (WStrLen(wstr) + 1) * sizeof (WCHAR); - WCHAR *retval = (WCHAR *) SDL_malloc(len); - if (retval) { - SDL_memcpy(retval, wstr, len); - } - return retval; -} - - -void -WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid) -{ - DevIdList *i; - DevIdList *next; - DevIdList *prev = NULL; - for (i = deviceid_list; i; i = next) { - next = i->next; - if (WStrEqual(i->str, devid)) { - if (prev) { - prev->next = next; - } else { - deviceid_list = next; - } - SDL_RemoveAudioDevice(iscapture, i->str); - SDL_free(i->str); - SDL_free(i); - } - prev = i; - } -} - -void -WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid) -{ - DevIdList *devidlist; - - /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever). - In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for - phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be - available and switch automatically. (!!! FIXME...?) */ - - /* see if we already have this one. */ - for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) { - if (WStrEqual(devidlist->str, devid)) { - return; /* we already have this. */ - } - } - - devidlist = (DevIdList *) SDL_malloc(sizeof (*devidlist)); - if (!devidlist) { - return; /* oh well. */ - } - - devid = WStrDupe(devid); - if (!devid) { - SDL_free(devidlist); - return; /* oh well. */ - } - - devidlist->str = (WCHAR *) devid; - devidlist->next = deviceid_list; - deviceid_list = devidlist; - - SDL_AddAudioDevice(iscapture, devname, (void *) devid); -} - -static void -WASAPI_DetectDevices(void) -{ - WASAPI_EnumerateEndpoints(); -} - -static int -WASAPI_GetPendingBytes(_THIS) -{ - UINT32 frames = 0; - - /* it's okay to fail here; we'll deal with failures in the audio thread. */ - /* FIXME: need a lock around checking this->hidden->client */ - if (this->hidden->client != NULL) { /* definitely activated? */ - if (FAILED(IAudioClient_GetCurrentPadding(this->hidden->client, &frames))) { - return 0; /* oh well. */ - } - } - return ((int) frames) * this->hidden->framesize; -} - -static SDL_INLINE SDL_bool -WasapiFailed(_THIS, const HRESULT err) -{ - if (err == S_OK) { - return SDL_FALSE; - } - - if (err == AUDCLNT_E_DEVICE_INVALIDATED) { - this->hidden->device_lost = SDL_TRUE; - } else if (SDL_AtomicGet(&this->enabled)) { - IAudioClient_Stop(this->hidden->client); - SDL_OpenedAudioDeviceDisconnected(this); - SDL_assert(!SDL_AtomicGet(&this->enabled)); - } - - return SDL_TRUE; -} - -static int -UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec) -{ - /* Since WASAPI requires us to handle all audio conversion, and our - device format might have changed, we might have to add/remove/change - the audio stream that the higher level uses to convert data, so - SDL keeps firing the callback as if nothing happened here. */ - - if ( (this->callbackspec.channels == this->spec.channels) && - (this->callbackspec.format == this->spec.format) && - (this->callbackspec.freq == this->spec.freq) && - (this->callbackspec.samples == this->spec.samples) ) { - /* no need to buffer/convert in an AudioStream! */ - SDL_FreeAudioStream(this->stream); - this->stream = NULL; - } else if ( (oldspec->channels == this->spec.channels) && - (oldspec->format == this->spec.format) && - (oldspec->freq == this->spec.freq) ) { - /* The existing audio stream is okay to keep using. */ - } else { - /* replace the audiostream for new format */ - SDL_FreeAudioStream(this->stream); - if (this->iscapture) { - this->stream = SDL_NewAudioStream(this->spec.format, - this->spec.channels, this->spec.freq, - this->callbackspec.format, - this->callbackspec.channels, - this->callbackspec.freq); - } else { - this->stream = SDL_NewAudioStream(this->callbackspec.format, - this->callbackspec.channels, - this->callbackspec.freq, this->spec.format, - this->spec.channels, this->spec.freq); - } - - if (!this->stream) { - return -1; - } - } - - /* make sure our scratch buffer can cover the new device spec. */ - if (this->spec.size > this->work_buffer_len) { - Uint8 *ptr = (Uint8 *) SDL_realloc(this->work_buffer, this->spec.size); - if (ptr == NULL) { - return SDL_OutOfMemory(); - } - this->work_buffer = ptr; - this->work_buffer_len = this->spec.size; - } - - return 0; -} - - -static void ReleaseWasapiDevice(_THIS); - -static SDL_bool -RecoverWasapiDevice(_THIS) -{ - ReleaseWasapiDevice(this); /* dump the lost device's handles. */ - - if (this->hidden->default_device_generation) { - this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); - } - - /* this can fail for lots of reasons, but the most likely is we had a - non-default device that was disconnected, so we can't recover. Default - devices try to reinitialize whatever the new default is, so it's more - likely to carry on here, but this handles a non-default device that - simply had its format changed in the Windows Control Panel. */ - if (WASAPI_ActivateDevice(this, SDL_TRUE) == -1) { - SDL_OpenedAudioDeviceDisconnected(this); - return SDL_FALSE; - } - - this->hidden->device_lost = SDL_FALSE; - - return SDL_TRUE; /* okay, carry on with new device details! */ -} - -static SDL_bool -RecoverWasapiIfLost(_THIS) -{ - const int generation = this->hidden->default_device_generation; - SDL_bool lost = this->hidden->device_lost; - - if (!SDL_AtomicGet(&this->enabled)) { - return SDL_FALSE; /* already failed. */ - } - - if (!this->hidden->client) { - return SDL_TRUE; /* still waiting for activation. */ - } - - if (!lost && (generation > 0)) { /* is a default device? */ - const int newgen = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); - if (generation != newgen) { /* the desired default device was changed, jump over to it. */ - lost = SDL_TRUE; - } - } - - return lost ? RecoverWasapiDevice(this) : SDL_TRUE; -} - -static Uint8 * -WASAPI_GetDeviceBuf(_THIS) -{ - /* get an endpoint buffer from WASAPI. */ - BYTE *buffer = NULL; - - while (RecoverWasapiIfLost(this) && this->hidden->render) { - if (!WasapiFailed(this, IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer))) { - return (Uint8 *) buffer; - } - SDL_assert(buffer == NULL); - } - - return (Uint8 *) buffer; -} - -static void -WASAPI_PlayDevice(_THIS) -{ - if (this->hidden->render != NULL) { /* definitely activated? */ - /* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */ - WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0)); - } -} - -static void -WASAPI_WaitDevice(_THIS) -{ - while (RecoverWasapiIfLost(this) && this->hidden->client && this->hidden->event) { - /*SDL_Log("WAITDEVICE");*/ - if (WaitForSingleObjectEx(this->hidden->event, INFINITE, FALSE) == WAIT_OBJECT_0) { - const UINT32 maxpadding = this->spec.samples; - UINT32 padding = 0; - if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) { - /*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/ - if (padding <= maxpadding) { - break; - } - } - } else { - /*SDL_Log("WASAPI FAILED EVENT!");*/ - IAudioClient_Stop(this->hidden->client); - SDL_OpenedAudioDeviceDisconnected(this); - } - } -} - -static int -WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - SDL_AudioStream *stream = this->hidden->capturestream; - const int avail = SDL_AudioStreamAvailable(stream); - if (avail > 0) { - const int cpy = SDL_min(buflen, avail); - SDL_AudioStreamGet(stream, buffer, cpy); - return cpy; - } - - while (RecoverWasapiIfLost(this)) { - HRESULT ret; - BYTE *ptr = NULL; - UINT32 frames = 0; - DWORD flags = 0; - - /* uhoh, client isn't activated yet, just return silence. */ - if (!this->hidden->capture) { - /* Delay so we run at about the speed that audio would be arriving. */ - SDL_Delay(((this->spec.samples * 1000) / this->spec.freq)); - SDL_memset(buffer, this->spec.silence, buflen); - return buflen; - } - - ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL); - if (ret != AUDCLNT_S_BUFFER_EMPTY) { - WasapiFailed(this, ret); /* mark device lost/failed if necessary. */ - } - - if ((ret == AUDCLNT_S_BUFFER_EMPTY) || !frames) { - WASAPI_WaitDevice(this); - } else if (ret == S_OK) { - const int total = ((int) frames) * this->hidden->framesize; - const int cpy = SDL_min(buflen, total); - const int leftover = total - cpy; - const SDL_bool silent = (flags & AUDCLNT_BUFFERFLAGS_SILENT) ? SDL_TRUE : SDL_FALSE; - - if (silent) { - SDL_memset(buffer, this->spec.silence, cpy); - } else { - SDL_memcpy(buffer, ptr, cpy); - } - - if (leftover > 0) { - ptr += cpy; - if (silent) { - SDL_memset(ptr, this->spec.silence, leftover); /* I guess this is safe? */ - } - - if (SDL_AudioStreamPut(stream, ptr, leftover) == -1) { - return -1; /* uhoh, out of memory, etc. Kill device. :( */ - } - } - - ret = IAudioCaptureClient_ReleaseBuffer(this->hidden->capture, frames); - WasapiFailed(this, ret); /* mark device lost/failed if necessary. */ - - return cpy; - } - } - - return -1; /* unrecoverable error. */ -} - -static void -WASAPI_FlushCapture(_THIS) -{ - BYTE *ptr = NULL; - UINT32 frames = 0; - DWORD flags = 0; - - if (!this->hidden->capture) { - return; /* not activated yet? */ - } - - /* just read until we stop getting packets, throwing them away. */ - while (SDL_TRUE) { - const HRESULT ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL); - if (ret == AUDCLNT_S_BUFFER_EMPTY) { - break; /* no more buffered data; we're done. */ - } else if (WasapiFailed(this, ret)) { - break; /* failed for some other reason, abort. */ - } else if (WasapiFailed(this, IAudioCaptureClient_ReleaseBuffer(this->hidden->capture, frames))) { - break; /* something broke. */ - } - } - SDL_AudioStreamClear(this->hidden->capturestream); -} - -static void -ReleaseWasapiDevice(_THIS) -{ - if (this->hidden->client) { - IAudioClient_Stop(this->hidden->client); - IAudioClient_SetEventHandle(this->hidden->client, NULL); - IAudioClient_Release(this->hidden->client); - this->hidden->client = NULL; - } - - if (this->hidden->render) { - IAudioRenderClient_Release(this->hidden->render); - this->hidden->render = NULL; - } - - if (this->hidden->capture) { - IAudioCaptureClient_Release(this->hidden->capture); - this->hidden->capture = NULL; - } - - if (this->hidden->waveformat) { - CoTaskMemFree(this->hidden->waveformat); - this->hidden->waveformat = NULL; - } - - if (this->hidden->capturestream) { - SDL_FreeAudioStream(this->hidden->capturestream); - this->hidden->capturestream = NULL; - } - - if (this->hidden->activation_handler) { - WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler); - this->hidden->activation_handler = NULL; - } - - if (this->hidden->event) { - CloseHandle(this->hidden->event); - this->hidden->event = NULL; - } -} - -static void -WASAPI_CloseDevice(_THIS) -{ - WASAPI_UnrefDevice(this); -} - -void -WASAPI_RefDevice(_THIS) -{ - SDL_AtomicIncRef(&this->hidden->refcount); -} - -void -WASAPI_UnrefDevice(_THIS) -{ - if (!SDL_AtomicDecRef(&this->hidden->refcount)) { - return; - } - - /* actual closing happens here. */ - - /* don't touch this->hidden->task in here; it has to be reverted from - our callback thread. We do that in WASAPI_ThreadDeinit(). - (likewise for this->hidden->coinitialized). */ - ReleaseWasapiDevice(this); - SDL_free(this->hidden->devid); - SDL_free(this->hidden); -} - -/* This is called once a device is activated, possibly asynchronously. */ -int -WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) -{ - /* !!! FIXME: we could request an exclusive mode stream, which is lower latency; - !!! it will write into the kernel's audio buffer directly instead of - !!! shared memory that a user-mode mixer then writes to the kernel with - !!! everything else. Doing this means any other sound using this device will - !!! stop playing, including the user's MP3 player and system notification - !!! sounds. You'd probably need to release the device when the app isn't in - !!! the foreground, to be a good citizen of the system. It's doable, but it's - !!! more work and causes some annoyances, and I don't know what the latency - !!! wins actually look like. Maybe add a hint to force exclusive mode at - !!! some point. To be sure, defaulting to shared mode is the right thing to - !!! do in any case. */ - const SDL_AudioSpec oldspec = this->spec; - const AUDCLNT_SHAREMODE sharemode = AUDCLNT_SHAREMODE_SHARED; - UINT32 bufsize = 0; /* this is in sample frames, not samples, not bytes. */ - REFERENCE_TIME duration = 0; - IAudioClient *client = this->hidden->client; - IAudioRenderClient *render = NULL; - IAudioCaptureClient *capture = NULL; - WAVEFORMATEX *waveformat = NULL; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - SDL_AudioFormat wasapi_format = 0; - SDL_bool valid_format = SDL_FALSE; - HRESULT ret = S_OK; - DWORD streamflags = 0; - - SDL_assert(client != NULL); - -#ifdef __WINRT__ /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */ - this->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS); -#else - this->hidden->event = CreateEventW(NULL, 0, 0, NULL); -#endif - - if (this->hidden->event == NULL) { - return WIN_SetError("WASAPI can't create an event handle"); - } - - ret = IAudioClient_GetMixFormat(client, &waveformat); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't determine mix format", ret); - } - - SDL_assert(waveformat != NULL); - this->hidden->waveformat = waveformat; - - this->spec.channels = (Uint8) waveformat->nChannels; - - /* Make sure we have a valid format that we can convert to whatever WASAPI wants. */ - if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_F32SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { - wasapi_format = AUDIO_S16SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_S32SYS; - } else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *) waveformat; - if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_F32SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { - wasapi_format = AUDIO_S16SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_S32SYS; - } - } - - while ((!valid_format) && (test_format)) { - if (test_format == wasapi_format) { - this->spec.format = test_format; - valid_format = SDL_TRUE; - break; - } - test_format = SDL_NextAudioFormat(); - } - - if (!valid_format) { - return SDL_SetError("WASAPI: Unsupported audio format"); - } - - ret = IAudioClient_GetDevicePeriod(client, NULL, &duration); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret); - } - - /* favor WASAPI's resampler over our own, in Win7+. */ - if (this->spec.freq != waveformat->nSamplesPerSec) { - /* RATEADJUST only works with output devices in share mode, and is available in Win7 and later.*/ - if (WIN_IsWindows7OrGreater() && !this->iscapture && (sharemode == AUDCLNT_SHAREMODE_SHARED)) { - streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST; - waveformat->nSamplesPerSec = this->spec.freq; - waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); - } - else { - this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in. */ - } - } - - streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK; - ret = IAudioClient_Initialize(client, sharemode, streamflags, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret); - } - - ret = IAudioClient_SetEventHandle(client, this->hidden->event); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't set event handle", ret); - } - - ret = IAudioClient_GetBufferSize(client, &bufsize); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret); - } - - this->spec.samples = (Uint16) bufsize; - if (!this->iscapture) { - this->spec.samples /= 2; /* fill half of the DMA buffer on each run. */ - } - - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&this->spec); - - this->hidden->framesize = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels; - - if (this->iscapture) { - this->hidden->capturestream = SDL_NewAudioStream(this->spec.format, this->spec.channels, this->spec.freq, this->spec.format, this->spec.channels, this->spec.freq); - if (!this->hidden->capturestream) { - return -1; /* already set SDL_Error */ - } - - ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void**) &capture); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't get capture client service", ret); - } - - SDL_assert(capture != NULL); - this->hidden->capture = capture; - ret = IAudioClient_Start(client); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't start capture", ret); - } - - WASAPI_FlushCapture(this); /* MSDN says you should flush capture endpoint right after startup. */ - } else { - ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void**) &render); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't get render client service", ret); - } - - SDL_assert(render != NULL); - this->hidden->render = render; - ret = IAudioClient_Start(client); - if (FAILED(ret)) { - return WIN_SetErrorFromHRESULT("WASAPI can't start playback", ret); - } - } - - if (updatestream) { - if (UpdateAudioStream(this, &oldspec) == -1) { - return -1; - } - } - - return 0; /* good to go. */ -} - - -static int -WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - LPCWSTR devid = (LPCWSTR) handle; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */ - - if (!devid) { /* is default device? */ - this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); - } else { - this->hidden->devid = WStrDupe(devid); - if (!this->hidden->devid) { - return SDL_OutOfMemory(); - } - } - - if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) { - return -1; /* already set error. */ - } - - /* Ready, but waiting for async device activation. - Until activation is successful, we will report silence from capture - devices and ignore data on playback devices. - Also, since we don't know the _actual_ device format until after - activation, we let the app have whatever it asks for. We set up - an SDL_AudioStream to convert, if necessary, once the activation - completes. */ - - return 0; -} - -static void -WASAPI_ThreadInit(_THIS) -{ - WASAPI_PlatformThreadInit(this); -} - -static void -WASAPI_ThreadDeinit(_THIS) -{ - WASAPI_PlatformThreadDeinit(this); -} - -void -WASAPI_BeginLoopIteration(_THIS) -{ - /* no-op. */ -} - -static void -WASAPI_Deinitialize(void) -{ - DevIdList *devidlist; - DevIdList *next; - - WASAPI_PlatformDeinit(); - - for (devidlist = deviceid_list; devidlist; devidlist = next) { - next = devidlist->next; - SDL_free(devidlist->str); - SDL_free(devidlist); - } - deviceid_list = NULL; -} - -static int -WASAPI_Init(SDL_AudioDriverImpl * impl) -{ - SDL_AtomicSet(&WASAPI_DefaultPlaybackGeneration, 1); - SDL_AtomicSet(&WASAPI_DefaultCaptureGeneration, 1); - - if (WASAPI_PlatformInit() == -1) { - return 0; - } - - /* Set the function pointers */ - impl->DetectDevices = WASAPI_DetectDevices; - impl->ThreadInit = WASAPI_ThreadInit; - impl->ThreadDeinit = WASAPI_ThreadDeinit; - impl->BeginLoopIteration = WASAPI_BeginLoopIteration; - impl->OpenDevice = WASAPI_OpenDevice; - impl->PlayDevice = WASAPI_PlayDevice; - impl->WaitDevice = WASAPI_WaitDevice; - impl->GetPendingBytes = WASAPI_GetPendingBytes; - impl->GetDeviceBuf = WASAPI_GetDeviceBuf; - impl->CaptureFromDevice = WASAPI_CaptureFromDevice; - impl->FlushCapture = WASAPI_FlushCapture; - impl->CloseDevice = WASAPI_CloseDevice; - impl->Deinitialize = WASAPI_Deinitialize; - impl->HasCaptureSupport = 1; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap WASAPI_bootstrap = { - "wasapi", "WASAPI", WASAPI_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_WASAPI */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.h b/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.h deleted file mode 100644 index 142c0e5..0000000 --- a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_wasapi_h_ -#define SDL_wasapi_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#ifdef __cplusplus -#define _THIS SDL_AudioDevice *_this -#else -#define _THIS SDL_AudioDevice *this -#endif - -struct SDL_PrivateAudioData -{ - SDL_atomic_t refcount; - WCHAR *devid; - WAVEFORMATEX *waveformat; - IAudioClient *client; - IAudioRenderClient *render; - IAudioCaptureClient *capture; - SDL_AudioStream *capturestream; - HANDLE event; - HANDLE task; - SDL_bool coinitialized; - int framesize; - int default_device_generation; - SDL_bool device_lost; - void *activation_handler; - SDL_atomic_t just_activated; -}; - -/* these increment as default devices change. Opened default devices pick up changes in their threads. */ -extern SDL_atomic_t WASAPI_DefaultPlaybackGeneration; -extern SDL_atomic_t WASAPI_DefaultCaptureGeneration; - -/* win32 and winrt implementations call into these. */ -int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream); -void WASAPI_RefDevice(_THIS); -void WASAPI_UnrefDevice(_THIS); -void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid); -void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid); - -/* These are functions that are implemented differently for Windows vs WinRT. */ -int WASAPI_PlatformInit(void); -void WASAPI_PlatformDeinit(void); -void WASAPI_EnumerateEndpoints(void); -int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery); -void WASAPI_PlatformThreadInit(_THIS); -void WASAPI_PlatformThreadDeinit(_THIS); -void WASAPI_PlatformDeleteActivationHandler(void *handler); -void WASAPI_BeginLoopIteration(_THIS); - -#ifdef __cplusplus -} -#endif - -#endif /* SDL_wasapi_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_win32.c b/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_win32.c deleted file mode 100644 index 9d7c159..0000000 --- a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_win32.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -/* This is code that Windows uses to talk to WASAPI-related system APIs. - This is for non-WinRT desktop apps. The C++/CX implementation of these - functions, exclusive to WinRT, are in SDL_wasapi_winrt.cpp. - The code in SDL_wasapi.c is used by both standard Windows and WinRT builds - to deal with audio and calls into these functions. */ - -#if SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) - -#include "../../core/windows/SDL_windows.h" -#include "SDL_audio.h" -#include "SDL_timer.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_assert.h" -#include "SDL_log.h" - -#define COBJMACROS -#include <mmdeviceapi.h> -#include <audioclient.h> - -#include "SDL_wasapi.h" - -static const ERole SDL_WASAPI_role = eConsole; /* !!! FIXME: should this be eMultimedia? Should be a hint? */ - -/* This is global to the WASAPI target, to handle hotplug and default device lookup. */ -static IMMDeviceEnumerator *enumerator = NULL; - -/* PropVariantInit() is an inline function/macro in PropIdl.h that calls the C runtime's memset() directly. Use ours instead, to avoid dependency. */ -#ifdef PropVariantInit -#undef PropVariantInit -#endif -#define PropVariantInit(p) SDL_zerop(p) - -/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */ -static HMODULE libavrt = NULL; -typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPWSTR, LPDWORD); -typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE); -static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL; -static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL; - -/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ -static const CLSID SDL_CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c,{ 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e } }; -static const IID SDL_IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35,{ 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6 } }; -static const IID SDL_IID_IMMNotificationClient = { 0x7991eec9, 0x7e89, 0x4d85,{ 0x83, 0x90, 0x6c, 0x70, 0x3c, 0xec, 0x60, 0xc0 } }; -static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,{ 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 } }; -static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,{ 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } }; -static const PROPERTYKEY SDL_PKEY_Device_FriendlyName = { { 0xa45c254e, 0xdf1c, 0x4efd,{ 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, } }, 14 }; - - -static char * -GetWasapiDeviceName(IMMDevice *device) -{ - /* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be - "SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in - its own UIs, like Volume Control, etc. */ - char *utf8dev = NULL; - IPropertyStore *props = NULL; - if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) { - PROPVARIANT var; - PropVariantInit(&var); - if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) { - utf8dev = WIN_StringToUTF8(var.pwszVal); - } - PropVariantClear(&var); - IPropertyStore_Release(props); - } - return utf8dev; -} - - -/* We need a COM subclass of IMMNotificationClient for hotplug support, which is - easy in C++, but we have to tapdance more to make work in C. - Thanks to this page for coaching on how to make this work: - https://www.codeproject.com/Articles/13601/COM-in-plain-C */ - -typedef struct SDLMMNotificationClient -{ - const IMMNotificationClientVtbl *lpVtbl; - SDL_atomic_t refcount; -} SDLMMNotificationClient; - -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_QueryInterface(IMMNotificationClient *this, REFIID iid, void **ppv) -{ - if ((WIN_IsEqualIID(iid, &IID_IUnknown)) || (WIN_IsEqualIID(iid, &SDL_IID_IMMNotificationClient))) - { - *ppv = this; - this->lpVtbl->AddRef(this); - return S_OK; - } - - *ppv = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE -SDLMMNotificationClient_AddRef(IMMNotificationClient *ithis) -{ - SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis; - return (ULONG) (SDL_AtomicIncRef(&this->refcount) + 1); -} - -static ULONG STDMETHODCALLTYPE -SDLMMNotificationClient_Release(IMMNotificationClient *ithis) -{ - /* this is a static object; we don't ever free it. */ - SDLMMNotificationClient *this = (SDLMMNotificationClient *) ithis; - const ULONG retval = SDL_AtomicDecRef(&this->refcount); - if (retval == 0) { - SDL_AtomicSet(&this->refcount, 0); /* uhh... */ - return 0; - } - return retval - 1; -} - -/* These are the entry points called when WASAPI device endpoints change. */ -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_OnDefaultDeviceChanged(IMMNotificationClient *ithis, EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) -{ - if (role != SDL_WASAPI_role) { - return S_OK; /* ignore it. */ - } - - /* Increment the "generation," so opened devices will pick this up in their threads. */ - switch (flow) { - case eRender: - SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1); - break; - - case eCapture: - SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1); - break; - - case eAll: - SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1); - SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1); - break; - - default: - SDL_assert(!"uhoh, unexpected OnDefaultDeviceChange flow!"); - break; - } - - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_OnDeviceAdded(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId) -{ - /* we ignore this; devices added here then progress to ACTIVE, if appropriate, in - OnDeviceStateChange, making that a better place to deal with device adds. More - importantly: the first time you plug in a USB audio device, this callback will - fire, but when you unplug it, it isn't removed (it's state changes to NOTPRESENT). - Plugging it back in won't fire this callback again. */ - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId) -{ - /* See notes in OnDeviceAdded handler about why we ignore this. */ - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId, DWORD dwNewState) -{ - IMMDevice *device = NULL; - - if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) { - IMMEndpoint *endpoint = NULL; - if (SUCCEEDED(IMMDevice_QueryInterface(device, &SDL_IID_IMMEndpoint, (void **) &endpoint))) { - EDataFlow flow; - if (SUCCEEDED(IMMEndpoint_GetDataFlow(endpoint, &flow))) { - const SDL_bool iscapture = (flow == eCapture); - if (dwNewState == DEVICE_STATE_ACTIVE) { - char *utf8dev = GetWasapiDeviceName(device); - if (utf8dev) { - WASAPI_AddDevice(iscapture, utf8dev, pwstrDeviceId); - SDL_free(utf8dev); - } - } else { - WASAPI_RemoveDevice(iscapture, pwstrDeviceId); - } - } - IMMEndpoint_Release(endpoint); - } - IMMDevice_Release(device); - } - - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE -SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *this, LPCWSTR pwstrDeviceId, const PROPERTYKEY key) -{ - return S_OK; /* we don't care about these. */ -} - -static const IMMNotificationClientVtbl notification_client_vtbl = { - SDLMMNotificationClient_QueryInterface, - SDLMMNotificationClient_AddRef, - SDLMMNotificationClient_Release, - SDLMMNotificationClient_OnDeviceStateChanged, - SDLMMNotificationClient_OnDeviceAdded, - SDLMMNotificationClient_OnDeviceRemoved, - SDLMMNotificationClient_OnDefaultDeviceChanged, - SDLMMNotificationClient_OnPropertyValueChanged -}; - -static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 } }; - - -int -WASAPI_PlatformInit(void) -{ - HRESULT ret; - - /* just skip the discussion with COM here. */ - if (!WIN_IsWindowsVistaOrGreater()) { - return SDL_SetError("WASAPI support requires Windows Vista or later"); - } - - if (FAILED(WIN_CoInitialize())) { - return SDL_SetError("WASAPI: CoInitialize() failed"); - } - - ret = CoCreateInstance(&SDL_CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_IMMDeviceEnumerator, (LPVOID) &enumerator); - if (FAILED(ret)) { - WIN_CoUninitialize(); - return WIN_SetErrorFromHRESULT("WASAPI CoCreateInstance(MMDeviceEnumerator)", ret); - } - - libavrt = LoadLibraryW(L"avrt.dll"); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */ - if (libavrt) { - pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW"); - pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics"); - } - - return 0; -} - -void -WASAPI_PlatformDeinit(void) -{ - if (enumerator) { - IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) ¬ification_client); - IMMDeviceEnumerator_Release(enumerator); - enumerator = NULL; - } - - if (libavrt) { - FreeLibrary(libavrt); - libavrt = NULL; - } - - pAvSetMmThreadCharacteristicsW = NULL; - pAvRevertMmThreadCharacteristics = NULL; - - WIN_CoUninitialize(); -} - -void -WASAPI_PlatformThreadInit(_THIS) -{ - /* this thread uses COM. */ - if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */ - this->hidden->coinitialized = SDL_TRUE; - } - - /* Set this thread to very high "Pro Audio" priority. */ - if (pAvSetMmThreadCharacteristicsW) { - DWORD idx = 0; - this->hidden->task = pAvSetMmThreadCharacteristicsW(TEXT("Pro Audio"), &idx); - } -} - -void -WASAPI_PlatformThreadDeinit(_THIS) -{ - /* Set this thread back to normal priority. */ - if (this->hidden->task && pAvRevertMmThreadCharacteristics) { - pAvRevertMmThreadCharacteristics(this->hidden->task); - this->hidden->task = NULL; - } - - if (this->hidden->coinitialized) { - WIN_CoUninitialize(); - this->hidden->coinitialized = SDL_FALSE; - } -} - -int -WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery) -{ - LPCWSTR devid = this->hidden->devid; - IMMDevice *device = NULL; - HRESULT ret; - - if (devid == NULL) { - const EDataFlow dataflow = this->iscapture ? eCapture : eRender; - ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_WASAPI_role, &device); - } else { - ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, &device); - } - - if (FAILED(ret)) { - SDL_assert(device == NULL); - this->hidden->client = NULL; - return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret); - } - - /* this is not async in standard win32, yay! */ - ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client); - IMMDevice_Release(device); - - if (FAILED(ret)) { - SDL_assert(this->hidden->client == NULL); - return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret); - } - - SDL_assert(this->hidden->client != NULL); - if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */ - return -1; - } - - return 0; /* good to go. */ -} - - -typedef struct -{ - LPWSTR devid; - char *devname; -} EndpointItem; - -static int sort_endpoints(const void *_a, const void *_b) -{ - LPWSTR a = ((const EndpointItem *) _a)->devid; - LPWSTR b = ((const EndpointItem *) _b)->devid; - if (!a && b) { - return -1; - } else if (a && !b) { - return 1; - } - - while (SDL_TRUE) { - if (*a < *b) { - return -1; - } else if (*a > *b) { - return 1; - } else if (*a == 0) { - break; - } - a++; - b++; - } - - return 0; -} - -static void -WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture) -{ - IMMDeviceCollection *collection = NULL; - EndpointItem *items; - UINT i, total; - - /* Note that WASAPI separates "adapter devices" from "audio endpoint devices" - ...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */ - - if (FAILED(IMMDeviceEnumerator_EnumAudioEndpoints(enumerator, iscapture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection))) { - return; - } - - if (FAILED(IMMDeviceCollection_GetCount(collection, &total))) { - IMMDeviceCollection_Release(collection); - return; - } - - items = (EndpointItem *) SDL_calloc(total, sizeof (EndpointItem)); - if (!items) { - return; /* oh well. */ - } - - for (i = 0; i < total; i++) { - EndpointItem *item = items + i; - IMMDevice *device = NULL; - if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) { - if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) { - item->devname = GetWasapiDeviceName(device); - } - IMMDevice_Release(device); - } - } - - /* sort the list of devices by their guid so list is consistent between runs */ - SDL_qsort(items, total, sizeof (*items), sort_endpoints); - - /* Send the sorted list on to the SDL's higher level. */ - for (i = 0; i < total; i++) { - EndpointItem *item = items + i; - if ((item->devid) && (item->devname)) { - WASAPI_AddDevice(iscapture, item->devname, item->devid); - } - SDL_free(item->devname); - CoTaskMemFree(item->devid); - } - - SDL_free(items); - IMMDeviceCollection_Release(collection); -} - -void -WASAPI_EnumerateEndpoints(void) -{ - WASAPI_EnumerateEndpointsForFlow(SDL_FALSE); /* playback */ - WASAPI_EnumerateEndpointsForFlow(SDL_TRUE); /* capture */ - - /* if this fails, we just won't get hotplug events. Carry on anyhow. */ - IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *) ¬ification_client); -} - -void -WASAPI_PlatformDeleteActivationHandler(void *handler) -{ - /* not asynchronous. */ - SDL_assert(!"This function should have only been called on WinRT."); -} - -#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */ - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_winrt.cpp b/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_winrt.cpp deleted file mode 100644 index 2ca09de..0000000 --- a/Source/3rdParty/SDL2/src/audio/wasapi/SDL_wasapi_winrt.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "../../SDL_internal.h" - -// This is C++/CX code that the WinRT port uses to talk to WASAPI-related -// system APIs. The C implementation of these functions, for non-WinRT apps, -// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard -// Windows and WinRT builds to deal with audio and calls into these functions. - -#if SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__) - -#include <Windows.h> -#include <windows.ui.core.h> -#include <windows.devices.enumeration.h> -#include <windows.media.devices.h> -#include <wrl/implements.h> - -extern "C" { -#include "../../core/windows/SDL_windows.h" -#include "SDL_audio.h" -#include "SDL_timer.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_assert.h" -#include "SDL_log.h" -} - -#define COBJMACROS -#include <mmdeviceapi.h> -#include <audioclient.h> - -#include "SDL_wasapi.h" - -using namespace Windows::Devices::Enumeration; -using namespace Windows::Media::Devices; -using namespace Windows::Foundation; -using namespace Microsoft::WRL; - -class SDL_WasapiDeviceEventHandler -{ -public: - SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture); - ~SDL_WasapiDeviceEventHandler(); - void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args); - void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args); - void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args); - void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args); - void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args); - -private: - const SDL_bool iscapture; - DeviceWatcher^ watcher; - Windows::Foundation::EventRegistrationToken added_handler; - Windows::Foundation::EventRegistrationToken removed_handler; - Windows::Foundation::EventRegistrationToken updated_handler; - Windows::Foundation::EventRegistrationToken default_changed_handler; -}; - -SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture) - : iscapture(_iscapture) - , watcher(DeviceInformation::CreateWatcher(_iscapture ? DeviceClass::AudioCapture : DeviceClass::AudioRender)) -{ - if (!watcher) - return; // uhoh. - - // !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan. - added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } ); - removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } ); - updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } ); - if (iscapture) { - default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioCaptureDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } ); - } else { - default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { OnDefaultRenderDeviceChanged(sender, args); } ); - } - watcher->Start(); -} - -SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler() -{ - if (watcher) { - watcher->Added -= added_handler; - watcher->Removed -= removed_handler; - watcher->Updated -= updated_handler; - watcher->Stop(); - watcher = nullptr; - } - - if (iscapture) { - MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler; - } else { - MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler; - } -} - -void -SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ info) -{ - SDL_assert(sender == this->watcher); - char *utf8dev = WIN_StringToUTF8(info->Name->Data()); - if (utf8dev) { - WASAPI_AddDevice(this->iscapture, utf8dev, info->Id->Data()); - SDL_free(utf8dev); - } -} - -void -SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ info) -{ - SDL_assert(sender == this->watcher); - WASAPI_RemoveDevice(this->iscapture, info->Id->Data()); -} - -void -SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args) -{ - SDL_assert(sender == this->watcher); -} - -void -SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) -{ - SDL_assert(this->iscapture); - SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1); -} - -void -SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) -{ - SDL_assert(!this->iscapture); - SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1); -} - - -static SDL_WasapiDeviceEventHandler *playback_device_event_handler; -static SDL_WasapiDeviceEventHandler *capture_device_event_handler; - -int WASAPI_PlatformInit(void) -{ - return 0; -} - -void WASAPI_PlatformDeinit(void) -{ - delete playback_device_event_handler; - playback_device_event_handler = nullptr; - delete capture_device_event_handler; - capture_device_event_handler = nullptr; -} - -void WASAPI_EnumerateEndpoints(void) -{ - // DeviceWatchers will fire an Added event for each existing device at - // startup, so we don't need to enumerate them separately before - // listening for updates. - playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE); - capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE); -} - -struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler > -{ - SDL_WasapiActivationHandler() : device(nullptr) {} - STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation); - SDL_AudioDevice *device; -}; - -HRESULT -SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async) -{ - // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races. - SDL_AtomicSet(&device->hidden->just_activated, 1); - WASAPI_UnrefDevice(device); - return S_OK; -} - -void -WASAPI_PlatformDeleteActivationHandler(void *handler) -{ - ((SDL_WasapiActivationHandler *) handler)->Release(); -} - -int -WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery) -{ - LPCWSTR devid = _this->hidden->devid; - Platform::String^ defdevid; - - if (devid == nullptr) { - defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default); - if (defdevid) { - devid = defdevid->Data(); - } - } - - SDL_AtomicSet(&_this->hidden->just_activated, 0); - - ComPtr<SDL_WasapiActivationHandler> handler = Make<SDL_WasapiActivationHandler>(); - if (handler == nullptr) { - return SDL_SetError("Failed to allocate WASAPI activation handler"); - } - - handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc. - handler.Get()->device = _this; - _this->hidden->activation_handler = handler.Get(); - - WASAPI_RefDevice(_this); /* completion handler will unref it. */ - IActivateAudioInterfaceAsyncOperation *async = nullptr; - const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async); - - if (FAILED(ret) || async == nullptr) { - if (async != nullptr) { - async->Release(); - } - handler.Get()->Release(); - WASAPI_UnrefDevice(_this); - return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret); - } - - /* Spin until the async operation is complete. - * If we don't PrepDevice before leaving this function, the bug list gets LONG: - * - device.spec is not filled with the correct information - * - The 'obtained' spec will be wrong for ALLOW_CHANGE properties - * - SDL_AudioStreams will/will not be allocated at the right time - * - SDL_assert(device->callbackspec.size == device->spec.size) will fail - * - When the assert is ignored, skipping or a buffer overflow will occur - */ - while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) { - SDL_Delay(1); - } - - HRESULT activateRes = S_OK; - IUnknown *iunknown = nullptr; - const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown); - async->Release(); - if (FAILED(getActivateRes)) { - return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes); - } else if (FAILED(activateRes)) { - return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes); - } - - iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client)); - if (!_this->hidden->client) { - return SDL_SetError("Failed to query WASAPI client interface"); - } - - if (WASAPI_PrepDevice(_this, isrecovery) == -1) { - return -1; - } - - return 0; -} - -void -WASAPI_PlatformThreadInit(_THIS) -{ - // !!! FIXME: set this thread to "Pro Audio" priority. -} - -void -WASAPI_PlatformThreadDeinit(_THIS) -{ - // !!! FIXME: set this thread to "Pro Audio" priority. -} - -#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__) - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.c b/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.c deleted file mode 100644 index 20426f1..0000000 --- a/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_WINMM - -/* Allow access to a raw mixing buffer */ - -#include "../../core/windows/SDL_windows.h" -#include <mmsystem.h> - -#include "SDL_assert.h" -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_winmm.h" - -/* MinGW32 mmsystem.h doesn't include these structures */ -#if defined(__MINGW32__) && defined(_MMSYSTEM_H) - -typedef struct tagWAVEINCAPS2W -{ - WORD wMid; - WORD wPid; - MMVERSION vDriverVersion; - WCHAR szPname[MAXPNAMELEN]; - DWORD dwFormats; - WORD wChannels; - WORD wReserved1; - GUID ManufacturerGuid; - GUID ProductGuid; - GUID NameGuid; -} WAVEINCAPS2W,*PWAVEINCAPS2W,*NPWAVEINCAPS2W,*LPWAVEINCAPS2W; - -typedef struct tagWAVEOUTCAPS2W -{ - WORD wMid; - WORD wPid; - MMVERSION vDriverVersion; - WCHAR szPname[MAXPNAMELEN]; - DWORD dwFormats; - WORD wChannels; - WORD wReserved1; - DWORD dwSupport; - GUID ManufacturerGuid; - GUID ProductGuid; - GUID NameGuid; -} WAVEOUTCAPS2W,*PWAVEOUTCAPS2W,*NPWAVEOUTCAPS2W,*LPWAVEOUTCAPS2W; - -#endif /* defined(__MINGW32__) && defined(_MMSYSTEM_H) */ - -#ifndef WAVE_FORMAT_IEEE_FLOAT -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 -#endif - -#define DETECT_DEV_IMPL(iscap, typ, capstyp) \ -static void DetectWave##typ##Devs(void) { \ - const UINT iscapture = iscap ? 1 : 0; \ - const UINT devcount = wave##typ##GetNumDevs(); \ - capstyp##2W caps; \ - UINT i; \ - for (i = 0; i < devcount; i++) { \ - if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ - char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ - if (name != NULL) { \ - SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ - SDL_free(name); \ - } \ - } \ - } \ -} - -DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS) -DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS) - -static void -WINMM_DetectDevices(void) -{ - DetectWaveInDevs(); - DetectWaveOutDevs(); -} - -static void CALLBACK -CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR dwParam1, DWORD_PTR dwParam2) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance; - - /* Only service "buffer is filled" messages */ - if (uMsg != WIM_DATA) - return; - - /* Signal that we have a new buffer of data */ - ReleaseSemaphore(this->hidden->audio_sem, 1, NULL); -} - - -/* The Win32 callback for filling the WAVE device */ -static void CALLBACK -FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR dwParam1, DWORD_PTR dwParam2) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance; - - /* Only service "buffer done playing" messages */ - if (uMsg != WOM_DONE) - return; - - /* Signal that we are done playing a buffer */ - ReleaseSemaphore(this->hidden->audio_sem, 1, NULL); -} - -static int -SetMMerror(char *function, MMRESULT code) -{ - int len; - char errbuf[MAXERRORLENGTH]; - wchar_t werrbuf[MAXERRORLENGTH]; - - SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: ", function); - len = SDL_static_cast(int, SDL_strlen(errbuf)); - - waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH - len); - WideCharToMultiByte(CP_ACP, 0, werrbuf, -1, errbuf + len, - MAXERRORLENGTH - len, NULL, NULL); - - return SDL_SetError("%s", errbuf); -} - -static void -WINMM_WaitDevice(_THIS) -{ - /* Wait for an audio chunk to finish */ - WaitForSingleObject(this->hidden->audio_sem, INFINITE); -} - -static Uint8 * -WINMM_GetDeviceBuf(_THIS) -{ - return (Uint8 *) (this->hidden-> - wavebuf[this->hidden->next_buffer].lpData); -} - -static void -WINMM_PlayDevice(_THIS) -{ - /* Queue it up */ - waveOutWrite(this->hidden->hout, - &this->hidden->wavebuf[this->hidden->next_buffer], - sizeof(this->hidden->wavebuf[0])); - this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; -} - -static int -WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) -{ - const int nextbuf = this->hidden->next_buffer; - MMRESULT result; - - SDL_assert(buflen == this->spec.size); - - /* Wait for an audio chunk to finish */ - WaitForSingleObject(this->hidden->audio_sem, INFINITE); - - /* Copy it to caller's buffer... */ - SDL_memcpy(buffer, this->hidden->wavebuf[nextbuf].lpData, this->spec.size); - - /* requeue the buffer that just finished. */ - result = waveInAddBuffer(this->hidden->hin, - &this->hidden->wavebuf[nextbuf], - sizeof (this->hidden->wavebuf[nextbuf])); - if (result != MMSYSERR_NOERROR) { - return -1; /* uhoh! Disable the device. */ - } - - /* queue the next buffer in sequence, next time. */ - this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS; - return this->spec.size; -} - -static void -WINMM_FlushCapture(_THIS) -{ - /* Wait for an audio chunk to finish */ - if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) { - const int nextbuf = this->hidden->next_buffer; - /* requeue the buffer that just finished without reading from it. */ - waveInAddBuffer(this->hidden->hin, - &this->hidden->wavebuf[nextbuf], - sizeof (this->hidden->wavebuf[nextbuf])); - this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS; - } -} - -static void -WINMM_CloseDevice(_THIS) -{ - int i; - - if (this->hidden->hout) { - waveOutReset(this->hidden->hout); - - /* Clean up mixing buffers */ - for (i = 0; i < NUM_BUFFERS; ++i) { - if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { - waveOutUnprepareHeader(this->hidden->hout, - &this->hidden->wavebuf[i], - sizeof (this->hidden->wavebuf[i])); - } - } - - waveOutClose(this->hidden->hout); - } - - if (this->hidden->hin) { - waveInReset(this->hidden->hin); - - /* Clean up mixing buffers */ - for (i = 0; i < NUM_BUFFERS; ++i) { - if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { - waveInUnprepareHeader(this->hidden->hin, - &this->hidden->wavebuf[i], - sizeof (this->hidden->wavebuf[i])); - } - } - waveInClose(this->hidden->hin); - } - - if (this->hidden->audio_sem) { - CloseHandle(this->hidden->audio_sem); - } - - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); -} - -static SDL_bool -PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture) -{ - SDL_zerop(pfmt); - - if (SDL_AUDIO_ISFLOAT(this->spec.format)) { - pfmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - } else { - pfmt->wFormatTag = WAVE_FORMAT_PCM; - } - pfmt->wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); - - pfmt->nChannels = this->spec.channels; - pfmt->nSamplesPerSec = this->spec.freq; - pfmt->nBlockAlign = pfmt->nChannels * (pfmt->wBitsPerSample / 8); - pfmt->nAvgBytesPerSec = pfmt->nSamplesPerSec * pfmt->nBlockAlign; - - if (iscapture) { - return (waveInOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0); - } else { - return (waveOutOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0); - } -} - -static int -WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - int valid_datatype = 0; - MMRESULT result; - WAVEFORMATEX waveformat; - UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ - UINT i; - - if (handle != NULL) { /* specific device requested? */ - /* -1 because we increment the original value to avoid NULL. */ - const size_t val = ((size_t) handle) - 1; - devId = (UINT) val; - } - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_zerop(this->hidden); - - /* Initialize the wavebuf structures for closing */ - for (i = 0; i < NUM_BUFFERS; ++i) - this->hidden->wavebuf[i].dwUser = 0xFFFF; - - if (this->spec.channels > 2) - this->spec.channels = 2; /* !!! FIXME: is this right? */ - - while ((!valid_datatype) && (test_format)) { - switch (test_format) { - case AUDIO_U8: - case AUDIO_S16: - case AUDIO_S32: - case AUDIO_F32: - this->spec.format = test_format; - if (PrepWaveFormat(this, devId, &waveformat, iscapture)) { - valid_datatype = 1; - } else { - test_format = SDL_NextAudioFormat(); - } - break; - - default: - test_format = SDL_NextAudioFormat(); - break; - } - } - - if (!valid_datatype) { - return SDL_SetError("Unsupported audio format"); - } - - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&this->spec); - - /* Open the audio device */ - if (iscapture) { - result = waveInOpen(&this->hidden->hin, devId, &waveformat, - (DWORD_PTR) CaptureSound, (DWORD_PTR) this, - CALLBACK_FUNCTION); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveInOpen()", result); - } - } else { - result = waveOutOpen(&this->hidden->hout, devId, &waveformat, - (DWORD_PTR) FillSound, (DWORD_PTR) this, - CALLBACK_FUNCTION); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveOutOpen()", result); - } - } - -#ifdef SOUND_DEBUG - /* Check the sound device we retrieved */ - { - if (iscapture) { - WAVEINCAPS caps; - result = waveInGetDevCaps((UINT) this->hidden->hout, - &caps, sizeof (caps)); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveInGetDevCaps()", result); - } - printf("Audio device: %s\n", caps.szPname); - } else { - WAVEOUTCAPS caps; - result = waveOutGetDevCaps((UINT) this->hidden->hout, - &caps, sizeof(caps)); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveOutGetDevCaps()", result); - } - printf("Audio device: %s\n", caps.szPname); - } - } -#endif - - /* Create the audio buffer semaphore */ - this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL); - if (this->hidden->audio_sem == NULL) { - return SDL_SetError("Couldn't create semaphore"); - } - - /* Create the sound buffers */ - this->hidden->mixbuf = - (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); - if (this->hidden->mixbuf == NULL) { - return SDL_OutOfMemory(); - } - - SDL_zero(this->hidden->wavebuf); - for (i = 0; i < NUM_BUFFERS; ++i) { - this->hidden->wavebuf[i].dwBufferLength = this->spec.size; - this->hidden->wavebuf[i].dwFlags = WHDR_DONE; - this->hidden->wavebuf[i].lpData = - (LPSTR) & this->hidden->mixbuf[i * this->spec.size]; - - if (iscapture) { - result = waveInPrepareHeader(this->hidden->hin, - &this->hidden->wavebuf[i], - sizeof(this->hidden->wavebuf[i])); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveInPrepareHeader()", result); - } - - result = waveInAddBuffer(this->hidden->hin, - &this->hidden->wavebuf[i], - sizeof(this->hidden->wavebuf[i])); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveInAddBuffer()", result); - } - } else { - result = waveOutPrepareHeader(this->hidden->hout, - &this->hidden->wavebuf[i], - sizeof(this->hidden->wavebuf[i])); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveOutPrepareHeader()", result); - } - } - } - - if (iscapture) { - result = waveInStart(this->hidden->hin); - if (result != MMSYSERR_NOERROR) { - return SetMMerror("waveInStart()", result); - } - } - - return 0; /* Ready to go! */ -} - - -static int -WINMM_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->DetectDevices = WINMM_DetectDevices; - impl->OpenDevice = WINMM_OpenDevice; - impl->PlayDevice = WINMM_PlayDevice; - impl->WaitDevice = WINMM_WaitDevice; - impl->GetDeviceBuf = WINMM_GetDeviceBuf; - impl->CaptureFromDevice = WINMM_CaptureFromDevice; - impl->FlushCapture = WINMM_FlushCapture; - impl->CloseDevice = WINMM_CloseDevice; - - impl->HasCaptureSupport = SDL_TRUE; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap WINMM_bootstrap = { - "winmm", "Windows Waveform Audio", WINMM_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_WINMM */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.h b/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.h deleted file mode 100644 index 9342bb9..0000000 --- a/Source/3rdParty/SDL2/src/audio/winmm/SDL_winmm.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifndef SDL_winmm_h_ -#define SDL_winmm_h_ - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this - -#define NUM_BUFFERS 2 /* -- Don't lower this! */ - -struct SDL_PrivateAudioData -{ - HWAVEOUT hout; - HWAVEIN hin; - HANDLE audio_sem; - Uint8 *mixbuf; /* The raw allocated mixing buffer */ - WAVEHDR wavebuf[NUM_BUFFERS]; /* Wave audio fragments */ - int next_buffer; -}; - -#endif /* SDL_winmm_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ |