aboutsummaryrefslogtreecommitdiffstats
path: root/alc/alu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r--alc/alu.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 36d4174a..748338ab 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1605,9 +1605,56 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
}
+void SendSourceStateEvent(ALCcontext *context, ALuint id, ALenum state)
+{
+ RingBuffer *ring{context->mAsyncEvents.get()};
+ auto evt_vec = ring->getWriteVector();
+ if(evt_vec.first.len < 1) return;
+
+ AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}};
+ evt->u.srcstate.id = id;
+ evt->u.srcstate.state = state;
+
+ ring->writeAdvance(1);
+}
+
+void ProcessVoiceChanges(ALCcontext *ctx)
+{
+ VoiceChange *cur{ctx->mCurrentVoiceChange.load(std::memory_order_acquire)};
+ VoiceChange *next{cur->mNext.load(std::memory_order_acquire)};
+ if(!next) return;
+
+ const ALbitfieldSOFT enabledevt{ctx->mEnabledEvts.load(std::memory_order_acquire)};
+ do {
+ cur = next;
+
+ bool success{false};
+ ALvoice *voice{cur->mVoice};
+ if(cur->mState == AL_INITIAL || cur->mState == AL_STOPPED)
+ {
+ if(voice)
+ {
+ voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed);
+ voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
+ voice->mSourceID.exchange(0u, std::memory_order_relaxed);
+ ALvoice::State oldvstate{ALvoice::Playing};
+ success = voice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping,
+ std::memory_order_relaxed, std::memory_order_acquire);
+ voice->mPendingStop.store(false, std::memory_order_release);
+ }
+ success |= (cur->mState == AL_INITIAL);
+ }
+ if(success && (enabledevt&EventType_SourceStateChange))
+ SendSourceStateEvent(ctx, cur->mSourceID, cur->mState);
+ } while((next=cur->mNext.load(std::memory_order_acquire)));
+ ctx->mCurrentVoiceChange.store(cur, std::memory_order_release);
+}
+
void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray &slots,
const al::span<ALvoice> voices)
{
+ ProcessVoiceChanges(ctx);
+
IncrementRef(ctx->mUpdateCount);
if LIKELY(!ctx->mHoldUpdates.load(std::memory_order_acquire))
{