7 #include "alc/effects/base.h"
11 #include "alnumeric.h"
12 #include "al/eax/effect.h"
13 #include "al/eax/exception.h"
14 #include "al/eax/utils.h"
20 constexpr EffectProps
genDefaultProps() noexcept
22 EqualizerProps props
{};
23 props
.LowCutoff
= AL_EQUALIZER_DEFAULT_LOW_CUTOFF
;
24 props
.LowGain
= AL_EQUALIZER_DEFAULT_LOW_GAIN
;
25 props
.Mid1Center
= AL_EQUALIZER_DEFAULT_MID1_CENTER
;
26 props
.Mid1Gain
= AL_EQUALIZER_DEFAULT_MID1_GAIN
;
27 props
.Mid1Width
= AL_EQUALIZER_DEFAULT_MID1_WIDTH
;
28 props
.Mid2Center
= AL_EQUALIZER_DEFAULT_MID2_CENTER
;
29 props
.Mid2Gain
= AL_EQUALIZER_DEFAULT_MID2_GAIN
;
30 props
.Mid2Width
= AL_EQUALIZER_DEFAULT_MID2_WIDTH
;
31 props
.HighCutoff
= AL_EQUALIZER_DEFAULT_HIGH_CUTOFF
;
32 props
.HighGain
= AL_EQUALIZER_DEFAULT_HIGH_GAIN
;
38 const EffectProps EqualizerEffectProps
{genDefaultProps()};
40 void EqualizerEffectHandler::SetParami(EqualizerProps
&, ALenum param
, int)
41 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer integer property 0x%04x", param
}; }
42 void EqualizerEffectHandler::SetParamiv(EqualizerProps
&, ALenum param
, const int*)
44 throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer integer-vector property 0x%04x",
47 void EqualizerEffectHandler::SetParamf(EqualizerProps
&props
, ALenum param
, float val
)
51 case AL_EQUALIZER_LOW_GAIN
:
52 if(!(val
>= AL_EQUALIZER_MIN_LOW_GAIN
&& val
<= AL_EQUALIZER_MAX_LOW_GAIN
))
53 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer low-band gain out of range"};
57 case AL_EQUALIZER_LOW_CUTOFF
:
58 if(!(val
>= AL_EQUALIZER_MIN_LOW_CUTOFF
&& val
<= AL_EQUALIZER_MAX_LOW_CUTOFF
))
59 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer low-band cutoff out of range"};
60 props
.LowCutoff
= val
;
63 case AL_EQUALIZER_MID1_GAIN
:
64 if(!(val
>= AL_EQUALIZER_MIN_MID1_GAIN
&& val
<= AL_EQUALIZER_MAX_MID1_GAIN
))
65 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid1-band gain out of range"};
69 case AL_EQUALIZER_MID1_CENTER
:
70 if(!(val
>= AL_EQUALIZER_MIN_MID1_CENTER
&& val
<= AL_EQUALIZER_MAX_MID1_CENTER
))
71 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid1-band center out of range"};
72 props
.Mid1Center
= val
;
75 case AL_EQUALIZER_MID1_WIDTH
:
76 if(!(val
>= AL_EQUALIZER_MIN_MID1_WIDTH
&& val
<= AL_EQUALIZER_MAX_MID1_WIDTH
))
77 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid1-band width out of range"};
78 props
.Mid1Width
= val
;
81 case AL_EQUALIZER_MID2_GAIN
:
82 if(!(val
>= AL_EQUALIZER_MIN_MID2_GAIN
&& val
<= AL_EQUALIZER_MAX_MID2_GAIN
))
83 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid2-band gain out of range"};
87 case AL_EQUALIZER_MID2_CENTER
:
88 if(!(val
>= AL_EQUALIZER_MIN_MID2_CENTER
&& val
<= AL_EQUALIZER_MAX_MID2_CENTER
))
89 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid2-band center out of range"};
90 props
.Mid2Center
= val
;
93 case AL_EQUALIZER_MID2_WIDTH
:
94 if(!(val
>= AL_EQUALIZER_MIN_MID2_WIDTH
&& val
<= AL_EQUALIZER_MAX_MID2_WIDTH
))
95 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer mid2-band width out of range"};
96 props
.Mid2Width
= val
;
99 case AL_EQUALIZER_HIGH_GAIN
:
100 if(!(val
>= AL_EQUALIZER_MIN_HIGH_GAIN
&& val
<= AL_EQUALIZER_MAX_HIGH_GAIN
))
101 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer high-band gain out of range"};
102 props
.HighGain
= val
;
105 case AL_EQUALIZER_HIGH_CUTOFF
:
106 if(!(val
>= AL_EQUALIZER_MIN_HIGH_CUTOFF
&& val
<= AL_EQUALIZER_MAX_HIGH_CUTOFF
))
107 throw effect_exception
{AL_INVALID_VALUE
, "Equalizer high-band cutoff out of range"};
108 props
.HighCutoff
= val
;
112 throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer float property 0x%04x", param
};
115 void EqualizerEffectHandler::SetParamfv(EqualizerProps
&props
, ALenum param
, const float *vals
)
116 { SetParamf(props
, param
, *vals
); }
118 void EqualizerEffectHandler::GetParami(const EqualizerProps
&, ALenum param
, int*)
119 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer integer property 0x%04x", param
}; }
120 void EqualizerEffectHandler::GetParamiv(const EqualizerProps
&, ALenum param
, int*)
122 throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer integer-vector property 0x%04x",
125 void EqualizerEffectHandler::GetParamf(const EqualizerProps
&props
, ALenum param
, float *val
)
129 case AL_EQUALIZER_LOW_GAIN
: *val
= props
.LowGain
; break;
130 case AL_EQUALIZER_LOW_CUTOFF
: *val
= props
.LowCutoff
; break;
131 case AL_EQUALIZER_MID1_GAIN
: *val
= props
.Mid1Gain
; break;
132 case AL_EQUALIZER_MID1_CENTER
: *val
= props
.Mid1Center
; break;
133 case AL_EQUALIZER_MID1_WIDTH
: *val
= props
.Mid1Width
; break;
134 case AL_EQUALIZER_MID2_GAIN
: *val
= props
.Mid2Gain
; break;
135 case AL_EQUALIZER_MID2_CENTER
: *val
= props
.Mid2Center
; break;
136 case AL_EQUALIZER_MID2_WIDTH
: *val
= props
.Mid2Width
; break;
137 case AL_EQUALIZER_HIGH_GAIN
: *val
= props
.HighGain
; break;
138 case AL_EQUALIZER_HIGH_CUTOFF
: *val
= props
.HighCutoff
; break;
141 throw effect_exception
{AL_INVALID_ENUM
, "Invalid equalizer float property 0x%04x", param
};
144 void EqualizerEffectHandler::GetParamfv(const EqualizerProps
&props
, ALenum param
, float *vals
)
145 { GetParamf(props
, param
, vals
); }
151 using EqualizerCommitter
= EaxCommitter
<EaxEqualizerCommitter
>;
153 struct LowGainValidator
{
154 void operator()(long lLowGain
) const
156 eax_validate_range
<EqualizerCommitter::Exception
>(
159 EAXEQUALIZER_MINLOWGAIN
,
160 EAXEQUALIZER_MAXLOWGAIN
);
162 }; // LowGainValidator
164 struct LowCutOffValidator
{
165 void operator()(float flLowCutOff
) const
167 eax_validate_range
<EqualizerCommitter::Exception
>(
170 EAXEQUALIZER_MINLOWCUTOFF
,
171 EAXEQUALIZER_MAXLOWCUTOFF
);
173 }; // LowCutOffValidator
175 struct Mid1GainValidator
{
176 void operator()(long lMid1Gain
) const
178 eax_validate_range
<EqualizerCommitter::Exception
>(
181 EAXEQUALIZER_MINMID1GAIN
,
182 EAXEQUALIZER_MAXMID1GAIN
);
184 }; // Mid1GainValidator
186 struct Mid1CenterValidator
{
187 void operator()(float flMid1Center
) const
189 eax_validate_range
<EqualizerCommitter::Exception
>(
192 EAXEQUALIZER_MINMID1CENTER
,
193 EAXEQUALIZER_MAXMID1CENTER
);
195 }; // Mid1CenterValidator
197 struct Mid1WidthValidator
{
198 void operator()(float flMid1Width
) const
200 eax_validate_range
<EqualizerCommitter::Exception
>(
203 EAXEQUALIZER_MINMID1WIDTH
,
204 EAXEQUALIZER_MAXMID1WIDTH
);
206 }; // Mid1WidthValidator
208 struct Mid2GainValidator
{
209 void operator()(long lMid2Gain
) const
211 eax_validate_range
<EqualizerCommitter::Exception
>(
214 EAXEQUALIZER_MINMID2GAIN
,
215 EAXEQUALIZER_MAXMID2GAIN
);
217 }; // Mid2GainValidator
219 struct Mid2CenterValidator
{
220 void operator()(float flMid2Center
) const
222 eax_validate_range
<EqualizerCommitter::Exception
>(
225 EAXEQUALIZER_MINMID2CENTER
,
226 EAXEQUALIZER_MAXMID2CENTER
);
228 }; // Mid2CenterValidator
230 struct Mid2WidthValidator
{
231 void operator()(float flMid2Width
) const
233 eax_validate_range
<EqualizerCommitter::Exception
>(
236 EAXEQUALIZER_MINMID2WIDTH
,
237 EAXEQUALIZER_MAXMID2WIDTH
);
239 }; // Mid2WidthValidator
241 struct HighGainValidator
{
242 void operator()(long lHighGain
) const
244 eax_validate_range
<EqualizerCommitter::Exception
>(
247 EAXEQUALIZER_MINHIGHGAIN
,
248 EAXEQUALIZER_MAXHIGHGAIN
);
250 }; // HighGainValidator
252 struct HighCutOffValidator
{
253 void operator()(float flHighCutOff
) const
255 eax_validate_range
<EqualizerCommitter::Exception
>(
258 EAXEQUALIZER_MINHIGHCUTOFF
,
259 EAXEQUALIZER_MAXHIGHCUTOFF
);
261 }; // HighCutOffValidator
263 struct AllValidator
{
264 void operator()(const EAXEQUALIZERPROPERTIES
& all
) const
266 LowGainValidator
{}(all
.lLowGain
);
267 LowCutOffValidator
{}(all
.flLowCutOff
);
268 Mid1GainValidator
{}(all
.lMid1Gain
);
269 Mid1CenterValidator
{}(all
.flMid1Center
);
270 Mid1WidthValidator
{}(all
.flMid1Width
);
271 Mid2GainValidator
{}(all
.lMid2Gain
);
272 Mid2CenterValidator
{}(all
.flMid2Center
);
273 Mid2WidthValidator
{}(all
.flMid2Width
);
274 HighGainValidator
{}(all
.lHighGain
);
275 HighCutOffValidator
{}(all
.flHighCutOff
);
282 struct EqualizerCommitter::Exception
: public EaxException
{
283 explicit Exception(const char* message
) : EaxException
{"EAX_EQUALIZER_EFFECT", message
}
288 [[noreturn
]] void EqualizerCommitter::fail(const char *message
)
290 throw Exception
{message
};
293 bool EaxEqualizerCommitter::commit(const EAXEQUALIZERPROPERTIES
&props
)
295 if(auto *cur
= std::get_if
<EAXEQUALIZERPROPERTIES
>(&mEaxProps
); cur
&& *cur
== props
)
300 EqualizerProps ret
{};
301 ret
.LowGain
= level_mb_to_gain(static_cast<float>(props
.lLowGain
));
302 ret
.LowCutoff
= props
.flLowCutOff
;
303 ret
.Mid1Gain
= level_mb_to_gain(static_cast<float>(props
.lMid1Gain
));
304 ret
.Mid1Center
= props
.flMid1Center
;
305 ret
.Mid1Width
= props
.flMid1Width
;
306 ret
.Mid2Gain
= level_mb_to_gain(static_cast<float>(props
.lMid2Gain
));
307 ret
.Mid2Center
= props
.flMid2Center
;
308 ret
.Mid2Width
= props
.flMid2Width
;
309 ret
.HighGain
= level_mb_to_gain(static_cast<float>(props
.lHighGain
));
310 ret
.HighCutoff
= props
.flHighCutOff
;
317 void EaxEqualizerCommitter::SetDefaults(EaxEffectProps
&props
)
319 static constexpr EAXEQUALIZERPROPERTIES defprops
{[]
321 EAXEQUALIZERPROPERTIES ret
{};
322 ret
.lLowGain
= EAXEQUALIZER_DEFAULTLOWGAIN
;
323 ret
.flLowCutOff
= EAXEQUALIZER_DEFAULTLOWCUTOFF
;
324 ret
.lMid1Gain
= EAXEQUALIZER_DEFAULTMID1GAIN
;
325 ret
.flMid1Center
= EAXEQUALIZER_DEFAULTMID1CENTER
;
326 ret
.flMid1Width
= EAXEQUALIZER_DEFAULTMID1WIDTH
;
327 ret
.lMid2Gain
= EAXEQUALIZER_DEFAULTMID2GAIN
;
328 ret
.flMid2Center
= EAXEQUALIZER_DEFAULTMID2CENTER
;
329 ret
.flMid2Width
= EAXEQUALIZER_DEFAULTMID2WIDTH
;
330 ret
.lHighGain
= EAXEQUALIZER_DEFAULTHIGHGAIN
;
331 ret
.flHighCutOff
= EAXEQUALIZER_DEFAULTHIGHCUTOFF
;
337 void EaxEqualizerCommitter::Get(const EaxCall
&call
, const EAXEQUALIZERPROPERTIES
&props
)
339 switch(call
.get_property_id())
341 case EAXEQUALIZER_NONE
: break;
342 case EAXEQUALIZER_ALLPARAMETERS
: call
.set_value
<Exception
>(props
); break;
343 case EAXEQUALIZER_LOWGAIN
: call
.set_value
<Exception
>(props
.lLowGain
); break;
344 case EAXEQUALIZER_LOWCUTOFF
: call
.set_value
<Exception
>(props
.flLowCutOff
); break;
345 case EAXEQUALIZER_MID1GAIN
: call
.set_value
<Exception
>(props
.lMid1Gain
); break;
346 case EAXEQUALIZER_MID1CENTER
: call
.set_value
<Exception
>(props
.flMid1Center
); break;
347 case EAXEQUALIZER_MID1WIDTH
: call
.set_value
<Exception
>(props
.flMid1Width
); break;
348 case EAXEQUALIZER_MID2GAIN
: call
.set_value
<Exception
>(props
.lMid2Gain
); break;
349 case EAXEQUALIZER_MID2CENTER
: call
.set_value
<Exception
>(props
.flMid2Center
); break;
350 case EAXEQUALIZER_MID2WIDTH
: call
.set_value
<Exception
>(props
.flMid2Width
); break;
351 case EAXEQUALIZER_HIGHGAIN
: call
.set_value
<Exception
>(props
.lHighGain
); break;
352 case EAXEQUALIZER_HIGHCUTOFF
: call
.set_value
<Exception
>(props
.flHighCutOff
); break;
353 default: fail_unknown_property_id();
357 void EaxEqualizerCommitter::Set(const EaxCall
&call
, EAXEQUALIZERPROPERTIES
&props
)
359 switch(call
.get_property_id())
361 case EAXEQUALIZER_NONE
: break;
362 case EAXEQUALIZER_ALLPARAMETERS
: defer
<AllValidator
>(call
, props
); break;
363 case EAXEQUALIZER_LOWGAIN
: defer
<LowGainValidator
>(call
, props
.lLowGain
); break;
364 case EAXEQUALIZER_LOWCUTOFF
: defer
<LowCutOffValidator
>(call
, props
.flLowCutOff
); break;
365 case EAXEQUALIZER_MID1GAIN
: defer
<Mid1GainValidator
>(call
, props
.lMid1Gain
); break;
366 case EAXEQUALIZER_MID1CENTER
: defer
<Mid1CenterValidator
>(call
, props
.flMid1Center
); break;
367 case EAXEQUALIZER_MID1WIDTH
: defer
<Mid1WidthValidator
>(call
, props
.flMid1Width
); break;
368 case EAXEQUALIZER_MID2GAIN
: defer
<Mid2GainValidator
>(call
, props
.lMid2Gain
); break;
369 case EAXEQUALIZER_MID2CENTER
: defer
<Mid2CenterValidator
>(call
, props
.flMid2Center
); break;
370 case EAXEQUALIZER_MID2WIDTH
: defer
<Mid2WidthValidator
>(call
, props
.flMid2Width
); break;
371 case EAXEQUALIZER_HIGHGAIN
: defer
<HighGainValidator
>(call
, props
.lHighGain
); break;
372 case EAXEQUALIZER_HIGHCUTOFF
: defer
<HighCutOffValidator
>(call
, props
.flHighCutOff
); break;
373 default: fail_unknown_property_id();