diff options
-rw-r--r-- | al/auxeffectslot.cpp | 2 | ||||
-rw-r--r-- | al/auxeffectslot.h | 4 | ||||
-rw-r--r-- | al/eax/effect.h | 77 | ||||
-rw-r--r-- | al/effects/compressor.cpp | 140 |
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 |