aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/source.cpp38
-rw-r--r--al/state.cpp29
-rw-r--r--alc/alc.cpp5
-rw-r--r--alc/alcontext.h3
-rw-r--r--alc/alu.cpp6
-rw-r--r--alc/backends/oboe.cpp4
-rw-r--r--alc/inprogext.h5
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