aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-02-26 03:46:15 -0800
committerChris Robinson <[email protected]>2020-02-26 03:52:40 -0800
commit4555b74bd75614418032bd46836b0335229d48d4 (patch)
tree4710e7fc95c3c98590ce41e44e317795900e5fb3 /alc
parent872096958bbe358c3b1d0e9de490d40b9c3ea95f (diff)
Use a VoiceChange object to change the offset of a playing source
Diffstat (limited to 'alc')
-rw-r--r--alc/alu.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 4d9c6f57..42642e75 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1677,6 +1677,32 @@ void ProcessVoiceChanges(ALCcontext *ctx)
ALvoice *voice{cur->mVoice};
voice->mPlayState.store(ALvoice::Playing, std::memory_order_release);
}
+ else if(cur->mState == AL_SAMPLE_OFFSET)
+ {
+ /* Changing a voice offset never sends a source change event. */
+ ALvoice *oldvoice{cur->mOldVoice};
+ oldvoice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed);
+ oldvoice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
+ /* If there's no sourceID, the old voice finished so don't start
+ * the new one at its new offset.
+ */
+ if(oldvoice->mSourceID.exchange(0u, std::memory_order_relaxed) != 0u)
+ {
+ /* Otherwise, set the voice to stopping if it's not already (it
+ * would already be if paused), and play the new voice as
+ * appropriate.
+ */
+ ALvoice::State oldvstate{ALvoice::Playing};
+ oldvoice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping,
+ std::memory_order_relaxed, std::memory_order_acquire);
+
+ ALvoice *voice{cur->mVoice};
+ if(oldvstate == ALvoice::Playing)
+ voice->mPlayState.store(ALvoice::Playing, std::memory_order_release);
+ voice->mPendingChange.store(false, std::memory_order_release);
+ }
+ oldvoice->mPendingChange.store(false, std::memory_order_release);
+ }
if(sendevt && (enabledevt&EventType_SourceStateChange))
SendSourceStateEvent(ctx, cur->mSourceID, cur->mState);
} while((next=cur->mNext.load(std::memory_order_acquire)));