aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-02-08 18:20:46 +0200
committerGitHub <[email protected]>2022-02-08 08:20:46 -0800
commitd42077680890fee9e8f150e99bc259435bbe5d44 (patch)
tree0606b99eba2a09c18a8b82a2b5aafe11557eba91 /al
parentf23c7fe8ba77d4d406d37c60501f961313db7d1a (diff)
EAX various fixes (#657)
* [EAX] Fix effect GUID validation Only NULL and REVERB was valid. * [EAX] Fix default FX slot flags EAX4 and EAX5 both sets to ENVIRONMENT. * [EAX] Set default values for legacy FX slots in the initialization * [EAX] Fix FX slot locking policy Fail on attempt to load an effect or change a lock for EAX4 "set" call. Unlock legacy FX slots on any EAX5 call. * [EAX] Allow DEFER flag for "get" calls. * [EAX] Make speaker configuration read-only * [EAX] Initialize speaker configuration * [EAX] Commit EAX source on a 3D source parameter call Reference: EAX 4.0 Programmer's Guide * [EAX] Commit EAX source on a 3D listener parameter call Reference: EAX 4.0 Programmer's Guide * [EAX] Commit source when it begins to play Reference: EAX 4.0 Programmer's Guide
Diffstat (limited to 'al')
-rw-r--r--al/auxeffectslot.cpp99
-rw-r--r--al/auxeffectslot.h22
-rw-r--r--al/eax_eax_call.cpp9
-rw-r--r--al/eax_fx_slots.cpp5
-rw-r--r--al/eax_fx_slots.h2
-rw-r--r--al/listener.cpp9
-rw-r--r--al/source.cpp50
-rw-r--r--al/source.h4
8 files changed, 133 insertions, 67 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 5ddd2a28..d0487925 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -1087,8 +1087,8 @@ void ALeffectslot::eax_initialize(
eax_fx_slot_index_ = index;
eax_initialize_eax();
+ eax_initialize_lock();
eax_initialize_effects();
- eax_set_default_slots_defaults();
}
const EAX50FXSLOTPROPERTIES& ALeffectslot::eax_get_eax_fx_slot() const noexcept
@@ -1096,11 +1096,30 @@ const EAX50FXSLOTPROPERTIES& ALeffectslot::eax_get_eax_fx_slot() const noexcept
return eax_eax_fx_slot_;
}
+void ALeffectslot::eax_ensure_is_unlocked() const
+{
+ if (eax_is_locked_)
+ eax_fail("Locked.");
+}
+
void ALeffectslot::eax_validate_fx_slot_effect(
const GUID& eax_effect_id)
{
+ eax_ensure_is_unlocked();
+
if (eax_effect_id != EAX_NULL_GUID &&
- eax_effect_id != EAX_REVERB_EFFECT)
+ eax_effect_id != EAX_REVERB_EFFECT &&
+ eax_effect_id != EAX_AGCCOMPRESSOR_EFFECT &&
+ eax_effect_id != EAX_AUTOWAH_EFFECT &&
+ eax_effect_id != EAX_CHORUS_EFFECT &&
+ eax_effect_id != EAX_DISTORTION_EFFECT &&
+ eax_effect_id != EAX_ECHO_EFFECT &&
+ eax_effect_id != EAX_EQUALIZER_EFFECT &&
+ eax_effect_id != EAX_FLANGER_EFFECT &&
+ eax_effect_id != EAX_FREQUENCYSHIFTER_EFFECT &&
+ eax_effect_id != EAX_VOCALMORPHER_EFFECT &&
+ eax_effect_id != EAX_PITCHSHIFTER_EFFECT &&
+ eax_effect_id != EAX_RINGMODULATOR_EFFECT)
{
eax_fail("Unsupported EAX effect GUID.");
}
@@ -1119,6 +1138,8 @@ void ALeffectslot::eax_validate_fx_slot_volume(
void ALeffectslot::eax_validate_fx_slot_lock(
long eax_lock)
{
+ eax_ensure_is_unlocked();
+
eax_validate_range<EaxFxSlotException>(
"Lock",
eax_lock,
@@ -1126,16 +1147,6 @@ void ALeffectslot::eax_validate_fx_slot_lock(
EAXFXSLOT_MAXLOCK);
}
-void ALeffectslot::eax_validate_fx_slot_lock_state(
- long eax_lock,
- const GUID& eax_effect_id)
-{
- if (eax_lock == EAXFXSLOT_LOCKED && eax_effect_id != eax_eax_fx_slot_.guidLoadEffect)
- {
- eax_fail("Loading an effect in a locked slot.");
- }
-}
-
void ALeffectslot::eax_validate_fx_slot_flags(
unsigned long eax_flags,
int eax_version)
@@ -1293,6 +1304,13 @@ bool ALeffectslot::eax_dispatch(
return eax_call.is_get() ? eax_get(eax_call) : eax_set(eax_call);
}
+void ALeffectslot::eax_unlock_legacy() noexcept
+{
+ assert(eax_fx_slot_index_ < 2);
+ eax_is_locked_ = false;
+ eax_eax_fx_slot_.lLock = EAXFXSLOT_UNLOCKED;
+}
+
[[noreturn]]
void ALeffectslot::eax_fail(
const char* message)
@@ -1300,55 +1318,44 @@ void ALeffectslot::eax_fail(
throw EaxFxSlotException{message};
}
-void ALeffectslot::eax_set_eax_fx_slot_defaults()
+GUID ALeffectslot::eax_get_eax_default_effect_guid() const noexcept
{
- eax_eax_fx_slot_.guidLoadEffect = EAX_NULL_GUID;
- eax_eax_fx_slot_.lVolume = EAXFXSLOT_DEFAULTVOLUME;
- eax_eax_fx_slot_.lLock = EAXFXSLOT_UNLOCKED;
- eax_eax_fx_slot_.ulFlags = EAX50FXSLOT_DEFAULTFLAGS;
- eax_eax_fx_slot_.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
- eax_eax_fx_slot_.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
+ switch (eax_fx_slot_index_)
+ {
+ case 0: return EAX_REVERB_EFFECT;
+ case 1: return EAX_CHORUS_EFFECT;
+ default: return EAX_NULL_GUID;
+ }
}
-void ALeffectslot::eax_initialize_eax()
+unsigned long ALeffectslot::eax_get_eax_default_lock() const noexcept
{
- eax_set_eax_fx_slot_defaults();
+ return eax_fx_slot_index_ < 2 ? EAXFXSLOT_LOCKED : EAXFXSLOT_UNLOCKED;
}
-void ALeffectslot::eax_initialize_effects()
+void ALeffectslot::eax_set_eax_fx_slot_defaults()
{
- eax_set_fx_slot_effect();
+ eax_eax_fx_slot_.guidLoadEffect = eax_get_eax_default_effect_guid();
+ eax_eax_fx_slot_.lVolume = EAXFXSLOT_DEFAULTVOLUME;
+ eax_eax_fx_slot_.lLock = eax_get_eax_default_lock();
+ eax_eax_fx_slot_.ulFlags = EAX40FXSLOT_DEFAULTFLAGS;
+ eax_eax_fx_slot_.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
+ eax_eax_fx_slot_.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
}
-void ALeffectslot::eax_set_default_slot_0_defaults()
+void ALeffectslot::eax_initialize_eax()
{
- eax_set_fx_slot_effect(EAX_REVERB_EFFECT);
+ eax_set_eax_fx_slot_defaults();
}
-void ALeffectslot::eax_set_default_slot_1_defaults()
+void ALeffectslot::eax_initialize_lock()
{
- eax_set_fx_slot_effect(EAX_CHORUS_EFFECT);
+ eax_is_locked_ = (eax_fx_slot_index_ < 2);
}
-void ALeffectslot::eax_set_default_slots_defaults()
+void ALeffectslot::eax_initialize_effects()
{
- switch (eax_fx_slot_index_)
- {
- case 0:
- eax_set_default_slot_0_defaults();
- break;
-
- case 1:
- eax_set_default_slot_1_defaults();
- break;
-
- case 2:
- case 3:
- break;
-
- default:
- eax_fail("FX slot index out of range.");
- }
+ eax_set_fx_slot_effect();
}
void ALeffectslot::eax_get_fx_slot_all(
@@ -1540,8 +1547,6 @@ void ALeffectslot::eax_set_fx_slot_effect(
eax_call.get_value<EaxFxSlotException, const decltype(EAX40FXSLOTPROPERTIES::guidLoadEffect)>();
eax_validate_fx_slot_effect(eax_effect_id);
- eax_validate_fx_slot_lock_state(eax_eax_fx_slot_.lLock, eax_effect_id);
-
eax_set_fx_slot_effect(eax_effect_id);
}
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 8182c082..0ee1d022 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -85,6 +85,8 @@ public:
bool eax_dispatch(
const EaxEaxCall& eax_call);
+ void eax_unlock_legacy() noexcept;
+
private:
ALCcontext* eax_al_context_{};
@@ -94,6 +96,7 @@ private:
EAX50FXSLOTPROPERTIES eax_eax_fx_slot_{};
EaxEffectUPtr eax_effect_{};
+ bool eax_is_locked_{};
[[noreturn]]
@@ -101,19 +104,17 @@ private:
const char* message);
+ GUID eax_get_eax_default_effect_guid() const noexcept;
+ unsigned long eax_get_eax_default_lock() const noexcept;
+
void eax_set_eax_fx_slot_defaults();
void eax_initialize_eax();
+ void eax_initialize_lock();
- void eax_initialize_effects();
-
-
- void eax_set_default_slot_0_defaults();
-
- void eax_set_default_slot_1_defaults();
- void eax_set_default_slots_defaults();
+ void eax_initialize_effects();
void eax_get_fx_slot_all(
@@ -143,6 +144,9 @@ private:
void eax_set_fx_slot_flags();
+ void eax_ensure_is_unlocked() const;
+
+
void eax_validate_fx_slot_effect(
const GUID& eax_effect_id);
@@ -152,10 +156,6 @@ private:
void eax_validate_fx_slot_lock(
long eax_lock);
- void eax_validate_fx_slot_lock_state(
- long eax_lock,
- const GUID& eax_effect_id);
-
void eax_validate_fx_slot_flags(
unsigned long eax_flags,
int eax_version);
diff --git a/al/eax_eax_call.cpp b/al/eax_eax_call.cpp
index 76f3dbfd..6c9b00ec 100644
--- a/al/eax_eax_call.cpp
+++ b/al/eax_eax_call.cpp
@@ -158,14 +158,7 @@ EaxEaxCall::EaxEaxCall(
fail("EAX version out of range.");
}
- if (is_deferred_)
- {
- if (is_get_)
- {
- fail("Getting deferred properties not supported.");
- }
- }
- else
+ if (!is_deferred_)
{
if (property_set_id_ != EaxEaxCallPropertySetId::fx_slot &&
property_id_ != 0)
diff --git a/al/eax_fx_slots.cpp b/al/eax_fx_slots.cpp
index f2db3ede..61d5e168 100644
--- a/al/eax_fx_slots.cpp
+++ b/al/eax_fx_slots.cpp
@@ -60,6 +60,11 @@ ALeffectslot& EaxFxSlots::get(
return const_cast<ALeffectslot&>(const_cast<const EaxFxSlots*>(this)->get(index));
}
+void EaxFxSlots::unlock_legacy() noexcept
+{
+ fx_slots_[0]->eax_unlock_legacy();
+ fx_slots_[1]->eax_unlock_legacy();
+}
[[noreturn]]
void EaxFxSlots::fail(
diff --git a/al/eax_fx_slots.h b/al/eax_fx_slots.h
index 6abe61b6..0ebb9b7d 100644
--- a/al/eax_fx_slots.h
+++ b/al/eax_fx_slots.h
@@ -26,6 +26,8 @@ public:
ALeffectslot& get(
EaxFxSlotIndex index);
+ void unlock_legacy() noexcept;
+
private:
using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;
diff --git a/al/listener.cpp b/al/listener.cpp
index 97652a9a..eb7b6b2f 100644
--- a/al/listener.cpp
+++ b/al/listener.cpp
@@ -95,6 +95,9 @@ START_API_FUNC
listener.Position[1] = value2;
listener.Position[2] = value3;
UpdateProps(listener, context.get());
+#ifdef ALSOFT_EAX
+ context->eax_on_3d_listener_param_call();
+#endif // ALSOFT_EAX
break;
case AL_VELOCITY:
@@ -104,6 +107,9 @@ START_API_FUNC
listener.Velocity[1] = value2;
listener.Velocity[2] = value3;
UpdateProps(listener, context.get());
+#ifdef ALSOFT_EAX
+ context->eax_on_3d_listener_param_call();
+#endif // ALSOFT_EAX
break;
default:
@@ -151,6 +157,9 @@ START_API_FUNC
listener.OrientUp[1] = values[4];
listener.OrientUp[2] = values[5];
UpdateProps(listener, context.get());
+#ifdef ALSOFT_EAX
+ context->eax_on_3d_listener_param_call();
+#endif // ALSOFT_EAX
break;
default:
diff --git a/al/source.cpp b/al/source.cpp
index 87696147..08049bce 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -74,7 +74,6 @@
#ifdef ALSOFT_EAX
#include "eax_exception.h"
-#include "eax_globals.h"
#endif // ALSOFT_EAX
namespace {
@@ -1177,6 +1176,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f);
Source->InnerAngle = values[0];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_CONE_OUTER_ANGLE:
@@ -1184,6 +1186,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f);
Source->OuterAngle = values[0];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_GAIN:
@@ -1198,6 +1203,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] >= 0.0f);
Source->MaxDistance = values[0];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_ROLLOFF_FACTOR:
@@ -1205,6 +1213,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] >= 0.0f);
Source->RolloffFactor = values[0];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_REFERENCE_DISTANCE:
@@ -1212,6 +1223,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] >= 0.0f);
Source->RefDistance = values[0];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_MIN_GAIN:
@@ -1314,6 +1328,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
Source->Position[0] = values[0];
Source->Position[1] = values[1];
Source->Position[2] = values[2];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_VELOCITY:
@@ -1323,6 +1340,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
Source->Velocity[0] = values[0];
Source->Velocity[1] = values[1];
Source->Velocity[2] = values[2];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_DIRECTION:
@@ -1332,6 +1352,9 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
Source->Direction[0] = values[0];
Source->Direction[1] = values[1];
Source->Direction[2] = values[2];
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_ORIENTATION:
@@ -1410,6 +1433,9 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
Source->HeadRelative = values[0] != AL_FALSE;
+#ifdef ALSOFT_EAX
+ Source->eax_commit();
+#endif // ALSOFT_EAX
return UpdateSourceProps(Source, Context);
case AL_LOOPING:
@@ -3099,6 +3125,9 @@ START_API_FUNC
cur = cur->mNext.load(std::memory_order_relaxed);
}
Voice *voice{GetSourceVoice(source, context.get())};
+#ifdef ALSOFT_EAX
+ auto eax_is_begins_to_play = false;
+#endif // ALSOFT_EAX
switch(GetSourceState(source, voice))
{
case AL_PAUSED:
@@ -3111,6 +3140,9 @@ START_API_FUNC
cur->mSourceID = source->id;
cur->mState = VChangeState::Play;
source->state = AL_PLAYING;
+#ifdef ALSOFT_EAX
+ eax_is_begins_to_play = true;
+#endif // ALSOFT_EAX
continue;
case AL_PLAYING:
@@ -3127,6 +3159,9 @@ START_API_FUNC
default:
assert(voice == nullptr);
cur->mOldVoice = nullptr;
+#ifdef ALSOFT_EAX
+ eax_is_begins_to_play = true;
+#endif // ALSOFT_EAX
break;
}
@@ -3173,6 +3208,11 @@ START_API_FUNC
cur->mVoice = voice;
cur->mSourceID = source->id;
cur->mState = VChangeState::Play;
+
+#ifdef ALSOFT_EAX
+ if (eax_is_begins_to_play)
+ source->eax_commit();
+#endif // ALSOFT_EAX
}
if LIKELY(tail)
SendVoiceChanges(context.get(), tail);
@@ -3715,6 +3755,14 @@ void ALsource::eax_update(
}
}
+void ALsource::eax_commit()
+{
+ if (!eax_is_initialized())
+ return;
+
+ eax_apply_deferred();
+}
+
ALsource* ALsource::eax_lookup_source(
ALCcontext& al_context,
ALuint source_id) noexcept
diff --git a/al/source.h b/al/source.h
index b2fea08b..0066b6b4 100644
--- a/al/source.h
+++ b/al/source.h
@@ -220,6 +220,8 @@ public:
void eax_update(
EaxContextSharedDirtyFlags dirty_flags);
+ void eax_commit();
+
static ALsource* eax_lookup_source(
ALCcontext& al_context,
@@ -265,6 +267,8 @@ private:
const char* message);
+ bool eax_is_initialized() const noexcept { return eax_al_context_; }
+
void eax_set_source_defaults() noexcept;
void eax_set_active_fx_slots_defaults() noexcept;
void eax_set_send_defaults(EAXSOURCEALLSENDPROPERTIES& eax_send) noexcept;