aboutsummaryrefslogtreecommitdiffstats
path: root/al/effects
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-05 13:52:12 +0100
committerSven Göthel <[email protected]>2024-01-05 13:52:12 +0100
commitec98cdacc85ff0202852472c7756586437912f22 (patch)
tree42414746a27ab35cb8cdbc95af521d74821e57f4 /al/effects
parentfd5269bec9a5fe4815974b1786a037e6a247bfd2 (diff)
parentb82cd2e60edb8fbe5fdd3567105ae76a016a554c (diff)
Merge remote-tracking branch 'upstream/master'HEADmaster
Diffstat (limited to 'al/effects')
-rw-r--r--al/effects/autowah.cpp119
-rw-r--r--al/effects/chorus.cpp269
-rw-r--r--al/effects/compressor.cpp65
-rw-r--r--al/effects/convolution.cpp82
-rw-r--r--al/effects/dedicated.cpp92
-rw-r--r--al/effects/distortion.cpp117
-rw-r--r--al/effects/echo.cpp117
-rw-r--r--al/effects/effects.h88
-rw-r--r--al/effects/equalizer.cpp172
-rw-r--r--al/effects/fshifter.cpp113
-rw-r--r--al/effects/modulator.cpp129
-rw-r--r--al/effects/null.cpp63
-rw-r--r--al/effects/pshifter.cpp89
-rw-r--r--al/effects/reverb.cpp834
-rw-r--r--al/effects/vmorpher.cpp208
15 files changed, 1063 insertions, 1494 deletions
diff --git a/al/effects/autowah.cpp b/al/effects/autowah.cpp
index 1a8b43fc..68704c11 100644
--- a/al/effects/autowah.cpp
+++ b/al/effects/autowah.cpp
@@ -20,100 +20,87 @@
namespace {
-void Autowah_setParamf(EffectProps *props, ALenum param, float val)
+EffectProps genDefaultProps() noexcept
+{
+ AutowahProps props{};
+ props.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
+ props.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
+ props.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
+ props.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
+ return props;
+}
+
+} // namespace
+
+const EffectProps AutowahEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(AutowahProps&, ALenum param, int)
+{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
+void EffectHandler::SetParamiv(AutowahProps&, ALenum param, const int*)
+{
+ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
+ param};
+}
+
+void EffectHandler::SetParamf(AutowahProps &props, ALenum param, float val)
{
switch(param)
{
case AL_AUTOWAH_ATTACK_TIME:
if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME))
throw effect_exception{AL_INVALID_VALUE, "Autowah attack time out of range"};
- props->Autowah.AttackTime = val;
+ props.AttackTime = val;
break;
case AL_AUTOWAH_RELEASE_TIME:
if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME))
throw effect_exception{AL_INVALID_VALUE, "Autowah release time out of range"};
- props->Autowah.ReleaseTime = val;
+ props.ReleaseTime = val;
break;
case AL_AUTOWAH_RESONANCE:
if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE))
throw effect_exception{AL_INVALID_VALUE, "Autowah resonance out of range"};
- props->Autowah.Resonance = val;
+ props.Resonance = val;
break;
case AL_AUTOWAH_PEAK_GAIN:
if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Autowah peak gain out of range"};
- props->Autowah.PeakGain = val;
+ props.PeakGain = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
}
}
-void Autowah_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Autowah_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(AutowahProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Autowah_setParami(EffectProps*, ALenum param, int)
+void EffectHandler::GetParami(const AutowahProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
-void Autowah_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::GetParamiv(const AutowahProps&, ALenum param, int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
param};
}
-void Autowah_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const AutowahProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_AUTOWAH_ATTACK_TIME:
- *val = props->Autowah.AttackTime;
- break;
-
- case AL_AUTOWAH_RELEASE_TIME:
- *val = props->Autowah.ReleaseTime;
- break;
-
- case AL_AUTOWAH_RESONANCE:
- *val = props->Autowah.Resonance;
- break;
-
- case AL_AUTOWAH_PEAK_GAIN:
- *val = props->Autowah.PeakGain;
- break;
+ case AL_AUTOWAH_ATTACK_TIME: *val = props.AttackTime; break;
+ case AL_AUTOWAH_RELEASE_TIME: *val = props.ReleaseTime; break;
+ case AL_AUTOWAH_RESONANCE: *val = props.Resonance; break;
+ case AL_AUTOWAH_PEAK_GAIN: *val = props.PeakGain; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
}
}
-void Autowah_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Autowah_getParamf(props, param, vals); }
-
-void Autowah_getParami(const EffectProps*, ALenum param, int*)
-{ throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
-void Autowah_getParamiv(const EffectProps*, ALenum param, int*)
-{
- throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
- param};
-}
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
- props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
- props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
- props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Autowah);
-
-const EffectProps AutowahEffectProps{genDefaultProps()};
+void EffectHandler::GetParamfv(const AutowahProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
#ifdef ALSOFT_EAX
namespace {
@@ -189,25 +176,25 @@ template<>
throw Exception{message};
}
-template<>
-bool AutowahCommitter::commit(const EaxEffectProps &props)
+bool EaxAutowahCommitter::commit(const EAXAUTOWAHPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXAUTOWAHPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
-
- auto &eaxprops = std::get<EAXAUTOWAHPROPERTIES>(props);
- mAlProps.Autowah.AttackTime = eaxprops.flAttackTime;
- mAlProps.Autowah.ReleaseTime = eaxprops.flReleaseTime;
- mAlProps.Autowah.Resonance = level_mb_to_gain(static_cast<float>(eaxprops.lResonance));
- mAlProps.Autowah.PeakGain = level_mb_to_gain(static_cast<float>(eaxprops.lPeakLevel));
+ mAlProps = [&]{
+ AutowahProps ret{};
+ ret.AttackTime = props.flAttackTime;
+ ret.ReleaseTime = props.flReleaseTime;
+ ret.Resonance = level_mb_to_gain(static_cast<float>(props.lResonance));
+ ret.PeakGain = level_mb_to_gain(static_cast<float>(props.lPeakLevel));
+ return ret;
+ }();
return true;
}
-template<>
-void AutowahCommitter::SetDefaults(EaxEffectProps &props)
+void EaxAutowahCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXAUTOWAHPROPERTIES defprops{[]
{
@@ -221,10 +208,8 @@ void AutowahCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void AutowahCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxAutowahCommitter::Get(const EaxCall &call, const EAXAUTOWAHPROPERTIES &props)
{
- auto &props = std::get<EAXAUTOWAHPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXAUTOWAH_NONE: break;
@@ -237,10 +222,8 @@ void AutowahCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void AutowahCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxAutowahCommitter::Set(const EaxCall &call, EAXAUTOWAHPROPERTIES &props)
{
- auto &props = std::get<EAXAUTOWAHPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXAUTOWAH_NONE: break;
diff --git a/al/effects/chorus.cpp b/al/effects/chorus.cpp
index 90b38e4d..913d1215 100644
--- a/al/effects/chorus.cpp
+++ b/al/effects/chorus.cpp
@@ -46,13 +46,41 @@ inline ALenum EnumFromWaveform(ChorusWaveform type)
throw std::runtime_error{"Invalid chorus waveform: "+std::to_string(static_cast<int>(type))};
}
-void Chorus_setParami(EffectProps *props, ALenum param, int val)
+EffectProps genDefaultChorusProps() noexcept
+{
+ ChorusProps props{};
+ props.Waveform = WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM).value();
+ props.Phase = AL_CHORUS_DEFAULT_PHASE;
+ props.Rate = AL_CHORUS_DEFAULT_RATE;
+ props.Depth = AL_CHORUS_DEFAULT_DEPTH;
+ props.Feedback = AL_CHORUS_DEFAULT_FEEDBACK;
+ props.Delay = AL_CHORUS_DEFAULT_DELAY;
+ return props;
+}
+
+EffectProps genDefaultFlangerProps() noexcept
+{
+ FlangerProps props{};
+ props.Waveform = WaveformFromEnum(AL_FLANGER_DEFAULT_WAVEFORM).value();
+ props.Phase = AL_FLANGER_DEFAULT_PHASE;
+ props.Rate = AL_FLANGER_DEFAULT_RATE;
+ props.Depth = AL_FLANGER_DEFAULT_DEPTH;
+ props.Feedback = AL_FLANGER_DEFAULT_FEEDBACK;
+ props.Delay = AL_FLANGER_DEFAULT_DELAY;
+ return props;
+}
+
+} // namespace
+
+const EffectProps ChorusEffectProps{genDefaultChorusProps()};
+
+void EffectHandler::SetParami(ChorusProps &props, ALenum param, int val)
{
switch(param)
{
case AL_CHORUS_WAVEFORM:
if(auto formopt = WaveformFromEnum(val))
- props->Chorus.Waveform = *formopt;
+ props.Waveform = *formopt;
else
throw effect_exception{AL_INVALID_VALUE, "Invalid chorus waveform: 0x%04x", val};
break;
@@ -60,115 +88,89 @@ void Chorus_setParami(EffectProps *props, ALenum param, int val)
case AL_CHORUS_PHASE:
if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE))
throw effect_exception{AL_INVALID_VALUE, "Chorus phase out of range: %d", val};
- props->Chorus.Phase = val;
+ props.Phase = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param};
}
}
-void Chorus_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Chorus_setParami(props, param, vals[0]); }
-void Chorus_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamiv(ChorusProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
+void EffectHandler::SetParamf(ChorusProps &props, ALenum param, float val)
{
switch(param)
{
case AL_CHORUS_RATE:
if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE))
throw effect_exception{AL_INVALID_VALUE, "Chorus rate out of range: %f", val};
- props->Chorus.Rate = val;
+ props.Rate = val;
break;
case AL_CHORUS_DEPTH:
if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH))
throw effect_exception{AL_INVALID_VALUE, "Chorus depth out of range: %f", val};
- props->Chorus.Depth = val;
+ props.Depth = val;
break;
case AL_CHORUS_FEEDBACK:
if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK))
throw effect_exception{AL_INVALID_VALUE, "Chorus feedback out of range: %f", val};
- props->Chorus.Feedback = val;
+ props.Feedback = val;
break;
case AL_CHORUS_DELAY:
if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY))
throw effect_exception{AL_INVALID_VALUE, "Chorus delay out of range: %f", val};
- props->Chorus.Delay = val;
+ props.Delay = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param};
}
}
-void Chorus_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Chorus_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(ChorusProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Chorus_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::GetParami(const ChorusProps &props, ALenum param, int *val)
{
switch(param)
{
- case AL_CHORUS_WAVEFORM:
- *val = EnumFromWaveform(props->Chorus.Waveform);
- break;
-
- case AL_CHORUS_PHASE:
- *val = props->Chorus.Phase;
- break;
+ case AL_CHORUS_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
+ case AL_CHORUS_PHASE: *val = props.Phase; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param};
}
}
-void Chorus_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Chorus_getParami(props, param, vals); }
-void Chorus_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamiv(const ChorusProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
+void EffectHandler::GetParamf(const ChorusProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_CHORUS_RATE:
- *val = props->Chorus.Rate;
- break;
-
- case AL_CHORUS_DEPTH:
- *val = props->Chorus.Depth;
- break;
-
- case AL_CHORUS_FEEDBACK:
- *val = props->Chorus.Feedback;
- break;
-
- case AL_CHORUS_DELAY:
- *val = props->Chorus.Delay;
- break;
+ case AL_CHORUS_RATE: *val = props.Rate; break;
+ case AL_CHORUS_DEPTH: *val = props.Depth; break;
+ case AL_CHORUS_FEEDBACK: *val = props.Feedback; break;
+ case AL_CHORUS_DELAY: *val = props.Delay; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param};
}
}
-void Chorus_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Chorus_getParamf(props, param, vals); }
+void EffectHandler::GetParamfv(const ChorusProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-EffectProps genDefaultChorusProps() noexcept
-{
- EffectProps props{};
- props.Chorus.Waveform = *WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM);
- props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE;
- props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE;
- props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH;
- props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK;
- props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY;
- return props;
-}
+const EffectProps FlangerEffectProps{genDefaultFlangerProps()};
-void Flanger_setParami(EffectProps *props, ALenum param, int val)
+void EffectHandler::SetParami(FlangerProps &props, ALenum param, int val)
{
switch(param)
{
case AL_FLANGER_WAVEFORM:
if(auto formopt = WaveformFromEnum(val))
- props->Chorus.Waveform = *formopt;
+ props.Waveform = *formopt;
else
throw effect_exception{AL_INVALID_VALUE, "Invalid flanger waveform: 0x%04x", val};
break;
@@ -176,124 +178,87 @@ void Flanger_setParami(EffectProps *props, ALenum param, int val)
case AL_FLANGER_PHASE:
if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE))
throw effect_exception{AL_INVALID_VALUE, "Flanger phase out of range: %d", val};
- props->Chorus.Phase = val;
+ props.Phase = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param};
}
}
-void Flanger_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Flanger_setParami(props, param, vals[0]); }
-void Flanger_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamiv(FlangerProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
+void EffectHandler::SetParamf(FlangerProps &props, ALenum param, float val)
{
switch(param)
{
case AL_FLANGER_RATE:
if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE))
throw effect_exception{AL_INVALID_VALUE, "Flanger rate out of range: %f", val};
- props->Chorus.Rate = val;
+ props.Rate = val;
break;
case AL_FLANGER_DEPTH:
if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH))
throw effect_exception{AL_INVALID_VALUE, "Flanger depth out of range: %f", val};
- props->Chorus.Depth = val;
+ props.Depth = val;
break;
case AL_FLANGER_FEEDBACK:
if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK))
throw effect_exception{AL_INVALID_VALUE, "Flanger feedback out of range: %f", val};
- props->Chorus.Feedback = val;
+ props.Feedback = val;
break;
case AL_FLANGER_DELAY:
if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY))
throw effect_exception{AL_INVALID_VALUE, "Flanger delay out of range: %f", val};
- props->Chorus.Delay = val;
+ props.Delay = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param};
}
}
-void Flanger_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Flanger_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(FlangerProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Flanger_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::GetParami(const FlangerProps &props, ALenum param, int *val)
{
switch(param)
{
- case AL_FLANGER_WAVEFORM:
- *val = EnumFromWaveform(props->Chorus.Waveform);
- break;
-
- case AL_FLANGER_PHASE:
- *val = props->Chorus.Phase;
- break;
+ case AL_FLANGER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
+ case AL_FLANGER_PHASE: *val = props.Phase; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param};
}
}
-void Flanger_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Flanger_getParami(props, param, vals); }
-void Flanger_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamiv(const FlangerProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
+void EffectHandler::GetParamf(const FlangerProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_FLANGER_RATE:
- *val = props->Chorus.Rate;
- break;
-
- case AL_FLANGER_DEPTH:
- *val = props->Chorus.Depth;
- break;
-
- case AL_FLANGER_FEEDBACK:
- *val = props->Chorus.Feedback;
- break;
-
- case AL_FLANGER_DELAY:
- *val = props->Chorus.Delay;
- break;
+ case AL_FLANGER_RATE: *val = props.Rate; break;
+ case AL_FLANGER_DEPTH: *val = props.Depth; break;
+ case AL_FLANGER_FEEDBACK: *val = props.Feedback; break;
+ case AL_FLANGER_DELAY: *val = props.Delay; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param};
}
}
-void Flanger_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Flanger_getParamf(props, param, vals); }
-
-EffectProps genDefaultFlangerProps() noexcept
-{
- EffectProps props{};
- props.Chorus.Waveform = *WaveformFromEnum(AL_FLANGER_DEFAULT_WAVEFORM);
- props.Chorus.Phase = AL_FLANGER_DEFAULT_PHASE;
- props.Chorus.Rate = AL_FLANGER_DEFAULT_RATE;
- props.Chorus.Depth = AL_FLANGER_DEFAULT_DEPTH;
- props.Chorus.Feedback = AL_FLANGER_DEFAULT_FEEDBACK;
- props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY;
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Chorus);
-
-const EffectProps ChorusEffectProps{genDefaultChorusProps()};
-
-DEFINE_ALEFFECT_VTABLE(Flanger);
-
-const EffectProps FlangerEffectProps{genDefaultFlangerProps()};
+void EffectHandler::GetParamfv(const FlangerProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
#ifdef ALSOFT_EAX
namespace {
struct EaxChorusTraits {
- using Props = EAXCHORUSPROPERTIES;
+ using EaxProps = EAXCHORUSPROPERTIES;
using Committer = EaxChorusCommitter;
+ using AlProps = ChorusProps;
static constexpr auto efx_effect() { return AL_EFFECT_CHORUS; }
@@ -357,8 +322,9 @@ struct EaxChorusTraits {
}; // EaxChorusTraits
struct EaxFlangerTraits {
- using Props = EAXFLANGERPROPERTIES;
+ using EaxProps = EAXFLANGERPROPERTIES;
using Committer = EaxFlangerCommitter;
+ using AlProps = FlangerProps;
static constexpr auto efx_effect() { return AL_EFFECT_FLANGER; }
@@ -424,7 +390,9 @@ struct EaxFlangerTraits {
template<typename TTraits>
struct ChorusFlangerEffect {
using Traits = TTraits;
+ using EaxProps = typename Traits::EaxProps;
using Committer = typename Traits::Committer;
+ using AlProps = typename Traits::AlProps;
using Exception = typename Committer::Exception;
struct WaveformValidator {
@@ -494,7 +462,7 @@ struct ChorusFlangerEffect {
}; // DelayValidator
struct AllValidator {
- void operator()(const typename Traits::Props& all) const
+ void operator()(const EaxProps& all) const
{
WaveformValidator{}(all.ulWaveform);
PhaseValidator{}(all.lPhase);
@@ -508,7 +476,7 @@ struct ChorusFlangerEffect {
public:
static void SetDefaults(EaxEffectProps &props)
{
- auto&& all = props.emplace<typename Traits::Props>();
+ auto&& all = props.emplace<EaxProps>();
all.ulWaveform = Traits::eax_default_waveform();
all.lPhase = Traits::eax_default_phase();
all.flRate = Traits::eax_default_rate();
@@ -518,102 +486,83 @@ public:
}
- static void Get(const EaxCall &call, const EaxEffectProps &props)
+ static void Get(const EaxCall &call, const EaxProps &all)
{
- auto&& all = std::get<typename Traits::Props>(props);
switch(call.get_property_id())
{
case Traits::eax_none_param_id():
break;
-
case Traits::eax_allparameters_param_id():
call.template set_value<Exception>(all);
break;
-
case Traits::eax_waveform_param_id():
call.template set_value<Exception>(all.ulWaveform);
break;
-
case Traits::eax_phase_param_id():
call.template set_value<Exception>(all.lPhase);
break;
-
case Traits::eax_rate_param_id():
call.template set_value<Exception>(all.flRate);
break;
-
case Traits::eax_depth_param_id():
call.template set_value<Exception>(all.flDepth);
break;
-
case Traits::eax_feedback_param_id():
call.template set_value<Exception>(all.flFeedback);
break;
-
case Traits::eax_delay_param_id():
call.template set_value<Exception>(all.flDelay);
break;
-
default:
Committer::fail_unknown_property_id();
}
}
- static void Set(const EaxCall &call, EaxEffectProps &props)
+ static void Set(const EaxCall &call, EaxProps &all)
{
- auto&& all = std::get<typename Traits::Props>(props);
switch(call.get_property_id())
{
case Traits::eax_none_param_id():
break;
-
case Traits::eax_allparameters_param_id():
Committer::template defer<AllValidator>(call, all);
break;
-
case Traits::eax_waveform_param_id():
Committer::template defer<WaveformValidator>(call, all.ulWaveform);
break;
-
case Traits::eax_phase_param_id():
Committer::template defer<PhaseValidator>(call, all.lPhase);
break;
-
case Traits::eax_rate_param_id():
Committer::template defer<RateValidator>(call, all.flRate);
break;
-
case Traits::eax_depth_param_id():
Committer::template defer<DepthValidator>(call, all.flDepth);
break;
-
case Traits::eax_feedback_param_id():
Committer::template defer<FeedbackValidator>(call, all.flFeedback);
break;
-
case Traits::eax_delay_param_id():
Committer::template defer<DelayValidator>(call, all.flDelay);
break;
-
default:
Committer::fail_unknown_property_id();
}
}
- static bool Commit(const EaxEffectProps &props, EaxEffectProps &props_, EffectProps &al_props_)
+ static bool Commit(const EaxProps &props, EaxEffectProps &props_, AlProps &al_props_)
{
- if(props == props_)
+ if(auto *cur = std::get_if<EaxProps>(&props_); cur && *cur == props)
return false;
props_ = props;
- auto&& dst = std::get<typename Traits::Props>(props);
- al_props_.Chorus.Waveform = Traits::eax_waveform(dst.ulWaveform);
- al_props_.Chorus.Phase = static_cast<int>(dst.lPhase);
- al_props_.Chorus.Rate = dst.flRate;
- al_props_.Chorus.Depth = dst.flDepth;
- al_props_.Chorus.Feedback = dst.flFeedback;
- al_props_.Chorus.Delay = dst.flDelay;
+ al_props_.Waveform = Traits::eax_waveform(props.ulWaveform);
+ al_props_.Phase = static_cast<int>(props.lPhase);
+ al_props_.Rate = props.flRate;
+ al_props_.Depth = props.flDepth;
+ al_props_.Feedback = props.flFeedback;
+ al_props_.Delay = props.flDelay;
return true;
}
@@ -638,29 +587,25 @@ template<>
throw Exception{message};
}
-template<>
-bool ChorusCommitter::commit(const EaxEffectProps &props)
+bool EaxChorusCommitter::commit(const EAXCHORUSPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxChorusTraits>;
- return Committer::Commit(props, mEaxProps, mAlProps);
+ return Committer::Commit(props, mEaxProps, mAlProps.emplace<ChorusProps>());
}
-template<>
-void ChorusCommitter::SetDefaults(EaxEffectProps &props)
+void EaxChorusCommitter::SetDefaults(EaxEffectProps &props)
{
using Committer = ChorusFlangerEffect<EaxChorusTraits>;
Committer::SetDefaults(props);
}
-template<>
-void ChorusCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
+void EaxChorusCommitter::Get(const EaxCall &call, const EAXCHORUSPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxChorusTraits>;
Committer::Get(call, props);
}
-template<>
-void ChorusCommitter::Set(const EaxCall &call, EaxEffectProps &props)
+void EaxChorusCommitter::Set(const EaxCall &call, EAXCHORUSPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxChorusTraits>;
Committer::Set(call, props);
@@ -679,29 +624,25 @@ template<>
throw Exception{message};
}
-template<>
-bool FlangerCommitter::commit(const EaxEffectProps &props)
+bool EaxFlangerCommitter::commit(const EAXFLANGERPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxFlangerTraits>;
- return Committer::Commit(props, mEaxProps, mAlProps);
+ return Committer::Commit(props, mEaxProps, mAlProps.emplace<FlangerProps>());
}
-template<>
-void FlangerCommitter::SetDefaults(EaxEffectProps &props)
+void EaxFlangerCommitter::SetDefaults(EaxEffectProps &props)
{
using Committer = ChorusFlangerEffect<EaxFlangerTraits>;
Committer::SetDefaults(props);
}
-template<>
-void FlangerCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
+void EaxFlangerCommitter::Get(const EaxCall &call, const EAXFLANGERPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxFlangerTraits>;
Committer::Get(call, props);
}
-template<>
-void FlangerCommitter::Set(const EaxCall &call, EaxEffectProps &props)
+void EaxFlangerCommitter::Set(const EaxCall &call, EAXFLANGERPROPERTIES &props)
{
using Committer = ChorusFlangerEffect<EaxFlangerTraits>;
Committer::Set(call, props);
diff --git a/al/effects/compressor.cpp b/al/effects/compressor.cpp
index ca8af84f..9fcc8c61 100644
--- a/al/effects/compressor.cpp
+++ b/al/effects/compressor.cpp
@@ -16,14 +16,25 @@
namespace {
-void Compressor_setParami(EffectProps *props, ALenum param, int val)
+EffectProps genDefaultProps() noexcept
+{
+ CompressorProps props{};
+ props.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
+ return props;
+}
+
+} // namespace
+
+const EffectProps CompressorEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(CompressorProps &props, ALenum param, int val)
{
switch(param)
{
case AL_COMPRESSOR_ONOFF:
if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF))
throw effect_exception{AL_INVALID_VALUE, "Compressor state out of range"};
- props->Compressor.OnOff = (val != AL_FALSE);
+ props.OnOff = (val != AL_FALSE);
break;
default:
@@ -31,22 +42,22 @@ void Compressor_setParami(EffectProps *props, ALenum param, int val)
param};
}
}
-void Compressor_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Compressor_setParami(props, param, vals[0]); }
-void Compressor_setParamf(EffectProps*, ALenum param, float)
+void EffectHandler::SetParamiv(CompressorProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
+void EffectHandler::SetParamf(CompressorProps&, ALenum param, float)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
-void Compressor_setParamfv(EffectProps*, ALenum param, const float*)
+void EffectHandler::SetParamfv(CompressorProps&, ALenum param, const float*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
param};
}
-void Compressor_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::GetParami(const CompressorProps &props, ALenum param, int *val)
{
switch(param)
{
case AL_COMPRESSOR_ONOFF:
- *val = props->Compressor.OnOff;
+ *val = props.OnOff;
break;
default:
@@ -54,28 +65,16 @@ void Compressor_getParami(const EffectProps *props, ALenum param, int *val)
param};
}
}
-void Compressor_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Compressor_getParami(props, param, vals); }
-void Compressor_getParamf(const EffectProps*, ALenum param, float*)
+void EffectHandler::GetParamiv(const CompressorProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
+void EffectHandler::GetParamf(const CompressorProps&, ALenum param, float*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
-void Compressor_getParamfv(const EffectProps*, ALenum param, float*)
+void EffectHandler::GetParamfv(const CompressorProps&, ALenum param, float*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
param};
}
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Compressor);
-
-const EffectProps CompressorEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -115,28 +114,24 @@ template<>
throw Exception{message};
}
-template<>
-bool CompressorCommitter::commit(const EaxEffectProps &props)
+bool EaxCompressorCommitter::commit(const EAXAGCCOMPRESSORPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXAGCCOMPRESSORPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
+ mAlProps = CompressorProps{props.ulOnOff != 0};
- mAlProps.Compressor.OnOff = (std::get<EAXAGCCOMPRESSORPROPERTIES>(props).ulOnOff != 0);
return true;
}
-template<>
-void CompressorCommitter::SetDefaults(EaxEffectProps &props)
+void EaxCompressorCommitter::SetDefaults(EaxEffectProps &props)
{
props = EAXAGCCOMPRESSORPROPERTIES{EAXAGCCOMPRESSOR_DEFAULTONOFF};
}
-template<>
-void CompressorCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxCompressorCommitter::Get(const EaxCall &call, const EAXAGCCOMPRESSORPROPERTIES &props)
{
- auto &props = std::get<EAXAGCCOMPRESSORPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXAGCCOMPRESSOR_NONE: break;
@@ -146,10 +141,8 @@ void CompressorCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void CompressorCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxCompressorCommitter::Set(const EaxCall &call, EAXAGCCOMPRESSORPROPERTIES &props)
{
- auto &props = std::get<EAXAGCCOMPRESSORPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXAGCCOMPRESSOR_NONE: break;
diff --git a/al/effects/convolution.cpp b/al/effects/convolution.cpp
index 9c091e53..1f8d1111 100644
--- a/al/effects/convolution.cpp
+++ b/al/effects/convolution.cpp
@@ -12,33 +12,45 @@
namespace {
-void Convolution_setParami(EffectProps* /*props*/, ALenum param, int /*val*/)
+EffectProps genDefaultProps() noexcept
+{
+ ConvolutionProps props{};
+ props.OrientAt = {0.0f, 0.0f, -1.0f};
+ props.OrientUp = {0.0f, 1.0f, 0.0f};
+ return props;
+}
+
+} // namespace
+
+const EffectProps ConvolutionEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(ConvolutionProps& /*props*/, ALenum param, int /*val*/)
{
switch(param)
{
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x",
+ throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x",
param};
}
}
-void Convolution_setParamiv(EffectProps *props, ALenum param, const int *vals)
+void EffectHandler::SetParamiv(ConvolutionProps &props, ALenum param, const int *vals)
{
switch(param)
{
default:
- Convolution_setParami(props, param, vals[0]);
+ SetParami(props, param, vals[0]);
}
}
-void Convolution_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/)
+void EffectHandler::SetParamf(ConvolutionProps& /*props*/, ALenum param, float /*val*/)
{
switch(param)
{
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x",
+ throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x",
param};
}
}
-void Convolution_setParamfv(EffectProps *props, ALenum param, const float *values)
+void EffectHandler::SetParamfv(ConvolutionProps &props, ALenum param, const float *values)
{
switch(param)
{
@@ -47,73 +59,59 @@ void Convolution_setParamfv(EffectProps *props, ALenum param, const float *value
&& std::isfinite(values[3]) && std::isfinite(values[4]) && std::isfinite(values[5])))
throw effect_exception{AL_INVALID_VALUE, "Property 0x%04x value out of range", param};
- props->Convolution.OrientAt[0] = values[0];
- props->Convolution.OrientAt[1] = values[1];
- props->Convolution.OrientAt[2] = values[2];
- props->Convolution.OrientUp[0] = values[3];
- props->Convolution.OrientUp[1] = values[4];
- props->Convolution.OrientUp[2] = values[5];
+ props.OrientAt[0] = values[0];
+ props.OrientAt[1] = values[1];
+ props.OrientAt[2] = values[2];
+ props.OrientUp[0] = values[3];
+ props.OrientUp[1] = values[4];
+ props.OrientUp[2] = values[5];
break;
default:
- Convolution_setParamf(props, param, values[0]);
+ SetParamf(props, param, values[0]);
}
}
-void Convolution_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/)
+void EffectHandler::GetParami(const ConvolutionProps& /*props*/, ALenum param, int* /*val*/)
{
switch(param)
{
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x",
+ throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect integer property 0x%04x",
param};
}
}
-void Convolution_getParamiv(const EffectProps *props, ALenum param, int *vals)
+void EffectHandler::GetParamiv(const ConvolutionProps &props, ALenum param, int *vals)
{
switch(param)
{
default:
- Convolution_getParami(props, param, vals);
+ GetParami(props, param, vals);
}
}
-void Convolution_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/)
+void EffectHandler::GetParamf(const ConvolutionProps& /*props*/, ALenum param, float* /*val*/)
{
switch(param)
{
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid null effect float property 0x%04x",
+ throw effect_exception{AL_INVALID_ENUM, "Invalid convolution effect float property 0x%04x",
param};
}
}
-void Convolution_getParamfv(const EffectProps *props, ALenum param, float *values)
+void EffectHandler::GetParamfv(const ConvolutionProps &props, ALenum param, float *values)
{
switch(param)
{
case AL_CONVOLUTION_ORIENTATION_SOFT:
- values[0] = props->Convolution.OrientAt[0];
- values[1] = props->Convolution.OrientAt[1];
- values[2] = props->Convolution.OrientAt[2];
- values[3] = props->Convolution.OrientUp[0];
- values[4] = props->Convolution.OrientUp[1];
- values[5] = props->Convolution.OrientUp[2];
+ values[0] = props.OrientAt[0];
+ values[1] = props.OrientAt[1];
+ values[2] = props.OrientAt[2];
+ values[3] = props.OrientUp[0];
+ values[4] = props.OrientUp[1];
+ values[5] = props.OrientUp[2];
break;
default:
- Convolution_getParamf(props, param, values);
+ GetParamf(props, param, values);
}
}
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Convolution.OrientAt = {0.0f, 0.0f, -1.0f};
- props.Convolution.OrientUp = {0.0f, 1.0f, 0.0f};
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Convolution);
-
-const EffectProps ConvolutionEffectProps{genDefaultProps()};
diff --git a/al/effects/dedicated.cpp b/al/effects/dedicated.cpp
index db57003c..518c224c 100644
--- a/al/effects/dedicated.cpp
+++ b/al/effects/dedicated.cpp
@@ -12,61 +12,115 @@
namespace {
-void Dedicated_setParami(EffectProps*, ALenum param, int)
+EffectProps genDefaultDialogProps() noexcept
+{
+ DedicatedDialogProps props{};
+ props.Gain = 1.0f;
+ return props;
+}
+
+EffectProps genDefaultLfeProps() noexcept
+{
+ DedicatedLfeProps props{};
+ props.Gain = 1.0f;
+ return props;
+}
+
+} // namespace
+
+const EffectProps DedicatedDialogEffectProps{genDefaultDialogProps()};
+
+void EffectHandler::SetParami(DedicatedDialogProps&, ALenum param, int)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
-void Dedicated_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::SetParamiv(DedicatedDialogProps&, ALenum param, const int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
param};
}
-void Dedicated_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamf(DedicatedDialogProps &props, ALenum param, float val)
{
switch(param)
{
case AL_DEDICATED_GAIN:
if(!(val >= 0.0f && std::isfinite(val)))
throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"};
- props->Dedicated.Gain = val;
+ props.Gain = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
}
}
-void Dedicated_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Dedicated_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(DedicatedDialogProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Dedicated_getParami(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParami(const DedicatedDialogProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
-void Dedicated_getParamiv(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParamiv(const DedicatedDialogProps&, ALenum param, int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
param};
}
-void Dedicated_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const DedicatedDialogProps &props, ALenum param, float *val)
{
switch(param)
{
case AL_DEDICATED_GAIN:
- *val = props->Dedicated.Gain;
+ *val = props.Gain;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
}
}
-void Dedicated_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Dedicated_getParamf(props, param, vals); }
+void EffectHandler::GetParamfv(const DedicatedDialogProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-EffectProps genDefaultProps() noexcept
+
+const EffectProps DedicatedLfeEffectProps{genDefaultLfeProps()};
+
+void EffectHandler::SetParami(DedicatedLfeProps&, ALenum param, int)
+{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
+void EffectHandler::SetParamiv(DedicatedLfeProps&, ALenum param, const int*)
{
- EffectProps props{};
- props.Dedicated.Gain = 1.0f;
- return props;
+ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
+ param};
}
+void EffectHandler::SetParamf(DedicatedLfeProps &props, ALenum param, float val)
+{
+ switch(param)
+ {
+ case AL_DEDICATED_GAIN:
+ if(!(val >= 0.0f && std::isfinite(val)))
+ throw effect_exception{AL_INVALID_VALUE, "Dedicated gain out of range"};
+ props.Gain = val;
+ break;
-} // namespace
+ default:
+ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
+ }
+}
+void EffectHandler::SetParamfv(DedicatedLfeProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-DEFINE_ALEFFECT_VTABLE(Dedicated);
+void EffectHandler::GetParami(const DedicatedLfeProps&, ALenum param, int*)
+{ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param}; }
+void EffectHandler::GetParamiv(const DedicatedLfeProps&, ALenum param, int*)
+{
+ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x",
+ param};
+}
+void EffectHandler::GetParamf(const DedicatedLfeProps &props, ALenum param, float *val)
+{
+ switch(param)
+ {
+ case AL_DEDICATED_GAIN:
+ *val = props.Gain;
+ break;
-const EffectProps DedicatedEffectProps{genDefaultProps()};
+ default:
+ throw effect_exception{AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param};
+ }
+}
+void EffectHandler::GetParamfv(const DedicatedLfeProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
diff --git a/al/effects/distortion.cpp b/al/effects/distortion.cpp
index e046d8e7..534b6c24 100644
--- a/al/effects/distortion.cpp
+++ b/al/effects/distortion.cpp
@@ -16,108 +16,93 @@
namespace {
-void Distortion_setParami(EffectProps*, ALenum param, int)
+EffectProps genDefaultProps() noexcept
+{
+ DistortionProps props{};
+ props.Edge = AL_DISTORTION_DEFAULT_EDGE;
+ props.Gain = AL_DISTORTION_DEFAULT_GAIN;
+ props.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
+ props.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
+ props.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
+ return props;
+}
+
+} // namespace
+
+const EffectProps DistortionEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(DistortionProps&, ALenum param, int)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
-void Distortion_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::SetParamiv(DistortionProps&, ALenum param, const int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
param};
}
-void Distortion_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamf(DistortionProps &props, ALenum param, float val)
{
switch(param)
{
case AL_DISTORTION_EDGE:
if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE))
throw effect_exception{AL_INVALID_VALUE, "Distortion edge out of range"};
- props->Distortion.Edge = val;
+ props.Edge = val;
break;
case AL_DISTORTION_GAIN:
if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Distortion gain out of range"};
- props->Distortion.Gain = val;
+ props.Gain = val;
break;
case AL_DISTORTION_LOWPASS_CUTOFF:
if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF))
throw effect_exception{AL_INVALID_VALUE, "Distortion low-pass cutoff out of range"};
- props->Distortion.LowpassCutoff = val;
+ props.LowpassCutoff = val;
break;
case AL_DISTORTION_EQCENTER:
if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER))
throw effect_exception{AL_INVALID_VALUE, "Distortion EQ center out of range"};
- props->Distortion.EQCenter = val;
+ props.EQCenter = val;
break;
case AL_DISTORTION_EQBANDWIDTH:
if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH))
throw effect_exception{AL_INVALID_VALUE, "Distortion EQ bandwidth out of range"};
- props->Distortion.EQBandwidth = val;
+ props.EQBandwidth = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
}
}
-void Distortion_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Distortion_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(DistortionProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Distortion_getParami(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParami(const DistortionProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
-void Distortion_getParamiv(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParamiv(const DistortionProps&, ALenum param, int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
param};
}
-void Distortion_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const DistortionProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_DISTORTION_EDGE:
- *val = props->Distortion.Edge;
- break;
-
- case AL_DISTORTION_GAIN:
- *val = props->Distortion.Gain;
- break;
-
- case AL_DISTORTION_LOWPASS_CUTOFF:
- *val = props->Distortion.LowpassCutoff;
- break;
-
- case AL_DISTORTION_EQCENTER:
- *val = props->Distortion.EQCenter;
- break;
-
- case AL_DISTORTION_EQBANDWIDTH:
- *val = props->Distortion.EQBandwidth;
- break;
+ case AL_DISTORTION_EDGE: *val = props.Edge; break;
+ case AL_DISTORTION_GAIN: *val = props.Gain; break;
+ case AL_DISTORTION_LOWPASS_CUTOFF: *val = props.LowpassCutoff; break;
+ case AL_DISTORTION_EQCENTER: *val = props.EQCenter; break;
+ case AL_DISTORTION_EQBANDWIDTH: *val = props.EQBandwidth; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
}
}
-void Distortion_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Distortion_getParamf(props, param, vals); }
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE;
- props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN;
- props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
- props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
- props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
- return props;
-}
+void EffectHandler::GetParamfv(const DistortionProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Distortion);
-
-const EffectProps DistortionEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -204,26 +189,26 @@ template<>
throw Exception{message};
}
-template<>
-bool DistortionCommitter::commit(const EaxEffectProps &props)
+bool EaxDistortionCommitter::commit(const EAXDISTORTIONPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXDISTORTIONPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
-
- auto &eaxprops = std::get<EAXDISTORTIONPROPERTIES>(props);
- mAlProps.Distortion.Edge = eaxprops.flEdge;
- mAlProps.Distortion.Gain = level_mb_to_gain(static_cast<float>(eaxprops.lGain));
- mAlProps.Distortion.LowpassCutoff = eaxprops.flLowPassCutOff;
- mAlProps.Distortion.EQCenter = eaxprops.flEQCenter;
- mAlProps.Distortion.EQBandwidth = eaxprops.flEdge;
+ mAlProps = [&]{
+ DistortionProps ret{};
+ ret.Edge = props.flEdge;
+ ret.Gain = level_mb_to_gain(static_cast<float>(props.lGain));
+ ret.LowpassCutoff = props.flLowPassCutOff;
+ ret.EQCenter = props.flEQCenter;
+ ret.EQBandwidth = props.flEdge;
+ return ret;
+ }();
return true;
}
-template<>
-void DistortionCommitter::SetDefaults(EaxEffectProps &props)
+void EaxDistortionCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXDISTORTIONPROPERTIES defprops{[]
{
@@ -238,10 +223,8 @@ void DistortionCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void DistortionCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxDistortionCommitter::Get(const EaxCall &call, const EAXDISTORTIONPROPERTIES &props)
{
- auto &props = std::get<EAXDISTORTIONPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXDISTORTION_NONE: break;
@@ -255,10 +238,8 @@ void DistortionCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void DistortionCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxDistortionCommitter::Set(const EaxCall &call, EAXDISTORTIONPROPERTIES &props)
{
- auto &props = std::get<EAXDISTORTIONPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXDISTORTION_NONE: break;
diff --git a/al/effects/echo.cpp b/al/effects/echo.cpp
index 48aacef3..9412039b 100644
--- a/al/effects/echo.cpp
+++ b/al/effects/echo.cpp
@@ -19,102 +19,87 @@ namespace {
static_assert(EchoMaxDelay >= AL_ECHO_MAX_DELAY, "Echo max delay too short");
static_assert(EchoMaxLRDelay >= AL_ECHO_MAX_LRDELAY, "Echo max left-right delay too short");
-void Echo_setParami(EffectProps*, ALenum param, int)
+EffectProps genDefaultProps() noexcept
+{
+ EchoProps props{};
+ props.Delay = AL_ECHO_DEFAULT_DELAY;
+ props.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
+ props.Damping = AL_ECHO_DEFAULT_DAMPING;
+ props.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
+ props.Spread = AL_ECHO_DEFAULT_SPREAD;
+ return props;
+}
+
+} // namespace
+
+const EffectProps EchoEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(EchoProps&, ALenum param, int)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
-void Echo_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::SetParamiv(EchoProps&, ALenum param, const int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
-void Echo_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamf(EchoProps &props, ALenum param, float val)
{
switch(param)
{
case AL_ECHO_DELAY:
if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY))
throw effect_exception{AL_INVALID_VALUE, "Echo delay out of range"};
- props->Echo.Delay = val;
+ props.Delay = val;
break;
case AL_ECHO_LRDELAY:
if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY))
throw effect_exception{AL_INVALID_VALUE, "Echo LR delay out of range"};
- props->Echo.LRDelay = val;
+ props.LRDelay = val;
break;
case AL_ECHO_DAMPING:
if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING))
throw effect_exception{AL_INVALID_VALUE, "Echo damping out of range"};
- props->Echo.Damping = val;
+ props.Damping = val;
break;
case AL_ECHO_FEEDBACK:
if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK))
throw effect_exception{AL_INVALID_VALUE, "Echo feedback out of range"};
- props->Echo.Feedback = val;
+ props.Feedback = val;
break;
case AL_ECHO_SPREAD:
if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD))
throw effect_exception{AL_INVALID_VALUE, "Echo spread out of range"};
- props->Echo.Spread = val;
+ props.Spread = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
}
}
-void Echo_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Echo_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(EchoProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Echo_getParami(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParami(const EchoProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
-void Echo_getParamiv(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParamiv(const EchoProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
-void Echo_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const EchoProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_ECHO_DELAY:
- *val = props->Echo.Delay;
- break;
-
- case AL_ECHO_LRDELAY:
- *val = props->Echo.LRDelay;
- break;
-
- case AL_ECHO_DAMPING:
- *val = props->Echo.Damping;
- break;
-
- case AL_ECHO_FEEDBACK:
- *val = props->Echo.Feedback;
- break;
-
- case AL_ECHO_SPREAD:
- *val = props->Echo.Spread;
- break;
+ case AL_ECHO_DELAY: *val = props.Delay; break;
+ case AL_ECHO_LRDELAY: *val = props.LRDelay; break;
+ case AL_ECHO_DAMPING: *val = props.Damping; break;
+ case AL_ECHO_FEEDBACK: *val = props.Feedback; break;
+ case AL_ECHO_SPREAD: *val = props.Spread; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
}
}
-void Echo_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Echo_getParamf(props, param, vals); }
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Echo.Delay = AL_ECHO_DEFAULT_DELAY;
- props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
- props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
- props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
- props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
- return props;
-}
+void EffectHandler::GetParamfv(const EchoProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Echo);
-
-const EffectProps EchoEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -201,26 +186,26 @@ template<>
throw Exception{message};
}
-template<>
-bool EchoCommitter::commit(const EaxEffectProps &props)
+bool EaxEchoCommitter::commit(const EAXECHOPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXECHOPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
-
- auto &eaxprops = std::get<EAXECHOPROPERTIES>(props);
- mAlProps.Echo.Delay = eaxprops.flDelay;
- mAlProps.Echo.LRDelay = eaxprops.flLRDelay;
- mAlProps.Echo.Damping = eaxprops.flDamping;
- mAlProps.Echo.Feedback = eaxprops.flFeedback;
- mAlProps.Echo.Spread = eaxprops.flSpread;
+ mAlProps = [&]{
+ EchoProps ret{};
+ ret.Delay = props.flDelay;
+ ret.LRDelay = props.flLRDelay;
+ ret.Damping = props.flDamping;
+ ret.Feedback = props.flFeedback;
+ ret.Spread = props.flSpread;
+ return ret;
+ }();
return true;
}
-template<>
-void EchoCommitter::SetDefaults(EaxEffectProps &props)
+void EaxEchoCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXECHOPROPERTIES defprops{[]
{
@@ -235,10 +220,8 @@ void EchoCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void EchoCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxEchoCommitter::Get(const EaxCall &call, const EAXECHOPROPERTIES &props)
{
- auto &props = std::get<EAXECHOPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXECHO_NONE: break;
@@ -252,10 +235,8 @@ void EchoCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void EchoCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxEchoCommitter::Set(const EaxCall &call, EAXECHOPROPERTIES &props)
{
- auto &props = std::get<EAXECHOPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXECHO_NONE: break;
diff --git a/al/effects/effects.h b/al/effects/effects.h
index 9d57dd82..38d47f86 100644
--- a/al/effects/effects.h
+++ b/al/effects/effects.h
@@ -3,52 +3,69 @@
#include "AL/al.h"
+#include "core/effects/base.h"
#include "core/except.h"
#ifdef ALSOFT_EAX
#include "al/eax/effect.h"
#endif // ALSOFT_EAX
-union EffectProps;
+struct EffectHandler {
+#define DECL_HANDLER(T) \
+ static void SetParami(T &props, ALenum param, int val); \
+ static void SetParamiv(T &props, ALenum param, const int *vals); \
+ static void SetParamf(T &props, ALenum param, float val); \
+ static void SetParamfv(T &props, ALenum param, const float *vals); \
+ static void GetParami(const T &props, ALenum param, int *val); \
+ static void GetParamiv(const T &props, ALenum param, int *vals); \
+ static void GetParamf(const T &props, ALenum param, float *val); \
+ static void GetParamfv(const T &props, ALenum param, float *vals);
+
+ DECL_HANDLER(std::monostate)
+ DECL_HANDLER(ReverbProps)
+ DECL_HANDLER(ChorusProps)
+ DECL_HANDLER(AutowahProps)
+ DECL_HANDLER(CompressorProps)
+ DECL_HANDLER(ConvolutionProps)
+ DECL_HANDLER(DedicatedDialogProps)
+ DECL_HANDLER(DedicatedLfeProps)
+ DECL_HANDLER(DistortionProps)
+ DECL_HANDLER(EchoProps)
+ DECL_HANDLER(EqualizerProps)
+ DECL_HANDLER(FlangerProps)
+ DECL_HANDLER(FshifterProps)
+ DECL_HANDLER(ModulatorProps)
+ DECL_HANDLER(PshifterProps)
+ DECL_HANDLER(VmorpherProps)
+#undef DECL_HANDLER
+
+ static void StdReverbSetParami(ReverbProps &props, ALenum param, int val);
+ static void StdReverbSetParamiv(ReverbProps &props, ALenum param, const int *vals);
+ static void StdReverbSetParamf(ReverbProps &props, ALenum param, float val);
+ static void StdReverbSetParamfv(ReverbProps &props, ALenum param, const float *vals);
+ static void StdReverbGetParami(const ReverbProps &props, ALenum param, int *val);
+ static void StdReverbGetParamiv(const ReverbProps &props, ALenum param, int *vals);
+ static void StdReverbGetParamf(const ReverbProps &props, ALenum param, float *val);
+ static void StdReverbGetParamfv(const ReverbProps &props, ALenum param, float *vals);
+};
class effect_exception final : public al::base_exception {
ALenum mErrorCode;
public:
-#ifdef __USE_MINGW_ANSI_STDIO
- [[gnu::format(gnu_printf, 3, 4)]]
+#ifdef __MINGW32__
+ [[gnu::format(__MINGW_PRINTF_FORMAT, 3, 4)]]
#else
[[gnu::format(printf, 3, 4)]]
#endif
effect_exception(ALenum code, const char *msg, ...);
~effect_exception() override;
- ALenum errorCode() const noexcept { return mErrorCode; }
+ [[nodiscard]] auto errorCode() const noexcept -> ALenum { return mErrorCode; }
};
-struct EffectVtable {
- void (*const setParami)(EffectProps *props, ALenum param, int val);
- void (*const setParamiv)(EffectProps *props, ALenum param, const int *vals);
- void (*const setParamf)(EffectProps *props, ALenum param, float val);
- void (*const setParamfv)(EffectProps *props, ALenum param, const float *vals);
-
- void (*const getParami)(const EffectProps *props, ALenum param, int *val);
- void (*const getParamiv)(const EffectProps *props, ALenum param, int *vals);
- void (*const getParamf)(const EffectProps *props, ALenum param, float *val);
- void (*const getParamfv)(const EffectProps *props, ALenum param, float *vals);
-};
-
-#define DEFINE_ALEFFECT_VTABLE(T) \
-const EffectVtable T##EffectVtable = { \
- T##_setParami, T##_setParamiv, \
- T##_setParamf, T##_setParamfv, \
- T##_getParami, T##_getParamiv, \
- T##_getParamf, T##_getParamfv, \
-}
-
-
/* Default properties for the given effect types. */
extern const EffectProps NullEffectProps;
extern const EffectProps ReverbEffectProps;
@@ -64,25 +81,8 @@ extern const EffectProps FshifterEffectProps;
extern const EffectProps ModulatorEffectProps;
extern const EffectProps PshifterEffectProps;
extern const EffectProps VmorpherEffectProps;
-extern const EffectProps DedicatedEffectProps;
+extern const EffectProps DedicatedDialogEffectProps;
+extern const EffectProps DedicatedLfeEffectProps;
extern const EffectProps ConvolutionEffectProps;
-/* Vtables to get/set properties for the given effect types. */
-extern const EffectVtable NullEffectVtable;
-extern const EffectVtable ReverbEffectVtable;
-extern const EffectVtable StdReverbEffectVtable;
-extern const EffectVtable AutowahEffectVtable;
-extern const EffectVtable ChorusEffectVtable;
-extern const EffectVtable CompressorEffectVtable;
-extern const EffectVtable DistortionEffectVtable;
-extern const EffectVtable EchoEffectVtable;
-extern const EffectVtable EqualizerEffectVtable;
-extern const EffectVtable FlangerEffectVtable;
-extern const EffectVtable FshifterEffectVtable;
-extern const EffectVtable ModulatorEffectVtable;
-extern const EffectVtable PshifterEffectVtable;
-extern const EffectVtable VmorpherEffectVtable;
-extern const EffectVtable DedicatedEffectVtable;
-extern const EffectVtable ConvolutionEffectVtable;
-
#endif /* AL_EFFECTS_EFFECTS_H */
diff --git a/al/effects/equalizer.cpp b/al/effects/equalizer.cpp
index 76d5bdef..74fc43fc 100644
--- a/al/effects/equalizer.cpp
+++ b/al/effects/equalizer.cpp
@@ -16,163 +16,133 @@
namespace {
-void Equalizer_setParami(EffectProps*, ALenum param, int)
+EffectProps genDefaultProps() noexcept
+{
+ EqualizerProps props{};
+ props.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
+ props.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
+ props.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
+ props.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
+ props.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
+ props.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
+ props.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
+ props.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
+ props.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
+ props.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
+ return props;
+}
+
+} // namespace
+
+const EffectProps EqualizerEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(EqualizerProps&, ALenum param, int)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
-void Equalizer_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::SetParamiv(EqualizerProps&, ALenum param, const int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
param};
}
-void Equalizer_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamf(EqualizerProps &props, ALenum param, float val)
{
switch(param)
{
case AL_EQUALIZER_LOW_GAIN:
if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band gain out of range"};
- props->Equalizer.LowGain = val;
+ props.LowGain = val;
break;
case AL_EQUALIZER_LOW_CUTOFF:
if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF))
throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band cutoff out of range"};
- props->Equalizer.LowCutoff = val;
+ props.LowCutoff = val;
break;
case AL_EQUALIZER_MID1_GAIN:
if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band gain out of range"};
- props->Equalizer.Mid1Gain = val;
+ props.Mid1Gain = val;
break;
case AL_EQUALIZER_MID1_CENTER:
if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band center out of range"};
- props->Equalizer.Mid1Center = val;
+ props.Mid1Center = val;
break;
case AL_EQUALIZER_MID1_WIDTH:
if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band width out of range"};
- props->Equalizer.Mid1Width = val;
+ props.Mid1Width = val;
break;
case AL_EQUALIZER_MID2_GAIN:
if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band gain out of range"};
- props->Equalizer.Mid2Gain = val;
+ props.Mid2Gain = val;
break;
case AL_EQUALIZER_MID2_CENTER:
if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band center out of range"};
- props->Equalizer.Mid2Center = val;
+ props.Mid2Center = val;
break;
case AL_EQUALIZER_MID2_WIDTH:
if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH))
throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band width out of range"};
- props->Equalizer.Mid2Width = val;
+ props.Mid2Width = val;
break;
case AL_EQUALIZER_HIGH_GAIN:
if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN))
throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band gain out of range"};
- props->Equalizer.HighGain = val;
+ props.HighGain = val;
break;
case AL_EQUALIZER_HIGH_CUTOFF:
if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF))
throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band cutoff out of range"};
- props->Equalizer.HighCutoff = val;
+ props.HighCutoff = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
}
}
-void Equalizer_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Equalizer_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(EqualizerProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Equalizer_getParami(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParami(const EqualizerProps&, ALenum param, int*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
-void Equalizer_getParamiv(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParamiv(const EqualizerProps&, ALenum param, int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
param};
}
-void Equalizer_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const EqualizerProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_EQUALIZER_LOW_GAIN:
- *val = props->Equalizer.LowGain;
- break;
-
- case AL_EQUALIZER_LOW_CUTOFF:
- *val = props->Equalizer.LowCutoff;
- break;
-
- case AL_EQUALIZER_MID1_GAIN:
- *val = props->Equalizer.Mid1Gain;
- break;
-
- case AL_EQUALIZER_MID1_CENTER:
- *val = props->Equalizer.Mid1Center;
- break;
-
- case AL_EQUALIZER_MID1_WIDTH:
- *val = props->Equalizer.Mid1Width;
- break;
-
- case AL_EQUALIZER_MID2_GAIN:
- *val = props->Equalizer.Mid2Gain;
- break;
-
- case AL_EQUALIZER_MID2_CENTER:
- *val = props->Equalizer.Mid2Center;
- break;
-
- case AL_EQUALIZER_MID2_WIDTH:
- *val = props->Equalizer.Mid2Width;
- break;
-
- case AL_EQUALIZER_HIGH_GAIN:
- *val = props->Equalizer.HighGain;
- break;
-
- case AL_EQUALIZER_HIGH_CUTOFF:
- *val = props->Equalizer.HighCutoff;
- break;
+ case AL_EQUALIZER_LOW_GAIN: *val = props.LowGain; break;
+ case AL_EQUALIZER_LOW_CUTOFF: *val = props.LowCutoff; break;
+ case AL_EQUALIZER_MID1_GAIN: *val = props.Mid1Gain; break;
+ case AL_EQUALIZER_MID1_CENTER: *val = props.Mid1Center; break;
+ case AL_EQUALIZER_MID1_WIDTH: *val = props.Mid1Width; break;
+ case AL_EQUALIZER_MID2_GAIN: *val = props.Mid2Gain; break;
+ case AL_EQUALIZER_MID2_CENTER: *val = props.Mid2Center; break;
+ case AL_EQUALIZER_MID2_WIDTH: *val = props.Mid2Width; break;
+ case AL_EQUALIZER_HIGH_GAIN: *val = props.HighGain; break;
+ case AL_EQUALIZER_HIGH_CUTOFF: *val = props.HighCutoff; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
}
}
-void Equalizer_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Equalizer_getParamf(props, param, vals); }
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
- props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
- props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
- props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
- props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
- props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
- props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
- props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
- props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
- props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
- return props;
-}
+void EffectHandler::GetParamfv(const EqualizerProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Equalizer);
-
-const EffectProps EqualizerEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -319,31 +289,31 @@ template<>
throw Exception{message};
}
-template<>
-bool EqualizerCommitter::commit(const EaxEffectProps &props)
+bool EaxEqualizerCommitter::commit(const EAXEQUALIZERPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXEQUALIZERPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
-
- auto &eaxprops = std::get<EAXEQUALIZERPROPERTIES>(props);
- mAlProps.Equalizer.LowGain = level_mb_to_gain(static_cast<float>(eaxprops.lLowGain));
- mAlProps.Equalizer.LowCutoff = eaxprops.flLowCutOff;
- mAlProps.Equalizer.Mid1Gain = level_mb_to_gain(static_cast<float>(eaxprops.lMid1Gain));
- mAlProps.Equalizer.Mid1Center = eaxprops.flMid1Center;
- mAlProps.Equalizer.Mid1Width = eaxprops.flMid1Width;
- mAlProps.Equalizer.Mid2Gain = level_mb_to_gain(static_cast<float>(eaxprops.lMid2Gain));
- mAlProps.Equalizer.Mid2Center = eaxprops.flMid2Center;
- mAlProps.Equalizer.Mid2Width = eaxprops.flMid2Width;
- mAlProps.Equalizer.HighGain = level_mb_to_gain(static_cast<float>(eaxprops.lHighGain));
- mAlProps.Equalizer.HighCutoff = eaxprops.flHighCutOff;
+ mAlProps = [&]{
+ EqualizerProps ret{};
+ ret.LowGain = level_mb_to_gain(static_cast<float>(props.lLowGain));
+ ret.LowCutoff = props.flLowCutOff;
+ ret.Mid1Gain = level_mb_to_gain(static_cast<float>(props.lMid1Gain));
+ ret.Mid1Center = props.flMid1Center;
+ ret.Mid1Width = props.flMid1Width;
+ ret.Mid2Gain = level_mb_to_gain(static_cast<float>(props.lMid2Gain));
+ ret.Mid2Center = props.flMid2Center;
+ ret.Mid2Width = props.flMid2Width;
+ ret.HighGain = level_mb_to_gain(static_cast<float>(props.lHighGain));
+ ret.HighCutoff = props.flHighCutOff;
+ return ret;
+ }();
return true;
}
-template<>
-void EqualizerCommitter::SetDefaults(EaxEffectProps &props)
+void EaxEqualizerCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXEQUALIZERPROPERTIES defprops{[]
{
@@ -363,10 +333,8 @@ void EqualizerCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void EqualizerCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxEqualizerCommitter::Get(const EaxCall &call, const EAXEQUALIZERPROPERTIES &props)
{
- auto &props = std::get<EAXEQUALIZERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXEQUALIZER_NONE: break;
@@ -385,10 +353,8 @@ void EqualizerCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void EqualizerCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxEqualizerCommitter::Set(const EaxCall &call, EAXEQUALIZERPROPERTIES &props)
{
- auto &props = std::get<EAXEQUALIZERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXEQUALIZER_NONE: break;
diff --git a/al/effects/fshifter.cpp b/al/effects/fshifter.cpp
index 37c372c3..556244ac 100644
--- a/al/effects/fshifter.cpp
+++ b/al/effects/fshifter.cpp
@@ -41,31 +41,26 @@ ALenum EnumFromDirection(FShifterDirection dir)
throw std::runtime_error{"Invalid direction: "+std::to_string(static_cast<int>(dir))};
}
-void Fshifter_setParamf(EffectProps *props, ALenum param, float val)
+EffectProps genDefaultProps() noexcept
{
- switch(param)
- {
- case AL_FREQUENCY_SHIFTER_FREQUENCY:
- if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY))
- throw effect_exception{AL_INVALID_VALUE, "Frequency shifter frequency out of range"};
- props->Fshifter.Frequency = val;
- break;
-
- default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x",
- param};
- }
+ FshifterProps props{};
+ props.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY;
+ props.LeftDirection = DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION).value();
+ props.RightDirection = DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION).value();
+ return props;
}
-void Fshifter_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Fshifter_setParamf(props, param, vals[0]); }
-void Fshifter_setParami(EffectProps *props, ALenum param, int val)
+} // namespace
+
+const EffectProps FshifterEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(FshifterProps &props, ALenum param, int val)
{
switch(param)
{
case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION:
if(auto diropt = DirectionFromEmum(val))
- props->Fshifter.LeftDirection = *diropt;
+ props.LeftDirection = *diropt;
else
throw effect_exception{AL_INVALID_VALUE,
"Unsupported frequency shifter left direction: 0x%04x", val};
@@ -73,7 +68,7 @@ void Fshifter_setParami(EffectProps *props, ALenum param, int val)
case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
if(auto diropt = DirectionFromEmum(val))
- props->Fshifter.RightDirection = *diropt;
+ props.RightDirection = *diropt;
else
throw effect_exception{AL_INVALID_VALUE,
"Unsupported frequency shifter right direction: 0x%04x", val};
@@ -84,33 +79,52 @@ void Fshifter_setParami(EffectProps *props, ALenum param, int val)
"Invalid frequency shifter integer property 0x%04x", param};
}
}
-void Fshifter_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Fshifter_setParami(props, param, vals[0]); }
+void EffectHandler::SetParamiv(FshifterProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
+
+void EffectHandler::SetParamf(FshifterProps &props, ALenum param, float val)
+{
+ switch(param)
+ {
+ case AL_FREQUENCY_SHIFTER_FREQUENCY:
+ if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY))
+ throw effect_exception{AL_INVALID_VALUE, "Frequency shifter frequency out of range"};
+ props.Frequency = val;
+ break;
+
+ default:
+ throw effect_exception{AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x",
+ param};
+ }
+}
+void EffectHandler::SetParamfv(FshifterProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Fshifter_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::GetParami(const FshifterProps &props, ALenum param, int *val)
{
switch(param)
{
case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION:
- *val = EnumFromDirection(props->Fshifter.LeftDirection);
+ *val = EnumFromDirection(props.LeftDirection);
break;
case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION:
- *val = EnumFromDirection(props->Fshifter.RightDirection);
+ *val = EnumFromDirection(props.RightDirection);
break;
+
default:
throw effect_exception{AL_INVALID_ENUM,
"Invalid frequency shifter integer property 0x%04x", param};
}
}
-void Fshifter_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Fshifter_getParami(props, param, vals); }
+void EffectHandler::GetParamiv(const FshifterProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
-void Fshifter_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const FshifterProps &props, ALenum param, float *val)
{
switch(param)
{
case AL_FREQUENCY_SHIFTER_FREQUENCY:
- *val = props->Fshifter.Frequency;
+ *val = props.Frequency;
break;
default:
@@ -118,23 +132,9 @@ void Fshifter_getParamf(const EffectProps *props, ALenum param, float *val)
param};
}
}
-void Fshifter_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Fshifter_getParamf(props, param, vals); }
+void EffectHandler::GetParamfv(const FshifterProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Fshifter.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY;
- props.Fshifter.LeftDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION);
- props.Fshifter.RightDirection = *DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION);
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Fshifter);
-
-const EffectProps FshifterEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -197,10 +197,9 @@ template<>
throw Exception{message};
}
-template<>
-bool FrequencyShifterCommitter::commit(const EaxEffectProps &props)
+bool EaxFrequencyShifterCommitter::commit(const EAXFREQUENCYSHIFTERPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXFREQUENCYSHIFTERPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
@@ -214,16 +213,18 @@ bool FrequencyShifterCommitter::commit(const EaxEffectProps &props)
return FShifterDirection::Off;
};
- auto &eaxprops = std::get<EAXFREQUENCYSHIFTERPROPERTIES>(props);
- mAlProps.Fshifter.Frequency = eaxprops.flFrequency;
- mAlProps.Fshifter.LeftDirection = get_direction(eaxprops.ulLeftDirection);
- mAlProps.Fshifter.RightDirection = get_direction(eaxprops.ulRightDirection);
+ mAlProps = [&]{
+ FshifterProps ret{};
+ ret.Frequency = props.flFrequency;
+ ret.LeftDirection = get_direction(props.ulLeftDirection);
+ ret.RightDirection = get_direction(props.ulRightDirection);
+ return ret;
+ }();
return true;
}
-template<>
-void FrequencyShifterCommitter::SetDefaults(EaxEffectProps &props)
+void EaxFrequencyShifterCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXFREQUENCYSHIFTERPROPERTIES defprops{[]
{
@@ -236,10 +237,8 @@ void FrequencyShifterCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void FrequencyShifterCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxFrequencyShifterCommitter::Get(const EaxCall &call, const EAXFREQUENCYSHIFTERPROPERTIES &props)
{
- auto &props = std::get<EAXFREQUENCYSHIFTERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXFREQUENCYSHIFTER_NONE: break;
@@ -251,10 +250,8 @@ void FrequencyShifterCommitter::Get(const EaxCall &call, const EaxEffectProps &p
}
}
-template<>
-void FrequencyShifterCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxFrequencyShifterCommitter::Set(const EaxCall &call, EAXFREQUENCYSHIFTERPROPERTIES &props)
{
- auto &props = std::get<EAXFREQUENCYSHIFTERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXFREQUENCYSHIFTER_NONE: break;
diff --git a/al/effects/modulator.cpp b/al/effects/modulator.cpp
index 366e7ef7..7e9424c0 100644
--- a/al/effects/modulator.cpp
+++ b/al/effects/modulator.cpp
@@ -42,40 +42,31 @@ ALenum EnumFromWaveform(ModulatorWaveform type)
std::to_string(static_cast<int>(type))};
}
-void Modulator_setParamf(EffectProps *props, ALenum param, float val)
+EffectProps genDefaultProps() noexcept
{
- switch(param)
- {
- case AL_RING_MODULATOR_FREQUENCY:
- if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY))
- throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val};
- props->Modulator.Frequency = val;
- break;
+ ModulatorProps props{};
+ props.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
+ props.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
+ props.Waveform = WaveformFromEmum(AL_RING_MODULATOR_DEFAULT_WAVEFORM).value();
+ return props;
+}
- case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
- if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF))
- throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val};
- props->Modulator.HighPassCutoff = val;
- break;
+} // namespace
- default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param};
- }
-}
-void Modulator_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Modulator_setParamf(props, param, vals[0]); }
-void Modulator_setParami(EffectProps *props, ALenum param, int val)
+const EffectProps ModulatorEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(ModulatorProps &props, ALenum param, int val)
{
switch(param)
{
case AL_RING_MODULATOR_FREQUENCY:
case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
- Modulator_setParamf(props, param, static_cast<float>(val));
+ SetParamf(props, param, static_cast<float>(val));
break;
case AL_RING_MODULATOR_WAVEFORM:
if(auto formopt = WaveformFromEmum(val))
- props->Modulator.Waveform = *formopt;
+ props.Waveform = *formopt;
else
throw effect_exception{AL_INVALID_VALUE, "Invalid modulator waveform: 0x%04x", val};
break;
@@ -85,62 +76,61 @@ void Modulator_setParami(EffectProps *props, ALenum param, int val)
param};
}
}
-void Modulator_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Modulator_setParami(props, param, vals[0]); }
+void EffectHandler::SetParamiv(ModulatorProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
-void Modulator_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::SetParamf(ModulatorProps &props, ALenum param, float val)
{
switch(param)
{
case AL_RING_MODULATOR_FREQUENCY:
- *val = static_cast<int>(props->Modulator.Frequency);
+ if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY))
+ throw effect_exception{AL_INVALID_VALUE, "Modulator frequency out of range: %f", val};
+ props.Frequency = val;
break;
+
case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
- *val = static_cast<int>(props->Modulator.HighPassCutoff);
- break;
- case AL_RING_MODULATOR_WAVEFORM:
- *val = EnumFromWaveform(props->Modulator.Waveform);
+ if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF))
+ throw effect_exception{AL_INVALID_VALUE, "Modulator high-pass cutoff out of range: %f", val};
+ props.HighPassCutoff = val;
break;
default:
+ throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param};
+ }
+}
+void EffectHandler::SetParamfv(ModulatorProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
+
+void EffectHandler::GetParami(const ModulatorProps &props, ALenum param, int *val)
+{
+ switch(param)
+ {
+ case AL_RING_MODULATOR_FREQUENCY: *val = static_cast<int>(props.Frequency); break;
+ case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = static_cast<int>(props.HighPassCutoff); break;
+ case AL_RING_MODULATOR_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
+
+ default:
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x",
param};
}
}
-void Modulator_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Modulator_getParami(props, param, vals); }
-void Modulator_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamiv(const ModulatorProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
+void EffectHandler::GetParamf(const ModulatorProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_RING_MODULATOR_FREQUENCY:
- *val = props->Modulator.Frequency;
- break;
- case AL_RING_MODULATOR_HIGHPASS_CUTOFF:
- *val = props->Modulator.HighPassCutoff;
- break;
+ case AL_RING_MODULATOR_FREQUENCY: *val = props.Frequency; break;
+ case AL_RING_MODULATOR_HIGHPASS_CUTOFF: *val = props.HighPassCutoff; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param};
}
}
-void Modulator_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Modulator_getParamf(props, param, vals); }
+void EffectHandler::GetParamfv(const ModulatorProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
- props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
- props.Modulator.Waveform = *WaveformFromEmum(AL_RING_MODULATOR_DEFAULT_WAVEFORM);
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Modulator);
-
-const EffectProps ModulatorEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -203,10 +193,9 @@ template<>
throw Exception{message};
}
-template<>
-bool ModulatorCommitter::commit(const EaxEffectProps &props)
+bool EaxModulatorCommitter::commit(const EAXRINGMODULATORPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXRINGMODULATORPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
@@ -222,16 +211,18 @@ bool ModulatorCommitter::commit(const EaxEffectProps &props)
return ModulatorWaveform::Sinusoid;
};
- auto &eaxprops = std::get<EAXRINGMODULATORPROPERTIES>(props);
- mAlProps.Modulator.Frequency = eaxprops.flFrequency;
- mAlProps.Modulator.HighPassCutoff = eaxprops.flHighPassCutOff;
- mAlProps.Modulator.Waveform = get_waveform(eaxprops.ulWaveform);
+ mAlProps = [&]{
+ ModulatorProps ret{};
+ ret.Frequency = props.flFrequency;
+ ret.HighPassCutoff = props.flHighPassCutOff;
+ ret.Waveform = get_waveform(props.ulWaveform);
+ return ret;
+ }();
return true;
}
-template<>
-void ModulatorCommitter::SetDefaults(EaxEffectProps &props)
+void EaxModulatorCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXRINGMODULATORPROPERTIES defprops{[]
{
@@ -244,10 +235,8 @@ void ModulatorCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void ModulatorCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxModulatorCommitter::Get(const EaxCall &call, const EAXRINGMODULATORPROPERTIES &props)
{
- auto &props = std::get<EAXRINGMODULATORPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXRINGMODULATOR_NONE: break;
@@ -259,11 +248,9 @@ void ModulatorCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
}
}
-template<>
-void ModulatorCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxModulatorCommitter::Set(const EaxCall &call, EAXRINGMODULATORPROPERTIES &props)
{
- auto &props = std::get<EAXRINGMODULATORPROPERTIES>(props_);
- switch (call.get_property_id())
+ switch(call.get_property_id())
{
case EAXRINGMODULATOR_NONE: break;
case EAXRINGMODULATOR_ALLPARAMETERS: defer<AllValidator>(call, props); break;
diff --git a/al/effects/null.cpp b/al/effects/null.cpp
index 1e8787e7..4b00ef4f 100644
--- a/al/effects/null.cpp
+++ b/al/effects/null.cpp
@@ -14,7 +14,17 @@
namespace {
-void Null_setParami(EffectProps* /*props*/, ALenum param, int /*val*/)
+EffectProps genDefaultProps() noexcept
+{
+ EffectProps props{};
+ return props;
+}
+
+} // namespace
+
+const EffectProps NullEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(std::monostate& /*props*/, ALenum param, int /*val*/)
{
switch(param)
{
@@ -23,15 +33,15 @@ void Null_setParami(EffectProps* /*props*/, ALenum param, int /*val*/)
param};
}
}
-void Null_setParamiv(EffectProps *props, ALenum param, const int *vals)
+void EffectHandler::SetParamiv(std::monostate &props, ALenum param, const int *vals)
{
switch(param)
{
default:
- Null_setParami(props, param, vals[0]);
+ SetParami(props, param, vals[0]);
}
}
-void Null_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/)
+void EffectHandler::SetParamf(std::monostate& /*props*/, ALenum param, float /*val*/)
{
switch(param)
{
@@ -40,16 +50,16 @@ void Null_setParamf(EffectProps* /*props*/, ALenum param, float /*val*/)
param};
}
}
-void Null_setParamfv(EffectProps *props, ALenum param, const float *vals)
+void EffectHandler::SetParamfv(std::monostate &props, ALenum param, const float *vals)
{
switch(param)
{
default:
- Null_setParamf(props, param, vals[0]);
+ SetParamf(props, param, vals[0]);
}
}
-void Null_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/)
+void EffectHandler::GetParami(const std::monostate& /*props*/, ALenum param, int* /*val*/)
{
switch(param)
{
@@ -58,15 +68,15 @@ void Null_getParami(const EffectProps* /*props*/, ALenum param, int* /*val*/)
param};
}
}
-void Null_getParamiv(const EffectProps *props, ALenum param, int *vals)
+void EffectHandler::GetParamiv(const std::monostate &props, ALenum param, int *vals)
{
switch(param)
{
default:
- Null_getParami(props, param, vals);
+ GetParami(props, param, vals);
}
}
-void Null_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/)
+void EffectHandler::GetParamf(const std::monostate& /*props*/, ALenum param, float* /*val*/)
{
switch(param)
{
@@ -75,27 +85,15 @@ void Null_getParamf(const EffectProps* /*props*/, ALenum param, float* /*val*/)
param};
}
}
-void Null_getParamfv(const EffectProps *props, ALenum param, float *vals)
+void EffectHandler::GetParamfv(const std::monostate &props, ALenum param, float *vals)
{
switch(param)
{
default:
- Null_getParamf(props, param, vals);
+ GetParamf(props, param, vals);
}
}
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Null);
-
-const EffectProps NullEffectProps{genDefaultProps()};
-
#ifdef ALSOFT_EAX
namespace {
@@ -117,29 +115,26 @@ template<>
throw Exception{message};
}
-template<>
-bool NullCommitter::commit(const EaxEffectProps &props)
+bool EaxNullCommitter::commit(const std::monostate &props)
{
- const bool ret{props != mEaxProps};
+ const bool ret{std::holds_alternative<std::monostate>(mEaxProps)};
mEaxProps = props;
+ mAlProps = std::monostate{};
return ret;
}
-template<>
-void NullCommitter::SetDefaults(EaxEffectProps &props)
+void EaxNullCommitter::SetDefaults(EaxEffectProps &props)
{
- props.emplace<std::monostate>();
+ props = std::monostate{};
}
-template<>
-void NullCommitter::Get(const EaxCall &call, const EaxEffectProps&)
+void EaxNullCommitter::Get(const EaxCall &call, const std::monostate&)
{
if(call.get_property_id() != 0)
fail_unknown_property_id();
}
-template<>
-void NullCommitter::Set(const EaxCall &call, EaxEffectProps&)
+void EaxNullCommitter::Set(const EaxCall &call, std::monostate&)
{
if(call.get_property_id() != 0)
fail_unknown_property_id();
diff --git a/al/effects/pshifter.cpp b/al/effects/pshifter.cpp
index 10824016..b36fe034 100644
--- a/al/effects/pshifter.cpp
+++ b/al/effects/pshifter.cpp
@@ -16,28 +16,32 @@
namespace {
-void Pshifter_setParamf(EffectProps*, ALenum param, float)
-{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
-void Pshifter_setParamfv(EffectProps*, ALenum param, const float*)
+EffectProps genDefaultProps() noexcept
{
- throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x",
- param};
+ PshifterProps props{};
+ props.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
+ props.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
+ return props;
}
-void Pshifter_setParami(EffectProps *props, ALenum param, int val)
+} // namespace
+
+const EffectProps PshifterEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(PshifterProps &props, ALenum param, int val)
{
switch(param)
{
case AL_PITCH_SHIFTER_COARSE_TUNE:
if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE))
throw effect_exception{AL_INVALID_VALUE, "Pitch shifter coarse tune out of range"};
- props->Pshifter.CoarseTune = val;
+ props.CoarseTune = val;
break;
case AL_PITCH_SHIFTER_FINE_TUNE:
if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE))
throw effect_exception{AL_INVALID_VALUE, "Pitch shifter fine tune out of range"};
- props->Pshifter.FineTune = val;
+ props.FineTune = val;
break;
default:
@@ -45,49 +49,40 @@ void Pshifter_setParami(EffectProps *props, ALenum param, int val)
param};
}
}
-void Pshifter_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Pshifter_setParami(props, param, vals[0]); }
+void EffectHandler::SetParamiv(PshifterProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
-void Pshifter_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::SetParamf(PshifterProps&, ALenum param, float)
+{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
+void EffectHandler::SetParamfv(PshifterProps&, ALenum param, const float*)
+{
+ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x",
+ param};
+}
+
+void EffectHandler::GetParami(const PshifterProps &props, ALenum param, int *val)
{
switch(param)
{
- case AL_PITCH_SHIFTER_COARSE_TUNE:
- *val = props->Pshifter.CoarseTune;
- break;
- case AL_PITCH_SHIFTER_FINE_TUNE:
- *val = props->Pshifter.FineTune;
- break;
+ case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; break;
+ case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
param};
}
}
-void Pshifter_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Pshifter_getParami(props, param, vals); }
+void EffectHandler::GetParamiv(const PshifterProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
-void Pshifter_getParamf(const EffectProps*, ALenum param, float*)
+void EffectHandler::GetParamf(const PshifterProps&, ALenum param, float*)
{ throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
-void Pshifter_getParamfv(const EffectProps*, ALenum param, float*)
+void EffectHandler::GetParamfv(const PshifterProps&, ALenum param, float*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x",
param};
}
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
- props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
- return props;
-}
-
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Pshifter);
-
-const EffectProps PshifterEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -138,32 +133,30 @@ template<>
throw Exception{message};
}
-template<>
-bool PitchShifterCommitter::commit(const EaxEffectProps &props)
+bool EaxPitchShifterCommitter::commit(const EAXPITCHSHIFTERPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXPITCHSHIFTERPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
-
- auto &eaxprops = std::get<EAXPITCHSHIFTERPROPERTIES>(props);
- mAlProps.Pshifter.CoarseTune = static_cast<int>(eaxprops.lCoarseTune);
- mAlProps.Pshifter.FineTune = static_cast<int>(eaxprops.lFineTune);
+ mAlProps = [&]{
+ PshifterProps ret{};
+ ret.CoarseTune = static_cast<int>(props.lCoarseTune);
+ ret.FineTune = static_cast<int>(props.lFineTune);
+ return ret;
+ }();
return true;
}
-template<>
-void PitchShifterCommitter::SetDefaults(EaxEffectProps &props)
+void EaxPitchShifterCommitter::SetDefaults(EaxEffectProps &props)
{
props = EAXPITCHSHIFTERPROPERTIES{EAXPITCHSHIFTER_DEFAULTCOARSETUNE,
EAXPITCHSHIFTER_DEFAULTFINETUNE};
}
-template<>
-void PitchShifterCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxPitchShifterCommitter::Get(const EaxCall &call, const EAXPITCHSHIFTERPROPERTIES &props)
{
- auto &props = std::get<EAXPITCHSHIFTERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXPITCHSHIFTER_NONE: break;
@@ -174,10 +167,8 @@ void PitchShifterCommitter::Get(const EaxCall &call, const EaxEffectProps &props
}
}
-template<>
-void PitchShifterCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxPitchShifterCommitter::Set(const EaxCall &call, EAXPITCHSHIFTERPROPERTIES &props)
{
- auto &props = std::get<EAXPITCHSHIFTERPROPERTIES>(props_);
switch(call.get_property_id())
{
case EAXPITCHSHIFTER_NONE: break;
diff --git a/al/effects/reverb.cpp b/al/effects/reverb.cpp
index b037443f..f0df51b2 100644
--- a/al/effects/reverb.cpp
+++ b/al/effects/reverb.cpp
@@ -20,14 +20,80 @@
namespace {
-void Reverb_setParami(EffectProps *props, ALenum param, int val)
+EffectProps genDefaultProps() noexcept
+{
+ ReverbProps props{};
+ props.Density = AL_EAXREVERB_DEFAULT_DENSITY;
+ props.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
+ props.Gain = AL_EAXREVERB_DEFAULT_GAIN;
+ props.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
+ props.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
+ props.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
+ props.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
+ props.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
+ props.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
+ props.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
+ props.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
+ props.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
+ props.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
+ props.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
+ props.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
+ props.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
+ props.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
+ props.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
+ props.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
+ props.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
+ props.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
+ props.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
+ props.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
+ props.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
+ props.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
+ props.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
+ props.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
+ return props;
+}
+
+EffectProps genDefaultStdProps() noexcept
+{
+ ReverbProps props{};
+ props.Density = AL_REVERB_DEFAULT_DENSITY;
+ props.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
+ props.Gain = AL_REVERB_DEFAULT_GAIN;
+ props.GainHF = AL_REVERB_DEFAULT_GAINHF;
+ props.GainLF = 1.0f;
+ props.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
+ props.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
+ props.DecayLFRatio = 1.0f;
+ props.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
+ props.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
+ props.ReflectionsPan = {0.0f, 0.0f, 0.0f};
+ props.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
+ props.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
+ props.LateReverbPan = {0.0f, 0.0f, 0.0f};
+ props.EchoTime = 0.25f;
+ props.EchoDepth = 0.0f;
+ props.ModulationTime = 0.25f;
+ props.ModulationDepth = 0.0f;
+ props.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
+ props.HFReference = 5000.0f;
+ props.LFReference = 250.0f;
+ props.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
+ props.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
+ return props;
+}
+
+} // namespace
+
+const EffectProps ReverbEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(ReverbProps &props, ALenum param, int val)
{
switch(param)
{
case AL_EAXREVERB_DECAY_HFLIMIT:
if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
- props->Reverb.DecayHFLimit = val != AL_FALSE;
+ props.DecayHFLimit = val != AL_FALSE;
break;
default:
@@ -35,167 +101,167 @@ void Reverb_setParami(EffectProps *props, ALenum param, int val)
param};
}
}
-void Reverb_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ Reverb_setParami(props, param, vals[0]); }
-void Reverb_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
+{ SetParami(props, param, vals[0]); }
+void EffectHandler::SetParamf(ReverbProps &props, ALenum param, float val)
{
switch(param)
{
case AL_EAXREVERB_DENSITY:
if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
- props->Reverb.Density = val;
+ props.Density = val;
break;
case AL_EAXREVERB_DIFFUSION:
if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
- props->Reverb.Diffusion = val;
+ props.Diffusion = val;
break;
case AL_EAXREVERB_GAIN:
if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
- props->Reverb.Gain = val;
+ props.Gain = val;
break;
case AL_EAXREVERB_GAINHF:
if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
- props->Reverb.GainHF = val;
+ props.GainHF = val;
break;
case AL_EAXREVERB_GAINLF:
if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainlf out of range"};
- props->Reverb.GainLF = val;
+ props.GainLF = val;
break;
case AL_EAXREVERB_DECAY_TIME:
if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
- props->Reverb.DecayTime = val;
+ props.DecayTime = val;
break;
case AL_EAXREVERB_DECAY_HFRATIO:
if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
- props->Reverb.DecayHFRatio = val;
+ props.DecayHFRatio = val;
break;
case AL_EAXREVERB_DECAY_LFRATIO:
if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range"};
- props->Reverb.DecayLFRatio = val;
+ props.DecayLFRatio = val;
break;
case AL_EAXREVERB_REFLECTIONS_GAIN:
if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
- props->Reverb.ReflectionsGain = val;
+ props.ReflectionsGain = val;
break;
case AL_EAXREVERB_REFLECTIONS_DELAY:
if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
- props->Reverb.ReflectionsDelay = val;
+ props.ReflectionsDelay = val;
break;
case AL_EAXREVERB_LATE_REVERB_GAIN:
if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
- props->Reverb.LateReverbGain = val;
+ props.LateReverbGain = val;
break;
case AL_EAXREVERB_LATE_REVERB_DELAY:
if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
- props->Reverb.LateReverbDelay = val;
+ props.LateReverbDelay = val;
break;
case AL_EAXREVERB_ECHO_TIME:
if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo time out of range"};
- props->Reverb.EchoTime = val;
+ props.EchoTime = val;
break;
case AL_EAXREVERB_ECHO_DEPTH:
if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo depth out of range"};
- props->Reverb.EchoDepth = val;
+ props.EchoDepth = val;
break;
case AL_EAXREVERB_MODULATION_TIME:
if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation time out of range"};
- props->Reverb.ModulationTime = val;
+ props.ModulationTime = val;
break;
case AL_EAXREVERB_MODULATION_DEPTH:
if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation depth out of range"};
- props->Reverb.ModulationDepth = val;
+ props.ModulationDepth = val;
break;
case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
- props->Reverb.AirAbsorptionGainHF = val;
+ props.AirAbsorptionGainHF = val;
break;
case AL_EAXREVERB_HFREFERENCE:
if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb hfreference out of range"};
- props->Reverb.HFReference = val;
+ props.HFReference = val;
break;
case AL_EAXREVERB_LFREFERENCE:
if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb lfreference out of range"};
- props->Reverb.LFReference = val;
+ props.LFReference = val;
break;
case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
- props->Reverb.RoomRolloffFactor = val;
+ props.RoomRolloffFactor = val;
break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
}
}
-void Reverb_setParamfv(EffectProps *props, ALenum param, const float *vals)
+void EffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals)
{
switch(param)
{
case AL_EAXREVERB_REFLECTIONS_PAN:
if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2])))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections pan out of range"};
- props->Reverb.ReflectionsPan[0] = vals[0];
- props->Reverb.ReflectionsPan[1] = vals[1];
- props->Reverb.ReflectionsPan[2] = vals[2];
+ props.ReflectionsPan[0] = vals[0];
+ props.ReflectionsPan[1] = vals[1];
+ props.ReflectionsPan[2] = vals[2];
break;
case AL_EAXREVERB_LATE_REVERB_PAN:
if(!(std::isfinite(vals[0]) && std::isfinite(vals[1]) && std::isfinite(vals[2])))
throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range"};
- props->Reverb.LateReverbPan[0] = vals[0];
- props->Reverb.LateReverbPan[1] = vals[1];
- props->Reverb.LateReverbPan[2] = vals[2];
+ props.LateReverbPan[0] = vals[0];
+ props.LateReverbPan[1] = vals[1];
+ props.LateReverbPan[2] = vals[2];
break;
default:
- Reverb_setParamf(props, param, vals[0]);
+ SetParamf(props, param, vals[0]);
break;
}
}
-void Reverb_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val)
{
switch(param)
{
case AL_EAXREVERB_DECAY_HFLIMIT:
- *val = props->Reverb.DecayHFLimit;
+ *val = props.DecayHFLimit;
break;
default:
@@ -203,365 +269,214 @@ void Reverb_getParami(const EffectProps *props, ALenum param, int *val)
param};
}
}
-void Reverb_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ Reverb_getParami(props, param, vals); }
-void Reverb_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
+{ GetParami(props, param, vals); }
+void EffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_EAXREVERB_DENSITY:
- *val = props->Reverb.Density;
- break;
-
- case AL_EAXREVERB_DIFFUSION:
- *val = props->Reverb.Diffusion;
- break;
-
- case AL_EAXREVERB_GAIN:
- *val = props->Reverb.Gain;
- break;
-
- case AL_EAXREVERB_GAINHF:
- *val = props->Reverb.GainHF;
- break;
-
- case AL_EAXREVERB_GAINLF:
- *val = props->Reverb.GainLF;
- break;
-
- case AL_EAXREVERB_DECAY_TIME:
- *val = props->Reverb.DecayTime;
- break;
-
- case AL_EAXREVERB_DECAY_HFRATIO:
- *val = props->Reverb.DecayHFRatio;
- break;
-
- case AL_EAXREVERB_DECAY_LFRATIO:
- *val = props->Reverb.DecayLFRatio;
- break;
-
- case AL_EAXREVERB_REFLECTIONS_GAIN:
- *val = props->Reverb.ReflectionsGain;
- break;
-
- case AL_EAXREVERB_REFLECTIONS_DELAY:
- *val = props->Reverb.ReflectionsDelay;
- break;
-
- case AL_EAXREVERB_LATE_REVERB_GAIN:
- *val = props->Reverb.LateReverbGain;
- break;
-
- case AL_EAXREVERB_LATE_REVERB_DELAY:
- *val = props->Reverb.LateReverbDelay;
- break;
-
- case AL_EAXREVERB_ECHO_TIME:
- *val = props->Reverb.EchoTime;
- break;
-
- case AL_EAXREVERB_ECHO_DEPTH:
- *val = props->Reverb.EchoDepth;
- break;
-
- case AL_EAXREVERB_MODULATION_TIME:
- *val = props->Reverb.ModulationTime;
- break;
-
- case AL_EAXREVERB_MODULATION_DEPTH:
- *val = props->Reverb.ModulationDepth;
- break;
-
- case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
- *val = props->Reverb.AirAbsorptionGainHF;
- break;
-
- case AL_EAXREVERB_HFREFERENCE:
- *val = props->Reverb.HFReference;
- break;
-
- case AL_EAXREVERB_LFREFERENCE:
- *val = props->Reverb.LFReference;
- break;
-
- case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
- *val = props->Reverb.RoomRolloffFactor;
- break;
+ case AL_EAXREVERB_DENSITY: *val = props.Density; break;
+ case AL_EAXREVERB_DIFFUSION: *val = props.Diffusion; break;
+ case AL_EAXREVERB_GAIN: *val = props.Gain; break;
+ case AL_EAXREVERB_GAINHF: *val = props.GainHF; break;
+ case AL_EAXREVERB_GAINLF: *val = props.GainLF; break;
+ case AL_EAXREVERB_DECAY_TIME: *val = props.DecayTime; break;
+ case AL_EAXREVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
+ case AL_EAXREVERB_DECAY_LFRATIO: *val = props.DecayLFRatio; break;
+ case AL_EAXREVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
+ case AL_EAXREVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
+ case AL_EAXREVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
+ case AL_EAXREVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
+ case AL_EAXREVERB_ECHO_TIME: *val = props.EchoTime; break;
+ case AL_EAXREVERB_ECHO_DEPTH: *val = props.EchoDepth; break;
+ case AL_EAXREVERB_MODULATION_TIME: *val = props.ModulationTime; break;
+ case AL_EAXREVERB_MODULATION_DEPTH: *val = props.ModulationDepth; break;
+ case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
+ case AL_EAXREVERB_HFREFERENCE: *val = props.HFReference; break;
+ case AL_EAXREVERB_LFREFERENCE: *val = props.LFReference; break;
+ case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
}
}
-void Reverb_getParamfv(const EffectProps *props, ALenum param, float *vals)
+void EffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals)
{
switch(param)
{
case AL_EAXREVERB_REFLECTIONS_PAN:
- vals[0] = props->Reverb.ReflectionsPan[0];
- vals[1] = props->Reverb.ReflectionsPan[1];
- vals[2] = props->Reverb.ReflectionsPan[2];
+ vals[0] = props.ReflectionsPan[0];
+ vals[1] = props.ReflectionsPan[1];
+ vals[2] = props.ReflectionsPan[2];
break;
case AL_EAXREVERB_LATE_REVERB_PAN:
- vals[0] = props->Reverb.LateReverbPan[0];
- vals[1] = props->Reverb.LateReverbPan[1];
- vals[2] = props->Reverb.LateReverbPan[2];
+ vals[0] = props.LateReverbPan[0];
+ vals[1] = props.LateReverbPan[1];
+ vals[2] = props.LateReverbPan[2];
break;
default:
- Reverb_getParamf(props, param, vals);
+ GetParamf(props, param, vals);
break;
}
}
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
- props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
- props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
- props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
- props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
- props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
- props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
- props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
- props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
- props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
- props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
- props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
- props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
- props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
- props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
- props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
- props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
- props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
- props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
- props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
- props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
- props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
- props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
- props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
- props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
- props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
- props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
- return props;
-}
+const EffectProps StdReverbEffectProps{genDefaultStdProps()};
-void StdReverb_setParami(EffectProps *props, ALenum param, int val)
+void EffectHandler::StdReverbSetParami(ReverbProps &props, ALenum param, int val)
{
switch(param)
{
case AL_REVERB_DECAY_HFLIMIT:
if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT))
- throw effect_exception{AL_INVALID_VALUE, "Reverb decay hflimit out of range"};
- props->Reverb.DecayHFLimit = val != AL_FALSE;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
+ props.DecayHFLimit = val != AL_FALSE;
break;
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param};
+ throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
+ param};
}
}
-void StdReverb_setParamiv(EffectProps *props, ALenum param, const int *vals)
-{ StdReverb_setParami(props, param, vals[0]); }
-void StdReverb_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::StdReverbSetParamiv(ReverbProps &props, ALenum param, const int *vals)
+{ StdReverbSetParami(props, param, vals[0]); }
+void EffectHandler::StdReverbSetParamf(ReverbProps &props, ALenum param, float val)
{
switch(param)
{
case AL_REVERB_DENSITY:
if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY))
- throw effect_exception{AL_INVALID_VALUE, "Reverb density out of range"};
- props->Reverb.Density = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
+ props.Density = val;
break;
case AL_REVERB_DIFFUSION:
if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION))
- throw effect_exception{AL_INVALID_VALUE, "Reverb diffusion out of range"};
- props->Reverb.Diffusion = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
+ props.Diffusion = val;
break;
case AL_REVERB_GAIN:
if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN))
- throw effect_exception{AL_INVALID_VALUE, "Reverb gain out of range"};
- props->Reverb.Gain = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
+ props.Gain = val;
break;
case AL_REVERB_GAINHF:
if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF))
- throw effect_exception{AL_INVALID_VALUE, "Reverb gainhf out of range"};
- props->Reverb.GainHF = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
+ props.GainHF = val;
break;
case AL_REVERB_DECAY_TIME:
if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME))
- throw effect_exception{AL_INVALID_VALUE, "Reverb decay time out of range"};
- props->Reverb.DecayTime = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
+ props.DecayTime = val;
break;
case AL_REVERB_DECAY_HFRATIO:
if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO))
- throw effect_exception{AL_INVALID_VALUE, "Reverb decay hfratio out of range"};
- props->Reverb.DecayHFRatio = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
+ props.DecayHFRatio = val;
break;
case AL_REVERB_REFLECTIONS_GAIN:
if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN))
- throw effect_exception{AL_INVALID_VALUE, "Reverb reflections gain out of range"};
- props->Reverb.ReflectionsGain = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
+ props.ReflectionsGain = val;
break;
case AL_REVERB_REFLECTIONS_DELAY:
if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY))
- throw effect_exception{AL_INVALID_VALUE, "Reverb reflections delay out of range"};
- props->Reverb.ReflectionsDelay = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
+ props.ReflectionsDelay = val;
break;
case AL_REVERB_LATE_REVERB_GAIN:
if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN))
- throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb gain out of range"};
- props->Reverb.LateReverbGain = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
+ props.LateReverbGain = val;
break;
case AL_REVERB_LATE_REVERB_DELAY:
if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY))
- throw effect_exception{AL_INVALID_VALUE, "Reverb late reverb delay out of range"};
- props->Reverb.LateReverbDelay = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
+ props.LateReverbDelay = val;
break;
case AL_REVERB_AIR_ABSORPTION_GAINHF:
if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF))
- throw effect_exception{AL_INVALID_VALUE, "Reverb air absorption gainhf out of range"};
- props->Reverb.AirAbsorptionGainHF = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
+ props.AirAbsorptionGainHF = val;
break;
case AL_REVERB_ROOM_ROLLOFF_FACTOR:
if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR))
- throw effect_exception{AL_INVALID_VALUE, "Reverb room rolloff factor out of range"};
- props->Reverb.RoomRolloffFactor = val;
+ throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
+ props.RoomRolloffFactor = val;
break;
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param};
+ throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
+ }
+}
+void EffectHandler::StdReverbSetParamfv(ReverbProps &props, ALenum param, const float *vals)
+{
+ switch(param)
+ {
+ default:
+ StdReverbSetParamf(props, param, vals[0]);
+ break;
}
}
-void StdReverb_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ StdReverb_setParamf(props, param, vals[0]); }
-void StdReverb_getParami(const EffectProps *props, ALenum param, int *val)
+void EffectHandler::StdReverbGetParami(const ReverbProps &props, ALenum param, int *val)
{
switch(param)
{
case AL_REVERB_DECAY_HFLIMIT:
- *val = props->Reverb.DecayHFLimit;
+ *val = props.DecayHFLimit;
break;
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param};
+ throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
+ param};
}
}
-void StdReverb_getParamiv(const EffectProps *props, ALenum param, int *vals)
-{ StdReverb_getParami(props, param, vals); }
-void StdReverb_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::StdReverbGetParamiv(const ReverbProps &props, ALenum param, int *vals)
+{ StdReverbGetParami(props, param, vals); }
+void EffectHandler::StdReverbGetParamf(const ReverbProps &props, ALenum param, float *val)
{
switch(param)
{
- case AL_REVERB_DENSITY:
- *val = props->Reverb.Density;
- break;
-
- case AL_REVERB_DIFFUSION:
- *val = props->Reverb.Diffusion;
- break;
-
- case AL_REVERB_GAIN:
- *val = props->Reverb.Gain;
- break;
-
- case AL_REVERB_GAINHF:
- *val = props->Reverb.GainHF;
- break;
-
- case AL_REVERB_DECAY_TIME:
- *val = props->Reverb.DecayTime;
- break;
-
- case AL_REVERB_DECAY_HFRATIO:
- *val = props->Reverb.DecayHFRatio;
- break;
-
- case AL_REVERB_REFLECTIONS_GAIN:
- *val = props->Reverb.ReflectionsGain;
- break;
-
- case AL_REVERB_REFLECTIONS_DELAY:
- *val = props->Reverb.ReflectionsDelay;
- break;
-
- case AL_REVERB_LATE_REVERB_GAIN:
- *val = props->Reverb.LateReverbGain;
- break;
-
- case AL_REVERB_LATE_REVERB_DELAY:
- *val = props->Reverb.LateReverbDelay;
- break;
-
- case AL_REVERB_AIR_ABSORPTION_GAINHF:
- *val = props->Reverb.AirAbsorptionGainHF;
- break;
-
- case AL_REVERB_ROOM_ROLLOFF_FACTOR:
- *val = props->Reverb.RoomRolloffFactor;
- break;
+ case AL_REVERB_DENSITY: *val = props.Density; break;
+ case AL_REVERB_DIFFUSION: *val = props.Diffusion; break;
+ case AL_REVERB_GAIN: *val = props.Gain; break;
+ case AL_REVERB_GAINHF: *val = props.GainHF; break;
+ case AL_REVERB_DECAY_TIME: *val = props.DecayTime; break;
+ case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
+ case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
+ case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
+ case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
+ case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
+ case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
+ case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
default:
- throw effect_exception{AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param};
+ throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
}
}
-void StdReverb_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ StdReverb_getParamf(props, param, vals); }
-
-EffectProps genDefaultStdProps() noexcept
+void EffectHandler::StdReverbGetParamfv(const ReverbProps &props, ALenum param, float *vals)
{
- EffectProps props{};
- props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY;
- props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
- props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN;
- props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF;
- props.Reverb.GainLF = 1.0f;
- props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
- props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
- props.Reverb.DecayLFRatio = 1.0f;
- props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
- props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
- props.Reverb.ReflectionsPan[0] = 0.0f;
- props.Reverb.ReflectionsPan[1] = 0.0f;
- props.Reverb.ReflectionsPan[2] = 0.0f;
- props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
- props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
- props.Reverb.LateReverbPan[0] = 0.0f;
- props.Reverb.LateReverbPan[1] = 0.0f;
- props.Reverb.LateReverbPan[2] = 0.0f;
- props.Reverb.EchoTime = 0.25f;
- props.Reverb.EchoDepth = 0.0f;
- props.Reverb.ModulationTime = 0.25f;
- props.Reverb.ModulationDepth = 0.0f;
- props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
- props.Reverb.HFReference = 5000.0f;
- props.Reverb.LFReference = 250.0f;
- props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
- props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
- return props;
+ switch(param)
+ {
+ default:
+ StdReverbGetParamf(props, param, vals);
+ break;
+ }
}
-} // namespace
-
-DEFINE_ALEFFECT_VTABLE(Reverb);
-
-const EffectProps ReverbEffectProps{genDefaultProps()};
-
-DEFINE_ALEFFECT_VTABLE(StdReverb);
-
-const EffectProps StdReverbEffectProps{genDefaultStdProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -1086,98 +1001,87 @@ struct EaxReverbCommitter::Exception : public EaxReverbEffectException
throw Exception{message};
}
-void EaxReverbCommitter::translate(const EAX_REVERBPROPERTIES& src, EaxEffectProps& dst) noexcept
+void EaxReverbCommitter::translate(const EAX_REVERBPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
{
assert(src.environment <= EAX1REVERB_MAXENVIRONMENT);
- auto&& eaxprops = dst.emplace<EAXREVERBPROPERTIES>(EAXREVERB_PRESETS[src.environment]);
- eaxprops.flDecayTime = src.fDecayTime_sec;
- eaxprops.flDecayHFRatio = src.fDamping;
- eaxprops.lReverb = mini(static_cast<int>(gain_to_level_mb(src.fVolume)), 0);
+ dst = EAXREVERB_PRESETS[src.environment];
+ dst.flDecayTime = src.fDecayTime_sec;
+ dst.flDecayHFRatio = src.fDamping;
+ dst.lReverb = mini(static_cast<int>(gain_to_level_mb(src.fVolume)), 0);
}
-void EaxReverbCommitter::translate(const EAX20LISTENERPROPERTIES& src, EaxEffectProps& dst) noexcept
+void EaxReverbCommitter::translate(const EAX20LISTENERPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
{
assert(src.dwEnvironment <= EAX1REVERB_MAXENVIRONMENT);
- auto&& eaxprops = dst.emplace<EAXREVERBPROPERTIES>(EAXREVERB_PRESETS[src.dwEnvironment]);
- eaxprops.ulEnvironment = src.dwEnvironment;
- eaxprops.flEnvironmentSize = src.flEnvironmentSize;
- eaxprops.flEnvironmentDiffusion = src.flEnvironmentDiffusion;
- eaxprops.lRoom = src.lRoom;
- eaxprops.lRoomHF = src.lRoomHF;
- eaxprops.flDecayTime = src.flDecayTime;
- eaxprops.flDecayHFRatio = src.flDecayHFRatio;
- eaxprops.lReflections = src.lReflections;
- eaxprops.flReflectionsDelay = src.flReflectionsDelay;
- eaxprops.lReverb = src.lReverb;
- eaxprops.flReverbDelay = src.flReverbDelay;
- eaxprops.flAirAbsorptionHF = src.flAirAbsorptionHF;
- eaxprops.flRoomRolloffFactor = src.flRoomRolloffFactor;
- eaxprops.ulFlags = src.dwFlags;
-}
-
-void EaxReverbCommitter::translate(const EAXREVERBPROPERTIES& src, EaxEffectProps& dst) noexcept
-{
- dst = src;
+ dst = EAXREVERB_PRESETS[src.dwEnvironment];
+ dst.ulEnvironment = src.dwEnvironment;
+ dst.flEnvironmentSize = src.flEnvironmentSize;
+ dst.flEnvironmentDiffusion = src.flEnvironmentDiffusion;
+ dst.lRoom = src.lRoom;
+ dst.lRoomHF = src.lRoomHF;
+ dst.flDecayTime = src.flDecayTime;
+ dst.flDecayHFRatio = src.flDecayHFRatio;
+ dst.lReflections = src.lReflections;
+ dst.flReflectionsDelay = src.flReflectionsDelay;
+ dst.lReverb = src.lReverb;
+ dst.flReverbDelay = src.flReverbDelay;
+ dst.flAirAbsorptionHF = src.flAirAbsorptionHF;
+ dst.flRoomRolloffFactor = src.flRoomRolloffFactor;
+ dst.ulFlags = src.dwFlags;
}
bool EaxReverbCommitter::commit(const EAX_REVERBPROPERTIES &props)
{
- EaxEffectProps dst{};
+ EAXREVERBPROPERTIES dst{};
translate(props, dst);
return commit(dst);
}
bool EaxReverbCommitter::commit(const EAX20LISTENERPROPERTIES &props)
{
- EaxEffectProps dst{};
+ EAXREVERBPROPERTIES dst{};
translate(props, dst);
return commit(dst);
}
bool EaxReverbCommitter::commit(const EAXREVERBPROPERTIES &props)
{
- EaxEffectProps dst{};
- translate(props, dst);
- return commit(dst);
-}
-
-bool EaxReverbCommitter::commit(const EaxEffectProps &props)
-{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXREVERBPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
- auto &eaxprops = std::get<EAXREVERBPROPERTIES>(props);
- const auto size = eaxprops.flEnvironmentSize;
- const auto density = (size * size * size) / 16.0F;
- mAlProps.Reverb.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY);
- mAlProps.Reverb.Diffusion = eaxprops.flEnvironmentDiffusion;
- mAlProps.Reverb.Gain = level_mb_to_gain(static_cast<float>(eaxprops.lRoom));
- mAlProps.Reverb.GainHF = level_mb_to_gain(static_cast<float>(eaxprops.lRoomHF));
- mAlProps.Reverb.GainLF = level_mb_to_gain(static_cast<float>(eaxprops.lRoomLF));
- mAlProps.Reverb.DecayTime = eaxprops.flDecayTime;
- mAlProps.Reverb.DecayHFRatio = eaxprops.flDecayHFRatio;
- mAlProps.Reverb.DecayLFRatio = eaxprops.flDecayLFRatio;
- mAlProps.Reverb.ReflectionsGain = level_mb_to_gain(static_cast<float>(eaxprops.lReflections));
- mAlProps.Reverb.ReflectionsDelay = eaxprops.flReflectionsDelay;
- mAlProps.Reverb.ReflectionsPan[0] = eaxprops.vReflectionsPan.x;
- mAlProps.Reverb.ReflectionsPan[1] = eaxprops.vReflectionsPan.y;
- mAlProps.Reverb.ReflectionsPan[2] = eaxprops.vReflectionsPan.z;
- mAlProps.Reverb.LateReverbGain = level_mb_to_gain(static_cast<float>(eaxprops.lReverb));
- mAlProps.Reverb.LateReverbDelay = eaxprops.flReverbDelay;
- mAlProps.Reverb.LateReverbPan[0] = eaxprops.vReverbPan.x;
- mAlProps.Reverb.LateReverbPan[1] = eaxprops.vReverbPan.y;
- mAlProps.Reverb.LateReverbPan[2] = eaxprops.vReverbPan.z;
- mAlProps.Reverb.EchoTime = eaxprops.flEchoTime;
- mAlProps.Reverb.EchoDepth = eaxprops.flEchoDepth;
- mAlProps.Reverb.ModulationTime = eaxprops.flModulationTime;
- mAlProps.Reverb.ModulationDepth = eaxprops.flModulationDepth;
- mAlProps.Reverb.AirAbsorptionGainHF = level_mb_to_gain(eaxprops.flAirAbsorptionHF);
- mAlProps.Reverb.HFReference = eaxprops.flHFReference;
- mAlProps.Reverb.LFReference = eaxprops.flLFReference;
- mAlProps.Reverb.RoomRolloffFactor = eaxprops.flRoomRolloffFactor;
- mAlProps.Reverb.DecayHFLimit = ((eaxprops.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
+ const auto size = props.flEnvironmentSize;
+ const auto density = (size * size * size) / 16.0f;
+ mAlProps = [&]{
+ ReverbProps ret{};
+ ret.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY);
+ ret.Diffusion = props.flEnvironmentDiffusion;
+ ret.Gain = level_mb_to_gain(static_cast<float>(props.lRoom));
+ ret.GainHF = level_mb_to_gain(static_cast<float>(props.lRoomHF));
+ ret.GainLF = level_mb_to_gain(static_cast<float>(props.lRoomLF));
+ ret.DecayTime = props.flDecayTime;
+ ret.DecayHFRatio = props.flDecayHFRatio;
+ ret.DecayLFRatio = props.flDecayLFRatio;
+ ret.ReflectionsGain = level_mb_to_gain(static_cast<float>(props.lReflections));
+ ret.ReflectionsDelay = props.flReflectionsDelay;
+ ret.ReflectionsPan = {props.vReflectionsPan.x, props.vReflectionsPan.y,
+ props.vReflectionsPan.z};
+ ret.LateReverbGain = level_mb_to_gain(static_cast<float>(props.lReverb));
+ ret.LateReverbDelay = props.flReverbDelay;
+ ret.LateReverbPan = {props.vReverbPan.x, props.vReverbPan.y, props.vReverbPan.z};
+ ret.EchoTime = props.flEchoTime;
+ ret.EchoDepth = props.flEchoDepth;
+ ret.ModulationTime = props.flModulationTime;
+ ret.ModulationDepth = props.flModulationDepth;
+ ret.AirAbsorptionGainHF = level_mb_to_gain(props.flAirAbsorptionHF);
+ ret.HFReference = props.flHFReference;
+ ret.LFReference = props.flLFReference;
+ ret.RoomRolloffFactor = props.flRoomRolloffFactor;
+ ret.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
+ return ret;
+ }();
+
return true;
}
@@ -1274,11 +1178,6 @@ void EaxReverbCommitter::Get(const EaxCall &call, const EAXREVERBPROPERTIES &pro
}
}
-void EaxReverbCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
-{
- Get(call, std::get<EAXREVERBPROPERTIES>(props));
-}
-
void EaxReverbCommitter::Set(const EaxCall &call, EAX_REVERBPROPERTIES &props)
{
@@ -1297,71 +1196,23 @@ void EaxReverbCommitter::Set(const EaxCall &call, EAX20LISTENERPROPERTIES &props
{
switch(call.get_property_id())
{
- case DSPROPERTY_EAX20LISTENER_NONE:
- break;
-
- case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
- defer<AllValidator2>(call, props);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ROOM:
- defer<RoomValidator>(call, props.lRoom);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ROOMHF:
- defer<RoomHFValidator>(call, props.lRoomHF);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
- defer<RoomRolloffFactorValidator>(call, props.flRoomRolloffFactor);
- break;
-
- case DSPROPERTY_EAX20LISTENER_DECAYTIME:
- defer<DecayTimeValidator>(call, props.flDecayTime);
- break;
-
- case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
- defer<DecayHFRatioValidator>(call, props.flDecayHFRatio);
- break;
-
- case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
- defer<ReflectionsValidator>(call, props.lReflections);
- break;
-
- case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
- defer<ReflectionsDelayValidator>(call, props.flReverbDelay);
- break;
-
- case DSPROPERTY_EAX20LISTENER_REVERB:
- defer<ReverbValidator>(call, props.lReverb);
- break;
-
- case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
- defer<ReverbDelayValidator>(call, props.flReverbDelay);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
- defer<EnvironmentValidator1, EnvironmentDeferrer2>(call, props, props.dwEnvironment);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
- defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer2>(call, props, props.flEnvironmentSize);
- break;
-
- case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
- defer<EnvironmentDiffusionValidator>(call, props.flEnvironmentDiffusion);
- break;
-
- case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
- defer<AirAbsorptionHFValidator>(call, props.flAirAbsorptionHF);
- break;
-
- case DSPROPERTY_EAX20LISTENER_FLAGS:
- defer<FlagsValidator2>(call, props.dwFlags);
- break;
-
- default:
- fail_unknown_property_id();
+ case DSPROPERTY_EAX20LISTENER_NONE: break;
+ case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS: defer<AllValidator2>(call, props); break;
+ case DSPROPERTY_EAX20LISTENER_ROOM: defer<RoomValidator>(call, props.lRoom); break;
+ case DSPROPERTY_EAX20LISTENER_ROOMHF: defer<RoomHFValidator>(call, props.lRoomHF); break;
+ case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR: defer<RoomRolloffFactorValidator>(call, props.flRoomRolloffFactor); break;
+ case DSPROPERTY_EAX20LISTENER_DECAYTIME: defer<DecayTimeValidator>(call, props.flDecayTime); break;
+ case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO: defer<DecayHFRatioValidator>(call, props.flDecayHFRatio); break;
+ case DSPROPERTY_EAX20LISTENER_REFLECTIONS: defer<ReflectionsValidator>(call, props.lReflections); break;
+ case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY: defer<ReflectionsDelayValidator>(call, props.flReverbDelay); break;
+ case DSPROPERTY_EAX20LISTENER_REVERB: defer<ReverbValidator>(call, props.lReverb); break;
+ case DSPROPERTY_EAX20LISTENER_REVERBDELAY: defer<ReverbDelayValidator>(call, props.flReverbDelay); break;
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENT: defer<EnvironmentValidator1, EnvironmentDeferrer2>(call, props, props.dwEnvironment); break;
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer2>(call, props, props.flEnvironmentSize); break;
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION: defer<EnvironmentDiffusionValidator>(call, props.flEnvironmentDiffusion); break;
+ case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF: defer<AirAbsorptionHFValidator>(call, props.flAirAbsorptionHF); break;
+ case DSPROPERTY_EAX20LISTENER_FLAGS: defer<FlagsValidator2>(call, props.dwFlags); break;
+ default: fail_unknown_property_id();
}
}
@@ -1369,117 +1220,34 @@ void EaxReverbCommitter::Set(const EaxCall &call, EAXREVERBPROPERTIES &props)
{
switch(call.get_property_id())
{
- case EAXREVERB_NONE:
- break;
-
- case EAXREVERB_ALLPARAMETERS:
- defer<AllValidator3>(call, props);
- break;
-
- case EAXREVERB_ENVIRONMENT:
- defer<EnvironmentValidator3, EnvironmentDeferrer3>(call, props, props.ulEnvironment);
- break;
-
- case EAXREVERB_ENVIRONMENTSIZE:
- defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer3>(call, props, props.flEnvironmentSize);
- break;
-
- case EAXREVERB_ENVIRONMENTDIFFUSION:
- defer3<EnvironmentDiffusionValidator>(call, props, props.flEnvironmentDiffusion);
- break;
-
- case EAXREVERB_ROOM:
- defer3<RoomValidator>(call, props, props.lRoom);
- break;
-
- case EAXREVERB_ROOMHF:
- defer3<RoomHFValidator>(call, props, props.lRoomHF);
- break;
-
- case EAXREVERB_ROOMLF:
- defer3<RoomLFValidator>(call, props, props.lRoomLF);
- break;
-
- case EAXREVERB_DECAYTIME:
- defer3<DecayTimeValidator>(call, props, props.flDecayTime);
- break;
-
- case EAXREVERB_DECAYHFRATIO:
- defer3<DecayHFRatioValidator>(call, props, props.flDecayHFRatio);
- break;
-
- case EAXREVERB_DECAYLFRATIO:
- defer3<DecayLFRatioValidator>(call, props, props.flDecayLFRatio);
- break;
-
- case EAXREVERB_REFLECTIONS:
- defer3<ReflectionsValidator>(call, props, props.lReflections);
- break;
-
- case EAXREVERB_REFLECTIONSDELAY:
- defer3<ReflectionsDelayValidator>(call, props, props.flReflectionsDelay);
- break;
-
- case EAXREVERB_REFLECTIONSPAN:
- defer3<VectorValidator>(call, props, props.vReflectionsPan);
- break;
-
- case EAXREVERB_REVERB:
- defer3<ReverbValidator>(call, props, props.lReverb);
- break;
-
- case EAXREVERB_REVERBDELAY:
- defer3<ReverbDelayValidator>(call, props, props.flReverbDelay);
- break;
-
- case EAXREVERB_REVERBPAN:
- defer3<VectorValidator>(call, props, props.vReverbPan);
- break;
-
- case EAXREVERB_ECHOTIME:
- defer3<EchoTimeValidator>(call, props, props.flEchoTime);
- break;
-
- case EAXREVERB_ECHODEPTH:
- defer3<EchoDepthValidator>(call, props, props.flEchoDepth);
- break;
-
- case EAXREVERB_MODULATIONTIME:
- defer3<ModulationTimeValidator>(call, props, props.flModulationTime);
- break;
-
- case EAXREVERB_MODULATIONDEPTH:
- defer3<ModulationDepthValidator>(call, props, props.flModulationDepth);
- break;
-
- case EAXREVERB_AIRABSORPTIONHF:
- defer3<AirAbsorptionHFValidator>(call, props, props.flAirAbsorptionHF);
- break;
-
- case EAXREVERB_HFREFERENCE:
- defer3<HFReferenceValidator>(call, props, props.flHFReference);
- break;
-
- case EAXREVERB_LFREFERENCE:
- defer3<LFReferenceValidator>(call, props, props.flLFReference);
- break;
-
- case EAXREVERB_ROOMROLLOFFFACTOR:
- defer3<RoomRolloffFactorValidator>(call, props, props.flRoomRolloffFactor);
- break;
-
- case EAXREVERB_FLAGS:
- defer3<FlagsValidator3>(call, props, props.ulFlags);
- break;
-
- default:
- fail_unknown_property_id();
+ case EAXREVERB_NONE: break;
+ case EAXREVERB_ALLPARAMETERS: defer<AllValidator3>(call, props); break;
+ case EAXREVERB_ENVIRONMENT: defer<EnvironmentValidator3, EnvironmentDeferrer3>(call, props, props.ulEnvironment); break;
+ case EAXREVERB_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer3>(call, props, props.flEnvironmentSize); break;
+ case EAXREVERB_ENVIRONMENTDIFFUSION: defer3<EnvironmentDiffusionValidator>(call, props, props.flEnvironmentDiffusion); break;
+ case EAXREVERB_ROOM: defer3<RoomValidator>(call, props, props.lRoom); break;
+ case EAXREVERB_ROOMHF: defer3<RoomHFValidator>(call, props, props.lRoomHF); break;
+ case EAXREVERB_ROOMLF: defer3<RoomLFValidator>(call, props, props.lRoomLF); break;
+ case EAXREVERB_DECAYTIME: defer3<DecayTimeValidator>(call, props, props.flDecayTime); break;
+ case EAXREVERB_DECAYHFRATIO: defer3<DecayHFRatioValidator>(call, props, props.flDecayHFRatio); break;
+ case EAXREVERB_DECAYLFRATIO: defer3<DecayLFRatioValidator>(call, props, props.flDecayLFRatio); break;
+ case EAXREVERB_REFLECTIONS: defer3<ReflectionsValidator>(call, props, props.lReflections); break;
+ case EAXREVERB_REFLECTIONSDELAY: defer3<ReflectionsDelayValidator>(call, props, props.flReflectionsDelay); break;
+ case EAXREVERB_REFLECTIONSPAN: defer3<VectorValidator>(call, props, props.vReflectionsPan); break;
+ case EAXREVERB_REVERB: defer3<ReverbValidator>(call, props, props.lReverb); break;
+ case EAXREVERB_REVERBDELAY: defer3<ReverbDelayValidator>(call, props, props.flReverbDelay); break;
+ case EAXREVERB_REVERBPAN: defer3<VectorValidator>(call, props, props.vReverbPan); break;
+ case EAXREVERB_ECHOTIME: defer3<EchoTimeValidator>(call, props, props.flEchoTime); break;
+ case EAXREVERB_ECHODEPTH: defer3<EchoDepthValidator>(call, props, props.flEchoDepth); break;
+ case EAXREVERB_MODULATIONTIME: defer3<ModulationTimeValidator>(call, props, props.flModulationTime); break;
+ case EAXREVERB_MODULATIONDEPTH: defer3<ModulationDepthValidator>(call, props, props.flModulationDepth); break;
+ case EAXREVERB_AIRABSORPTIONHF: defer3<AirAbsorptionHFValidator>(call, props, props.flAirAbsorptionHF); break;
+ case EAXREVERB_HFREFERENCE: defer3<HFReferenceValidator>(call, props, props.flHFReference); break;
+ case EAXREVERB_LFREFERENCE: defer3<LFReferenceValidator>(call, props, props.flLFReference); break;
+ case EAXREVERB_ROOMROLLOFFFACTOR: defer3<RoomRolloffFactorValidator>(call, props, props.flRoomRolloffFactor); break;
+ case EAXREVERB_FLAGS: defer3<FlagsValidator3>(call, props, props.ulFlags); break;
+ default: fail_unknown_property_id();
}
}
-void EaxReverbCommitter::Set(const EaxCall &call, EaxEffectProps &props)
-{
- Set(call, std::get<EAXREVERBPROPERTIES>(props));
-}
-
#endif // ALSOFT_EAX
diff --git a/al/effects/vmorpher.cpp b/al/effects/vmorpher.cpp
index f2551229..35a64d32 100644
--- a/al/effects/vmorpher.cpp
+++ b/al/effects/vmorpher.cpp
@@ -122,13 +122,29 @@ ALenum EnumFromWaveform(VMorpherWaveform type)
std::to_string(static_cast<int>(type))};
}
-void Vmorpher_setParami(EffectProps *props, ALenum param, int val)
+EffectProps genDefaultProps() noexcept
+{
+ VmorpherProps props{};
+ props.Rate = AL_VOCAL_MORPHER_DEFAULT_RATE;
+ props.PhonemeA = PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA).value();
+ props.PhonemeB = PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB).value();
+ props.PhonemeACoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING;
+ props.PhonemeBCoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING;
+ props.Waveform = WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM).value();
+ return props;
+}
+
+} // namespace
+
+const EffectProps VmorpherEffectProps{genDefaultProps()};
+
+void EffectHandler::SetParami(VmorpherProps &props, ALenum param, int val)
{
switch(param)
{
case AL_VOCAL_MORPHER_PHONEMEA:
if(auto phenomeopt = PhenomeFromEnum(val))
- props->Vmorpher.PhonemeA = *phenomeopt;
+ props.PhonemeA = *phenomeopt;
else
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a out of range: 0x%04x", val};
break;
@@ -136,12 +152,12 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val)
case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING:
if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING))
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-a coarse tuning out of range"};
- props->Vmorpher.PhonemeACoarseTuning = val;
+ props.PhonemeACoarseTuning = val;
break;
case AL_VOCAL_MORPHER_PHONEMEB:
if(auto phenomeopt = PhenomeFromEnum(val))
- props->Vmorpher.PhonemeB = *phenomeopt;
+ props.PhonemeB = *phenomeopt;
else
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b out of range: 0x%04x", val};
break;
@@ -149,12 +165,12 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val)
case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING:
if(!(val >= AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING && val <= AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING))
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher phoneme-b coarse tuning out of range"};
- props->Vmorpher.PhonemeBCoarseTuning = val;
+ props.PhonemeBCoarseTuning = val;
break;
case AL_VOCAL_MORPHER_WAVEFORM:
if(auto formopt = WaveformFromEmum(val))
- props->Vmorpher.Waveform = *formopt;
+ props.Waveform = *formopt;
else
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher waveform out of range: 0x%04x", val};
break;
@@ -164,19 +180,19 @@ void Vmorpher_setParami(EffectProps *props, ALenum param, int val)
param};
}
}
-void Vmorpher_setParamiv(EffectProps*, ALenum param, const int*)
+void EffectHandler::SetParamiv(VmorpherProps&, ALenum param, const int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
param};
}
-void Vmorpher_setParamf(EffectProps *props, ALenum param, float val)
+void EffectHandler::SetParamf(VmorpherProps &props, ALenum param, float val)
{
switch(param)
{
case AL_VOCAL_MORPHER_RATE:
if(!(val >= AL_VOCAL_MORPHER_MIN_RATE && val <= AL_VOCAL_MORPHER_MAX_RATE))
throw effect_exception{AL_INVALID_VALUE, "Vocal morpher rate out of range"};
- props->Vmorpher.Rate = val;
+ props.Rate = val;
break;
default:
@@ -184,49 +200,35 @@ void Vmorpher_setParamf(EffectProps *props, ALenum param, float val)
param};
}
}
-void Vmorpher_setParamfv(EffectProps *props, ALenum param, const float *vals)
-{ Vmorpher_setParamf(props, param, vals[0]); }
+void EffectHandler::SetParamfv(VmorpherProps &props, ALenum param, const float *vals)
+{ SetParamf(props, param, vals[0]); }
-void Vmorpher_getParami(const EffectProps *props, ALenum param, int* val)
+void EffectHandler::GetParami(const VmorpherProps &props, ALenum param, int* val)
{
switch(param)
{
- case AL_VOCAL_MORPHER_PHONEMEA:
- *val = EnumFromPhenome(props->Vmorpher.PhonemeA);
- break;
-
- case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING:
- *val = props->Vmorpher.PhonemeACoarseTuning;
- break;
-
- case AL_VOCAL_MORPHER_PHONEMEB:
- *val = EnumFromPhenome(props->Vmorpher.PhonemeB);
- break;
-
- case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING:
- *val = props->Vmorpher.PhonemeBCoarseTuning;
- break;
-
- case AL_VOCAL_MORPHER_WAVEFORM:
- *val = EnumFromWaveform(props->Vmorpher.Waveform);
- break;
+ case AL_VOCAL_MORPHER_PHONEMEA: *val = EnumFromPhenome(props.PhonemeA); break;
+ case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING: *val = props.PhonemeACoarseTuning; break;
+ case AL_VOCAL_MORPHER_PHONEMEB: *val = EnumFromPhenome(props.PhonemeB); break;
+ case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING: *val = props.PhonemeBCoarseTuning; break;
+ case AL_VOCAL_MORPHER_WAVEFORM: *val = EnumFromWaveform(props.Waveform); break;
default:
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer property 0x%04x",
param};
}
}
-void Vmorpher_getParamiv(const EffectProps*, ALenum param, int*)
+void EffectHandler::GetParamiv(const VmorpherProps&, ALenum param, int*)
{
throw effect_exception{AL_INVALID_ENUM, "Invalid vocal morpher integer-vector property 0x%04x",
param};
}
-void Vmorpher_getParamf(const EffectProps *props, ALenum param, float *val)
+void EffectHandler::GetParamf(const VmorpherProps &props, ALenum param, float *val)
{
switch(param)
{
case AL_VOCAL_MORPHER_RATE:
- *val = props->Vmorpher.Rate;
+ *val = props.Rate;
break;
default:
@@ -234,26 +236,9 @@ void Vmorpher_getParamf(const EffectProps *props, ALenum param, float *val)
param};
}
}
-void Vmorpher_getParamfv(const EffectProps *props, ALenum param, float *vals)
-{ Vmorpher_getParamf(props, param, vals); }
-
-EffectProps genDefaultProps() noexcept
-{
- EffectProps props{};
- props.Vmorpher.Rate = AL_VOCAL_MORPHER_DEFAULT_RATE;
- props.Vmorpher.PhonemeA = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA);
- props.Vmorpher.PhonemeB = *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB);
- props.Vmorpher.PhonemeACoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING;
- props.Vmorpher.PhonemeBCoarseTuning = AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING;
- props.Vmorpher.Waveform = *WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM);
- return props;
-}
-
-} // namespace
+void EffectHandler::GetParamfv(const VmorpherProps &props, ALenum param, float *vals)
+{ GetParamf(props, param, vals); }
-DEFINE_ALEFFECT_VTABLE(Vmorpher);
-
-const EffectProps VmorpherEffectProps{genDefaultProps()};
#ifdef ALSOFT_EAX
namespace {
@@ -352,10 +337,9 @@ template<>
throw Exception{message};
}
-template<>
-bool VocalMorpherCommitter::commit(const EaxEffectProps &props)
+bool EaxVocalMorpherCommitter::commit(const EAXVOCALMORPHERPROPERTIES &props)
{
- if(props == mEaxProps)
+ if(auto *cur = std::get_if<EAXVOCALMORPHERPROPERTIES>(&mEaxProps); cur && *cur == props)
return false;
mEaxProps = props;
@@ -407,19 +391,21 @@ bool VocalMorpherCommitter::commit(const EaxEffectProps &props)
return VMorpherWaveform::Sinusoid;
};
- auto &eaxprops = std::get<EAXVOCALMORPHERPROPERTIES>(props);
- mAlProps.Vmorpher.PhonemeA = get_phoneme(eaxprops.ulPhonemeA);
- mAlProps.Vmorpher.PhonemeACoarseTuning = static_cast<int>(eaxprops.lPhonemeACoarseTuning);
- mAlProps.Vmorpher.PhonemeB = get_phoneme(eaxprops.ulPhonemeB);
- mAlProps.Vmorpher.PhonemeBCoarseTuning = static_cast<int>(eaxprops.lPhonemeBCoarseTuning);
- mAlProps.Vmorpher.Waveform = get_waveform(eaxprops.ulWaveform);
- mAlProps.Vmorpher.Rate = eaxprops.flRate;
+ mAlProps = [&]{
+ VmorpherProps ret{};
+ ret.PhonemeA = get_phoneme(props.ulPhonemeA);
+ ret.PhonemeACoarseTuning = static_cast<int>(props.lPhonemeACoarseTuning);
+ ret.PhonemeB = get_phoneme(props.ulPhonemeB);
+ ret.PhonemeBCoarseTuning = static_cast<int>(props.lPhonemeBCoarseTuning);
+ ret.Waveform = get_waveform(props.ulWaveform);
+ ret.Rate = props.flRate;
+ return ret;
+ }();
return true;
}
-template<>
-void VocalMorpherCommitter::SetDefaults(EaxEffectProps &props)
+void EaxVocalMorpherCommitter::SetDefaults(EaxEffectProps &props)
{
static constexpr EAXVOCALMORPHERPROPERTIES defprops{[]
{
@@ -435,87 +421,35 @@ void VocalMorpherCommitter::SetDefaults(EaxEffectProps &props)
props = defprops;
}
-template<>
-void VocalMorpherCommitter::Get(const EaxCall &call, const EaxEffectProps &props_)
+void EaxVocalMorpherCommitter::Get(const EaxCall &call, const EAXVOCALMORPHERPROPERTIES &props)
{
- auto &props = std::get<EAXVOCALMORPHERPROPERTIES>(props_);
switch(call.get_property_id())
{
- case EAXVOCALMORPHER_NONE:
- break;
-
- case EAXVOCALMORPHER_ALLPARAMETERS:
- call.set_value<Exception>(props);
- break;
-
- case EAXVOCALMORPHER_PHONEMEA:
- call.set_value<Exception>(props.ulPhonemeA);
- break;
-
- case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
- call.set_value<Exception>(props.lPhonemeACoarseTuning);
- break;
-
- case EAXVOCALMORPHER_PHONEMEB:
- call.set_value<Exception>(props.ulPhonemeB);
- break;
-
- case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
- call.set_value<Exception>(props.lPhonemeBCoarseTuning);
- break;
-
- case EAXVOCALMORPHER_WAVEFORM:
- call.set_value<Exception>(props.ulWaveform);
- break;
-
- case EAXVOCALMORPHER_RATE:
- call.set_value<Exception>(props.flRate);
- break;
-
- default:
- fail_unknown_property_id();
+ case EAXVOCALMORPHER_NONE: break;
+ case EAXVOCALMORPHER_ALLPARAMETERS: call.set_value<Exception>(props); break;
+ case EAXVOCALMORPHER_PHONEMEA: call.set_value<Exception>(props.ulPhonemeA); break;
+ case EAXVOCALMORPHER_PHONEMEACOARSETUNING: call.set_value<Exception>(props.lPhonemeACoarseTuning); break;
+ case EAXVOCALMORPHER_PHONEMEB: call.set_value<Exception>(props.ulPhonemeB); break;
+ case EAXVOCALMORPHER_PHONEMEBCOARSETUNING: call.set_value<Exception>(props.lPhonemeBCoarseTuning); break;
+ case EAXVOCALMORPHER_WAVEFORM: call.set_value<Exception>(props.ulWaveform); break;
+ case EAXVOCALMORPHER_RATE: call.set_value<Exception>(props.flRate); break;
+ default: fail_unknown_property_id();
}
}
-template<>
-void VocalMorpherCommitter::Set(const EaxCall &call, EaxEffectProps &props_)
+void EaxVocalMorpherCommitter::Set(const EaxCall &call, EAXVOCALMORPHERPROPERTIES &props)
{
- auto &props = std::get<EAXVOCALMORPHERPROPERTIES>(props_);
switch(call.get_property_id())
{
- case EAXVOCALMORPHER_NONE:
- break;
-
- case EAXVOCALMORPHER_ALLPARAMETERS:
- defer<AllValidator>(call, props);
- break;
-
- case EAXVOCALMORPHER_PHONEMEA:
- defer<PhonemeAValidator>(call, props.ulPhonemeA);
- break;
-
- case EAXVOCALMORPHER_PHONEMEACOARSETUNING:
- defer<PhonemeACoarseTuningValidator>(call, props.lPhonemeACoarseTuning);
- break;
-
- case EAXVOCALMORPHER_PHONEMEB:
- defer<PhonemeBValidator>(call, props.ulPhonemeB);
- break;
-
- case EAXVOCALMORPHER_PHONEMEBCOARSETUNING:
- defer<PhonemeBCoarseTuningValidator>(call, props.lPhonemeBCoarseTuning);
- break;
-
- case EAXVOCALMORPHER_WAVEFORM:
- defer<WaveformValidator>(call, props.ulWaveform);
- break;
-
- case EAXVOCALMORPHER_RATE:
- defer<RateValidator>(call, props.flRate);
- break;
-
- default:
- fail_unknown_property_id();
+ case EAXVOCALMORPHER_NONE: break;
+ case EAXVOCALMORPHER_ALLPARAMETERS: defer<AllValidator>(call, props); break;
+ case EAXVOCALMORPHER_PHONEMEA: defer<PhonemeAValidator>(call, props.ulPhonemeA); break;
+ case EAXVOCALMORPHER_PHONEMEACOARSETUNING: defer<PhonemeACoarseTuningValidator>(call, props.lPhonemeACoarseTuning); break;
+ case EAXVOCALMORPHER_PHONEMEB: defer<PhonemeBValidator>(call, props.ulPhonemeB); break;
+ case EAXVOCALMORPHER_PHONEMEBCOARSETUNING: defer<PhonemeBCoarseTuningValidator>(call, props.lPhonemeBCoarseTuning); break;
+ case EAXVOCALMORPHER_WAVEFORM: defer<WaveformValidator>(call, props.ulWaveform); break;
+ case EAXVOCALMORPHER_RATE: defer<RateValidator>(call, props.flRate); break;
+ default: fail_unknown_property_id();
}
}