aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-09-05 19:11:57 -0700
committerChris Robinson <[email protected]>2020-09-05 19:11:57 -0700
commit9975aeb37f0bcb9a35b1cba7a755abc4774883d0 (patch)
treebd4f60088f5495e5626e69fb4d51afdcc7999bc8 /al
parent7851f7d4ceff78f2722a4a2e3957c75dec26da1d (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.cpp115
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;