aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax
diff options
context:
space:
mode:
Diffstat (limited to 'al/eax')
-rw-r--r--al/eax/api.h16
-rw-r--r--al/eax/effect.h113
2 files changed, 70 insertions, 59 deletions
diff --git a/al/eax/api.h b/al/eax/api.h
index d254da1f..b3a09d29 100644
--- a/al/eax/api.h
+++ b/al/eax/api.h
@@ -38,6 +38,9 @@ inline bool operator!=(const GUID& lhs, const GUID& rhs) noexcept
#endif // _SYS_GUID_OPERATOR_EQ_
#endif // GUID_DEFINED
+#define DECL_EQOP(T) \
+friend bool operator==(const T &lhs, const T &rhs) noexcept { return std::memcmp(&lhs, &rhs, sizeof(T)) == 0; } \
+friend bool operator!=(const T &lhs, const T &rhs) noexcept { return !(lhs == rhs); }
extern const GUID DSPROPSETID_EAX_ReverbProperties;
@@ -836,6 +839,7 @@ struct EAXREVERBPROPERTIES {
float flLFReference; // reference low frequency
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
unsigned long ulFlags; // modifies the behavior of properties
+ DECL_EQOP(EAXREVERBPROPERTIES)
}; // EAXREVERBPROPERTIES
@@ -965,6 +969,7 @@ enum EAXAGCCOMPRESSOR_PROPERTY : unsigned int {
struct EAXAGCCOMPRESSORPROPERTIES {
unsigned long ulOnOff; // Switch Compressor on or off
+ DECL_EQOP(EAXAGCCOMPRESSORPROPERTIES)
}; // EAXAGCCOMPRESSORPROPERTIES
@@ -991,6 +996,7 @@ struct EAXAUTOWAHPROPERTIES {
float flReleaseTime; // Release time (seconds)
long lResonance; // Resonance (mB)
long lPeakLevel; // Peak level (mB)
+ DECL_EQOP(EAXAUTOWAHPROPERTIES)
}; // EAXAUTOWAHPROPERTIES
@@ -1038,6 +1044,7 @@ struct EAXCHORUSPROPERTIES {
float flDepth; // Depth (0 to 1)
float flFeedback; // Feedback (-1 to 1)
float flDelay; // Delay (seconds)
+ DECL_EQOP(EAXCHORUSPROPERTIES)
}; // EAXCHORUSPROPERTIES
@@ -1086,6 +1093,7 @@ struct EAXDISTORTIONPROPERTIES {
float flLowPassCutOff; // Controls the cut-off of the filter pre-distortion (Hz)
float flEQCenter; // Controls the center frequency of the EQ post-distortion (Hz)
float flEQBandwidth; // Controls the bandwidth of the EQ post-distortion (Hz)
+ DECL_EQOP(EAXDISTORTIONPROPERTIES)
}; // EAXDISTORTIONPROPERTIES
@@ -1130,6 +1138,7 @@ struct EAXECHOPROPERTIES {
float flDamping; // Controls a low-pass filter that dampens the echoes (0 to 1)
float flFeedback; // Controls the duration of echo repetition (0 to 1)
float flSpread; // Controls the left-right spread of the echoes
+ DECL_EQOP(EAXECHOPROPERTIES)
}; // EAXECHOPROPERTIES
@@ -1184,6 +1193,7 @@ struct EAXEQUALIZERPROPERTIES {
float flMid2Width; // (octaves)
long lHighGain; // (mB)
float flHighCutOff; // (Hz)
+ DECL_EQOP(EAXEQUALIZERPROPERTIES)
}; // EAXEQUALIZERPROPERTIES
@@ -1255,6 +1265,7 @@ struct EAXFLANGERPROPERTIES {
float flDepth; // Depth (0 to 1)
float flFeedback; // Feedback (0 to 1)
float flDelay; // Delay (seconds)
+ DECL_EQOP(EAXFLANGERPROPERTIES)
}; // EAXFLANGERPROPERTIES
@@ -1305,6 +1316,7 @@ struct EAXFREQUENCYSHIFTERPROPERTIES {
float flFrequency; // (Hz)
unsigned long ulLeftDirection; // see enum above
unsigned long ulRightDirection; // see enum above
+ DECL_EQOP(EAXFREQUENCYSHIFTERPROPERTIES)
}; // EAXFREQUENCYSHIFTERPROPERTIES
@@ -1383,6 +1395,7 @@ struct EAXVOCALMORPHERPROPERTIES {
long lPhonemeBCoarseTuning; // (semitones)
unsigned long ulWaveform; // Waveform selector - see enum above
float flRate; // (Hz)
+ DECL_EQOP(EAXVOCALMORPHERPROPERTIES)
}; // EAXVOCALMORPHERPROPERTIES
@@ -1425,6 +1438,7 @@ enum EAXPITCHSHIFTER_PROPERTY : unsigned int {
struct EAXPITCHSHIFTERPROPERTIES {
long lCoarseTune; // Amount of pitch shift (semitones)
long lFineTune; // Amount of pitch shift (cents)
+ DECL_EQOP(EAXPITCHSHIFTERPROPERTIES)
}; // EAXPITCHSHIFTERPROPERTIES
@@ -1460,6 +1474,7 @@ struct EAXRINGMODULATORPROPERTIES {
float flFrequency; // Frequency of modulation (Hz)
float flHighPassCutOff; // Cut-off frequency of high-pass filter (Hz)
unsigned long ulWaveform; // Waveform selector - see enum above
+ DECL_EQOP(EAXRINGMODULATORPROPERTIES)
}; // EAXRINGMODULATORPROPERTIES
@@ -1490,4 +1505,5 @@ using LPEAXGET = ALenum(AL_APIENTRY*)(
ALvoid* property_buffer,
ALuint property_size);
+#undef DECL_EQOP
#endif // !EAX_API_INCLUDED
diff --git a/al/eax/effect.h b/al/eax/effect.h
index a0b4e71b..afe4d94d 100644
--- a/al/eax/effect.h
+++ b/al/eax/effect.h
@@ -4,60 +4,55 @@
#include <cassert>
#include <memory>
+#include <variant>
#include "alnumeric.h"
#include "AL/al.h"
#include "core/effects/base.h"
#include "call.h"
-struct EaxEffectErrorMessages
-{
+struct EaxEffectErrorMessages {
static constexpr auto unknown_property_id() noexcept { return "Unknown property id."; }
static constexpr auto unknown_version() noexcept { return "Unknown version."; }
}; // EaxEffectErrorMessages
-/* TODO: Use std::variant (C++17). */
-enum class EaxEffectType {
- None, Reverb, Chorus, Autowah, Compressor, Distortion, Echo, Equalizer, Flanger,
- FrequencyShifter, Modulator, PitchShifter, VocalMorpher
-};
-struct EaxEffectProps {
- EaxEffectType mType;
- union {
- EAXREVERBPROPERTIES mReverb;
- EAXCHORUSPROPERTIES mChorus;
- EAXAUTOWAHPROPERTIES mAutowah;
- EAXAGCCOMPRESSORPROPERTIES mCompressor;
- EAXDISTORTIONPROPERTIES mDistortion;
- EAXECHOPROPERTIES mEcho;
- EAXEQUALIZERPROPERTIES mEqualizer;
- EAXFLANGERPROPERTIES mFlanger;
- EAXFREQUENCYSHIFTERPROPERTIES mFrequencyShifter;
- EAXRINGMODULATORPROPERTIES mModulator;
- EAXPITCHSHIFTERPROPERTIES mPitchShifter;
- EAXVOCALMORPHERPROPERTIES mVocalMorpher;
- };
-};
-
-constexpr ALenum EnumFromEaxEffectType(const EaxEffectProps &props)
+using EaxEffectProps = std::variant<std::monostate,
+ EAXREVERBPROPERTIES,
+ EAXCHORUSPROPERTIES,
+ EAXAUTOWAHPROPERTIES,
+ EAXAGCCOMPRESSORPROPERTIES,
+ EAXDISTORTIONPROPERTIES,
+ EAXECHOPROPERTIES,
+ EAXEQUALIZERPROPERTIES,
+ EAXFLANGERPROPERTIES,
+ EAXFREQUENCYSHIFTERPROPERTIES,
+ EAXRINGMODULATORPROPERTIES,
+ EAXPITCHSHIFTERPROPERTIES,
+ EAXVOCALMORPHERPROPERTIES>;
+
+template<typename... Ts>
+struct overloaded : Ts... { using Ts::operator()...; };
+
+template<typename... Ts>
+overloaded(Ts...) -> overloaded<Ts...>;
+
+constexpr ALenum EnumFromEaxEffectType(const EaxEffectProps &props) noexcept
{
- switch(props.mType)
- {
- case EaxEffectType::None: break;
- case EaxEffectType::Reverb: return AL_EFFECT_EAXREVERB;
- case EaxEffectType::Chorus: return AL_EFFECT_CHORUS;
- case EaxEffectType::Autowah: return AL_EFFECT_AUTOWAH;
- case EaxEffectType::Compressor: return AL_EFFECT_COMPRESSOR;
- case EaxEffectType::Distortion: return AL_EFFECT_DISTORTION;
- case EaxEffectType::Echo: return AL_EFFECT_ECHO;
- case EaxEffectType::Equalizer: return AL_EFFECT_EQUALIZER;
- case EaxEffectType::Flanger: return AL_EFFECT_FLANGER;
- case EaxEffectType::FrequencyShifter: return AL_EFFECT_FREQUENCY_SHIFTER;
- case EaxEffectType::Modulator: return AL_EFFECT_RING_MODULATOR;
- case EaxEffectType::PitchShifter: return AL_EFFECT_PITCH_SHIFTER;
- case EaxEffectType::VocalMorpher: return AL_EFFECT_VOCAL_MORPHER;
- }
- return AL_EFFECT_NULL;
+ return std::visit(overloaded{
+ [](const std::monostate&) noexcept { return AL_EFFECT_NULL; },
+ [](const EAXREVERBPROPERTIES&) noexcept { return AL_EFFECT_EAXREVERB; },
+ [](const EAXCHORUSPROPERTIES&) noexcept { return AL_EFFECT_CHORUS; },
+ [](const EAXAUTOWAHPROPERTIES&) noexcept { return AL_EFFECT_AUTOWAH; },
+ [](const EAXAGCCOMPRESSORPROPERTIES&) noexcept { return AL_EFFECT_COMPRESSOR; },
+ [](const EAXDISTORTIONPROPERTIES&) noexcept { return AL_EFFECT_DISTORTION; },
+ [](const EAXECHOPROPERTIES&) noexcept { return AL_EFFECT_ECHO; },
+ [](const EAXEQUALIZERPROPERTIES&) noexcept { return AL_EFFECT_EQUALIZER; },
+ [](const EAXFLANGERPROPERTIES&) noexcept { return AL_EFFECT_FLANGER; },
+ [](const EAXFREQUENCYSHIFTERPROPERTIES&) noexcept { return AL_EFFECT_FREQUENCY_SHIFTER; },
+ [](const EAXRINGMODULATORPROPERTIES&) noexcept { return AL_EFFECT_RING_MODULATOR; },
+ [](const EAXPITCHSHIFTERPROPERTIES&) noexcept { return AL_EFFECT_PITCH_SHIFTER; },
+ [](const EAXVOCALMORPHERPROPERTIES&) noexcept { return AL_EFFECT_VOCAL_MORPHER; }
+ }, props);
}
struct EaxReverbCommitter {
@@ -300,30 +295,30 @@ public:
}
-#define EAXCALL(T, Callable, ...) \
- if(T == EaxEffectType::Reverb) \
+#define EAXCALL(Props, Callable, ...) \
+ if(std::holds_alternative<EAXREVERBPROPERTIES>(Props)) \
return Callable<EaxReverbCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Chorus) \
+ if(std::holds_alternative<EAXCHORUSPROPERTIES>(Props)) \
return Callable<EaxChorusCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Autowah) \
+ if(std::holds_alternative<EAXAUTOWAHPROPERTIES>(Props)) \
return Callable<EaxAutowahCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Compressor) \
+ if(std::holds_alternative<EAXAGCCOMPRESSORPROPERTIES>(Props)) \
return Callable<EaxCompressorCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Distortion) \
+ if(std::holds_alternative<EAXDISTORTIONPROPERTIES>(Props)) \
return Callable<EaxDistortionCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Echo) \
+ if(std::holds_alternative<EAXECHOPROPERTIES>(Props)) \
return Callable<EaxEchoCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Equalizer) \
+ if(std::holds_alternative<EAXEQUALIZERPROPERTIES>(Props)) \
return Callable<EaxEqualizerCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Flanger) \
+ if(std::holds_alternative<EAXFLANGERPROPERTIES>(Props)) \
return Callable<EaxFlangerCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::FrequencyShifter) \
+ if(std::holds_alternative<EAXFREQUENCYSHIFTERPROPERTIES>(Props)) \
return Callable<EaxFrequencyShifterCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::Modulator) \
+ if(std::holds_alternative<EAXRINGMODULATORPROPERTIES>(Props)) \
return Callable<EaxModulatorCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::PitchShifter) \
+ if(std::holds_alternative<EAXPITCHSHIFTERPROPERTIES>(Props)) \
return Callable<EaxPitchShifterCommitter>(__VA_ARGS__); \
- if(T == EaxEffectType::VocalMorpher) \
+ if(std::holds_alternative<EAXVOCALMORPHERPROPERTIES>(Props)) \
return Callable<EaxVocalMorpherCommitter>(__VA_ARGS__); \
return Callable<EaxNullCommitter>(__VA_ARGS__)
@@ -332,7 +327,7 @@ public:
{ return T::Set(std::forward<Args>(args)...); }
static void call_set(const EaxCall &call, EaxEffectProps &props)
- { EAXCALL(props.mType, call_set, call, props); }
+ { EAXCALL(props, call_set, call, props); }
void set(const EaxCall &call)
{
@@ -353,7 +348,7 @@ public:
{ return T::Get(std::forward<Args>(args)...); }
static void call_get(const EaxCall &call, const EaxEffectProps &props)
- { EAXCALL(props.mType, call_get, call, props); }
+ { EAXCALL(props, call_get, call, props); }
void get(const EaxCall &call)
{
@@ -373,7 +368,7 @@ public:
{ return T{props_, al_effect_props_}.commit(std::forward<Args>(args)...); }
bool call_commit(const EaxEffectProps &props)
- { EAXCALL(props.mType, call_commit, props); }
+ { EAXCALL(props, call_commit, props); }
bool commit(int eax_version)
{