aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/auxeffectslot.cpp2
-rw-r--r--al/auxeffectslot.h4
-rw-r--r--al/eax/effect.h77
-rw-r--r--al/effects/compressor.cpp140
4 files changed, 93 insertions, 130 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 7bfd14ae..3e755569 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -1089,7 +1089,7 @@ void ALeffectslot::eax_commit()
eax_fx_slot_set_flags();
}
- if(eax_effect_->do_commit(eax_version_))
+ if(eax_effect_->commit(eax_version_))
eax_set_efx_slot_effect(*eax_effect_);
}
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index e9889bff..cfb8a0f2 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -132,8 +132,8 @@ private:
void operator()(const GUID& guidLoadEffect) const
{
if (guidLoadEffect != EAX_NULL_GUID &&
- guidLoadEffect != EAX_REVERB_EFFECT /*&&
- guidLoadEffect != EAX_AGCCOMPRESSOR_EFFECT &&
+ guidLoadEffect != EAX_REVERB_EFFECT &&
+ guidLoadEffect != EAX_AGCCOMPRESSOR_EFFECT /*&&
guidLoadEffect != EAX_AUTOWAH_EFFECT*/ &&
guidLoadEffect != EAX_CHORUS_EFFECT /*&&
guidLoadEffect != EAX_DISTORTION_EFFECT &&
diff --git a/al/eax/effect.h b/al/eax/effect.h
index 5308ae10..a8dc903a 100644
--- a/al/eax/effect.h
+++ b/al/eax/effect.h
@@ -168,6 +168,9 @@ struct EaxCommitter {
struct EaxChorusCommitter : public EaxCommitter<EaxChorusCommitter> {
using EaxCommitter<EaxChorusCommitter>::EaxCommitter;
};
+struct EaxCompressorCommitter : public EaxCommitter<EaxCompressorCommitter> {
+ using EaxCommitter<EaxCompressorCommitter>::EaxCommitter;
+};
struct EaxFlangerCommitter : public EaxCommitter<EaxFlangerCommitter> {
using EaxCommitter<EaxFlangerCommitter>::EaxCommitter;
};
@@ -233,6 +236,8 @@ public:
return call_set_defaults<EaxReverbCommitter>(props);
if(altype == AL_EFFECT_CHORUS)
return call_set_defaults<EaxChorusCommitter>(props);
+ if(altype == AL_EFFECT_COMPRESSOR)
+ return call_set_defaults<EaxCompressorCommitter>(props);
if(altype == AL_EFFECT_FLANGER)
return call_set_defaults<EaxFlangerCommitter>(props);
return call_set_defaults<EaxNullCommitter>(props);
@@ -267,59 +272,54 @@ public:
}
+#define EAXCALL(T, Callable, ...) \
+ if(T == EaxEffectType::Reverb) \
+ return Callable<EaxReverbCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::Chorus) \
+ return Callable<EaxChorusCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::Compressor) \
+ return Callable<EaxCompressorCommitter>(__VA_ARGS__); \
+ if(T == EaxEffectType::Flanger) \
+ return Callable<EaxFlangerCommitter>(__VA_ARGS__); \
+ return Callable<EaxNullCommitter>(__VA_ARGS__)
+
template<typename T, typename ...Args>
- void do_set(Args&& ...args)
+ static void call_set(Args&& ...args)
{ return T::Set(std::forward<Args>(args)...); }
- void do_set(const EaxCall &call, EaxEffectProps &props)
- {
- if(props.mType == EaxEffectType::Reverb)
- return do_set<EaxReverbCommitter>(call, props);
- if(props.mType == EaxEffectType::Chorus)
- return do_set<EaxChorusCommitter>(call, props);
- if(props.mType == EaxEffectType::Flanger)
- return do_set<EaxFlangerCommitter>(call, props);
- return do_set<EaxNullCommitter>(call, props);
- }
+ static void call_set(const EaxCall &call, EaxEffectProps &props)
+ { EAXCALL(props.mType, call_set, call, props); }
void set(const EaxCall &call)
{
switch(call.get_version())
{
- case 1: do_set<EaxReverbCommitter>(call, state1_.d); break;
- case 2: do_set<EaxReverbCommitter>(call, state2_.d); break;
- case 3: do_set<EaxReverbCommitter>(call, state3_.d); break;
- case 4: do_set(call, state4_.d); break;
- case 5: do_set(call, state5_.d); break;
+ case 1: call_set<EaxReverbCommitter>(call, state1_.d); break;
+ case 2: call_set<EaxReverbCommitter>(call, state2_.d); break;
+ case 3: call_set<EaxReverbCommitter>(call, state3_.d); break;
+ case 4: call_set(call, state4_.d); break;
+ case 5: call_set(call, state5_.d); break;
}
changed_ = true;
}
template<typename T, typename ...Args>
- void do_get(Args&& ...args)
+ static void call_get(Args&& ...args)
{ return T::Get(std::forward<Args>(args)...); }
- void do_get(const EaxCall &call, const EaxEffectProps &props)
- {
- if(props.mType == EaxEffectType::Reverb)
- return do_get<EaxReverbCommitter>(call, props);
- if(props.mType == EaxEffectType::Chorus)
- return do_get<EaxChorusCommitter>(call, props);
- if(props.mType == EaxEffectType::Flanger)
- return do_get<EaxFlangerCommitter>(call, props);
- return do_get<EaxNullCommitter>(call, props);
- }
+ static void call_get(const EaxCall &call, const EaxEffectProps &props)
+ { EAXCALL(props.mType, call_get, call, props); }
void get(const EaxCall &call)
{
switch(call.get_version())
{
- case 1: do_get<EaxReverbCommitter>(call, state1_.d); break;
- case 2: do_get<EaxReverbCommitter>(call, state2_.d); break;
- case 3: do_get<EaxReverbCommitter>(call, state3_.d); break;
- case 4: do_get(call, state4_.d); break;
- case 5: do_get(call, state5_.d); break;
+ case 1: call_get<EaxReverbCommitter>(call, state1_.d); break;
+ case 2: call_get<EaxReverbCommitter>(call, state2_.d); break;
+ case 3: call_get<EaxReverbCommitter>(call, state3_.d); break;
+ case 4: call_get(call, state4_.d); break;
+ case 5: call_get(call, state5_.d); break;
}
}
@@ -329,17 +329,9 @@ public:
{ return T{props_, al_effect_props_}.commit(std::forward<Args>(args)...); }
bool call_commit(const EaxEffectProps &props)
- {
- if(props.mType == EaxEffectType::Reverb)
- return call_commit<EaxReverbCommitter>(props);
- if(props.mType == EaxEffectType::Chorus)
- return call_commit<EaxChorusCommitter>(props);
- if(props.mType == EaxEffectType::Flanger)
- return call_commit<EaxFlangerCommitter>(props);
- return call_commit<EaxNullCommitter>(props);
- }
+ { EAXCALL(props.mType, call_commit, props); }
- bool do_commit(int eax_version)
+ bool commit(int eax_version)
{
changed_ |= version_ != eax_version;
if(!changed_) return false;
@@ -374,6 +366,7 @@ public:
al_effect_type_ = EnumFromEaxEffectType(props_);
return ret;
}
+#undef EAXCALL
}; // EaxEffect
// Base class for EAX4+ effects.
diff --git a/al/effects/compressor.cpp b/al/effects/compressor.cpp
index 7a4fb028..ecd43f2f 100644
--- a/al/effects/compressor.cpp
+++ b/al/effects/compressor.cpp
@@ -80,112 +80,82 @@ const EffectProps CompressorEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
-class EaxCompressorEffectException : public EaxException
-{
-public:
- explicit EaxCompressorEffectException(const char* message)
- : EaxException{"EAX_COMPRESSOR_EFFECT", message}
- {}
-}; // EaxCompressorEffectException
+using CompressorCommitter = EaxCommitter<EaxCompressorCommitter>;
-class EaxCompressorEffect final : public EaxEffect4<EaxCompressorEffectException>
-{
-public:
- EaxCompressorEffect(int eax_version);
-
-private:
- struct OnOffValidator {
- void operator()(unsigned long ulOnOff) const
- {
- eax_validate_range<Exception>(
- "On-Off",
- ulOnOff,
- EAXAGCCOMPRESSOR_MINONOFF,
- EAXAGCCOMPRESSOR_MAXONOFF);
- }
- }; // OnOffValidator
-
- struct AllValidator {
- void operator()(const EAXAGCCOMPRESSORPROPERTIES& all) const
- {
- OnOffValidator{}(all.ulOnOff);
- }
- }; // AllValidator
-
- void set_defaults(Props4& props) override;
-
- void set_efx_on_off() noexcept;
- void set_efx_defaults() override;
-
- void get(const EaxCall& call, const Props4& props) override;
- void set(const EaxCall& call, Props4& props) override;
- bool commit_props(const Props4& props) override;
-}; // EaxCompressorEffect
-
-EaxCompressorEffect::EaxCompressorEffect(int eax_version)
- : EaxEffect4{AL_EFFECT_COMPRESSOR, eax_version}
-{}
-
-void EaxCompressorEffect::set_defaults(Props4& props)
+struct OnOffValidator {
+ void operator()(unsigned long ulOnOff) const
+ {
+ eax_validate_range<CompressorCommitter::Exception>(
+ "On-Off",
+ ulOnOff,
+ EAXAGCCOMPRESSOR_MINONOFF,
+ EAXAGCCOMPRESSOR_MAXONOFF);
+ }
+}; // OnOffValidator
+
+struct AllValidator {
+ void operator()(const EAXAGCCOMPRESSORPROPERTIES& all) const
+ {
+ OnOffValidator{}(all.ulOnOff);
+ }
+}; // AllValidator
+
+} // namespace
+
+template<>
+struct CompressorCommitter::Exception : public EaxException
{
- props.mType = EaxEffectType::Compressor;
- props.mCompressor.ulOnOff = EAXAGCCOMPRESSOR_DEFAULTONOFF;
-}
+ explicit Exception(const char *message) : EaxException{"EAX_CHORUS_EFFECT", message}
+ { }
+};
-void EaxCompressorEffect::set_efx_on_off() noexcept
+template<>
+[[noreturn]] void CompressorCommitter::fail(const char *message)
{
- const auto on_off = clamp(
- static_cast<ALint>(props_.mCompressor.ulOnOff),
- AL_COMPRESSOR_MIN_ONOFF,
- AL_COMPRESSOR_MAX_ONOFF);
- al_effect_props_.Compressor.OnOff = (on_off != AL_FALSE);
+ throw Exception{message};
}
-void EaxCompressorEffect::set_efx_defaults()
+template<>
+bool CompressorCommitter::commit(const EaxEffectProps &props)
{
- set_efx_on_off();
+ const auto orig = props_;
+ props_ = props;
+ if(orig.mType == props_.mType && orig.mCompressor.ulOnOff == props_.mCompressor.ulOnOff)
+ return false;
+
+ al_effect_props_.Compressor.OnOff = (props_.mCompressor.ulOnOff != 0);
+ return true;
}
-void EaxCompressorEffect::get(const EaxCall& call, const Props4& props)
+template<>
+void CompressorCommitter::SetDefaults(EaxEffectProps &props)
{
- switch(call.get_property_id())
- {
- case EAXAGCCOMPRESSOR_NONE: break;
- case EAXAGCCOMPRESSOR_ALLPARAMETERS: call.set_value<Exception>(props.mCompressor); break;
- case EAXAGCCOMPRESSOR_ONOFF: call.set_value<Exception>(props.mCompressor.ulOnOff); break;
- default: fail_unknown_property_id();
- }
+ props.mType = EaxEffectType::Compressor;
+ props.mCompressor.ulOnOff = EAXAGCCOMPRESSOR_DEFAULTONOFF;
}
-void EaxCompressorEffect::set(const EaxCall& call, Props4& props)
+template<>
+void CompressorCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
{
switch(call.get_property_id())
{
- case EAXAGCCOMPRESSOR_NONE: break;
- case EAXAGCCOMPRESSOR_ALLPARAMETERS: defer<AllValidator>(call, props.mCompressor); break;
- case EAXAGCCOMPRESSOR_ONOFF: defer<OnOffValidator>(call, props.mCompressor.ulOnOff); break;
- default: fail_unknown_property_id();
+ case EAXAGCCOMPRESSOR_NONE: break;
+ case EAXAGCCOMPRESSOR_ALLPARAMETERS: call.set_value<Exception>(props.mCompressor); break;
+ case EAXAGCCOMPRESSOR_ONOFF: call.set_value<Exception>(props.mCompressor.ulOnOff); break;
+ default: fail_unknown_property_id();
}
}
-bool EaxCompressorEffect::commit_props(const Props4& props)
+template<>
+void CompressorCommitter::Set(const EaxCall &call, EaxEffectProps &props)
{
- auto is_dirty = false;
-
- if (props_.mCompressor.ulOnOff != props.mCompressor.ulOnOff)
+ switch(call.get_property_id())
{
- is_dirty = true;
- set_efx_on_off();
+ case EAXAGCCOMPRESSOR_NONE: break;
+ case EAXAGCCOMPRESSOR_ALLPARAMETERS: defer<AllValidator>(call, props.mCompressor); break;
+ case EAXAGCCOMPRESSOR_ONOFF: defer<OnOffValidator>(call, props.mCompressor.ulOnOff); break;
+ default: fail_unknown_property_id();
}
-
- return is_dirty;
-}
-
-} // namespace
-
-EaxEffectUPtr eax_create_eax_compressor_effect(int eax_version)
-{
- return eax_create_eax4_effect<EaxCompressorEffect>(eax_version);
}
#endif // ALSOFT_EAX