diff options
-rw-r--r-- | al/source.cpp | 38 | ||||
-rw-r--r-- | al/state.cpp | 29 | ||||
-rw-r--r-- | alc/alc.cpp | 5 | ||||
-rw-r--r-- | alc/alcontext.h | 3 | ||||
-rw-r--r-- | alc/alu.cpp | 6 | ||||
-rw-r--r-- | alc/backends/oboe.cpp | 4 | ||||
-rw-r--r-- | alc/inprogext.h | 5 |
7 files changed, 69 insertions, 21 deletions
diff --git a/al/source.cpp b/al/source.cpp index 4855b72d..27eeff9c 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -551,15 +551,20 @@ void SendVoiceChanges(ALCcontext *ctx, VoiceChange *tail) device->waitForMix(); if UNLIKELY(!connected) { - /* If the device is disconnected, just ignore all pending changes. */ - VoiceChange *cur{ctx->mCurrentVoiceChange.load(std::memory_order_acquire)}; - while(VoiceChange *next{cur->mNext.load(std::memory_order_acquire)}) + if(ctx->mStopVoicesOnDisconnect.load(std::memory_order_acquire)) { - cur = next; - if(Voice *voice{cur->mVoice}) - voice->mSourceID.store(0, std::memory_order_relaxed); + /* If the device is disconnected and voices are stopped, just + * ignore all pending changes. + */ + VoiceChange *cur{ctx->mCurrentVoiceChange.load(std::memory_order_acquire)}; + while(VoiceChange *next{cur->mNext.load(std::memory_order_acquire)}) + { + cur = next; + if(Voice *voice{cur->mVoice}) + voice->mSourceID.store(0, std::memory_order_relaxed); + } + ctx->mCurrentVoiceChange.store(cur, std::memory_order_release); } - ctx->mCurrentVoiceChange.store(cur, std::memory_order_release); } } @@ -2925,17 +2930,22 @@ START_API_FUNC } ALCdevice *device{context->mALDevice.get()}; - /* If the device is disconnected, go right to stopped. */ + /* If the device is disconnected, and voices stop on disconnect, go right + * to stopped. + */ if UNLIKELY(!device->Connected.load(std::memory_order_acquire)) { - /* TODO: Send state change event? */ - for(ALsource *source : srchandles) + if(context->mStopVoicesOnDisconnect.load(std::memory_order_acquire)) { - source->Offset = 0.0; - source->OffsetType = AL_NONE; - source->state = AL_STOPPED; + for(ALsource *source : srchandles) + { + /* TODO: Send state change event? */ + source->Offset = 0.0; + source->OffsetType = AL_NONE; + source->state = AL_STOPPED; + } + return; } - return; } /* Count the number of reusable voices. */ diff --git a/al/state.cpp b/al/state.cpp index e2f164ca..86a85b4d 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -32,6 +32,7 @@ #include "AL/alc.h" #include "AL/alext.h" +#include "alcmain.h" #include "alcontext.h" #include "almalloc.h" #include "alnumeric.h" @@ -152,12 +153,18 @@ START_API_FUNC ContextRef context{GetContextRef()}; if UNLIKELY(!context) return; - std::lock_guard<std::mutex> _{context->mPropLock}; switch(capability) { case AL_SOURCE_DISTANCE_MODEL: - context->mSourceDistanceModel = true; - DO_UPDATEPROPS(); + { + std::lock_guard<std::mutex> _{context->mPropLock}; + context->mSourceDistanceModel = true; + DO_UPDATEPROPS(); + } + break; + + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + context->setError(AL_INVALID_OPERATION, "Re-enabling AL_STOP_SOURCES_ON_DISCONNECT_SOFT not yet supported"); break; default: @@ -172,12 +179,18 @@ START_API_FUNC ContextRef context{GetContextRef()}; if UNLIKELY(!context) return; - std::lock_guard<std::mutex> _{context->mPropLock}; switch(capability) { case AL_SOURCE_DISTANCE_MODEL: - context->mSourceDistanceModel = false; - DO_UPDATEPROPS(); + { + std::lock_guard<std::mutex> _{context->mPropLock}; + context->mSourceDistanceModel = false; + DO_UPDATEPROPS(); + } + break; + + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + context->mStopVoicesOnDisconnect = false; break; default: @@ -200,6 +213,10 @@ START_API_FUNC value = context->mSourceDistanceModel ? AL_TRUE : AL_FALSE; break; + case AL_STOP_SOURCES_ON_DISCONNECT_SOFT: + value = context->mStopVoicesOnDisconnect ? AL_TRUE : AL_FALSE; + break; + default: context->setError(AL_INVALID_VALUE, "Invalid is enabled property 0x%04x", capability); } diff --git a/alc/alc.cpp b/alc/alc.cpp index d06ca067..47b77758 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -834,6 +834,8 @@ constexpr struct { DECL(AL_FORMAT_UHJ4CHN8_SOFT), DECL(AL_FORMAT_UHJ4CHN16_SOFT), DECL(AL_FORMAT_UHJ4CHN_FLOAT32_SOFT), + + DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT), }; #undef DECL @@ -889,6 +891,7 @@ constexpr ALchar alExtList[] = "AL_SOFT_events " "AL_SOFTX_filter_gain_ex " "AL_SOFT_gain_clamp_ex " + "AL_SOFTX_hold_on_disconnect " "AL_SOFT_loop_points " "AL_SOFTX_map_buffer " "AL_SOFT_MSADPCM " @@ -2269,6 +2272,8 @@ static bool ResetDeviceParams(ALCdevice *device, const int *attrList) for(ContextBase *ctxbase : *device->mContexts.load(std::memory_order_acquire)) { auto *ctx = static_cast<ALCcontext*>(ctxbase); + if(!ctx->mStopVoicesOnDisconnect.load(std::memory_order_acquire)) + continue; /* Clear any pending voice changes and reallocate voices to get a * clean restart. diff --git a/alc/alcontext.h b/alc/alcontext.h index b1b41e76..075e6a55 100644 --- a/alc/alcontext.h +++ b/alc/alcontext.h @@ -35,6 +35,8 @@ struct Voice; struct VoiceChange; struct VoicePropsItem; +using uint = unsigned int; + enum class DistanceModel : unsigned char { Disable, @@ -108,6 +110,7 @@ struct ContextBase { */ RefCount mUpdateCount{0u}; std::atomic<bool> mHoldUpdates{false}; + std::atomic<bool> mStopVoicesOnDisconnect{true}; float mGainBoost{1.0f}; diff --git a/alc/alu.cpp b/alc/alu.cpp index 168f0112..d7f4410f 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -2030,6 +2030,12 @@ void DeviceBase::handleDisconnect(const char *msg, ...) } } + if(!ctx->mStopVoicesOnDisconnect) + { + ProcessVoiceChanges(ctx); + continue; + } + auto voicelist = ctx->getVoicesSpanAcquired(); auto stop_voice = [](Voice *voice) -> void { diff --git a/alc/backends/oboe.cpp b/alc/backends/oboe.cpp index d82db834..28ade849 100644 --- a/alc/backends/oboe.cpp +++ b/alc/backends/oboe.cpp @@ -5,8 +5,10 @@ #include <cassert> #include <cstring> +#include <stdint.h> -#include "alu.h" +#include "alnumeric.h" +#include "core/device.h" #include "core/logging.h" #include "oboe/Oboe.h" diff --git a/alc/inprogext.h b/alc/inprogext.h index 091703e2..781ccfd3 100644 --- a/alc/inprogext.h +++ b/alc/inprogext.h @@ -89,6 +89,11 @@ ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, const ALCchar *de #define AL_FORMAT_UHJ4CHN_FLOAT32_SOFT 0x19AA #endif +#ifndef AL_SOFT_hold_on_disconnect +#define AL_SOFT_hold_on_disconnect +#define AL_STOP_SOURCES_ON_DISCONNECT_SOFT 0x19AB +#endif + #ifdef __cplusplus } /* extern "C" */ #endif |