Simplify replaying a source
This commit is contained in:
parent
8554e6cde2
commit
90d45984dc
@ -2744,6 +2744,7 @@ START_API_FUNC
|
||||
case AL_PAUSED:
|
||||
assert(voice != nullptr);
|
||||
/* A source that's paused simply resumes. */
|
||||
cur->mOldVoice = nullptr;
|
||||
cur->mVoice = voice;
|
||||
cur->mSourceID = source->id;
|
||||
cur->mState = AL_PLAYING;
|
||||
@ -2757,17 +2758,13 @@ START_API_FUNC
|
||||
* fades back to the beginning.
|
||||
*/
|
||||
voice->mPendingStop.store(true, std::memory_order_relaxed);
|
||||
cur->mVoice = voice;
|
||||
cur->mSourceID = source->id;
|
||||
cur->mState = AL_STOPPED;
|
||||
cur->mOldVoice = voice;
|
||||
voice = nullptr;
|
||||
|
||||
cur->mNext.store(GetVoiceChanger(context.get()), std::memory_order_relaxed);
|
||||
cur = cur->mNext.load(std::memory_order_relaxed);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(voice == nullptr);
|
||||
cur->mOldVoice = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ struct ALcontextProps {
|
||||
|
||||
|
||||
struct VoiceChange {
|
||||
ALvoice *mOldVoice{nullptr};
|
||||
ALvoice *mVoice{nullptr};
|
||||
ALuint mSourceID{0};
|
||||
ALenum mState{0};
|
||||
|
35
alc/alu.cpp
35
alc/alu.cpp
@ -1628,35 +1628,56 @@ void ProcessVoiceChanges(ALCcontext *ctx)
|
||||
do {
|
||||
cur = next;
|
||||
|
||||
bool success{false};
|
||||
bool sendevt{false};
|
||||
if(cur->mState == AL_INITIAL || cur->mState == AL_STOPPED)
|
||||
{
|
||||
if(ALvoice *voice{cur->mVoice})
|
||||
{
|
||||
voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed);
|
||||
voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
|
||||
voice->mSourceID.exchange(0u, std::memory_order_relaxed);
|
||||
voice->mSourceID.store(0u, std::memory_order_relaxed);
|
||||
ALvoice::State oldvstate{ALvoice::Playing};
|
||||
success = voice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping,
|
||||
sendevt = 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);
|
||||
/* AL_INITIAL state change events are always sent, even if the
|
||||
* voice is already stopped or even if there is no voice.
|
||||
*/
|
||||
sendevt |= (cur->mState == AL_INITIAL);
|
||||
}
|
||||
else if(cur->mState == AL_PAUSED)
|
||||
{
|
||||
ALvoice *voice{cur->mVoice};
|
||||
ALvoice::State oldvstate{ALvoice::Playing};
|
||||
success = voice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping,
|
||||
sendevt = voice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping,
|
||||
std::memory_order_release, std::memory_order_acquire);
|
||||
}
|
||||
else if(cur->mState == AL_PLAYING)
|
||||
{
|
||||
/* NOTE: When playing a voice, sending a source state change event
|
||||
* depends if there's an old voice to stop and if that stop is
|
||||
* successful. If there is no old voice, a playing event is always
|
||||
* sent. If there is an old voice, an event is sent only if the
|
||||
* voice is already stopped.
|
||||
*/
|
||||
if(ALvoice *oldvoice{cur->mOldVoice})
|
||||
{
|
||||
oldvoice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed);
|
||||
oldvoice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
|
||||
oldvoice->mSourceID.store(0u, std::memory_order_relaxed);
|
||||
ALvoice::State oldvstate{ALvoice::Playing};
|
||||
sendevt = !oldvoice->mPlayState.compare_exchange_strong(oldvstate,
|
||||
ALvoice::Stopping, std::memory_order_relaxed, std::memory_order_acquire);
|
||||
oldvoice->mPendingStop.store(false, std::memory_order_release);
|
||||
}
|
||||
else
|
||||
sendevt = true;
|
||||
|
||||
ALvoice *voice{cur->mVoice};
|
||||
voice->mPlayState.store(ALvoice::Playing, std::memory_order_release);
|
||||
success = true;
|
||||
}
|
||||
if(success && (enabledevt&EventType_SourceStateChange) && cur->mSourceID != 0)
|
||||
if(sendevt && (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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user