14 #include "al/eax/effect.h"
15 #include "al/eax/exception.h"
16 #include "al/eax/utils.h"
22 static_assert(ChorusMaxDelay
>= AL_CHORUS_MAX_DELAY
, "Chorus max delay too small");
23 static_assert(FlangerMaxDelay
>= AL_FLANGER_MAX_DELAY
, "Flanger max delay too small");
25 static_assert(AL_CHORUS_WAVEFORM_SINUSOID
== AL_FLANGER_WAVEFORM_SINUSOID
, "Chorus/Flanger waveform value mismatch");
26 static_assert(AL_CHORUS_WAVEFORM_TRIANGLE
== AL_FLANGER_WAVEFORM_TRIANGLE
, "Chorus/Flanger waveform value mismatch");
28 constexpr std::optional
<ChorusWaveform
> WaveformFromEnum(ALenum type
) noexcept
32 case AL_CHORUS_WAVEFORM_SINUSOID
: return ChorusWaveform::Sinusoid
;
33 case AL_CHORUS_WAVEFORM_TRIANGLE
: return ChorusWaveform::Triangle
;
37 constexpr ALenum
EnumFromWaveform(ChorusWaveform type
)
41 case ChorusWaveform::Sinusoid
: return AL_CHORUS_WAVEFORM_SINUSOID
;
42 case ChorusWaveform::Triangle
: return AL_CHORUS_WAVEFORM_TRIANGLE
;
44 throw std::runtime_error
{"Invalid chorus waveform: "+std::to_string(static_cast<int>(type
))};
47 constexpr EffectProps
genDefaultChorusProps() noexcept
50 props
.Waveform
= WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM
).value();
51 props
.Phase
= AL_CHORUS_DEFAULT_PHASE
;
52 props
.Rate
= AL_CHORUS_DEFAULT_RATE
;
53 props
.Depth
= AL_CHORUS_DEFAULT_DEPTH
;
54 props
.Feedback
= AL_CHORUS_DEFAULT_FEEDBACK
;
55 props
.Delay
= AL_CHORUS_DEFAULT_DELAY
;
59 constexpr EffectProps
genDefaultFlangerProps() noexcept
62 props
.Waveform
= WaveformFromEnum(AL_FLANGER_DEFAULT_WAVEFORM
).value();
63 props
.Phase
= AL_FLANGER_DEFAULT_PHASE
;
64 props
.Rate
= AL_FLANGER_DEFAULT_RATE
;
65 props
.Depth
= AL_FLANGER_DEFAULT_DEPTH
;
66 props
.Feedback
= AL_FLANGER_DEFAULT_FEEDBACK
;
67 props
.Delay
= AL_FLANGER_DEFAULT_DELAY
;
73 const EffectProps ChorusEffectProps
{genDefaultChorusProps()};
75 void ChorusEffectHandler::SetParami(ChorusProps
&props
, ALenum param
, int val
)
79 case AL_CHORUS_WAVEFORM
:
80 if(auto formopt
= WaveformFromEnum(val
))
81 props
.Waveform
= *formopt
;
83 throw effect_exception
{AL_INVALID_VALUE
, "Invalid chorus waveform: 0x%04x", val
};
87 if(!(val
>= AL_CHORUS_MIN_PHASE
&& val
<= AL_CHORUS_MAX_PHASE
))
88 throw effect_exception
{AL_INVALID_VALUE
, "Chorus phase out of range: %d", val
};
93 throw effect_exception
{AL_INVALID_ENUM
, "Invalid chorus integer property 0x%04x", param
};
96 void ChorusEffectHandler::SetParamiv(ChorusProps
&props
, ALenum param
, const int *vals
)
97 { SetParami(props
, param
, *vals
); }
98 void ChorusEffectHandler::SetParamf(ChorusProps
&props
, ALenum param
, float val
)
103 if(!(val
>= AL_CHORUS_MIN_RATE
&& val
<= AL_CHORUS_MAX_RATE
))
104 throw effect_exception
{AL_INVALID_VALUE
, "Chorus rate out of range: %f", val
};
108 case AL_CHORUS_DEPTH
:
109 if(!(val
>= AL_CHORUS_MIN_DEPTH
&& val
<= AL_CHORUS_MAX_DEPTH
))
110 throw effect_exception
{AL_INVALID_VALUE
, "Chorus depth out of range: %f", val
};
114 case AL_CHORUS_FEEDBACK
:
115 if(!(val
>= AL_CHORUS_MIN_FEEDBACK
&& val
<= AL_CHORUS_MAX_FEEDBACK
))
116 throw effect_exception
{AL_INVALID_VALUE
, "Chorus feedback out of range: %f", val
};
117 props
.Feedback
= val
;
120 case AL_CHORUS_DELAY
:
121 if(!(val
>= AL_CHORUS_MIN_DELAY
&& val
<= AL_CHORUS_MAX_DELAY
))
122 throw effect_exception
{AL_INVALID_VALUE
, "Chorus delay out of range: %f", val
};
127 throw effect_exception
{AL_INVALID_ENUM
, "Invalid chorus float property 0x%04x", param
};
130 void ChorusEffectHandler::SetParamfv(ChorusProps
&props
, ALenum param
, const float *vals
)
131 { SetParamf(props
, param
, *vals
); }
133 void ChorusEffectHandler::GetParami(const ChorusProps
&props
, ALenum param
, int *val
)
137 case AL_CHORUS_WAVEFORM
: *val
= EnumFromWaveform(props
.Waveform
); break;
138 case AL_CHORUS_PHASE
: *val
= props
.Phase
; break;
141 throw effect_exception
{AL_INVALID_ENUM
, "Invalid chorus integer property 0x%04x", param
};
144 void ChorusEffectHandler::GetParamiv(const ChorusProps
&props
, ALenum param
, int *vals
)
145 { GetParami(props
, param
, vals
); }
146 void ChorusEffectHandler::GetParamf(const ChorusProps
&props
, ALenum param
, float *val
)
150 case AL_CHORUS_RATE
: *val
= props
.Rate
; break;
151 case AL_CHORUS_DEPTH
: *val
= props
.Depth
; break;
152 case AL_CHORUS_FEEDBACK
: *val
= props
.Feedback
; break;
153 case AL_CHORUS_DELAY
: *val
= props
.Delay
; break;
156 throw effect_exception
{AL_INVALID_ENUM
, "Invalid chorus float property 0x%04x", param
};
159 void ChorusEffectHandler::GetParamfv(const ChorusProps
&props
, ALenum param
, float *vals
)
160 { GetParamf(props
, param
, vals
); }
163 const EffectProps FlangerEffectProps
{genDefaultFlangerProps()};
165 void FlangerEffectHandler::SetParami(ChorusProps
&props
, ALenum param
, int val
)
169 case AL_FLANGER_WAVEFORM
:
170 if(auto formopt
= WaveformFromEnum(val
))
171 props
.Waveform
= *formopt
;
173 throw effect_exception
{AL_INVALID_VALUE
, "Invalid flanger waveform: 0x%04x", val
};
176 case AL_FLANGER_PHASE
:
177 if(!(val
>= AL_FLANGER_MIN_PHASE
&& val
<= AL_FLANGER_MAX_PHASE
))
178 throw effect_exception
{AL_INVALID_VALUE
, "Flanger phase out of range: %d", val
};
183 throw effect_exception
{AL_INVALID_ENUM
, "Invalid flanger integer property 0x%04x", param
};
186 void FlangerEffectHandler::SetParamiv(ChorusProps
&props
, ALenum param
, const int *vals
)
187 { SetParami(props
, param
, *vals
); }
188 void FlangerEffectHandler::SetParamf(ChorusProps
&props
, ALenum param
, float val
)
192 case AL_FLANGER_RATE
:
193 if(!(val
>= AL_FLANGER_MIN_RATE
&& val
<= AL_FLANGER_MAX_RATE
))
194 throw effect_exception
{AL_INVALID_VALUE
, "Flanger rate out of range: %f", val
};
198 case AL_FLANGER_DEPTH
:
199 if(!(val
>= AL_FLANGER_MIN_DEPTH
&& val
<= AL_FLANGER_MAX_DEPTH
))
200 throw effect_exception
{AL_INVALID_VALUE
, "Flanger depth out of range: %f", val
};
204 case AL_FLANGER_FEEDBACK
:
205 if(!(val
>= AL_FLANGER_MIN_FEEDBACK
&& val
<= AL_FLANGER_MAX_FEEDBACK
))
206 throw effect_exception
{AL_INVALID_VALUE
, "Flanger feedback out of range: %f", val
};
207 props
.Feedback
= val
;
210 case AL_FLANGER_DELAY
:
211 if(!(val
>= AL_FLANGER_MIN_DELAY
&& val
<= AL_FLANGER_MAX_DELAY
))
212 throw effect_exception
{AL_INVALID_VALUE
, "Flanger delay out of range: %f", val
};
217 throw effect_exception
{AL_INVALID_ENUM
, "Invalid flanger float property 0x%04x", param
};
220 void FlangerEffectHandler::SetParamfv(ChorusProps
&props
, ALenum param
, const float *vals
)
221 { SetParamf(props
, param
, *vals
); }
223 void FlangerEffectHandler::GetParami(const ChorusProps
&props
, ALenum param
, int *val
)
227 case AL_FLANGER_WAVEFORM
: *val
= EnumFromWaveform(props
.Waveform
); break;
228 case AL_FLANGER_PHASE
: *val
= props
.Phase
; break;
231 throw effect_exception
{AL_INVALID_ENUM
, "Invalid flanger integer property 0x%04x", param
};
234 void FlangerEffectHandler::GetParamiv(const ChorusProps
&props
, ALenum param
, int *vals
)
235 { GetParami(props
, param
, vals
); }
236 void FlangerEffectHandler::GetParamf(const ChorusProps
&props
, ALenum param
, float *val
)
240 case AL_FLANGER_RATE
: *val
= props
.Rate
; break;
241 case AL_FLANGER_DEPTH
: *val
= props
.Depth
; break;
242 case AL_FLANGER_FEEDBACK
: *val
= props
.Feedback
; break;
243 case AL_FLANGER_DELAY
: *val
= props
.Delay
; break;
246 throw effect_exception
{AL_INVALID_ENUM
, "Invalid flanger float property 0x%04x", param
};
249 void FlangerEffectHandler::GetParamfv(const ChorusProps
&props
, ALenum param
, float *vals
)
250 { GetParamf(props
, param
, vals
); }
256 struct EaxChorusTraits
{
257 using EaxProps
= EAXCHORUSPROPERTIES
;
258 using Committer
= EaxChorusCommitter
;
260 static constexpr auto efx_effect() { return AL_EFFECT_CHORUS
; }
262 static constexpr auto eax_none_param_id() { return EAXCHORUS_NONE
; }
263 static constexpr auto eax_allparameters_param_id() { return EAXCHORUS_ALLPARAMETERS
; }
264 static constexpr auto eax_waveform_param_id() { return EAXCHORUS_WAVEFORM
; }
265 static constexpr auto eax_phase_param_id() { return EAXCHORUS_PHASE
; }
266 static constexpr auto eax_rate_param_id() { return EAXCHORUS_RATE
; }
267 static constexpr auto eax_depth_param_id() { return EAXCHORUS_DEPTH
; }
268 static constexpr auto eax_feedback_param_id() { return EAXCHORUS_FEEDBACK
; }
269 static constexpr auto eax_delay_param_id() { return EAXCHORUS_DELAY
; }
271 static constexpr auto eax_min_waveform() { return EAXCHORUS_MINWAVEFORM
; }
272 static constexpr auto eax_min_phase() { return EAXCHORUS_MINPHASE
; }
273 static constexpr auto eax_min_rate() { return EAXCHORUS_MINRATE
; }
274 static constexpr auto eax_min_depth() { return EAXCHORUS_MINDEPTH
; }
275 static constexpr auto eax_min_feedback() { return EAXCHORUS_MINFEEDBACK
; }
276 static constexpr auto eax_min_delay() { return EAXCHORUS_MINDELAY
; }
278 static constexpr auto eax_max_waveform() { return EAXCHORUS_MAXWAVEFORM
; }
279 static constexpr auto eax_max_phase() { return EAXCHORUS_MAXPHASE
; }
280 static constexpr auto eax_max_rate() { return EAXCHORUS_MAXRATE
; }
281 static constexpr auto eax_max_depth() { return EAXCHORUS_MAXDEPTH
; }
282 static constexpr auto eax_max_feedback() { return EAXCHORUS_MAXFEEDBACK
; }
283 static constexpr auto eax_max_delay() { return EAXCHORUS_MAXDELAY
; }
285 static constexpr auto eax_default_waveform() { return EAXCHORUS_DEFAULTWAVEFORM
; }
286 static constexpr auto eax_default_phase() { return EAXCHORUS_DEFAULTPHASE
; }
287 static constexpr auto eax_default_rate() { return EAXCHORUS_DEFAULTRATE
; }
288 static constexpr auto eax_default_depth() { return EAXCHORUS_DEFAULTDEPTH
; }
289 static constexpr auto eax_default_feedback() { return EAXCHORUS_DEFAULTFEEDBACK
; }
290 static constexpr auto eax_default_delay() { return EAXCHORUS_DEFAULTDELAY
; }
292 static constexpr auto efx_min_waveform() { return AL_CHORUS_MIN_WAVEFORM
; }
293 static constexpr auto efx_min_phase() { return AL_CHORUS_MIN_PHASE
; }
294 static constexpr auto efx_min_rate() { return AL_CHORUS_MIN_RATE
; }
295 static constexpr auto efx_min_depth() { return AL_CHORUS_MIN_DEPTH
; }
296 static constexpr auto efx_min_feedback() { return AL_CHORUS_MIN_FEEDBACK
; }
297 static constexpr auto efx_min_delay() { return AL_CHORUS_MIN_DELAY
; }
299 static constexpr auto efx_max_waveform() { return AL_CHORUS_MAX_WAVEFORM
; }
300 static constexpr auto efx_max_phase() { return AL_CHORUS_MAX_PHASE
; }
301 static constexpr auto efx_max_rate() { return AL_CHORUS_MAX_RATE
; }
302 static constexpr auto efx_max_depth() { return AL_CHORUS_MAX_DEPTH
; }
303 static constexpr auto efx_max_feedback() { return AL_CHORUS_MAX_FEEDBACK
; }
304 static constexpr auto efx_max_delay() { return AL_CHORUS_MAX_DELAY
; }
306 static constexpr auto efx_default_waveform() { return AL_CHORUS_DEFAULT_WAVEFORM
; }
307 static constexpr auto efx_default_phase() { return AL_CHORUS_DEFAULT_PHASE
; }
308 static constexpr auto efx_default_rate() { return AL_CHORUS_DEFAULT_RATE
; }
309 static constexpr auto efx_default_depth() { return AL_CHORUS_DEFAULT_DEPTH
; }
310 static constexpr auto efx_default_feedback() { return AL_CHORUS_DEFAULT_FEEDBACK
; }
311 static constexpr auto efx_default_delay() { return AL_CHORUS_DEFAULT_DELAY
; }
313 static ChorusWaveform
eax_waveform(unsigned long type
)
315 if(type
== EAX_CHORUS_SINUSOID
) return ChorusWaveform::Sinusoid
;
316 if(type
== EAX_CHORUS_TRIANGLE
) return ChorusWaveform::Triangle
;
317 return ChorusWaveform::Sinusoid
;
319 }; // EaxChorusTraits
321 struct EaxFlangerTraits
{
322 using EaxProps
= EAXFLANGERPROPERTIES
;
323 using Committer
= EaxFlangerCommitter
;
325 static constexpr auto efx_effect() { return AL_EFFECT_FLANGER
; }
327 static constexpr auto eax_none_param_id() { return EAXFLANGER_NONE
; }
328 static constexpr auto eax_allparameters_param_id() { return EAXFLANGER_ALLPARAMETERS
; }
329 static constexpr auto eax_waveform_param_id() { return EAXFLANGER_WAVEFORM
; }
330 static constexpr auto eax_phase_param_id() { return EAXFLANGER_PHASE
; }
331 static constexpr auto eax_rate_param_id() { return EAXFLANGER_RATE
; }
332 static constexpr auto eax_depth_param_id() { return EAXFLANGER_DEPTH
; }
333 static constexpr auto eax_feedback_param_id() { return EAXFLANGER_FEEDBACK
; }
334 static constexpr auto eax_delay_param_id() { return EAXFLANGER_DELAY
; }
336 static constexpr auto eax_min_waveform() { return EAXFLANGER_MINWAVEFORM
; }
337 static constexpr auto eax_min_phase() { return EAXFLANGER_MINPHASE
; }
338 static constexpr auto eax_min_rate() { return EAXFLANGER_MINRATE
; }
339 static constexpr auto eax_min_depth() { return EAXFLANGER_MINDEPTH
; }
340 static constexpr auto eax_min_feedback() { return EAXFLANGER_MINFEEDBACK
; }
341 static constexpr auto eax_min_delay() { return EAXFLANGER_MINDELAY
; }
343 static constexpr auto eax_max_waveform() { return EAXFLANGER_MAXWAVEFORM
; }
344 static constexpr auto eax_max_phase() { return EAXFLANGER_MAXPHASE
; }
345 static constexpr auto eax_max_rate() { return EAXFLANGER_MAXRATE
; }
346 static constexpr auto eax_max_depth() { return EAXFLANGER_MAXDEPTH
; }
347 static constexpr auto eax_max_feedback() { return EAXFLANGER_MAXFEEDBACK
; }
348 static constexpr auto eax_max_delay() { return EAXFLANGER_MAXDELAY
; }
350 static constexpr auto eax_default_waveform() { return EAXFLANGER_DEFAULTWAVEFORM
; }
351 static constexpr auto eax_default_phase() { return EAXFLANGER_DEFAULTPHASE
; }
352 static constexpr auto eax_default_rate() { return EAXFLANGER_DEFAULTRATE
; }
353 static constexpr auto eax_default_depth() { return EAXFLANGER_DEFAULTDEPTH
; }
354 static constexpr auto eax_default_feedback() { return EAXFLANGER_DEFAULTFEEDBACK
; }
355 static constexpr auto eax_default_delay() { return EAXFLANGER_DEFAULTDELAY
; }
357 static constexpr auto efx_min_waveform() { return AL_FLANGER_MIN_WAVEFORM
; }
358 static constexpr auto efx_min_phase() { return AL_FLANGER_MIN_PHASE
; }
359 static constexpr auto efx_min_rate() { return AL_FLANGER_MIN_RATE
; }
360 static constexpr auto efx_min_depth() { return AL_FLANGER_MIN_DEPTH
; }
361 static constexpr auto efx_min_feedback() { return AL_FLANGER_MIN_FEEDBACK
; }
362 static constexpr auto efx_min_delay() { return AL_FLANGER_MIN_DELAY
; }
364 static constexpr auto efx_max_waveform() { return AL_FLANGER_MAX_WAVEFORM
; }
365 static constexpr auto efx_max_phase() { return AL_FLANGER_MAX_PHASE
; }
366 static constexpr auto efx_max_rate() { return AL_FLANGER_MAX_RATE
; }
367 static constexpr auto efx_max_depth() { return AL_FLANGER_MAX_DEPTH
; }
368 static constexpr auto efx_max_feedback() { return AL_FLANGER_MAX_FEEDBACK
; }
369 static constexpr auto efx_max_delay() { return AL_FLANGER_MAX_DELAY
; }
371 static constexpr auto efx_default_waveform() { return AL_FLANGER_DEFAULT_WAVEFORM
; }
372 static constexpr auto efx_default_phase() { return AL_FLANGER_DEFAULT_PHASE
; }
373 static constexpr auto efx_default_rate() { return AL_FLANGER_DEFAULT_RATE
; }
374 static constexpr auto efx_default_depth() { return AL_FLANGER_DEFAULT_DEPTH
; }
375 static constexpr auto efx_default_feedback() { return AL_FLANGER_DEFAULT_FEEDBACK
; }
376 static constexpr auto efx_default_delay() { return AL_FLANGER_DEFAULT_DELAY
; }
378 static ChorusWaveform
eax_waveform(unsigned long type
)
380 if(type
== EAX_FLANGER_SINUSOID
) return ChorusWaveform::Sinusoid
;
381 if(type
== EAX_FLANGER_TRIANGLE
) return ChorusWaveform::Triangle
;
382 return ChorusWaveform::Sinusoid
;
384 }; // EaxFlangerTraits
386 template<typename TTraits
>
387 struct ChorusFlangerEffect
{
388 using Traits
= TTraits
;
389 using EaxProps
= typename
Traits::EaxProps
;
390 using Committer
= typename
Traits::Committer
;
391 using Exception
= typename
Committer::Exception
;
393 struct WaveformValidator
{
394 void operator()(unsigned long ulWaveform
) const
396 eax_validate_range
<Exception
>(
399 Traits::eax_min_waveform(),
400 Traits::eax_max_waveform());
402 }; // WaveformValidator
404 struct PhaseValidator
{
405 void operator()(long lPhase
) const
407 eax_validate_range
<Exception
>(
410 Traits::eax_min_phase(),
411 Traits::eax_max_phase());
415 struct RateValidator
{
416 void operator()(float flRate
) const
418 eax_validate_range
<Exception
>(
421 Traits::eax_min_rate(),
422 Traits::eax_max_rate());
426 struct DepthValidator
{
427 void operator()(float flDepth
) const
429 eax_validate_range
<Exception
>(
432 Traits::eax_min_depth(),
433 Traits::eax_max_depth());
437 struct FeedbackValidator
{
438 void operator()(float flFeedback
) const
440 eax_validate_range
<Exception
>(
443 Traits::eax_min_feedback(),
444 Traits::eax_max_feedback());
446 }; // FeedbackValidator
448 struct DelayValidator
{
449 void operator()(float flDelay
) const
451 eax_validate_range
<Exception
>(
454 Traits::eax_min_delay(),
455 Traits::eax_max_delay());
459 struct AllValidator
{
460 void operator()(const EaxProps
& all
) const
462 WaveformValidator
{}(all
.ulWaveform
);
463 PhaseValidator
{}(all
.lPhase
);
464 RateValidator
{}(all
.flRate
);
465 DepthValidator
{}(all
.flDepth
);
466 FeedbackValidator
{}(all
.flFeedback
);
467 DelayValidator
{}(all
.flDelay
);
472 static void SetDefaults(EaxEffectProps
&props
)
474 auto&& all
= props
.emplace
<EaxProps
>();
475 all
.ulWaveform
= Traits::eax_default_waveform();
476 all
.lPhase
= Traits::eax_default_phase();
477 all
.flRate
= Traits::eax_default_rate();
478 all
.flDepth
= Traits::eax_default_depth();
479 all
.flFeedback
= Traits::eax_default_feedback();
480 all
.flDelay
= Traits::eax_default_delay();
484 static void Get(const EaxCall
&call
, const EaxProps
&all
)
486 switch(call
.get_property_id())
488 case Traits::eax_none_param_id():
490 case Traits::eax_allparameters_param_id():
491 call
.template set_value
<Exception
>(all
);
493 case Traits::eax_waveform_param_id():
494 call
.template set_value
<Exception
>(all
.ulWaveform
);
496 case Traits::eax_phase_param_id():
497 call
.template set_value
<Exception
>(all
.lPhase
);
499 case Traits::eax_rate_param_id():
500 call
.template set_value
<Exception
>(all
.flRate
);
502 case Traits::eax_depth_param_id():
503 call
.template set_value
<Exception
>(all
.flDepth
);
505 case Traits::eax_feedback_param_id():
506 call
.template set_value
<Exception
>(all
.flFeedback
);
508 case Traits::eax_delay_param_id():
509 call
.template set_value
<Exception
>(all
.flDelay
);
512 Committer::fail_unknown_property_id();
516 static void Set(const EaxCall
&call
, EaxProps
&all
)
518 switch(call
.get_property_id())
520 case Traits::eax_none_param_id():
522 case Traits::eax_allparameters_param_id():
523 Committer::template defer
<AllValidator
>(call
, all
);
525 case Traits::eax_waveform_param_id():
526 Committer::template defer
<WaveformValidator
>(call
, all
.ulWaveform
);
528 case Traits::eax_phase_param_id():
529 Committer::template defer
<PhaseValidator
>(call
, all
.lPhase
);
531 case Traits::eax_rate_param_id():
532 Committer::template defer
<RateValidator
>(call
, all
.flRate
);
534 case Traits::eax_depth_param_id():
535 Committer::template defer
<DepthValidator
>(call
, all
.flDepth
);
537 case Traits::eax_feedback_param_id():
538 Committer::template defer
<FeedbackValidator
>(call
, all
.flFeedback
);
540 case Traits::eax_delay_param_id():
541 Committer::template defer
<DelayValidator
>(call
, all
.flDelay
);
544 Committer::fail_unknown_property_id();
548 static bool Commit(const EaxProps
&props
, EaxEffectProps
&props_
, ChorusProps
&al_props_
)
550 if(auto *cur
= std::get_if
<EaxProps
>(&props_
); cur
&& *cur
== props
)
555 al_props_
.Waveform
= Traits::eax_waveform(props
.ulWaveform
);
556 al_props_
.Phase
= static_cast<int>(props
.lPhase
);
557 al_props_
.Rate
= props
.flRate
;
558 al_props_
.Depth
= props
.flDepth
;
559 al_props_
.Feedback
= props
.flFeedback
;
560 al_props_
.Delay
= props
.flDelay
;
564 }; // EaxChorusFlangerEffect
567 using ChorusCommitter
= EaxCommitter
<EaxChorusCommitter
>;
568 using FlangerCommitter
= EaxCommitter
<EaxFlangerCommitter
>;
573 struct ChorusCommitter::Exception
: public EaxException
575 explicit Exception(const char *message
) : EaxException
{"EAX_CHORUS_EFFECT", message
}
580 [[noreturn
]] void ChorusCommitter::fail(const char *message
)
582 throw Exception
{message
};
585 bool EaxChorusCommitter::commit(const EAXCHORUSPROPERTIES
&props
)
587 using Committer
= ChorusFlangerEffect
<EaxChorusTraits
>;
588 return Committer::Commit(props
, mEaxProps
, mAlProps
.emplace
<ChorusProps
>());
591 void EaxChorusCommitter::SetDefaults(EaxEffectProps
&props
)
593 using Committer
= ChorusFlangerEffect
<EaxChorusTraits
>;
594 Committer::SetDefaults(props
);
597 void EaxChorusCommitter::Get(const EaxCall
&call
, const EAXCHORUSPROPERTIES
&props
)
599 using Committer
= ChorusFlangerEffect
<EaxChorusTraits
>;
600 Committer::Get(call
, props
);
603 void EaxChorusCommitter::Set(const EaxCall
&call
, EAXCHORUSPROPERTIES
&props
)
605 using Committer
= ChorusFlangerEffect
<EaxChorusTraits
>;
606 Committer::Set(call
, props
);
610 struct FlangerCommitter::Exception
: public EaxException
612 explicit Exception(const char *message
) : EaxException
{"EAX_FLANGER_EFFECT", message
}
617 [[noreturn
]] void FlangerCommitter::fail(const char *message
)
619 throw Exception
{message
};
622 bool EaxFlangerCommitter::commit(const EAXFLANGERPROPERTIES
&props
)
624 using Committer
= ChorusFlangerEffect
<EaxFlangerTraits
>;
625 return Committer::Commit(props
, mEaxProps
, mAlProps
.emplace
<ChorusProps
>());
628 void EaxFlangerCommitter::SetDefaults(EaxEffectProps
&props
)
630 using Committer
= ChorusFlangerEffect
<EaxFlangerTraits
>;
631 Committer::SetDefaults(props
);
634 void EaxFlangerCommitter::Get(const EaxCall
&call
, const EAXFLANGERPROPERTIES
&props
)
636 using Committer
= ChorusFlangerEffect
<EaxFlangerTraits
>;
637 Committer::Get(call
, props
);
640 void EaxFlangerCommitter::Set(const EaxCall
&call
, EAXFLANGERPROPERTIES
&props
)
642 using Committer
= ChorusFlangerEffect
<EaxFlangerTraits
>;
643 Committer::Set(call
, props
);