diff options
-rw-r--r-- | al/event.cpp | 31 | ||||
-rw-r--r-- | al/event.h | 21 | ||||
-rw-r--r-- | al/source.cpp | 14 | ||||
-rw-r--r-- | alc/alu.cpp | 12 | ||||
-rw-r--r-- | alc/voice.cpp | 3 | ||||
-rw-r--r-- | alc/voice_change.h | 9 |
6 files changed, 59 insertions, 31 deletions
diff --git a/al/event.cpp b/al/event.cpp index 6014a4a1..9db36137 100644 --- a/al/event.cpp +++ b/al/event.cpp @@ -27,6 +27,7 @@ #include "opthelpers.h" #include "ringbuffer.h" #include "threads.h" +#include "voice_change.h" static int EventThread(ALCcontext *context) @@ -68,15 +69,33 @@ static int EventThread(ALCcontext *context) { if(!(enabledevts&EventType_SourceStateChange)) continue; + ALuint state{}; std::string msg{"Source ID " + std::to_string(evt.u.srcstate.id)}; msg += " state has changed to "; - msg += (evt.u.srcstate.state==AL_INITIAL) ? "AL_INITIAL" : - (evt.u.srcstate.state==AL_PLAYING) ? "AL_PLAYING" : - (evt.u.srcstate.state==AL_PAUSED) ? "AL_PAUSED" : - (evt.u.srcstate.state==AL_STOPPED) ? "AL_STOPPED" : "<unknown>"; + switch(evt.u.srcstate.state) + { + case VChangeState::Reset: + msg += "AL_INITIAL"; + state = AL_INITIAL; + break; + case VChangeState::Stop: + msg += "AL_STOPPED"; + state = AL_STOPPED; + break; + case VChangeState::Play: + msg += "AL_PLAYING"; + state = AL_PLAYING; + break; + case VChangeState::Pause: + msg += "AL_PAUSED"; + state = AL_PAUSED; + break; + /* Shouldn't happen */ + case VChangeState::Restart: + break; + } context->mEventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.u.srcstate.id, - static_cast<ALuint>(evt.u.srcstate.state), static_cast<ALsizei>(msg.length()), - msg.c_str(), context->mEventParam); + state, static_cast<ALsizei>(msg.length()), msg.c_str(), context->mEventParam); } else if(evt.EnumType == EventType_BufferCompleted) { @@ -1,12 +1,13 @@ #ifndef AL_EVENT_H #define AL_EVENT_H -#include "AL/al.h" -#include "AL/alc.h" - #include "almalloc.h" +struct ALCcontext; struct EffectState; +enum class VChangeState; + +using uint = unsigned int; enum { @@ -23,25 +24,25 @@ enum { }; struct AsyncEvent { - unsigned int EnumType{0u}; + uint EnumType{0u}; union { char dummy; struct { - ALuint id; - ALenum state; + uint id; + VChangeState state; } srcstate; struct { - ALuint id; - ALuint count; + uint id; + uint count; } bufcomp; struct { - ALchar msg[244]; + char msg[244]; } disconnect; EffectState *mEffectState; } u{}; AsyncEvent() noexcept = default; - constexpr AsyncEvent(unsigned int type) noexcept : EnumType{type} { } + constexpr AsyncEvent(uint type) noexcept : EnumType{type} { } DISABLE_ALLOC() }; diff --git a/al/source.cpp b/al/source.cpp index 22edc8a7..6bdfa01a 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -619,7 +619,7 @@ bool SetVoiceOffset(Voice *oldvoice, const VoicePos &vpos, ALsource *source, ALC vchg->mOldVoice = oldvoice; vchg->mVoice = newvoice; vchg->mSourceID = source->id; - vchg->mState = AL_SAMPLE_OFFSET; + vchg->mState = VChangeState::Restart; SendVoiceChanges(context, vchg); /* If the old voice still has a sourceID, it's still active and the change- @@ -740,7 +740,7 @@ void FreeSource(ALCcontext *context, ALsource *source) voice->mPendingChange.store(true, std::memory_order_relaxed); vchg->mVoice = voice; vchg->mSourceID = source->id; - vchg->mState = AL_STOPPED; + vchg->mState = VChangeState::Stop; SendVoiceChanges(context, vchg); } @@ -2935,7 +2935,7 @@ START_API_FUNC if(!voice) break; cur->mVoice = voice; cur->mSourceID = source->id; - cur->mState = AL_PLAYING; + cur->mState = VChangeState::Play; source->state = AL_PLAYING; continue; @@ -2997,7 +2997,7 @@ START_API_FUNC cur->mVoice = voice; cur->mSourceID = source->id; - cur->mState = AL_PLAYING; + cur->mState = VChangeState::Play; } if LIKELY(tail) SendVoiceChanges(context.get(), tail); @@ -3059,7 +3059,7 @@ START_API_FUNC } cur->mVoice = voice; cur->mSourceID = source->id; - cur->mState = AL_PAUSED; + cur->mState = VChangeState::Pause; } } if LIKELY(tail) @@ -3131,7 +3131,7 @@ START_API_FUNC voice->mPendingChange.store(true, std::memory_order_relaxed); cur->mVoice = voice; cur->mSourceID = source->id; - cur->mState = AL_STOPPED; + cur->mState = VChangeState::Stop; source->state = AL_STOPPED; } source->Offset = 0.0; @@ -3196,7 +3196,7 @@ START_API_FUNC voice->mPendingChange.store(true, std::memory_order_relaxed); cur->mVoice = voice; cur->mSourceID = source->id; - cur->mState = AL_INITIAL; + cur->mState = VChangeState::Reset; source->state = AL_INITIAL; } source->Offset = 0.0; diff --git a/alc/alu.cpp b/alc/alu.cpp index 36113b80..7b7f5006 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -1564,7 +1564,7 @@ void CalcSourceParams(Voice *voice, ALCcontext *context, bool force) } -void SendSourceStateEvent(ALCcontext *context, ALuint id, ALenum state) +void SendSourceStateEvent(ALCcontext *context, uint id, VChangeState state) { RingBuffer *ring{context->mAsyncEvents.get()}; auto evt_vec = ring->getWriteVector(); @@ -1588,7 +1588,7 @@ void ProcessVoiceChanges(ALCcontext *ctx) cur = next; bool sendevt{false}; - if(cur->mState == AL_INITIAL || cur->mState == AL_STOPPED) + if(cur->mState == VChangeState::Reset || cur->mState == VChangeState::Stop) { if(Voice *voice{cur->mVoice}) { @@ -1603,16 +1603,16 @@ void ProcessVoiceChanges(ALCcontext *ctx) /* 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); + sendevt |= (cur->mState == VChangeState::Reset); } - else if(cur->mState == AL_PAUSED) + else if(cur->mState == VChangeState::Pause) { Voice *voice{cur->mVoice}; Voice::State oldvstate{Voice::Playing}; sendevt = voice->mPlayState.compare_exchange_strong(oldvstate, Voice::Stopping, std::memory_order_release, std::memory_order_acquire); } - else if(cur->mState == AL_PLAYING) + else if(cur->mState == VChangeState::Play) { /* 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 @@ -1636,7 +1636,7 @@ void ProcessVoiceChanges(ALCcontext *ctx) Voice *voice{cur->mVoice}; voice->mPlayState.store(Voice::Playing, std::memory_order_release); } - else if(cur->mState == AL_SAMPLE_OFFSET) + else if(cur->mState == VChangeState::Restart) { /* Changing a voice offset never sends a source change event. */ Voice *oldvoice{cur->mOldVoice}; diff --git a/alc/voice.cpp b/alc/voice.cpp index 04ca51f3..6c00a6a2 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -60,6 +60,7 @@ #include "ringbuffer.h" #include "threads.h" #include "vector.h" +#include "voice_change.h" struct CTag; #ifdef HAVE_SSE @@ -184,7 +185,7 @@ void SendSourceStoppedEvent(ALCcontext *context, uint id) AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}}; evt->u.srcstate.id = id; - evt->u.srcstate.state = AL_STOPPED; + evt->u.srcstate.state = VChangeState::Stop; ring->writeAdvance(1); } diff --git a/alc/voice_change.h b/alc/voice_change.h index 1ce28f50..ddc6186f 100644 --- a/alc/voice_change.h +++ b/alc/voice_change.h @@ -10,11 +10,18 @@ struct Voice; using uint = unsigned int; +enum class VChangeState { + Reset, + Stop, + Play, + Pause, + Restart +}; struct VoiceChange { Voice *mOldVoice{nullptr}; Voice *mVoice{nullptr}; uint mSourceID{0}; - int mState{0}; + VChangeState mState{}; std::atomic<VoiceChange*> mNext{nullptr}; |