From 5a079a2d114f96d4847d1ee305d5b7c16eeec50e Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 27 Dec 2025 12:03:39 -0800 Subject: Initial commit --- contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.c | 551 +++++++++++++++++++++ contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.h | 38 ++ .../SDL-3.2.8/src/audio/aaudio/SDL_aaudiofuncs.h | 82 +++ 3 files changed, 671 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.c create mode 100644 contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.h create mode 100644 contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudiofuncs.h (limited to 'contrib/SDL-3.2.8/src/audio/aaudio') diff --git a/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.c b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.c new file mode 100644 index 0000000..3360bec --- /dev/null +++ b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.c @@ -0,0 +1,551 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + 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" + +#ifdef SDL_AUDIO_DRIVER_AAUDIO + +#include "../SDL_sysaudio.h" +#include "SDL_aaudio.h" + +#include "../../core/android/SDL_android.h" +#include + +#if __ANDROID_API__ < 31 +#define AAUDIO_FORMAT_PCM_I32 4 +#endif + +struct SDL_PrivateAudioData +{ + AAudioStream *stream; + int num_buffers; + Uint8 *mixbuf; // Raw mixing buffer + size_t mixbuf_bytes; // num_buffers * device->buffer_size + size_t callback_bytes; + size_t processed_bytes; + SDL_Semaphore *semaphore; + SDL_AtomicInt error_callback_triggered; +}; + +// Debug +#if 0 +#define LOGI(...) SDL_Log(__VA_ARGS__); +#else +#define LOGI(...) +#endif + +#define LIB_AAUDIO_SO "libaaudio.so" + +typedef struct AAUDIO_Data +{ + SDL_SharedObject *handle; +#define SDL_PROC(ret, func, params) ret (*func) params; +#include "SDL_aaudiofuncs.h" +} AAUDIO_Data; +static AAUDIO_Data ctx; + +static bool AAUDIO_LoadFunctions(AAUDIO_Data *data) +{ +#define SDL_PROC(ret, func, params) \ + do { \ + data->func = (ret (*) params)SDL_LoadFunction(data->handle, #func); \ + if (!data->func) { \ + return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \ + } \ + } while (0); +#include "SDL_aaudiofuncs.h" + return true; +} + + +static void AAUDIO_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error) +{ + LOGI("SDL AAUDIO_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error)); + + // You MUST NOT close the audio stream from this callback, so we cannot call SDL_AudioDeviceDisconnected here. + // Just flag the device so we can kill it in PlayDevice instead. + SDL_AudioDevice *device = (SDL_AudioDevice *) userData; + SDL_SetAtomicInt(&device->hidden->error_callback_triggered, (int) error); // AAUDIO_OK is zero, so !triggered means no error. + SDL_SignalSemaphore(device->hidden->semaphore); // in case we're blocking in WaitDevice. +} + +static aaudio_data_callback_result_t AAUDIO_dataCallback(AAudioStream *stream, void *userData, void *audioData, int32_t numFrames) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *) userData; + struct SDL_PrivateAudioData *hidden = device->hidden; + size_t framesize = SDL_AUDIO_FRAMESIZE(device->spec); + size_t callback_bytes = numFrames * framesize; + size_t old_buffer_index = hidden->callback_bytes / device->buffer_size; + + if (device->recording) { + const Uint8 *input = (const Uint8 *)audioData; + size_t available_bytes = hidden->mixbuf_bytes - (hidden->callback_bytes - hidden->processed_bytes); + size_t size = SDL_min(available_bytes, callback_bytes); + size_t offset = hidden->callback_bytes % hidden->mixbuf_bytes; + size_t end = (offset + size) % hidden->mixbuf_bytes; + SDL_assert(size <= hidden->mixbuf_bytes); + +//LOGI("Recorded %zu frames, %zu available, %zu max (%zu written, %zu read)", callback_bytes / framesize, available_bytes / framesize, hidden->mixbuf_bytes / framesize, hidden->callback_bytes / framesize, hidden->processed_bytes / framesize); + + if (offset <= end) { + SDL_memcpy(&hidden->mixbuf[offset], input, size); + } else { + size_t partial = (hidden->mixbuf_bytes - offset); + SDL_memcpy(&hidden->mixbuf[offset], &input[0], partial); + SDL_memcpy(&hidden->mixbuf[0], &input[partial], end); + } + + SDL_MemoryBarrierRelease(); + hidden->callback_bytes += size; + + if (size < callback_bytes) { + LOGI("Audio recording overflow, dropped %zu frames", (callback_bytes - size) / framesize); + } + } else { + Uint8 *output = (Uint8 *)audioData; + size_t available_bytes = (hidden->processed_bytes - hidden->callback_bytes); + size_t size = SDL_min(available_bytes, callback_bytes); + size_t offset = hidden->callback_bytes % hidden->mixbuf_bytes; + size_t end = (offset + size) % hidden->mixbuf_bytes; + SDL_assert(size <= hidden->mixbuf_bytes); + +//LOGI("Playing %zu frames, %zu available, %zu max (%zu written, %zu read)", callback_bytes / framesize, available_bytes / framesize, hidden->mixbuf_bytes / framesize, hidden->processed_bytes / framesize, hidden->callback_bytes / framesize); + + SDL_MemoryBarrierAcquire(); + if (offset <= end) { + SDL_memcpy(output, &hidden->mixbuf[offset], size); + } else { + size_t partial = (hidden->mixbuf_bytes - offset); + SDL_memcpy(&output[0], &hidden->mixbuf[offset], partial); + SDL_memcpy(&output[partial], &hidden->mixbuf[0], end); + } + hidden->callback_bytes += size; + + if (size < callback_bytes) { + LOGI("Audio playback underflow, missed %zu frames", (callback_bytes - size) / framesize); + SDL_memset(&output[size], device->silence_value, (callback_bytes - size)); + } + } + + size_t new_buffer_index = hidden->callback_bytes / device->buffer_size; + while (old_buffer_index < new_buffer_index) { + // Trigger audio processing + SDL_SignalSemaphore(hidden->semaphore); + ++old_buffer_index; + } + + return AAUDIO_CALLBACK_RESULT_CONTINUE; +} + +static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + size_t offset = (hidden->processed_bytes % hidden->mixbuf_bytes); + return &hidden->mixbuf[offset]; +} + +static bool AAUDIO_WaitDevice(SDL_AudioDevice *device) +{ + while (!SDL_GetAtomicInt(&device->shutdown)) { + // this semaphore won't fire when the app is in the background (AAUDIO_PauseDevices was called). + if (SDL_WaitSemaphoreTimeout(device->hidden->semaphore, 100)) { + return true; // semaphore was signaled, let's go! + } + // Still waiting on the semaphore (or the system), check other things then wait again. + } + return true; +} + +static bool BuildAAudioStream(SDL_AudioDevice *device); + +static bool RecoverAAudioDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + + // attempt to build a new stream, in case there's a new default device. + ctx.AAudioStream_requestStop(hidden->stream); + ctx.AAudioStream_close(hidden->stream); + hidden->stream = NULL; + + SDL_aligned_free(hidden->mixbuf); + hidden->mixbuf = NULL; + + SDL_DestroySemaphore(hidden->semaphore); + hidden->semaphore = NULL; + + const int prev_sample_frames = device->sample_frames; + SDL_AudioSpec prevspec; + SDL_copyp(&prevspec, &device->spec); + + if (!BuildAAudioStream(device)) { + return false; // oh well, we tried. + } + + // we don't know the new device spec until we open the new device, so we saved off the old one and force it back + // so SDL_AudioDeviceFormatChanged can set up all the important state if necessary and then set it back to the new spec. + const int new_sample_frames = device->sample_frames; + SDL_AudioSpec newspec; + SDL_copyp(&newspec, &device->spec); + + device->sample_frames = prev_sample_frames; + SDL_copyp(&device->spec, &prevspec); + if (!SDL_AudioDeviceFormatChangedAlreadyLocked(device, &newspec, new_sample_frames)) { + return false; // ugh + } + return true; +} + + +static bool AAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + + // AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice. But make sure we didn't fail here. + const aaudio_result_t err = (aaudio_result_t) SDL_GetAtomicInt(&hidden->error_callback_triggered); + if (err) { + SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "aaudio: Audio device triggered error %d (%s)", (int) err, ctx.AAudio_convertResultToText(err)); + + if (!RecoverAAudioDevice(device)) { + return false; // oh well, we went down hard. + } + } else { + SDL_MemoryBarrierRelease(); + hidden->processed_bytes += buflen; + } + return true; +} + +static int AAUDIO_RecordDevice(SDL_AudioDevice *device, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + + // AAUDIO_dataCallback picks up our work and unblocks AAUDIO_WaitDevice. But make sure we didn't fail here. + if (SDL_GetAtomicInt(&hidden->error_callback_triggered)) { + SDL_SetAtomicInt(&hidden->error_callback_triggered, 0); + return -1; + } + + SDL_assert(buflen == device->buffer_size); // If this isn't true, we need to change semaphore trigger logic and account for wrapping copies here + size_t offset = (hidden->processed_bytes % hidden->mixbuf_bytes); + SDL_MemoryBarrierAcquire(); + SDL_memcpy(buffer, &hidden->mixbuf[offset], buflen); + hidden->processed_bytes += buflen; + return buflen; +} + +static void AAUDIO_CloseDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + LOGI(__func__); + + if (hidden) { + if (hidden->stream) { + ctx.AAudioStream_requestStop(hidden->stream); + // !!! FIXME: do we have to wait for the state to change to make sure all buffered audio has played, or will close do this (or will the system do this after the close)? + // !!! FIXME: also, will this definitely wait for a running data callback to finish, and then stop the callback from firing again? + ctx.AAudioStream_close(hidden->stream); + } + + if (hidden->semaphore) { + SDL_DestroySemaphore(hidden->semaphore); + } + + SDL_aligned_free(hidden->mixbuf); + SDL_free(hidden); + device->hidden = NULL; + } +} + +static bool BuildAAudioStream(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + const bool recording = device->recording; + aaudio_result_t res; + + SDL_SetAtomicInt(&hidden->error_callback_triggered, 0); + + AAudioStreamBuilder *builder = NULL; + res = ctx.AAudio_createStreamBuilder(&builder); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudio_createStreamBuilder %d", res); + return SDL_SetError("SDL Failed AAudio_createStreamBuilder %d", res); + } else if (!builder) { + LOGI("SDL Failed AAudio_createStreamBuilder - builder NULL"); + return SDL_SetError("SDL Failed AAudio_createStreamBuilder - builder NULL"); + } + +#if ALLOW_MULTIPLE_ANDROID_AUDIO_DEVICES + const int aaudio_device_id = (int) ((size_t) device->handle); + LOGI("Opening device id %d", aaudio_device_id); + ctx.AAudioStreamBuilder_setDeviceId(builder, aaudio_device_id); +#endif + + aaudio_format_t format; + if ((device->spec.format == SDL_AUDIO_S32) && (SDL_GetAndroidSDKVersion() >= 31)) { + format = AAUDIO_FORMAT_PCM_I32; + } else if (device->spec.format == SDL_AUDIO_F32) { + format = AAUDIO_FORMAT_PCM_FLOAT; + } else { + format = AAUDIO_FORMAT_PCM_I16; // sint16 is a safe bet for everything else. + } + ctx.AAudioStreamBuilder_setFormat(builder, format); + ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq); + ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels); + + const aaudio_direction_t direction = (recording ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); + ctx.AAudioStreamBuilder_setDirection(builder, direction); + ctx.AAudioStreamBuilder_setErrorCallback(builder, AAUDIO_errorCallback, device); + ctx.AAudioStreamBuilder_setDataCallback(builder, AAUDIO_dataCallback, device); + // Some devices have flat sounding audio when low latency mode is enabled, but this is a better experience for most people + if (SDL_GetHintBoolean(SDL_HINT_ANDROID_LOW_LATENCY_AUDIO, true)) { + SDL_Log("Low latency audio enabled"); + ctx.AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); + } else { + SDL_Log("Low latency audio disabled"); + } + + LOGI("AAudio Try to open %u hz %s %u channels samples %u", + device->spec.freq, SDL_GetAudioFormatName(device->spec.format), + device->spec.channels, device->sample_frames); + + res = ctx.AAudioStreamBuilder_openStream(builder, &hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res); + ctx.AAudioStreamBuilder_delete(builder); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + ctx.AAudioStreamBuilder_delete(builder); + + device->sample_frames = (int)ctx.AAudioStream_getFramesPerDataCallback(hidden->stream); + if (device->sample_frames == AAUDIO_UNSPECIFIED) { + // We'll get variable frames in the callback, make sure we have at least half a buffer available + device->sample_frames = (int)ctx.AAudioStream_getBufferCapacityInFrames(hidden->stream) / 2; + } + + device->spec.freq = ctx.AAudioStream_getSampleRate(hidden->stream); + device->spec.channels = ctx.AAudioStream_getChannelCount(hidden->stream); + + format = ctx.AAudioStream_getFormat(hidden->stream); + if (format == AAUDIO_FORMAT_PCM_I16) { + device->spec.format = SDL_AUDIO_S16; + } else if (format == AAUDIO_FORMAT_PCM_I32) { + device->spec.format = SDL_AUDIO_S32; + } else if (format == AAUDIO_FORMAT_PCM_FLOAT) { + device->spec.format = SDL_AUDIO_F32; + } else { + return SDL_SetError("Got unexpected audio format %d from AAudioStream_getFormat", (int) format); + } + + SDL_UpdatedAudioDeviceFormat(device); + + // Allocate a triple buffered mixing buffer + // Two buffers can be in the process of being filled while the third is being read + hidden->num_buffers = 3; + hidden->mixbuf_bytes = (hidden->num_buffers * device->buffer_size); + hidden->mixbuf = (Uint8 *)SDL_aligned_alloc(SDL_GetSIMDAlignment(), hidden->mixbuf_bytes); + if (!hidden->mixbuf) { + return false; + } + hidden->processed_bytes = 0; + hidden->callback_bytes = 0; + + hidden->semaphore = SDL_CreateSemaphore(recording ? 0 : hidden->num_buffers); + if (!hidden->semaphore) { + LOGI("SDL Failed SDL_CreateSemaphore %s recording:%d", SDL_GetError(), recording); + return false; + } + + LOGI("AAudio Actually opened %u hz %s %u channels samples %u, buffers %d", + device->spec.freq, SDL_GetAudioFormatName(device->spec.format), + device->spec.channels, device->sample_frames, hidden->num_buffers); + + res = ctx.AAudioStream_requestStart(hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d recording:%d", res, recording); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + LOGI("SDL AAudioStream_requestStart OK"); + + return true; +} + +// !!! FIXME: make this non-blocking! +static void SDLCALL RequestAndroidPermissionBlockingCallback(void *userdata, const char *permission, bool granted) +{ + SDL_SetAtomicInt((SDL_AtomicInt *) userdata, granted ? 1 : -1); +} + +static bool AAUDIO_OpenDevice(SDL_AudioDevice *device) +{ +#if ALLOW_MULTIPLE_ANDROID_AUDIO_DEVICES + SDL_assert(device->handle); // AAUDIO_UNSPECIFIED is zero, so legit devices should all be non-zero. +#endif + + LOGI(__func__); + + if (device->recording) { + // !!! FIXME: make this non-blocking! + SDL_AtomicInt permission_response; + SDL_SetAtomicInt(&permission_response, 0); + if (!SDL_RequestAndroidPermission("android.permission.RECORD_AUDIO", RequestAndroidPermissionBlockingCallback, &permission_response)) { + return false; + } + + while (SDL_GetAtomicInt(&permission_response) == 0) { + SDL_Delay(10); + } + + if (SDL_GetAtomicInt(&permission_response) < 0) { + LOGI("This app doesn't have RECORD_AUDIO permission"); + return SDL_SetError("This app doesn't have RECORD_AUDIO permission"); + } + } + + device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden)); + if (!device->hidden) { + return false; + } + + return BuildAAudioStream(device); +} + +static bool PauseOneDevice(SDL_AudioDevice *device, void *userdata) +{ + struct SDL_PrivateAudioData *hidden = (struct SDL_PrivateAudioData *)device->hidden; + if (hidden) { + if (hidden->stream) { + aaudio_result_t res; + + if (device->recording) { + // Pause() isn't implemented for recording, use Stop() + res = ctx.AAudioStream_requestStop(hidden->stream); + } else { + res = ctx.AAudioStream_requestPause(hidden->stream); + } + + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestPause %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + } + return false; // keep enumerating. +} + +// Pause (block) all non already paused audio devices by taking their mixer lock +void AAUDIO_PauseDevices(void) +{ + if (ctx.handle) { // AAUDIO driver is used? + (void) SDL_FindPhysicalAudioDeviceByCallback(PauseOneDevice, NULL); + } +} + +// Resume (unblock) all non already paused audio devices by releasing their mixer lock +static bool ResumeOneDevice(SDL_AudioDevice *device, void *userdata) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + if (hidden) { + if (hidden->stream) { + aaudio_result_t res = ctx.AAudioStream_requestStart(hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + } + return false; // keep enumerating. +} + +void AAUDIO_ResumeDevices(void) +{ + if (ctx.handle) { // AAUDIO driver is used? + (void) SDL_FindPhysicalAudioDeviceByCallback(ResumeOneDevice, NULL); + } +} + +static void AAUDIO_Deinitialize(void) +{ + Android_StopAudioHotplug(); + + LOGI(__func__); + if (ctx.handle) { + SDL_UnloadObject(ctx.handle); + } + SDL_zero(ctx); + LOGI("End AAUDIO %s", SDL_GetError()); +} + + +static bool AAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + LOGI(__func__); + + /* AAudio was introduced in Android 8.0, but has reference counting crash issues in that release, + * so don't use it until 8.1. + * + * See https://github.com/google/oboe/issues/40 for more information. + */ + if (SDL_GetAndroidSDKVersion() < 27) { + return false; + } + + SDL_zero(ctx); + + ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO); + if (!ctx.handle) { + LOGI("SDL couldn't find " LIB_AAUDIO_SO); + return false; + } + + if (!AAUDIO_LoadFunctions(&ctx)) { + SDL_UnloadObject(ctx.handle); + SDL_zero(ctx); + return false; + } + + impl->ThreadInit = Android_AudioThreadInit; + impl->Deinitialize = AAUDIO_Deinitialize; + impl->OpenDevice = AAUDIO_OpenDevice; + impl->CloseDevice = AAUDIO_CloseDevice; + impl->WaitDevice = AAUDIO_WaitDevice; + impl->PlayDevice = AAUDIO_PlayDevice; + impl->GetDeviceBuf = AAUDIO_GetDeviceBuf; + impl->WaitRecordingDevice = AAUDIO_WaitDevice; + impl->RecordDevice = AAUDIO_RecordDevice; + + impl->HasRecordingSupport = true; + +#if ALLOW_MULTIPLE_ANDROID_AUDIO_DEVICES + impl->DetectDevices = Android_StartAudioHotplug; +#else + impl->OnlyHasDefaultPlaybackDevice = true; + impl->OnlyHasDefaultRecordingDevice = true; +#endif + + LOGI("SDL AAUDIO_Init OK"); + return true; +} + +AudioBootStrap AAUDIO_bootstrap = { + "AAudio", "AAudio audio driver", AAUDIO_Init, false, false +}; + +#endif // SDL_AUDIO_DRIVER_AAUDIO diff --git a/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.h b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.h new file mode 100644 index 0000000..5326bad --- /dev/null +++ b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudio.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + 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_aaudio_h_ +#define SDL_aaudio_h_ + +#ifdef SDL_AUDIO_DRIVER_AAUDIO + +extern void AAUDIO_ResumeDevices(void); +extern void AAUDIO_PauseDevices(void); + +#else + +#define AAUDIO_ResumeDevices() +#define AAUDIO_PauseDevices() + +#endif + +#endif // SDL_aaudio_h_ diff --git a/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudiofuncs.h b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudiofuncs.h new file mode 100644 index 0000000..0298821 --- /dev/null +++ b/contrib/SDL-3.2.8/src/audio/aaudio/SDL_aaudiofuncs.h @@ -0,0 +1,82 @@ +/* + Simple DirectMedia Layer + Copyright , (C) 1997-2025 Sam Lantinga + + 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. +*/ + +#define SDL_PROC_UNUSED(ret, func, params) + +SDL_PROC(const char *, AAudio_convertResultToText, (aaudio_result_t returnCode)) +SDL_PROC(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state)) +SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder * *builder)) +SDL_PROC(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder * builder, int32_t deviceId)) +SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder * builder, int32_t sampleRate)) +SDL_PROC(void, AAudioStreamBuilder_setChannelCount, (AAudioStreamBuilder * builder, int32_t channelCount)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuilder * builder, int32_t samplesPerFrame)) +SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode)) +SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) +SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28 +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) // API 28 +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) // API 28 +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) // API 29 +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder * builder, aaudio_session_id_t sessionId)) // API 28 +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder * builder, bool privacySensitive)) // API 30 +SDL_PROC(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData)) +SDL_PROC(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder * builder, int32_t numFrames)) +SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder * builder, AAudioStream_errorCallback callback, void *userData)) +SDL_PROC(aaudio_result_t, AAudioStreamBuilder_openStream, (AAudioStreamBuilder * builder, AAudioStream **stream)) +SDL_PROC(aaudio_result_t, AAudioStreamBuilder_delete, (AAudioStreamBuilder * builder)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_release, (AAudioStream * stream)) // API 30 +SDL_PROC(aaudio_result_t, AAudioStream_close, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestStart, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestPause, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_requestFlush, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestStop, (AAudioStream * stream)) +SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream * stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_write, (AAudioStream * stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream * stream, int32_t numFrames)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getXRunCount, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getDeviceId, (AAudioStream * stream)) +SDL_PROC(aaudio_format_t, AAudioStream_getFormat, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_sharing_mode_t, AAudioStream_getSharingMode, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_performance_mode_t, AAudioStream_getPerformanceMode, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream * stream)) +SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream * stream)) +SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream * stream)) // API 28 +SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream * stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds)) +SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream * stream)) // API 28 +SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream * stream)) // API 28 +SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream * stream)) // API 28 +SDL_PROC_UNUSED(aaudio_allowed_capture_policy_t, AAudioStream_getAllowedCapturePolicy, (AAudioStream * stream)) // API 29 +SDL_PROC_UNUSED(bool, AAudioStream_isPrivacySensitive, (AAudioStream * stream)) // API 30 + +#undef SDL_PROC +#undef SDL_PROC_UNUSED -- cgit v1.2.3