diff options
author | Chris Robinson <[email protected]> | 2020-09-05 19:11:57 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-09-05 19:11:57 -0700 |
commit | 9975aeb37f0bcb9a35b1cba7a755abc4774883d0 (patch) | |
tree | bd4f60088f5495e5626e69fb4d51afdcc7999bc8 /al | |
parent | 7851f7d4ceff78f2722a4a2e3957c75dec26da1d (diff) |
Add methods to start and stop effect slot processing
A newly-created effect slot is in an AL_INITIAL state, in which processing is
stopped but will automatically become AL_PLAYING after successfully setting an
AL_EFFECTSLOT_EFFECT value (including AL_EFFECT_NULL or 0). Calling Play[v] or
Stop[v] will set the effect slot to AL_PLAYING or AL_STOPPED respectively.
While stopped, the effect won't produce audio and will not be processed.
Diffstat (limited to 'al')
-rw-r--r-- | al/auxeffectslot.cpp | 115 |
1 files changed, 113 insertions, 2 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index 5f71ea97..d9f459ba 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -369,6 +369,108 @@ START_API_FUNC END_API_FUNC +AL_API void AL_APIENTRY alAuxiliaryEffectSlotPlaySOFT(ALuint slotid) +START_API_FUNC +{ + ContextRef context{GetContextRef()}; + if UNLIKELY(!context) return; + + std::lock_guard<std::mutex> _{context->mEffectSlotLock}; + ALeffectslot *slot{LookupEffectSlot(context.get(), slotid)}; + if UNLIKELY(!slot) + { + context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", slotid); + return; + } + + AddActiveEffectSlots(&slotid, 1, context.get()); + slot->mState = SlotState::Playing; +} +END_API_FUNC + +AL_API void AL_APIENTRY alAuxiliaryEffectSlotPlayvSOFT(ALsizei n, const ALuint *slotids) +START_API_FUNC +{ + ContextRef context{GetContextRef()}; + if UNLIKELY(!context) return; + + if UNLIKELY(n < 0) + context->setError(AL_INVALID_VALUE, "Playing %d effect slots", n); + if UNLIKELY(n <= 0) return; + + al::vector<ALeffectslot*> slots; + slots.reserve(static_cast<ALuint>(n)); + std::lock_guard<std::mutex> _{context->mEffectSlotLock}; + auto validate_slot = [&context,&slots](const ALuint id) -> bool + { + ALeffectslot *slot{LookupEffectSlot(context.get(), id)}; + if UNLIKELY(!slot) + { + context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", id); + return false; + } + slots.emplace_back(slot); + return true; + }; + auto slotids_end = slotids + n; + auto bad_slot = std::find_if_not(slotids, slotids_end, validate_slot); + if UNLIKELY(bad_slot != slotids_end) return; + + AddActiveEffectSlots(slotids, static_cast<ALuint>(n), context.get()); + for(auto slot : slots) + slot->mState = SlotState::Playing; +} +END_API_FUNC + +AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopSOFT(ALuint slotid) +START_API_FUNC +{ + ContextRef context{GetContextRef()}; + if UNLIKELY(!context) return; + + std::lock_guard<std::mutex> _{context->mEffectSlotLock}; + ALeffectslot *slot{LookupEffectSlot(context.get(), slotid)}; + if UNLIKELY(!slot) + { + context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", slotid); + return; + } + + RemoveActiveEffectSlots(&slotid, 1, context.get()); + slot->mState = SlotState::Stopped; +} +END_API_FUNC + +AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopvSOFT(ALsizei n, const ALuint *slotids) +START_API_FUNC +{ + ContextRef context{GetContextRef()}; + if UNLIKELY(!context) return; + + if UNLIKELY(n < 0) + context->setError(AL_INVALID_VALUE, "Stopping %d effect slots", n); + if UNLIKELY(n <= 0) return; + + std::lock_guard<std::mutex> _{context->mEffectSlotLock}; + auto validate_slot = [&context](const ALuint id) -> bool + { + ALeffectslot *slot{LookupEffectSlot(context.get(), id)}; + if UNLIKELY(!slot) + { + context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", id); + return false; + } + return true; + }; + auto slotids_end = slotids + n; + auto bad_slot = std::find_if_not(slotids, slotids_end, validate_slot); + if UNLIKELY(bad_slot != slotids_end) return; + + RemoveActiveEffectSlots(slotids, static_cast<ALuint>(n), context.get()); +} +END_API_FUNC + + AL_API void AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value) START_API_FUNC { @@ -397,12 +499,12 @@ START_API_FUNC SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid effect ID %u", value); err = slot->initEffect(effect, context.get()); } - if(err != AL_NO_ERROR) + if UNLIKELY(err != AL_NO_ERROR) { context->setError(err, "Effect initialization failed"); return; } - if(slot->mState == SlotState::Initial) + if UNLIKELY(slot->mState == SlotState::Initial) { AddActiveEffectSlots(&slot->id, 1, context.get()); slot->mState = SlotState::Playing; @@ -477,6 +579,9 @@ START_API_FUNC } break; + case AL_EFFECTSLOT_STATE_SOFT: + SETERR_RETURN(context, AL_INVALID_OPERATION,, "AL_EFFECTSLOT_STATE_SOFT is read-only"); + default: SETERR_RETURN(context, AL_INVALID_ENUM,, "Invalid effect slot integer property 0x%04x", param); @@ -493,6 +598,7 @@ START_API_FUNC case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: case AL_EFFECTSLOT_TARGET_SOFT: + case AL_EFFECTSLOT_STATE_SOFT: case AL_BUFFER: alAuxiliaryEffectSloti(effectslot, param, values[0]); return; @@ -595,6 +701,10 @@ START_API_FUNC *value = 0; break; + case AL_EFFECTSLOT_STATE_SOFT: + *value = static_cast<int>(slot->mState); + break; + case AL_BUFFER: if(auto *buffer = slot->Buffer) *value = static_cast<ALint>(buffer->id); @@ -616,6 +726,7 @@ START_API_FUNC case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: case AL_EFFECTSLOT_TARGET_SOFT: + case AL_EFFECTSLOT_STATE_SOFT: case AL_BUFFER: alGetAuxiliaryEffectSloti(effectslot, param, values); return; |