From e1ca4218a8c9f24e172433081d87bc9d864e04e8 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 26 Feb 2025 04:46:35 -0500 Subject: [PATCH 1/7] Initial commit for SDL3 (dynamic) backend. --- include/soloud.h | 12 ++ src/backend/sdl/soloud_sdl3.cpp | 188 ++++++++++++++++++++++++++++++ src/backend/sdl/soloud_sdl3_dll.c | 172 +++++++++++++++++++++++++++ src/core/soloud.cpp | 158 ++++++++++++++++--------- src/core/soloud_core_getters.cpp | 34 +++--- src/core/soloud_core_setters.cpp | 14 ++- 6 files changed, 506 insertions(+), 72 deletions(-) create mode 100644 src/backend/sdl/soloud_sdl3.cpp create mode 100644 src/backend/sdl/soloud_sdl3_dll.c diff --git a/include/soloud.h b/include/soloud.h index e3b47d8e..d6d7f12f 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -48,10 +48,12 @@ freely, subject to the following restrictions: #endif #ifdef WITH_SDL +#undef WITH_SDL3 #undef WITH_SDL2 #undef WITH_SDL1 #define WITH_SDL1 #define WITH_SDL2 +#define WITH_SDL3 #endif #ifdef WITH_SDL_STATIC @@ -194,6 +196,7 @@ namespace SoLoud MINIAUDIO, NOSOUND, NULLDRIVER, + SDL3, BACKEND_MAX, }; @@ -229,6 +232,9 @@ namespace SoLoud // Initialize SoLoud. Must be called before SoLoud can be used. result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2); + // Initialize SoLoud. Must be called before SoLoud can be used. + result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, int deviceId = NULL ); + result pause(); result resume(); @@ -251,6 +257,10 @@ namespace SoLoud unsigned int getBackendSamplerate(); // Returns current backend buffer size unsigned int getBackendBufferSize(); + // Returns current backend device ID + unsigned int getBackendDeviceId(); + // Sets the backend device ID + void setBackendDeviceId(unsigned int deviceId); // Set speaker position in 3d space result setSpeakerPosition(unsigned int aChannel, float aX, float aY, float aZ); @@ -530,6 +540,8 @@ namespace SoLoud unsigned int mBackendID; // Current backend string const char * mBackendString; + // Current backend device ID + unsigned int mBackendDeviceId; // Maximum size of output buffer; used to calculate needed scratch. unsigned int mBufferSize; // Flags; see Soloud::FLAGS diff --git a/src/backend/sdl/soloud_sdl3.cpp b/src/backend/sdl/soloud_sdl3.cpp new file mode 100644 index 00000000..47f8ff4c --- /dev/null +++ b/src/backend/sdl/soloud_sdl3.cpp @@ -0,0 +1,188 @@ +/* +SoLoud audio engine +Copyright (c) 2013-2018 Jari Komppa + +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 + +#include "soloud.h" + +#if !defined(WITH_SDL3) + +namespace SoLoud +{ + result sdl3_init( + SoLoud::Soloud * aSoloud, + unsigned int aFlags, + unsigned int aSamplerate, + unsigned int aBuffer, + unsigned int aChannels, + int deviceId + ) + { + return NOT_IMPLEMENTED; + } +} + +#else + +#include "SDL3/SDL.h" +#include + +extern "C" +{ + int dll_SDL3_found(); + + Uint32 dll_SDL3_WasInit(Uint32 flags); + int dll_SDL3_InitSubSystem(Uint32 flags); + SDL_AudioStream * dll_SDL3_OpenAudioDeviceStream( + SDL_AudioDeviceID device, + SDL_AudioSpec const * spec, + SDL_AudioStreamCallback callback, + void * userdata + ); + void dll_SDL3_CloseAudioDevice(SDL_AudioDeviceID dev); + bool dll_SDL3_PauseAudioStreamDevice(SDL_AudioStream * dev); +}; + +namespace SoLoud +{ + static SDL_AudioSpec gActiveAudioSpec; + static SDL_AudioStream * gAudioStream; + static SDL_AudioDeviceID gAudioDeviceId; + + void soloud_sdl2_audiomixer(Uint8 * stream, void * userdata, int len) + { + SoLoud::Soloud *soloud = (SoLoud::Soloud *)userdata; + if (gActiveAudioSpec.format == SDL_AUDIO_F32) + { + int samples = len / (gActiveAudioSpec.channels * sizeof(float)); + soloud->mix((float *)stream, samples); + } + else // assume s16 if not float + { + int samples = len / (gActiveAudioSpec.channels * sizeof(short)); + soloud->mixSigned16((short *)stream, samples); + } + } + + void soloud_sdl3_audiomixer(void *userdata, SDL_AudioStream *stream, int additionalAmount, int totalAmount) + { + SoLoud::Soloud *soloud = (SoLoud::Soloud *)userdata; + + if (additionalAmount > 0) + { + Uint8 * data = SDL_stack_alloc(Uint8, additionalAmount); + if (data) + { + soloud_sdl2_audiomixer( + data, + userdata, + additionalAmount + ); + SDL_PutAudioStreamData(stream, data, additionalAmount); + SDL_stack_free(data); + } + } + } + + static void soloud_sdl3_deinit(SoLoud::Soloud * /*aSoloud*/) + { + dll_SDL3_CloseAudioDevice(gAudioDeviceId); + } + + result sdl3_init( + SoLoud::Soloud *aSoloud, + unsigned int aFlags, + unsigned int aSamplerate, + unsigned int aBuffer, + unsigned int aChannels, + unsigned int deviceId + ) + { + if (!dll_SDL3_found()) + return DLL_NOT_FOUND; + + if (!dll_SDL3_WasInit(SDL_INIT_AUDIO)) + { + if (dll_SDL3_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + return UNKNOWN_ERROR; + } + } + + SDL_AudioSpec as{}; + as.freq = aSamplerate; + as.format = SDL_AUDIO_F32; + as.channels = (Uint8)aChannels; + + auto * audioStream = dll_SDL3_OpenAudioDeviceStream( + deviceId, + &as, + soloud_sdl3_audiomixer, + static_cast(aSoloud) + ); + + auto const deviceIdFromStream = SDL_GetAudioStreamDevice(audioStream); + + gAudioDeviceId = deviceIdFromStream; + + if (gAudioDeviceId == NULL) + { + as.format = SDL_AUDIO_S16; + audioStream = dll_SDL3_OpenAudioDeviceStream( + deviceId, + NULL, + soloud_sdl3_audiomixer, + static_cast(aSoloud) + ); + + gAudioDeviceId = SDL_GetAudioStreamDevice(audioStream); + + if (gAudioDeviceId == NULL) + { + return UNKNOWN_ERROR; + } + } + + SDL_GetAudioDeviceFormat( + gAudioDeviceId, + &gActiveAudioSpec, + NULL + ); + + aSoloud->setDeviceId(gAudioDeviceId); + + aSoloud->postinit_internal( + gActiveAudioSpec.freq, + aBuffer, + aFlags, + gActiveAudioSpec.channels + ); + + aSoloud->mBackendCleanupFunc = soloud_sdl3_deinit; + + dll_SDL3_PauseAudioStreamDevice(gAudioStream); + aSoloud->mBackendString = "SDL3 (dynamic)"; + return 0; + } +}; +#endif diff --git a/src/backend/sdl/soloud_sdl3_dll.c b/src/backend/sdl/soloud_sdl3_dll.c new file mode 100644 index 00000000..e4185d96 --- /dev/null +++ b/src/backend/sdl/soloud_sdl3_dll.c @@ -0,0 +1,172 @@ +/* +SoLoud audio engine +Copyright (c) 2013-2018 Jari Komppa + +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. +*/ +#ifdef WITH_SDL3 + +#include +#if defined(_MSC_VER) +#define WINDOWS_VERSION +#endif +#include "SDL3/SDL.h" +#include + + +typedef Uint32 (*SDL3_WasInit_t)(Uint32 flags); +typedef int (*SDL3_InitSubSystem_t)(Uint32 flags); +typedef SDL_AudioStream * (*SDL3_OpenAudioDeviceStream_t)( + SDL_AudioDeviceID deviceId, + SDL_AudioSpec const * spec, + SDL_AudioStreamCallback callback, + void * userdata +); + +typedef void (*SDL3_CloseAudioDevice_t)(SDL_AudioDeviceID dev); +typedef bool (*SDL3_PauseAudioStreamDevice_t)(SDL_AudioStream * dev); + +static SDL3_WasInit_t SDL3_WasInit = NULL; +static SDL3_InitSubSystem_t SDL3_InitSubSystem = NULL; +static SDL3_OpenAudioDeviceStream_t SDL3_OpenAudioDeviceStream = NULL; +static SDL3_CloseAudioDevice_t SDL3_CloseAudioDevice = NULL; +static SDL3_PauseAudioStreamDevice_t SDL3_PauseAudioStreamDevice = NULL; + +#ifdef WINDOWS_VERSION +#include + +static HMODULE sdl3_openDll() +{ + HMODULE res = LoadLibraryA("SDL3.dll"); + return res; +} + +static void* sdl3_getDllProc(HMODULE aDllHandle, const char *aProcName) +{ + return (void*)GetProcAddress(aDllHandle, (LPCSTR)aProcName); +} + +#else +#include // dll functions + +static void * sdl3_openDll() +{ + void * res; + res = dlopen("/Library/Frameworks/SDL3.framework/SDL3", RTLD_LAZY); + if (!res) res = dlopen("SDL3.so", RTLD_LAZY); + if (!res) res = dlopen("libSDL3.so", RTLD_LAZY); + return res; +} + +static void* sdl3_getDllProc(void * aLibrary, const char *aProcName) +{ + return dlsym(aLibrary, aProcName); +} + +#endif + +static int sdl3_load_dll() +{ +#ifdef WINDOWS_VERSION + HMODULE dll = NULL; +#else + void * dll = NULL; +#endif + + if (SDL3_OpenAudioDeviceStream != NULL) + { + return 1; + } + + dll = sdl3_openDll(); + + if (dll) + { + SDL3_WasInit = (SDL3_WasInit_t)sdl3_getDllProc(dll, "SDL_WasInit"); + SDL3_InitSubSystem = (SDL3_InitSubSystem_t)sdl3_getDllProc(dll, "SDL_InitSubSystem"); + SDL3_OpenAudioDeviceStream = (SDL3_OpenAudioDeviceStream_t)sdl3_getDllProc(dll, "SDL_OpenAudioDeviceStream"); + SDL3_CloseAudioDevice = (SDL3_CloseAudioDevice_t)sdl3_getDllProc(dll, "SDL_CloseAudioDevice"); + SDL3_PauseAudioStreamDevice = (SDL3_PauseAudioStreamDevice_t)sdl3_getDllProc(dll, "SDL_PauseAudioStreamDevice"); + + if (SDL3_WasInit && + SDL3_InitSubSystem && + SDL3_OpenAudioDeviceStream && + SDL3_CloseAudioDevice && + SDL3_PauseAudioStreamDevice) + { + return 1; + } + } + SDL3_OpenAudioDeviceStream = NULL; + return 0; +} + +int dll_SDL3_found() +{ + return sdl3_load_dll(); +} + +Uint32 dll_SDL3_WasInit(Uint32 flags) +{ + if (SDL3_WasInit) + return SDL3_WasInit(flags); + return 0; +} + +int dll_SDL3_InitSubSystem(Uint32 flags) +{ + if (SDL3_InitSubSystem) + return SDL3_InitSubSystem(flags); + return -1; +} + +SDL_AudioStream * dll_SDL3_OpenAudioDeviceStream( + SDL_AudioDeviceID deviceId, + SDL_AudioSpec const * spec, + SDL_AudioStreamCallback callback, + void * userdata +) +{ + if (SDL3_OpenAudioDeviceStream) + { + return SDL3_OpenAudioDeviceStream( + deviceId, + spec, + callback, + userdata + ); + } + return 0; +} + +void dll_SDL3_CloseAudioDevice (SDL_AudioDeviceID dev) +{ + if (SDL3_CloseAudioDevice) + SDL3_CloseAudioDevice(dev); +} + +bool dll_SDL3_PauseAudioStreamDevice(SDL_AudioStream * dev) +{ + if (SDL3_PauseAudioStreamDevice) + return SDL3_PauseAudioStreamDevice(dev); + return false; +} + +#endif diff --git a/src/core/soloud.cpp b/src/core/soloud.cpp index e2544572..7a95111f 100644 --- a/src/core/soloud.cpp +++ b/src/core/soloud.cpp @@ -118,7 +118,7 @@ namespace SoLoud mBackendCleanupFunc = NULL; mBackendPauseFunc = NULL; mBackendResumeFunc = NULL; - mChannels = 2; + mChannels = 2; mStreamTime = 0; mLastClockedTime = 0; mAudioSourceID = 1; @@ -159,10 +159,10 @@ namespace SoLoud m3dAt[2] = -1; m3dUp[0] = 0; m3dUp[1] = 1; - m3dUp[2] = 0; + m3dUp[2] = 0; m3dVelocity[0] = 0; m3dVelocity[1] = 0; - m3dVelocity[2] = 0; + m3dVelocity[2] = 0; m3dSoundSpeed = 343.3f; mMaxActiveVoices = 16; mHighestVoice = 0; @@ -205,7 +205,7 @@ namespace SoLoud } result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels) - { + { if (aBackend >= BACKEND_MAX || aChannels == 3 || aChannels == 5 || aChannels == 7 || aChannels > MAX_CHANNELS) return INVALID_PARAMETER; @@ -225,7 +225,7 @@ namespace SoLoud #if defined(WITH_SDL1_STATIC) if (!inited && - (aBackend == Soloud::SDL1 || + (aBackend == Soloud::SDL1 || aBackend == Soloud::AUTO)) { if (aBufferSize == Soloud::AUTO) buffersize = 2048; @@ -238,7 +238,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -282,7 +282,7 @@ namespace SoLoud #if defined(WITH_SDL1) if (!inited && - (aBackend == Soloud::SDL1 || + (aBackend == Soloud::SDL1 || aBackend == Soloud::AUTO)) { if (aBufferSize == Soloud::AUTO) buffersize = 2048; @@ -295,7 +295,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -333,7 +333,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -352,7 +352,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -371,7 +371,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -391,7 +391,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -410,7 +410,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -429,7 +429,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -448,7 +448,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -467,7 +467,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -486,7 +486,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -505,13 +505,13 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif #if defined(WITH_VITA_HOMEBREW) if (!inited && - (aBackend == Soloud::VITA_HOMEBREW || + (aBackend == Soloud::VITA_HOMEBREW || aBackend == Soloud::AUTO)) { int ret = vita_homebrew_init(this, aFlags, samplerate, buffersize, aChannels); @@ -522,7 +522,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -560,7 +560,7 @@ namespace SoLoud } if (ret != 0) - return ret; + return ret; } #endif @@ -571,6 +571,58 @@ namespace SoLoud return 0; } + result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels, int deviceId) + { +#if defined(WITH_SDL3) + if (aBackend >= BACKEND_MAX || aChannels == 3 || aChannels == 5 || aChannels == 7 || aChannels > MAX_CHANNELS) + return INVALID_PARAMETER; + + deinit(); + + mAudioThreadMutex = Thread::createMutex(); + + mBackendID = 0; + mBackendString = 0; + + int samplerate = 44100; + int buffersize = 2048; + int inited = 0; + + if (aSamplerate != Soloud::AUTO) samplerate = aSamplerate; + if (aBufferSize != Soloud::AUTO) buffersize = aBufferSize; + + if (!inited && + (aBackend == Soloud::SDL3 || + aBackend == Soloud::AUTO)) + { + if (aBufferSize == Soloud::AUTO) buffersize = 2048; + + int ret = sdl3_init( + this, + aFlags, + samplerate, + buffersize, + aChannels, + deviceId + ); + + if (ret == 0) + { + inited = 1; + mBackendID = Soloud::SDL3; + } + + if (ret != 0 && aBackend != Soloud::AUTO) + return ret; + } +#endif + if (!inited && aBackend != Soloud::AUTO) + return NOT_IMPLEMENTED; + if (!inited) + return UNKNOWN_ERROR; + return 0; + } + result Soloud::pause() { if (mBackendPauseFunc) @@ -589,7 +641,7 @@ namespace SoLoud void Soloud::postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels) - { + { mGlobalVolume = 1; mChannels = aChannels; mSamplerate = aSamplerate; @@ -602,7 +654,7 @@ namespace SoLoud mResampleData = new float*[mMaxActiveVoices * 2]; mResampleDataOwner = new AudioSourceInstance*[mMaxActiveVoices]; mResampleDataBuffer.init(mMaxActiveVoices * 2 * SAMPLE_GRANULARITY * MAX_CHANNELS); - unsigned int i; + unsigned int i; for (i = 0; i < mMaxActiveVoices * 2; i++) mResampleData[i] = mResampleDataBuffer.mData + (SAMPLE_GRANULARITY * MAX_CHANNELS * i); for (i = 0; i < mMaxActiveVoices; i++) @@ -648,7 +700,7 @@ namespace SoLoud m3dSpeakerPosition[1 * 3 + 1] = 0; m3dSpeakerPosition[1 * 3 + 2] = 1; - // center and subwoofer. + // center and subwoofer. m3dSpeakerPosition[2 * 3 + 0] = 0; m3dSpeakerPosition[2 * 3 + 1] = 0; m3dSpeakerPosition[2 * 3 + 2] = 1; @@ -674,7 +726,7 @@ namespace SoLoud m3dSpeakerPosition[1 * 3 + 1] = 0; m3dSpeakerPosition[1 * 3 + 2] = 1; - // center and subwoofer. + // center and subwoofer. m3dSpeakerPosition[2 * 3 + 0] = 0; m3dSpeakerPosition[2 * 3 + 1] = 0; m3dSpeakerPosition[2 * 3 + 2] = 1; @@ -853,7 +905,7 @@ namespace SoLoud for (j = 0; j < mChannels; j++) { __m128 vol = _mm_load_ps(volumes.mData); - for (i = 0; i < samplequads; i++) + for (i = 0; i < samplequads; i++) { //float f1 = aBuffer.mData[c] * v; c++; v += vd; __m128 f = _mm_load_ps(&aBuffer.mData[c]); @@ -914,7 +966,7 @@ namespace SoLoud for (j = 0; j < mChannels; j++) { v = aVolume0; - for (i = 0; i < samplequads; i++) + for (i = 0; i < samplequads; i++) { float f1 = aBuffer.mData[c] * v; c++; v += vd; float f2 = aBuffer.mData[c] * v; c++; v += vd; @@ -1171,7 +1223,7 @@ namespace SoLoud c += 4; } } - + // If buffer size or samples to read are not divisible by 4, handle leftovers for (j = c; j < aSamplesToRead; j++) { @@ -1611,7 +1663,7 @@ namespace SoLoud } } - // Accumulate sound sources + // Accumulate sound sources for (i = 0; i < mActiveVoiceCount; i++) { AudioSourceInstance *voice = mVoice[mActiveVoice[i]]; @@ -1626,7 +1678,7 @@ namespace SoLoud step = 0; unsigned int step_fixed = (int)floor(step * FIXPOINT_FRAC_MUL); unsigned int outofs = 0; - + if (voice->mDelaySamples) { if (voice->mDelaySamples > aSamplesToRead) @@ -1639,14 +1691,14 @@ namespace SoLoud outofs = voice->mDelaySamples; voice->mDelaySamples = 0; } - + // Clear scratch where we're skipping unsigned int k; for (k = 0; k < voice->mChannels; k++) { - memset(aScratch + k * aBufferSize, 0, sizeof(float) * outofs); + memset(aScratch + k * aBufferSize, 0, sizeof(float) * outofs); } - } + } while (step_fixed != 0 && outofs < aSamplesToRead) { @@ -1697,7 +1749,7 @@ namespace SoLoud voice->mSrcOffset -= SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL; } - + // Run the per-stream filters to get our source data for (j = 0; j < FILTERS_PER_STREAM; j++) @@ -1789,7 +1841,7 @@ namespace SoLoud // Move source pointer onwards (writesamples may be zero) voice->mSrcOffset += writesamples * step_fixed; } - + // Handle panning and channel expansion (and/or shrinking) panAndExpand(voice, aBuffer, aSamplesToRead, aBufferSize, aScratch, aChannels); @@ -2017,37 +2069,37 @@ namespace SoLoud int len = candidates - mustlive; unsigned int *data = mActiveVoice + mustlive; int k = mActiveVoiceCount; - for (;;) - { - for (; left + 1 < len; len++) - { - if (pos == 24) len = stack[pos = 0]; + for (;;) + { + for (; left + 1 < len; len++) + { + if (pos == 24) len = stack[pos = 0]; int pivot = data[left]; float pivotvol = mVoice[pivot]->mOverallVolume; - stack[pos++] = len; - for (right = left - 1;;) + stack[pos++] = len; + for (right = left - 1;;) { - do + do { right++; - } + } while (mVoice[data[right]]->mOverallVolume > pivotvol); do { len--; } while (pivotvol > mVoice[data[len]]->mOverallVolume); - if (right >= len) break; + if (right >= len) break; int temp = data[right]; data[right] = data[len]; data[len] = temp; - } + } } - if (pos == 0) break; + if (pos == 0) break; if (left >= k) break; - left = len; - len = stack[--pos]; - } + left = len; + len = stack[--pos]; + } // TODO: should the rest of the voices be flagged INAUDIBLE? mapResampleBuffers_internal(); } @@ -2144,7 +2196,7 @@ namespace SoLoud mVoice[i]->mStreamPosition += (double)buffertime * (double)mVoice[i]->mOverallRelativePlaySpeed; // TODO: this is actually unstable, because mStreamTime depends on the relative - // play speed. + // play speed. if (mVoice[i]->mRelativePlaySpeedFader.mActive > 0) { float speed = mVoice[i]->mRelativePlaySpeedFader.get(mVoice[i]->mStreamTime); @@ -2192,7 +2244,7 @@ namespace SoLoud if (mActiveVoiceDirty) calcActiveVoices_internal(); - + mixBus_internal(mOutputScratch.mData, aSamples, aStride, mScratch.mData, 0, (float)mSamplerate, mChannels, mResampler); for (i = 0; i < FILTERS_PER_STREAM; i++) @@ -2204,7 +2256,7 @@ namespace SoLoud } unlockAudioMutex_internal(); - + // Note: clipping channels*aStride, not channels*aSamples, so we're possibly clipping some unused data. // The buffers should be large enough for it, we just may do a few bytes of unneccessary work. clip_internal(mOutputScratch, mScratch, aStride, globalVolume[0], globalVolume[1]); diff --git a/src/core/soloud_core_getters.cpp b/src/core/soloud_core_getters.cpp index 2fca9a6c..b1f99ba6 100644 --- a/src/core/soloud_core_getters.cpp +++ b/src/core/soloud_core_getters.cpp @@ -61,7 +61,7 @@ namespace SoLoud handle *h = voiceGroupHandleToArray_internal(aVoiceHandle); if (h != NULL) aVoiceHandle = *h; - if (aVoiceHandle == 0) + if (aVoiceHandle == 0) { return -1; } @@ -73,7 +73,7 @@ namespace SoLoud { return ch; } - return -1; + return -1; } unsigned int Soloud::getMaxActiveVoiceCount() const @@ -98,7 +98,7 @@ namespace SoLoud int c = 0; for (i = 0; i < (signed)mHighestVoice; i++) { - if (mVoice[i]) + if (mVoice[i]) { c++; } @@ -184,7 +184,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -212,7 +212,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -226,7 +226,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -254,7 +254,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 1; @@ -268,7 +268,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -282,7 +282,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -296,7 +296,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -311,11 +311,11 @@ namespace SoLoud int i; unsigned int lowest_play_index_value = 0xffffffff; int lowest_play_index = -1; - + // (slowly) drag the highest active voice index down if (mHighestVoice > 0 && mVoice[mHighestVoice - 1] == NULL) mHighestVoice--; - + for (i = 0; i < VOICE_COUNT; i++) { if (mVoice[i] == NULL) @@ -326,7 +326,7 @@ namespace SoLoud } return i; } - if (((mVoice[i]->mFlags & AudioSourceInstance::PROTECTED) == 0) && + if (((mVoice[i]->mFlags & AudioSourceInstance::PROTECTED) == 0) && mVoice[i]->mPlayIndex < lowest_play_index_value) { lowest_play_index_value = mVoice[i]->mPlayIndex; @@ -341,7 +341,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -382,6 +382,12 @@ namespace SoLoud return mBufferSize; } + // Returns current backend device ID + unsigned int Soloud::getBackendDeviceId() + { + return mBackendDeviceId; + } + // Get speaker position in 3d space result Soloud::getSpeakerPosition(unsigned int aChannel, float &aX, float &aY, float &aZ) { diff --git a/src/core/soloud_core_setters.cpp b/src/core/soloud_core_setters.cpp index 718ff8ec..38c80e16 100644 --- a/src/core/soloud_core_setters.cpp +++ b/src/core/soloud_core_setters.cpp @@ -43,7 +43,7 @@ namespace SoLoud { mGlobalVolumeFader.mActive = 0; mGlobalVolume = aVolume; - } + } result Soloud::setRelativePlaySpeed(handle aVoiceHandle, float aSpeed) { @@ -117,14 +117,14 @@ namespace SoLoud } void Soloud::setPan(handle aVoiceHandle, float aPan) - { + { FOR_ALL_VOICES_PRE setVoicePan_internal(ch, aPan); FOR_ALL_VOICES_POST } void Soloud::setChannelVolume(handle aVoiceHandle, unsigned int aChannel, float aVolume) - { + { FOR_ALL_VOICES_PRE if (mVoice[ch]->mChannels > aChannel) { @@ -136,8 +136,8 @@ namespace SoLoud void Soloud::setPanAbsolute(handle aVoiceHandle, float aLVolume, float aRVolume) { FOR_ALL_VOICES_PRE - mVoice[ch]->mPanFader.mActive = 0; - mVoice[ch]->mChannelVolume[0] = aLVolume; + mVoice[ch]->mPanFader.mActive = 0; + mVoice[ch]->mChannelVolume[0] = aLVolume; mVoice[ch]->mChannelVolume[1] = aRVolume; if (mVoice[ch]->mChannels == 4) { @@ -250,4 +250,8 @@ namespace SoLoud return SO_NO_ERROR; } + void Soloud::setBackendDeviceId(unsigned int deviceId) + { + mBackendDeviceId = deviceId; + } } From 2dc2fd15cb43ba5b587f02c8eef4390df1780cda Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 26 Feb 2025 04:51:41 -0500 Subject: [PATCH 2/7] Added my name to AUTHORS. --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index e8a1b8eb..92d863a5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -40,3 +40,4 @@ lexander Yashin https://github.com/yashin-alexander Nils Duval https://github.com/nlsdvl JackRedstonia jackredstonia64@gmail.com David Bullock https://github.com/dwbullock +Sam Gubernick https://github.com/samgubernick From acfb367a253ff30c3085be1d17e0ea0cbea2b2a5 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 26 Feb 2025 05:12:53 -0500 Subject: [PATCH 3/7] Require deviceId in init overload for SDL3. --- include/soloud.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/soloud.h b/include/soloud.h index d6d7f12f..3ed6bbba 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -233,7 +233,7 @@ namespace SoLoud result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2); // Initialize SoLoud. Must be called before SoLoud can be used. - result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, int deviceId = NULL ); + result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, int deviceId); result pause(); result resume(); From 924251ddce7c350d6c471d96c9772aea38ec4b28 Mon Sep 17 00:00:00 2001 From: Sam Gubernick Date: Fri, 28 Feb 2025 23:50:14 -0500 Subject: [PATCH 4/7] Simplify changes by using mBackendData; add data object for SDL3 backend. --- include/soloud.h | 12 +- include/soloud_backend_data_sdl3.h | 53 ++++++++ include/soloud_internal.h | 3 + src/backend/sdl/soloud_sdl3.cpp | 59 +++++---- src/core/soloud.cpp | 205 +++++++++++++---------------- src/core/soloud_core_getters.cpp | 34 ++--- src/core/soloud_core_setters.cpp | 15 +-- 7 files changed, 201 insertions(+), 180 deletions(-) create mode 100644 include/soloud_backend_data_sdl3.h diff --git a/include/soloud.h b/include/soloud.h index 3ed6bbba..5a8c3c50 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -230,13 +230,9 @@ namespace SoLoud }; // Initialize SoLoud. Must be called before SoLoud can be used. - result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2); - - // Initialize SoLoud. Must be called before SoLoud can be used. - result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, int deviceId); - + result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, void const * clientData = NULL); result pause(); - result resume(); + result resume(); // Deinitialize SoLoud. Must be called before shutting down. void deinit(); @@ -257,10 +253,6 @@ namespace SoLoud unsigned int getBackendSamplerate(); // Returns current backend buffer size unsigned int getBackendBufferSize(); - // Returns current backend device ID - unsigned int getBackendDeviceId(); - // Sets the backend device ID - void setBackendDeviceId(unsigned int deviceId); // Set speaker position in 3d space result setSpeakerPosition(unsigned int aChannel, float aX, float aY, float aZ); diff --git a/include/soloud_backend_data_sdl3.h b/include/soloud_backend_data_sdl3.h new file mode 100644 index 00000000..34cb56ef --- /dev/null +++ b/include/soloud_backend_data_sdl3.h @@ -0,0 +1,53 @@ +/* +SoLoud audio engine +Copyright (c) 2013-2015 Jari Komppa + +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 SOLOUD_BACKEND_DATA_SDL3_H +#define SOLOUD_BACKEND_DATA_SDL3_H + +#include "SDL3/SDL.h" + +namespace SoLoud +{ + struct SoLoudBackendDataSdl3 + { + SoLoudBackendDataSdl3() + : audioStream{NULL} + , audioDeviceId{0} + , activeAudioSpec{} + {} + SDL_AudioStream * audioStream; + SDL_AudioDeviceID audioDeviceId; + SDL_AudioSpec activeAudioSpec; + }; + + struct SoLoudClientDataSdl3 + { + SoLoudClientDataSdl3(unsigned int deviceId) + : deviceId(deviceId) + {} + unsigned int deviceId; + }; +} + +#endif diff --git a/include/soloud_internal.h b/include/soloud_internal.h index c0589abd..de20acaf 100644 --- a/include/soloud_internal.h +++ b/include/soloud_internal.h @@ -35,6 +35,9 @@ namespace SoLoud // SDL2 back-end initialization call result sdl2_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2); + // SDL3 back-end initialization call + result sdl3_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2, void const * clientData = NULL); + // SDL1 "non-dynamic" back-end initialization call result sdl1static_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2); diff --git a/src/backend/sdl/soloud_sdl3.cpp b/src/backend/sdl/soloud_sdl3.cpp index 47f8ff4c..1c8bb6a1 100644 --- a/src/backend/sdl/soloud_sdl3.cpp +++ b/src/backend/sdl/soloud_sdl3.cpp @@ -1,3 +1,4 @@ + /* SoLoud audio engine Copyright (c) 2013-2018 Jari Komppa @@ -24,6 +25,7 @@ freely, subject to the following restrictions: #include #include "soloud.h" +#include "soloud_backend_data_sdl3.h" #if !defined(WITH_SDL3) @@ -35,7 +37,7 @@ namespace SoLoud unsigned int aSamplerate, unsigned int aBuffer, unsigned int aChannels, - int deviceId + void const * backendData ) { return NOT_IMPLEMENTED; @@ -65,21 +67,19 @@ extern "C" namespace SoLoud { - static SDL_AudioSpec gActiveAudioSpec; - static SDL_AudioStream * gAudioStream; - static SDL_AudioDeviceID gAudioDeviceId; + static SoLoudBackendDataSdl3 gBackendData{}; void soloud_sdl2_audiomixer(Uint8 * stream, void * userdata, int len) { SoLoud::Soloud *soloud = (SoLoud::Soloud *)userdata; - if (gActiveAudioSpec.format == SDL_AUDIO_F32) + if (gBackendData.activeAudioSpec.format == SDL_AUDIO_F32) { - int samples = len / (gActiveAudioSpec.channels * sizeof(float)); + int samples = len / (gBackendData.activeAudioSpec.channels * sizeof(float)); soloud->mix((float *)stream, samples); } else // assume s16 if not float { - int samples = len / (gActiveAudioSpec.channels * sizeof(short)); + int samples = len / (gBackendData.activeAudioSpec.channels * sizeof(short)); soloud->mixSigned16((short *)stream, samples); } } @@ -106,7 +106,7 @@ namespace SoLoud static void soloud_sdl3_deinit(SoLoud::Soloud * /*aSoloud*/) { - dll_SDL3_CloseAudioDevice(gAudioDeviceId); + dll_SDL3_CloseAudioDevice(gBackendData.audioDeviceId); } result sdl3_init( @@ -115,7 +115,7 @@ namespace SoLoud unsigned int aSamplerate, unsigned int aBuffer, unsigned int aChannels, - unsigned int deviceId + void const * clientData ) { if (!dll_SDL3_found()) @@ -129,58 +129,67 @@ namespace SoLoud } } + SoLoudClientDataSdl3 const * data = NULL; + if (clientData != NULL) + { + data = static_cast(clientData); + gBackendData.audioDeviceId = data->deviceId; + } + else + { + gBackendData.audioDeviceId = 0; + } + + SDL_AudioDeviceID const deviceId = gBackendData.audioDeviceId; SDL_AudioSpec as{}; as.freq = aSamplerate; as.format = SDL_AUDIO_F32; as.channels = (Uint8)aChannels; - auto * audioStream = dll_SDL3_OpenAudioDeviceStream( - deviceId, + gBackendData.audioStream = dll_SDL3_OpenAudioDeviceStream( + gBackendData.audioDeviceId, &as, soloud_sdl3_audiomixer, static_cast(aSoloud) ); - auto const deviceIdFromStream = SDL_GetAudioStreamDevice(audioStream); + gBackendData.audioDeviceId = SDL_GetAudioStreamDevice(gBackendData.audioStream); - gAudioDeviceId = deviceIdFromStream; - - if (gAudioDeviceId == NULL) + if (gBackendData.audioDeviceId == NULL) { as.format = SDL_AUDIO_S16; - audioStream = dll_SDL3_OpenAudioDeviceStream( + gBackendData.audioStream = dll_SDL3_OpenAudioDeviceStream( deviceId, NULL, soloud_sdl3_audiomixer, static_cast(aSoloud) ); - gAudioDeviceId = SDL_GetAudioStreamDevice(audioStream); + gBackendData.audioDeviceId = SDL_GetAudioStreamDevice(gBackendData.audioStream); - if (gAudioDeviceId == NULL) + if (gBackendData.audioDeviceId == NULL) { return UNKNOWN_ERROR; } } SDL_GetAudioDeviceFormat( - gAudioDeviceId, - &gActiveAudioSpec, + gBackendData.audioDeviceId, + &gBackendData.activeAudioSpec, NULL ); - aSoloud->setDeviceId(gAudioDeviceId); - aSoloud->postinit_internal( - gActiveAudioSpec.freq, + gBackendData.activeAudioSpec.freq, aBuffer, aFlags, - gActiveAudioSpec.channels + gBackendData.activeAudioSpec.channels ); aSoloud->mBackendCleanupFunc = soloud_sdl3_deinit; - dll_SDL3_PauseAudioStreamDevice(gAudioStream); + dll_SDL3_PauseAudioStreamDevice(gBackendData.audioStream); + aSoloud->mBackendData = &gBackendData; aSoloud->mBackendString = "SDL3 (dynamic)"; return 0; } diff --git a/src/core/soloud.cpp b/src/core/soloud.cpp index 7a95111f..c6bb2a8a 100644 --- a/src/core/soloud.cpp +++ b/src/core/soloud.cpp @@ -41,7 +41,7 @@ freely, subject to the following restrictions: //#define FLOATING_POINT_DEBUG -#if !defined(WITH_SDL2) && !defined(WITH_SDL1) && !defined(WITH_PORTAUDIO) && \ +#if !defined(WITH_SDL3) && !defined(WITH_SDL2) && !defined(WITH_SDL1) && !defined(WITH_PORTAUDIO) && \ !defined(WITH_OPENAL) && !defined(WITH_XAUDIO2) && !defined(WITH_WINMM) && \ !defined(WITH_WASAPI) && !defined(WITH_OSS) && !defined(WITH_SDL1_STATIC) && \ !defined(WITH_SDL2_STATIC) && !defined(WITH_ALSA) && !defined(WITH_OPENSLES) && \ @@ -118,7 +118,7 @@ namespace SoLoud mBackendCleanupFunc = NULL; mBackendPauseFunc = NULL; mBackendResumeFunc = NULL; - mChannels = 2; + mChannels = 2; mStreamTime = 0; mLastClockedTime = 0; mAudioSourceID = 1; @@ -159,10 +159,10 @@ namespace SoLoud m3dAt[2] = -1; m3dUp[0] = 0; m3dUp[1] = 1; - m3dUp[2] = 0; + m3dUp[2] = 0; m3dVelocity[0] = 0; m3dVelocity[1] = 0; - m3dVelocity[2] = 0; + m3dVelocity[2] = 0; m3dSoundSpeed = 343.3f; mMaxActiveVoices = 16; mHighestVoice = 0; @@ -204,7 +204,7 @@ namespace SoLoud mAudioThreadMutex = NULL; } - result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels) + result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels, void const * clientData) { if (aBackend >= BACKEND_MAX || aChannels == 3 || aChannels == 5 || aChannels == 7 || aChannels > MAX_CHANNELS) return INVALID_PARAMETER; @@ -225,7 +225,7 @@ namespace SoLoud #if defined(WITH_SDL1_STATIC) if (!inited && - (aBackend == Soloud::SDL1 || + (aBackend == Soloud::SDL1 || aBackend == Soloud::AUTO)) { if (aBufferSize == Soloud::AUTO) buffersize = 2048; @@ -238,7 +238,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -261,6 +261,33 @@ namespace SoLoud } #endif +#if defined(WITH_SDL3) + if (!inited && + (aBackend == Soloud::SDL3 || + aBackend == Soloud::AUTO)) + { + if (aBufferSize == Soloud::AUTO) buffersize = 2048; + + int ret = sdl3_init( + this, + aFlags, + samplerate, + buffersize, + aChannels, + clientData + ); + + if (ret == 0) + { + inited = 1; + mBackendID = Soloud::SDL3; + } + + if (ret != 0 && aBackend != Soloud::AUTO) + return ret; + } +#endif + #if defined(WITH_SDL2) if (!inited && (aBackend == Soloud::SDL2 || @@ -282,7 +309,7 @@ namespace SoLoud #if defined(WITH_SDL1) if (!inited && - (aBackend == Soloud::SDL1 || + (aBackend == Soloud::SDL1 || aBackend == Soloud::AUTO)) { if (aBufferSize == Soloud::AUTO) buffersize = 2048; @@ -295,7 +322,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -333,7 +360,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -352,7 +379,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -371,7 +398,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -391,7 +418,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -410,10 +437,10 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif - + #if defined(WITH_JACK) if (!inited && (aBackend == Soloud::JACK || @@ -429,7 +456,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -448,7 +475,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -467,7 +494,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -486,7 +513,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -505,13 +532,13 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif #if defined(WITH_VITA_HOMEBREW) if (!inited && - (aBackend == Soloud::VITA_HOMEBREW || + (aBackend == Soloud::VITA_HOMEBREW || aBackend == Soloud::AUTO)) { int ret = vita_homebrew_init(this, aFlags, samplerate, buffersize, aChannels); @@ -522,7 +549,7 @@ namespace SoLoud } if (ret != 0 && aBackend != Soloud::AUTO) - return ret; + return ret; } #endif @@ -560,7 +587,7 @@ namespace SoLoud } if (ret != 0) - return ret; + return ret; } #endif @@ -571,58 +598,7 @@ namespace SoLoud return 0; } - result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels, int deviceId) - { -#if defined(WITH_SDL3) - if (aBackend >= BACKEND_MAX || aChannels == 3 || aChannels == 5 || aChannels == 7 || aChannels > MAX_CHANNELS) - return INVALID_PARAMETER; - - deinit(); - - mAudioThreadMutex = Thread::createMutex(); - - mBackendID = 0; - mBackendString = 0; - - int samplerate = 44100; - int buffersize = 2048; - int inited = 0; - - if (aSamplerate != Soloud::AUTO) samplerate = aSamplerate; - if (aBufferSize != Soloud::AUTO) buffersize = aBufferSize; - - if (!inited && - (aBackend == Soloud::SDL3 || - aBackend == Soloud::AUTO)) - { - if (aBufferSize == Soloud::AUTO) buffersize = 2048; - - int ret = sdl3_init( - this, - aFlags, - samplerate, - buffersize, - aChannels, - deviceId - ); - - if (ret == 0) - { - inited = 1; - mBackendID = Soloud::SDL3; - } - - if (ret != 0 && aBackend != Soloud::AUTO) - return ret; - } -#endif - if (!inited && aBackend != Soloud::AUTO) - return NOT_IMPLEMENTED; - if (!inited) - return UNKNOWN_ERROR; - return 0; - } - + result Soloud::pause() { if (mBackendPauseFunc) @@ -638,10 +614,10 @@ namespace SoLoud return NOT_IMPLEMENTED; } - - + + void Soloud::postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels) - { + { mGlobalVolume = 1; mChannels = aChannels; mSamplerate = aSamplerate; @@ -700,7 +676,7 @@ namespace SoLoud m3dSpeakerPosition[1 * 3 + 1] = 0; m3dSpeakerPosition[1 * 3 + 2] = 1; - // center and subwoofer. + // center and subwoofer. m3dSpeakerPosition[2 * 3 + 0] = 0; m3dSpeakerPosition[2 * 3 + 1] = 0; m3dSpeakerPosition[2 * 3 + 2] = 1; @@ -726,7 +702,7 @@ namespace SoLoud m3dSpeakerPosition[1 * 3 + 1] = 0; m3dSpeakerPosition[1 * 3 + 2] = 1; - // center and subwoofer. + // center and subwoofer. m3dSpeakerPosition[2 * 3 + 0] = 0; m3dSpeakerPosition[2 * 3 + 1] = 0; m3dSpeakerPosition[2 * 3 + 2] = 1; @@ -905,7 +881,7 @@ namespace SoLoud for (j = 0; j < mChannels; j++) { __m128 vol = _mm_load_ps(volumes.mData); - for (i = 0; i < samplequads; i++) + for (i = 0; i < samplequads; i++) { //float f1 = aBuffer.mData[c] * v; c++; v += vd; __m128 f = _mm_load_ps(&aBuffer.mData[c]); @@ -966,7 +942,7 @@ namespace SoLoud for (j = 0; j < mChannels; j++) { v = aVolume0; - for (i = 0; i < samplequads; i++) + for (i = 0; i < samplequads; i++) { float f1 = aBuffer.mData[c] * v; c++; v += vd; float f2 = aBuffer.mData[c] * v; c++; v += vd; @@ -1005,9 +981,9 @@ namespace SoLoud static void resample_catmullrom(float* aSrc, float* aSrc1, float* aDst, - int aSrcOffset, - int aDstSampleCount, - int aStepFixed) + int aSrcOffset, + int aDstSampleCount, + int aStepFixed) { int i; int pos = aSrcOffset; @@ -1663,7 +1639,7 @@ namespace SoLoud } } - // Accumulate sound sources + // Accumulate sound sources for (i = 0; i < mActiveVoiceCount; i++) { AudioSourceInstance *voice = mVoice[mActiveVoice[i]]; @@ -1678,7 +1654,7 @@ namespace SoLoud step = 0; unsigned int step_fixed = (int)floor(step * FIXPOINT_FRAC_MUL); unsigned int outofs = 0; - + if (voice->mDelaySamples) { if (voice->mDelaySamples > aSamplesToRead) @@ -1691,14 +1667,14 @@ namespace SoLoud outofs = voice->mDelaySamples; voice->mDelaySamples = 0; } - + // Clear scratch where we're skipping unsigned int k; for (k = 0; k < voice->mChannels; k++) { - memset(aScratch + k * aBufferSize, 0, sizeof(float) * outofs); + memset(aScratch + k * aBufferSize, 0, sizeof(float) * outofs); } - } + } while (step_fixed != 0 && outofs < aSamplesToRead) { @@ -1749,7 +1725,7 @@ namespace SoLoud voice->mSrcOffset -= SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL; } - + // Run the per-stream filters to get our source data for (j = 0; j < FILTERS_PER_STREAM; j++) @@ -1758,7 +1734,7 @@ namespace SoLoud { voice->mFilter[j]->filter( voice->mResampleData[0], - SAMPLE_GRANULARITY, + SAMPLE_GRANULARITY, SAMPLE_GRANULARITY, voice->mChannels, voice->mSamplerate, @@ -1803,12 +1779,12 @@ namespace SoLoud case RESAMPLER_POINT: resample_point(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, voice->mResampleData[1] + SAMPLE_GRANULARITY * j, - aScratch + aBufferSize * j + outofs, - voice->mSrcOffset, - writesamples, + aScratch + aBufferSize * j + outofs, + voice->mSrcOffset, + writesamples, /*voice->mSamplerate, aSamplerate,*/ - step_fixed); + step_fixed); break; case RESAMPLER_CATMULLROM: resample_catmullrom(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, @@ -1831,9 +1807,9 @@ namespace SoLoud aSamplerate,*/ step_fixed); break; - } } } + } // Keep track of how many samples we've written so far outofs += writesamples; @@ -1841,7 +1817,7 @@ namespace SoLoud // Move source pointer onwards (writesamples may be zero) voice->mSrcOffset += writesamples * step_fixed; } - + // Handle panning and channel expansion (and/or shrinking) panAndExpand(voice, aBuffer, aSamplesToRead, aBufferSize, aScratch, aChannels); @@ -2069,37 +2045,37 @@ namespace SoLoud int len = candidates - mustlive; unsigned int *data = mActiveVoice + mustlive; int k = mActiveVoiceCount; - for (;;) - { - for (; left + 1 < len; len++) - { - if (pos == 24) len = stack[pos = 0]; + for (;;) + { + for (; left + 1 < len; len++) + { + if (pos == 24) len = stack[pos = 0]; int pivot = data[left]; float pivotvol = mVoice[pivot]->mOverallVolume; - stack[pos++] = len; - for (right = left - 1;;) + stack[pos++] = len; + for (right = left - 1;;) { - do + do { right++; - } + } while (mVoice[data[right]]->mOverallVolume > pivotvol); do { len--; } while (pivotvol > mVoice[data[len]]->mOverallVolume); - if (right >= len) break; + if (right >= len) break; int temp = data[right]; data[right] = data[len]; data[len] = temp; - } + } } - if (pos == 0) break; + if (pos == 0) break; if (left >= k) break; - left = len; - len = stack[--pos]; - } + left = len; + len = stack[--pos]; + } // TODO: should the rest of the voices be flagged INAUDIBLE? mapResampleBuffers_internal(); } @@ -2196,7 +2172,7 @@ namespace SoLoud mVoice[i]->mStreamPosition += (double)buffertime * (double)mVoice[i]->mOverallRelativePlaySpeed; // TODO: this is actually unstable, because mStreamTime depends on the relative - // play speed. + // play speed. if (mVoice[i]->mRelativePlaySpeedFader.mActive > 0) { float speed = mVoice[i]->mRelativePlaySpeedFader.get(mVoice[i]->mStreamTime); @@ -2368,5 +2344,4 @@ namespace SoLoud Thread::unlockMutex(mAudioThreadMutex); } } - }; diff --git a/src/core/soloud_core_getters.cpp b/src/core/soloud_core_getters.cpp index b1f99ba6..2fca9a6c 100644 --- a/src/core/soloud_core_getters.cpp +++ b/src/core/soloud_core_getters.cpp @@ -61,7 +61,7 @@ namespace SoLoud handle *h = voiceGroupHandleToArray_internal(aVoiceHandle); if (h != NULL) aVoiceHandle = *h; - if (aVoiceHandle == 0) + if (aVoiceHandle == 0) { return -1; } @@ -73,7 +73,7 @@ namespace SoLoud { return ch; } - return -1; + return -1; } unsigned int Soloud::getMaxActiveVoiceCount() const @@ -98,7 +98,7 @@ namespace SoLoud int c = 0; for (i = 0; i < (signed)mHighestVoice; i++) { - if (mVoice[i]) + if (mVoice[i]) { c++; } @@ -184,7 +184,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -212,7 +212,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -226,7 +226,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -254,7 +254,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 1; @@ -268,7 +268,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -282,7 +282,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -296,7 +296,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -311,11 +311,11 @@ namespace SoLoud int i; unsigned int lowest_play_index_value = 0xffffffff; int lowest_play_index = -1; - + // (slowly) drag the highest active voice index down if (mHighestVoice > 0 && mVoice[mHighestVoice - 1] == NULL) mHighestVoice--; - + for (i = 0; i < VOICE_COUNT; i++) { if (mVoice[i] == NULL) @@ -326,7 +326,7 @@ namespace SoLoud } return i; } - if (((mVoice[i]->mFlags & AudioSourceInstance::PROTECTED) == 0) && + if (((mVoice[i]->mFlags & AudioSourceInstance::PROTECTED) == 0) && mVoice[i]->mPlayIndex < lowest_play_index_value) { lowest_play_index_value = mVoice[i]->mPlayIndex; @@ -341,7 +341,7 @@ namespace SoLoud { lockAudioMutex_internal(); int ch = getVoiceFromHandle_internal(aVoiceHandle); - if (ch == -1) + if (ch == -1) { unlockAudioMutex_internal(); return 0; @@ -382,12 +382,6 @@ namespace SoLoud return mBufferSize; } - // Returns current backend device ID - unsigned int Soloud::getBackendDeviceId() - { - return mBackendDeviceId; - } - // Get speaker position in 3d space result Soloud::getSpeakerPosition(unsigned int aChannel, float &aX, float &aY, float &aZ) { diff --git a/src/core/soloud_core_setters.cpp b/src/core/soloud_core_setters.cpp index 38c80e16..26b52319 100644 --- a/src/core/soloud_core_setters.cpp +++ b/src/core/soloud_core_setters.cpp @@ -43,7 +43,7 @@ namespace SoLoud { mGlobalVolumeFader.mActive = 0; mGlobalVolume = aVolume; - } + } result Soloud::setRelativePlaySpeed(handle aVoiceHandle, float aSpeed) { @@ -117,7 +117,7 @@ namespace SoLoud } void Soloud::setPan(handle aVoiceHandle, float aPan) - { + { FOR_ALL_VOICES_PRE setVoicePan_internal(ch, aPan); FOR_ALL_VOICES_POST @@ -136,8 +136,8 @@ namespace SoLoud void Soloud::setPanAbsolute(handle aVoiceHandle, float aLVolume, float aRVolume) { FOR_ALL_VOICES_PRE - mVoice[ch]->mPanFader.mActive = 0; - mVoice[ch]->mChannelVolume[0] = aLVolume; + mVoice[ch]->mPanFader.mActive = 0; + mVoice[ch]->mChannelVolume[0] = aLVolume; mVoice[ch]->mChannelVolume[1] = aRVolume; if (mVoice[ch]->mChannels == 4) { @@ -160,7 +160,7 @@ namespace SoLoud mVoice[ch]->mChannelVolume[6] = aLVolume; mVoice[ch]->mChannelVolume[7] = aRVolume; } - FOR_ALL_VOICES_POST + FOR_ALL_VOICES_POST } void Soloud::setInaudibleBehavior(handle aVoiceHandle, bool aMustTick, bool aKill) @@ -249,9 +249,4 @@ namespace SoLoud m3dSpeakerPosition[3 * aChannel + 2] = aZ; return SO_NO_ERROR; } - - void Soloud::setBackendDeviceId(unsigned int deviceId) - { - mBackendDeviceId = deviceId; - } } From c25f98efc34c3bf5803673c8ebcfdae591abdc8b Mon Sep 17 00:00:00 2001 From: Sam Gubernick Date: Fri, 28 Feb 2025 23:56:11 -0500 Subject: [PATCH 5/7] Fix formatting issues. --- include/soloud.h | 5 ++--- src/core/soloud.cpp | 24 +++++++++++------------- src/core/soloud_core_setters.cpp | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/soloud.h b/include/soloud.h index 5a8c3c50..ff58b172 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -231,8 +231,9 @@ namespace SoLoud // Initialize SoLoud. Must be called before SoLoud can be used. result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, void const * clientData = NULL); + result pause(); - result resume(); + result resume(); // Deinitialize SoLoud. Must be called before shutting down. void deinit(); @@ -532,8 +533,6 @@ namespace SoLoud unsigned int mBackendID; // Current backend string const char * mBackendString; - // Current backend device ID - unsigned int mBackendDeviceId; // Maximum size of output buffer; used to calculate needed scratch. unsigned int mBufferSize; // Flags; see Soloud::FLAGS diff --git a/src/core/soloud.cpp b/src/core/soloud.cpp index c6bb2a8a..708f9de8 100644 --- a/src/core/soloud.cpp +++ b/src/core/soloud.cpp @@ -440,7 +440,7 @@ namespace SoLoud return ret; } #endif - + #if defined(WITH_JACK) if (!inited && (aBackend == Soloud::JACK || @@ -598,7 +598,6 @@ namespace SoLoud return 0; } - result Soloud::pause() { if (mBackendPauseFunc) @@ -614,8 +613,7 @@ namespace SoLoud return NOT_IMPLEMENTED; } - - + void Soloud::postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels) { mGlobalVolume = 1; @@ -981,9 +979,9 @@ namespace SoLoud static void resample_catmullrom(float* aSrc, float* aSrc1, float* aDst, - int aSrcOffset, - int aDstSampleCount, - int aStepFixed) + int aSrcOffset, + int aDstSampleCount, + int aStepFixed) { int i; int pos = aSrcOffset; @@ -1734,7 +1732,7 @@ namespace SoLoud { voice->mFilter[j]->filter( voice->mResampleData[0], - SAMPLE_GRANULARITY, + SAMPLE_GRANULARITY, SAMPLE_GRANULARITY, voice->mChannels, voice->mSamplerate, @@ -1779,12 +1777,12 @@ namespace SoLoud case RESAMPLER_POINT: resample_point(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, voice->mResampleData[1] + SAMPLE_GRANULARITY * j, - aScratch + aBufferSize * j + outofs, - voice->mSrcOffset, - writesamples, + aScratch + aBufferSize * j + outofs, + voice->mSrcOffset, + writesamples, /*voice->mSamplerate, aSamplerate,*/ - step_fixed); + step_fixed); break; case RESAMPLER_CATMULLROM: resample_catmullrom(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, @@ -1807,9 +1805,9 @@ namespace SoLoud aSamplerate,*/ step_fixed); break; + } } } - } // Keep track of how many samples we've written so far outofs += writesamples; diff --git a/src/core/soloud_core_setters.cpp b/src/core/soloud_core_setters.cpp index 26b52319..7f491580 100644 --- a/src/core/soloud_core_setters.cpp +++ b/src/core/soloud_core_setters.cpp @@ -160,7 +160,7 @@ namespace SoLoud mVoice[ch]->mChannelVolume[6] = aLVolume; mVoice[ch]->mChannelVolume[7] = aRVolume; } - FOR_ALL_VOICES_POST + FOR_ALL_VOICES_POST } void Soloud::setInaudibleBehavior(handle aVoiceHandle, bool aMustTick, bool aKill) From 2ec0ff258079443b0916b0badcd9eb9843c86aee Mon Sep 17 00:00:00 2001 From: Sam Gubernick Date: Fri, 28 Feb 2025 23:56:11 -0500 Subject: [PATCH 6/7] Fix formatting issues. --- include/soloud.h | 5 ++--- src/backend/sdl/soloud_sdl3.cpp | 1 - src/core/soloud.cpp | 24 +++++++++++------------- src/core/soloud_core_setters.cpp | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/soloud.h b/include/soloud.h index 5a8c3c50..ff58b172 100644 --- a/include/soloud.h +++ b/include/soloud.h @@ -231,8 +231,9 @@ namespace SoLoud // Initialize SoLoud. Must be called before SoLoud can be used. result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aBackend = Soloud::AUTO, unsigned int aSamplerate = Soloud::AUTO, unsigned int aBufferSize = Soloud::AUTO, unsigned int aChannels = 2, void const * clientData = NULL); + result pause(); - result resume(); + result resume(); // Deinitialize SoLoud. Must be called before shutting down. void deinit(); @@ -532,8 +533,6 @@ namespace SoLoud unsigned int mBackendID; // Current backend string const char * mBackendString; - // Current backend device ID - unsigned int mBackendDeviceId; // Maximum size of output buffer; used to calculate needed scratch. unsigned int mBufferSize; // Flags; see Soloud::FLAGS diff --git a/src/backend/sdl/soloud_sdl3.cpp b/src/backend/sdl/soloud_sdl3.cpp index 1c8bb6a1..0f341f02 100644 --- a/src/backend/sdl/soloud_sdl3.cpp +++ b/src/backend/sdl/soloud_sdl3.cpp @@ -1,4 +1,3 @@ - /* SoLoud audio engine Copyright (c) 2013-2018 Jari Komppa diff --git a/src/core/soloud.cpp b/src/core/soloud.cpp index c6bb2a8a..708f9de8 100644 --- a/src/core/soloud.cpp +++ b/src/core/soloud.cpp @@ -440,7 +440,7 @@ namespace SoLoud return ret; } #endif - + #if defined(WITH_JACK) if (!inited && (aBackend == Soloud::JACK || @@ -598,7 +598,6 @@ namespace SoLoud return 0; } - result Soloud::pause() { if (mBackendPauseFunc) @@ -614,8 +613,7 @@ namespace SoLoud return NOT_IMPLEMENTED; } - - + void Soloud::postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels) { mGlobalVolume = 1; @@ -981,9 +979,9 @@ namespace SoLoud static void resample_catmullrom(float* aSrc, float* aSrc1, float* aDst, - int aSrcOffset, - int aDstSampleCount, - int aStepFixed) + int aSrcOffset, + int aDstSampleCount, + int aStepFixed) { int i; int pos = aSrcOffset; @@ -1734,7 +1732,7 @@ namespace SoLoud { voice->mFilter[j]->filter( voice->mResampleData[0], - SAMPLE_GRANULARITY, + SAMPLE_GRANULARITY, SAMPLE_GRANULARITY, voice->mChannels, voice->mSamplerate, @@ -1779,12 +1777,12 @@ namespace SoLoud case RESAMPLER_POINT: resample_point(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, voice->mResampleData[1] + SAMPLE_GRANULARITY * j, - aScratch + aBufferSize * j + outofs, - voice->mSrcOffset, - writesamples, + aScratch + aBufferSize * j + outofs, + voice->mSrcOffset, + writesamples, /*voice->mSamplerate, aSamplerate,*/ - step_fixed); + step_fixed); break; case RESAMPLER_CATMULLROM: resample_catmullrom(voice->mResampleData[0] + SAMPLE_GRANULARITY * j, @@ -1807,9 +1805,9 @@ namespace SoLoud aSamplerate,*/ step_fixed); break; + } } } - } // Keep track of how many samples we've written so far outofs += writesamples; diff --git a/src/core/soloud_core_setters.cpp b/src/core/soloud_core_setters.cpp index 26b52319..7f491580 100644 --- a/src/core/soloud_core_setters.cpp +++ b/src/core/soloud_core_setters.cpp @@ -160,7 +160,7 @@ namespace SoLoud mVoice[ch]->mChannelVolume[6] = aLVolume; mVoice[ch]->mChannelVolume[7] = aRVolume; } - FOR_ALL_VOICES_POST + FOR_ALL_VOICES_POST } void Soloud::setInaudibleBehavior(handle aVoiceHandle, bool aMustTick, bool aKill) From 0bb2d0d0616e26723e697e0307e26377aae0b9e6 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 11 Mar 2025 23:28:48 -0400 Subject: [PATCH 7/7] Add SDL3 to GENie script; ignore SDL3 backend data header if WITH_SDL3 is not defined. --- build/genie.lua | 83 ++++++++++++++++++++++++++++++ include/soloud_backend_data_sdl3.h | 2 + 2 files changed, 85 insertions(+) diff --git a/build/genie.lua b/build/genie.lua index 572187a9..af1378a7 100644 --- a/build/genie.lua +++ b/build/genie.lua @@ -1,5 +1,6 @@ local WITH_SDL = 0 local WITH_SDL2 = 0 +local WITH_SDL3 = 0 local WITH_SDL_STATIC = 0 local WITH_SDL2_STATIC = 0 local WITH_PORTAUDIO = 0 @@ -30,6 +31,7 @@ end local sdl_root = "/libraries/sdl" local sdl2_root = "/libraries/sdl2" +local sdl3_root = "/libraries/sdl3" local dxsdk_root = os.getenv("DXSDK_DIR") and os.getenv("DXSDK_DIR") or "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)" local portaudio_root = "/libraries/portaudio" local openal_root = "/libraries/openal" @@ -40,6 +42,9 @@ local sdl_include = sdl_root .. "/include" local sdl2_include = sdl2_root .. "/include" local sdl2_lib_x86 = sdl2_root .. "/lib/x86" local sdl2_lib_x64 = sdl2_root .. "/lib/x64" +local sdl3_include = sdl3_root .. "/include" +local sdl3_lib_x86 = sdl3_root .. "/lib/x86" +local sdl3_lib_x64 = sdl3_root .. "/lib/x64" local dxsdk_include = dxsdk_root .. "/include" local portaudio_include = portaudio_root .. "/include" local openal_include = openal_root .. "/include" @@ -69,6 +74,11 @@ newoption { description = "Include SDL2 backend in build" } +newoption { + trigger = "with-sdl3", + description = "Include SDL3 backend in build" +} + newoption { trigger = "with-portaudio", description = "Include PortAudio backend in build" @@ -109,6 +119,11 @@ newoption { description = "Only include sdl2 that doesn't use dyndll in build" } +newoption { + trigger = "with-sdl3-only", + description = "Only include sdl3 in build" +} + newoption { trigger = "with-coreaudio", description = "Include OS X CoreAudio backend in build" @@ -157,6 +172,7 @@ newoption { if _OPTIONS["soloud-devel"] then WITH_SDL = 0 WITH_SDL2 = 1 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 1 @@ -178,6 +194,7 @@ end if _OPTIONS["with-common-backends"] then WITH_SDL = 1 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 1 @@ -221,6 +238,10 @@ if _OPTIONS["with-sdl2"] then WITH_SDL2 = 1 end +if _OPTIONS["with-sdl3"] then + WITH_SDL3 = 1 +end + if _OPTIONS["with-wasapi"] then WITH_WASAPI = 1 end @@ -232,6 +253,7 @@ end if _OPTIONS["with-sdl-only"] then WITH_SDL = 1 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -247,6 +269,23 @@ end if _OPTIONS["with-sdl2-only"] then WITH_SDL = 0 WITH_SDL2 = 1 + WITH_SDL3 = 0 + WITH_SDL_STATIC = 0 + WITH_SDL2_STATIC = 0 + WITH_PORTAUDIO = 0 + WITH_OPENAL = 0 + WITH_XAUDIO2 = 0 + WITH_WINMM = 0 + WITH_WASAPI = 0 + WITH_OSS = 0 + WITH_NOSOUND = 0 + WITH_MINIAUDIO = 0 +end + +if _OPTIONS["with-sdl3-only"] then + WITH_SDL = 0 + WITH_SDL2 = 0 + WITH_SDL3 = 1 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -262,6 +301,7 @@ end if _OPTIONS["with-sdlstatic-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 1 WITH_PORTAUDIO = 0 WITH_OPENAL = 0 @@ -276,6 +316,7 @@ end if _OPTIONS["with-sdl2static-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 1 WITH_PORTAUDIO = 0 @@ -291,6 +332,7 @@ end if _OPTIONS["with-sdl2static-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 1 WITH_PORTAUDIO = 0 @@ -306,6 +348,7 @@ end if _OPTIONS["with-vita-homebrew-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -331,6 +374,7 @@ end if _OPTIONS["with-jack-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -354,6 +398,7 @@ end if _OPTIONS["with-miniaudio-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -373,6 +418,7 @@ end if _OPTIONS["with-native-only"] then WITH_SDL = 0 WITH_SDL2 = 0 + WITH_SDL3 = 0 WITH_SDL_STATIC = 0 WITH_SDL2_STATIC = 0 WITH_PORTAUDIO = 0 @@ -400,6 +446,7 @@ print ("") print ("Active options:") print ("WITH_SDL = ", WITH_SDL) print ("WITH_SDL2 = ", WITH_SDL2) +print ("WITH_SDL3 = ", WITH_SDL3) print ("WITH_PORTAUDIO = ", WITH_PORTAUDIO) print ("WITH_OPENAL = ", WITH_OPENAL) print ("WITH_XAUDIO2 = ", WITH_XAUDIO2) @@ -601,6 +648,31 @@ if (WITH_SDL2 == 1 or WITH_SDL2STATIC) then targetname "solouddemocommon" end +-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- + +if (WITH_SDL3 == 1) then + + project "SoloudDemoCommon" + kind "StaticLib" + targetdir "../lib" + language "C++" + + files { + "../demos/common/**.c*", + "../demos/common/imgui/**.c*", + "../demos/common/glew/GL/**.c*" + } + includedirs { + "../include", + "../demos/common", + "../demos/common/imgui", + "../demos/common/glew", + sdl3_include + } + defines { "GLEW_STATIC" } + + targetname "solouddemocommon" +end -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- project "SoloudStatic" @@ -715,6 +787,17 @@ if (WITH_SDL2 == 1) then } end +if (WITH_SDL3 == 1) then + defines { "WITH_SDL3" } + files { + "../src/backend/sdl/**.c*" + } + includedirs { + "../include", + sdl3_include + } +end + if (WITH_SDL_STATIC == 1) then defines { "WITH_SDL_STATIC" } files { diff --git a/include/soloud_backend_data_sdl3.h b/include/soloud_backend_data_sdl3.h index 34cb56ef..4eba7f5f 100644 --- a/include/soloud_backend_data_sdl3.h +++ b/include/soloud_backend_data_sdl3.h @@ -25,6 +25,7 @@ freely, subject to the following restrictions: #ifndef SOLOUD_BACKEND_DATA_SDL3_H #define SOLOUD_BACKEND_DATA_SDL3_H +#ifdef WITH_SDL3 #include "SDL3/SDL.h" namespace SoLoud @@ -49,5 +50,6 @@ namespace SoLoud unsigned int deviceId; }; } +#endif #endif