aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-09-06 21:20:20 -0700
committerChris Robinson <[email protected]>2019-09-06 21:20:20 -0700
commit987fd13796d5761b7adc5f6e137e7a6149d02f7b (patch)
treec8f0e0e0eb0ace651159317799ffe796e2a90af1 /al
parente5c9643dd55721ce36ea84bf15134127e04aba71 (diff)
Use a new voice when restarting a playing source
Diffstat (limited to 'al')
-rw-r--r--al/source.cpp28
1 files changed, 18 insertions, 10 deletions
diff --git a/al/source.cpp b/al/source.cpp
index 1b5aa851..44c46d65 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -2716,14 +2716,6 @@ START_API_FUNC
ALvoice *voice{GetSourceVoice(source, context.get())};
switch(GetSourceState(source, voice))
{
- case AL_PLAYING:
- assert(voice != nullptr);
- /* A source that's already playing is restarted from the beginning. */
- voice->mCurrentBuffer.store(BufferList, std::memory_order_relaxed);
- voice->mPosition.store(0u, std::memory_order_relaxed);
- voice->mPositionFrac.store(0, std::memory_order_release);
- return;
-
case AL_PAUSED:
assert(voice != nullptr);
/* A source that's paused simply resumes. */
@@ -2732,6 +2724,19 @@ START_API_FUNC
SendStateChangeEvent(context.get(), source->id, AL_PLAYING);
return;
+ case AL_PLAYING:
+ assert(voice != nullptr);
+ /* A source that's already playing is restarted from the beginning.
+ * Stop the current voice and start a new one so it properly cross-
+ * fades back to the beginning.
+ */
+ voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed);
+ voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
+ voice->mSourceID.store(0u, std::memory_order_release);
+ voice->mPlayState.store(ALvoice::Stopping, std::memory_order_release);
+ voice = nullptr;
+ break;
+
default:
assert(voice == nullptr);
break;
@@ -2851,10 +2856,13 @@ START_API_FUNC
voice->mSourceID.store(source->id, std::memory_order_relaxed);
voice->mPlayState.store(ALvoice::Playing, std::memory_order_release);
- source->state = AL_PLAYING;
source->VoiceIdx = vidx;
- SendStateChangeEvent(context.get(), source->id, AL_PLAYING);
+ if(source->state != AL_PLAYING)
+ {
+ source->state = AL_PLAYING;
+ SendStateChangeEvent(context.get(), source->id, AL_PLAYING);
+ }
};
std::for_each(srchandles, srchandles+n, start_source);
}