Define the CoreAudio default name only when needed
[openal-soft.git] / al / effects / equalizer.cpp
blob43597972f345cc682fdac63d15fd62dd990a4128
2 #include "config.h"
4 #include "AL/al.h"
5 #include "AL/efx.h"
7 #include "alc/effects/base.h"
8 #include "effects.h"
10 #ifdef ALSOFT_EAX
11 #include "alnumeric.h"
13 #include "al/eax_exception.h"
14 #include "al/eax_utils.h"
15 #endif // ALSOFT_EAX
18 namespace {
20 void Equalizer_setParami(EffectProps*, ALenum param, int)
21 { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
22 void Equalizer_setParamiv(EffectProps*, ALenum param, const int*)
24 throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
25 param};
27 void Equalizer_setParamf(EffectProps *props, ALenum param, float val)
29 switch(param)
31 case AL_EQUALIZER_LOW_GAIN:
32 if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN))
33 throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band gain out of range"};
34 props->Equalizer.LowGain = val;
35 break;
37 case AL_EQUALIZER_LOW_CUTOFF:
38 if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF))
39 throw effect_exception{AL_INVALID_VALUE, "Equalizer low-band cutoff out of range"};
40 props->Equalizer.LowCutoff = val;
41 break;
43 case AL_EQUALIZER_MID1_GAIN:
44 if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN))
45 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band gain out of range"};
46 props->Equalizer.Mid1Gain = val;
47 break;
49 case AL_EQUALIZER_MID1_CENTER:
50 if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER))
51 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band center out of range"};
52 props->Equalizer.Mid1Center = val;
53 break;
55 case AL_EQUALIZER_MID1_WIDTH:
56 if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH))
57 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid1-band width out of range"};
58 props->Equalizer.Mid1Width = val;
59 break;
61 case AL_EQUALIZER_MID2_GAIN:
62 if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN))
63 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band gain out of range"};
64 props->Equalizer.Mid2Gain = val;
65 break;
67 case AL_EQUALIZER_MID2_CENTER:
68 if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER))
69 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band center out of range"};
70 props->Equalizer.Mid2Center = val;
71 break;
73 case AL_EQUALIZER_MID2_WIDTH:
74 if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH))
75 throw effect_exception{AL_INVALID_VALUE, "Equalizer mid2-band width out of range"};
76 props->Equalizer.Mid2Width = val;
77 break;
79 case AL_EQUALIZER_HIGH_GAIN:
80 if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN))
81 throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band gain out of range"};
82 props->Equalizer.HighGain = val;
83 break;
85 case AL_EQUALIZER_HIGH_CUTOFF:
86 if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF))
87 throw effect_exception{AL_INVALID_VALUE, "Equalizer high-band cutoff out of range"};
88 props->Equalizer.HighCutoff = val;
89 break;
91 default:
92 throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
95 void Equalizer_setParamfv(EffectProps *props, ALenum param, const float *vals)
96 { Equalizer_setParamf(props, param, vals[0]); }
98 void Equalizer_getParami(const EffectProps*, ALenum param, int*)
99 { throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param}; }
100 void Equalizer_getParamiv(const EffectProps*, ALenum param, int*)
102 throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x",
103 param};
105 void Equalizer_getParamf(const EffectProps *props, ALenum param, float *val)
107 switch(param)
109 case AL_EQUALIZER_LOW_GAIN:
110 *val = props->Equalizer.LowGain;
111 break;
113 case AL_EQUALIZER_LOW_CUTOFF:
114 *val = props->Equalizer.LowCutoff;
115 break;
117 case AL_EQUALIZER_MID1_GAIN:
118 *val = props->Equalizer.Mid1Gain;
119 break;
121 case AL_EQUALIZER_MID1_CENTER:
122 *val = props->Equalizer.Mid1Center;
123 break;
125 case AL_EQUALIZER_MID1_WIDTH:
126 *val = props->Equalizer.Mid1Width;
127 break;
129 case AL_EQUALIZER_MID2_GAIN:
130 *val = props->Equalizer.Mid2Gain;
131 break;
133 case AL_EQUALIZER_MID2_CENTER:
134 *val = props->Equalizer.Mid2Center;
135 break;
137 case AL_EQUALIZER_MID2_WIDTH:
138 *val = props->Equalizer.Mid2Width;
139 break;
141 case AL_EQUALIZER_HIGH_GAIN:
142 *val = props->Equalizer.HighGain;
143 break;
145 case AL_EQUALIZER_HIGH_CUTOFF:
146 *val = props->Equalizer.HighCutoff;
147 break;
149 default:
150 throw effect_exception{AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param};
153 void Equalizer_getParamfv(const EffectProps *props, ALenum param, float *vals)
154 { Equalizer_getParamf(props, param, vals); }
156 EffectProps genDefaultProps() noexcept
158 EffectProps props{};
159 props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
160 props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
161 props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
162 props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
163 props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
164 props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
165 props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
166 props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
167 props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
168 props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
169 return props;
172 } // namespace
174 DEFINE_ALEFFECT_VTABLE(Equalizer);
176 const EffectProps EqualizerEffectProps{genDefaultProps()};
178 #ifdef ALSOFT_EAX
179 namespace {
181 using EaxEqualizerEffectDirtyFlagsValue = std::uint_least16_t;
183 struct EaxEqualizerEffectDirtyFlags
185 using EaxIsBitFieldStruct = bool;
187 EaxEqualizerEffectDirtyFlagsValue lLowGain : 1;
188 EaxEqualizerEffectDirtyFlagsValue flLowCutOff : 1;
189 EaxEqualizerEffectDirtyFlagsValue lMid1Gain : 1;
190 EaxEqualizerEffectDirtyFlagsValue flMid1Center : 1;
191 EaxEqualizerEffectDirtyFlagsValue flMid1Width : 1;
192 EaxEqualizerEffectDirtyFlagsValue lMid2Gain : 1;
193 EaxEqualizerEffectDirtyFlagsValue flMid2Center : 1;
194 EaxEqualizerEffectDirtyFlagsValue flMid2Width : 1;
195 EaxEqualizerEffectDirtyFlagsValue lHighGain : 1;
196 EaxEqualizerEffectDirtyFlagsValue flHighCutOff : 1;
197 }; // EaxEqualizerEffectDirtyFlags
200 class EaxEqualizerEffect final :
201 public EaxEffect
203 public:
204 EaxEqualizerEffect();
207 // [[nodiscard]]
208 bool dispatch(
209 const EaxEaxCall& eax_call) override;
212 private:
213 EAXEQUALIZERPROPERTIES eax_{};
214 EAXEQUALIZERPROPERTIES eax_d_{};
215 EaxEqualizerEffectDirtyFlags eax_dirty_flags_{};
218 void set_eax_defaults();
221 void set_efx_low_gain();
223 void set_efx_low_cutoff();
225 void set_efx_mid1_gain();
227 void set_efx_mid1_center();
229 void set_efx_mid1_width();
231 void set_efx_mid2_gain();
233 void set_efx_mid2_center();
235 void set_efx_mid2_width();
237 void set_efx_high_gain();
239 void set_efx_high_cutoff();
241 void set_efx_defaults();
244 // [[nodiscard]]
245 bool get(
246 const EaxEaxCall& eax_call);
249 void validate_low_gain(
250 long lLowGain);
252 void validate_low_cutoff(
253 float flLowCutOff);
255 void validate_mid1_gain(
256 long lMid1Gain);
258 void validate_mid1_center(
259 float flMid1Center);
261 void validate_mid1_width(
262 float flMid1Width);
264 void validate_mid2_gain(
265 long lMid2Gain);
267 void validate_mid2_center(
268 float flMid2Center);
270 void validate_mid2_width(
271 float flMid2Width);
273 void validate_high_gain(
274 long lHighGain);
276 void validate_high_cutoff(
277 float flHighCutOff);
279 void validate_all(
280 const EAXEQUALIZERPROPERTIES& all);
283 void defer_low_gain(
284 long lLowGain);
286 void defer_low_cutoff(
287 float flLowCutOff);
289 void defer_mid1_gain(
290 long lMid1Gain);
292 void defer_mid1_center(
293 float flMid1Center);
295 void defer_mid1_width(
296 float flMid1Width);
298 void defer_mid2_gain(
299 long lMid2Gain);
301 void defer_mid2_center(
302 float flMid2Center);
304 void defer_mid2_width(
305 float flMid2Width);
307 void defer_high_gain(
308 long lHighGain);
310 void defer_high_cutoff(
311 float flHighCutOff);
313 void defer_all(
314 const EAXEQUALIZERPROPERTIES& all);
317 void defer_low_gain(
318 const EaxEaxCall& eax_call);
320 void defer_low_cutoff(
321 const EaxEaxCall& eax_call);
323 void defer_mid1_gain(
324 const EaxEaxCall& eax_call);
326 void defer_mid1_center(
327 const EaxEaxCall& eax_call);
329 void defer_mid1_width(
330 const EaxEaxCall& eax_call);
332 void defer_mid2_gain(
333 const EaxEaxCall& eax_call);
335 void defer_mid2_center(
336 const EaxEaxCall& eax_call);
338 void defer_mid2_width(
339 const EaxEaxCall& eax_call);
341 void defer_high_gain(
342 const EaxEaxCall& eax_call);
344 void defer_high_cutoff(
345 const EaxEaxCall& eax_call);
347 void defer_all(
348 const EaxEaxCall& eax_call);
351 // [[nodiscard]]
352 bool apply_deferred();
354 // [[nodiscard]]
355 bool set(
356 const EaxEaxCall& eax_call);
357 }; // EaxEqualizerEffect
360 class EaxEqualizerEffectException :
361 public EaxException
363 public:
364 explicit EaxEqualizerEffectException(
365 const char* message)
367 EaxException{"EAX_EQUALIZER_EFFECT", message}
370 }; // EaxEqualizerEffectException
373 EaxEqualizerEffect::EaxEqualizerEffect()
374 : EaxEffect{AL_EFFECT_EQUALIZER}
376 set_eax_defaults();
377 set_efx_defaults();
380 // [[nodiscard]]
381 bool EaxEqualizerEffect::dispatch(
382 const EaxEaxCall& eax_call)
384 return eax_call.is_get() ? get(eax_call) : set(eax_call);
387 void EaxEqualizerEffect::set_eax_defaults()
389 eax_.lLowGain = EAXEQUALIZER_DEFAULTLOWGAIN;
390 eax_.flLowCutOff = EAXEQUALIZER_DEFAULTLOWCUTOFF;
391 eax_.lMid1Gain = EAXEQUALIZER_DEFAULTMID1GAIN;
392 eax_.flMid1Center = EAXEQUALIZER_DEFAULTMID1CENTER;
393 eax_.flMid1Width = EAXEQUALIZER_DEFAULTMID1WIDTH;
394 eax_.lMid2Gain = EAXEQUALIZER_DEFAULTMID2GAIN;
395 eax_.flMid2Center = EAXEQUALIZER_DEFAULTMID2CENTER;
396 eax_.flMid2Width = EAXEQUALIZER_DEFAULTMID2WIDTH;
397 eax_.lHighGain = EAXEQUALIZER_DEFAULTHIGHGAIN;
398 eax_.flHighCutOff = EAXEQUALIZER_DEFAULTHIGHCUTOFF;
400 eax_d_ = eax_;
403 void EaxEqualizerEffect::set_efx_low_gain()
405 const auto low_gain = clamp(
406 level_mb_to_gain(static_cast<float>(eax_.lLowGain)),
407 AL_EQUALIZER_MIN_LOW_GAIN,
408 AL_EQUALIZER_MAX_LOW_GAIN);
410 al_effect_props_.Equalizer.LowGain = low_gain;
413 void EaxEqualizerEffect::set_efx_low_cutoff()
415 const auto low_cutoff = clamp(
416 eax_.flLowCutOff,
417 AL_EQUALIZER_MIN_LOW_CUTOFF,
418 AL_EQUALIZER_MAX_LOW_CUTOFF);
420 al_effect_props_.Equalizer.LowCutoff = low_cutoff;
423 void EaxEqualizerEffect::set_efx_mid1_gain()
425 const auto mid1_gain = clamp(
426 level_mb_to_gain(static_cast<float>(eax_.lMid1Gain)),
427 AL_EQUALIZER_MIN_MID1_GAIN,
428 AL_EQUALIZER_MAX_MID1_GAIN);
430 al_effect_props_.Equalizer.Mid1Gain = mid1_gain;
433 void EaxEqualizerEffect::set_efx_mid1_center()
435 const auto mid1_center = clamp(
436 eax_.flMid1Center,
437 AL_EQUALIZER_MIN_MID1_CENTER,
438 AL_EQUALIZER_MAX_MID1_CENTER);
440 al_effect_props_.Equalizer.Mid1Center = mid1_center;
443 void EaxEqualizerEffect::set_efx_mid1_width()
445 const auto mid1_width = clamp(
446 eax_.flMid1Width,
447 AL_EQUALIZER_MIN_MID1_WIDTH,
448 AL_EQUALIZER_MAX_MID1_WIDTH);
450 al_effect_props_.Equalizer.Mid1Width = mid1_width;
453 void EaxEqualizerEffect::set_efx_mid2_gain()
455 const auto mid2_gain = clamp(
456 level_mb_to_gain(static_cast<float>(eax_.lMid2Gain)),
457 AL_EQUALIZER_MIN_MID2_GAIN,
458 AL_EQUALIZER_MAX_MID2_GAIN);
460 al_effect_props_.Equalizer.Mid2Gain = mid2_gain;
463 void EaxEqualizerEffect::set_efx_mid2_center()
465 const auto mid2_center = clamp(
466 eax_.flMid2Center,
467 AL_EQUALIZER_MIN_MID2_CENTER,
468 AL_EQUALIZER_MAX_MID2_CENTER);
470 al_effect_props_.Equalizer.Mid2Center = mid2_center;
473 void EaxEqualizerEffect::set_efx_mid2_width()
475 const auto mid2_width = clamp(
476 eax_.flMid2Width,
477 AL_EQUALIZER_MIN_MID2_WIDTH,
478 AL_EQUALIZER_MAX_MID2_WIDTH);
480 al_effect_props_.Equalizer.Mid2Width = mid2_width;
483 void EaxEqualizerEffect::set_efx_high_gain()
485 const auto high_gain = clamp(
486 level_mb_to_gain(static_cast<float>(eax_.lHighGain)),
487 AL_EQUALIZER_MIN_HIGH_GAIN,
488 AL_EQUALIZER_MAX_HIGH_GAIN);
490 al_effect_props_.Equalizer.HighGain = high_gain;
493 void EaxEqualizerEffect::set_efx_high_cutoff()
495 const auto high_cutoff = clamp(
496 eax_.flHighCutOff,
497 AL_EQUALIZER_MIN_HIGH_CUTOFF,
498 AL_EQUALIZER_MAX_HIGH_CUTOFF);
500 al_effect_props_.Equalizer.HighCutoff = high_cutoff;
503 void EaxEqualizerEffect::set_efx_defaults()
505 set_efx_low_gain();
506 set_efx_low_cutoff();
507 set_efx_mid1_gain();
508 set_efx_mid1_center();
509 set_efx_mid1_width();
510 set_efx_mid2_gain();
511 set_efx_mid2_center();
512 set_efx_mid2_width();
513 set_efx_high_gain();
514 set_efx_high_cutoff();
517 // [[nodiscard]]
518 bool EaxEqualizerEffect::get(
519 const EaxEaxCall& eax_call)
521 switch (eax_call.get_property_id())
523 case EAXEQUALIZER_NONE:
524 break;
526 case EAXEQUALIZER_ALLPARAMETERS:
527 eax_call.set_value<EaxEqualizerEffectException>(eax_);
528 break;
530 case EAXEQUALIZER_LOWGAIN:
531 eax_call.set_value<EaxEqualizerEffectException>(eax_.lLowGain);
532 break;
534 case EAXEQUALIZER_LOWCUTOFF:
535 eax_call.set_value<EaxEqualizerEffectException>(eax_.flLowCutOff);
536 break;
538 case EAXEQUALIZER_MID1GAIN:
539 eax_call.set_value<EaxEqualizerEffectException>(eax_.lMid1Gain);
540 break;
542 case EAXEQUALIZER_MID1CENTER:
543 eax_call.set_value<EaxEqualizerEffectException>(eax_.flMid1Center);
544 break;
546 case EAXEQUALIZER_MID1WIDTH:
547 eax_call.set_value<EaxEqualizerEffectException>(eax_.flMid1Width);
548 break;
550 case EAXEQUALIZER_MID2GAIN:
551 eax_call.set_value<EaxEqualizerEffectException>(eax_.lMid2Gain);
552 break;
554 case EAXEQUALIZER_MID2CENTER:
555 eax_call.set_value<EaxEqualizerEffectException>(eax_.flMid2Center);
556 break;
558 case EAXEQUALIZER_MID2WIDTH:
559 eax_call.set_value<EaxEqualizerEffectException>(eax_.flMid2Width);
560 break;
562 case EAXEQUALIZER_HIGHGAIN:
563 eax_call.set_value<EaxEqualizerEffectException>(eax_.lHighGain);
564 break;
566 case EAXEQUALIZER_HIGHCUTOFF:
567 eax_call.set_value<EaxEqualizerEffectException>(eax_.flHighCutOff);
568 break;
570 default:
571 throw EaxEqualizerEffectException{"Unsupported property id."};
574 return false;
577 void EaxEqualizerEffect::validate_low_gain(
578 long lLowGain)
580 eax_validate_range<EaxEqualizerEffectException>(
581 "Low Gain",
582 lLowGain,
583 EAXEQUALIZER_MINLOWGAIN,
584 EAXEQUALIZER_MAXLOWGAIN);
587 void EaxEqualizerEffect::validate_low_cutoff(
588 float flLowCutOff)
590 eax_validate_range<EaxEqualizerEffectException>(
591 "Low Cutoff",
592 flLowCutOff,
593 EAXEQUALIZER_MINLOWCUTOFF,
594 EAXEQUALIZER_MAXLOWCUTOFF);
597 void EaxEqualizerEffect::validate_mid1_gain(
598 long lMid1Gain)
600 eax_validate_range<EaxEqualizerEffectException>(
601 "Mid1 Gain",
602 lMid1Gain,
603 EAXEQUALIZER_MINMID1GAIN,
604 EAXEQUALIZER_MAXMID1GAIN);
607 void EaxEqualizerEffect::validate_mid1_center(
608 float flMid1Center)
610 eax_validate_range<EaxEqualizerEffectException>(
611 "Mid1 Center",
612 flMid1Center,
613 EAXEQUALIZER_MINMID1CENTER,
614 EAXEQUALIZER_MAXMID1CENTER);
617 void EaxEqualizerEffect::validate_mid1_width(
618 float flMid1Width)
620 eax_validate_range<EaxEqualizerEffectException>(
621 "Mid1 Width",
622 flMid1Width,
623 EAXEQUALIZER_MINMID1WIDTH,
624 EAXEQUALIZER_MAXMID1WIDTH);
627 void EaxEqualizerEffect::validate_mid2_gain(
628 long lMid2Gain)
630 eax_validate_range<EaxEqualizerEffectException>(
631 "Mid2 Gain",
632 lMid2Gain,
633 EAXEQUALIZER_MINMID2GAIN,
634 EAXEQUALIZER_MAXMID2GAIN);
637 void EaxEqualizerEffect::validate_mid2_center(
638 float flMid2Center)
640 eax_validate_range<EaxEqualizerEffectException>(
641 "Mid2 Center",
642 flMid2Center,
643 EAXEQUALIZER_MINMID2CENTER,
644 EAXEQUALIZER_MAXMID2CENTER);
647 void EaxEqualizerEffect::validate_mid2_width(
648 float flMid2Width)
650 eax_validate_range<EaxEqualizerEffectException>(
651 "Mid2 Width",
652 flMid2Width,
653 EAXEQUALIZER_MINMID2WIDTH,
654 EAXEQUALIZER_MAXMID2WIDTH);
657 void EaxEqualizerEffect::validate_high_gain(
658 long lHighGain)
660 eax_validate_range<EaxEqualizerEffectException>(
661 "High Gain",
662 lHighGain,
663 EAXEQUALIZER_MINHIGHGAIN,
664 EAXEQUALIZER_MAXHIGHGAIN);
667 void EaxEqualizerEffect::validate_high_cutoff(
668 float flHighCutOff)
670 eax_validate_range<EaxEqualizerEffectException>(
671 "High Cutoff",
672 flHighCutOff,
673 EAXEQUALIZER_MINHIGHCUTOFF,
674 EAXEQUALIZER_MAXHIGHCUTOFF);
677 void EaxEqualizerEffect::validate_all(
678 const EAXEQUALIZERPROPERTIES& all)
680 validate_low_gain(all.lLowGain);
681 validate_low_cutoff(all.flLowCutOff);
682 validate_mid1_gain(all.lMid1Gain);
683 validate_mid1_center(all.flMid1Center);
684 validate_mid1_width(all.flMid1Width);
685 validate_mid2_gain(all.lMid2Gain);
686 validate_mid2_center(all.flMid2Center);
687 validate_mid2_width(all.flMid2Width);
688 validate_high_gain(all.lHighGain);
689 validate_high_cutoff(all.flHighCutOff);
692 void EaxEqualizerEffect::defer_low_gain(
693 long lLowGain)
695 eax_d_.lLowGain = lLowGain;
696 eax_dirty_flags_.lLowGain = (eax_.lLowGain != eax_d_.lLowGain);
699 void EaxEqualizerEffect::defer_low_cutoff(
700 float flLowCutOff)
702 eax_d_.flLowCutOff = flLowCutOff;
703 eax_dirty_flags_.flLowCutOff = (eax_.flLowCutOff != eax_d_.flLowCutOff);
706 void EaxEqualizerEffect::defer_mid1_gain(
707 long lMid1Gain)
709 eax_d_.lMid1Gain = lMid1Gain;
710 eax_dirty_flags_.lMid1Gain = (eax_.lMid1Gain != eax_d_.lMid1Gain);
713 void EaxEqualizerEffect::defer_mid1_center(
714 float flMid1Center)
716 eax_d_.flMid1Center = flMid1Center;
717 eax_dirty_flags_.flMid1Center = (eax_.flMid1Center != eax_d_.flMid1Center);
720 void EaxEqualizerEffect::defer_mid1_width(
721 float flMid1Width)
723 eax_d_.flMid1Width = flMid1Width;
724 eax_dirty_flags_.flMid1Width = (eax_.flMid1Width != eax_d_.flMid1Width);
727 void EaxEqualizerEffect::defer_mid2_gain(
728 long lMid2Gain)
730 eax_d_.lMid2Gain = lMid2Gain;
731 eax_dirty_flags_.lMid2Gain = (eax_.lMid2Gain != eax_d_.lMid2Gain);
734 void EaxEqualizerEffect::defer_mid2_center(
735 float flMid2Center)
737 eax_d_.flMid2Center = flMid2Center;
738 eax_dirty_flags_.flMid2Center = (eax_.flMid2Center != eax_d_.flMid2Center);
741 void EaxEqualizerEffect::defer_mid2_width(
742 float flMid2Width)
744 eax_d_.flMid2Width = flMid2Width;
745 eax_dirty_flags_.flMid2Width = (eax_.flMid2Width != eax_d_.flMid2Width);
748 void EaxEqualizerEffect::defer_high_gain(
749 long lHighGain)
751 eax_d_.lHighGain = lHighGain;
752 eax_dirty_flags_.lHighGain = (eax_.lHighGain != eax_d_.lHighGain);
755 void EaxEqualizerEffect::defer_high_cutoff(
756 float flHighCutOff)
758 eax_d_.flHighCutOff = flHighCutOff;
759 eax_dirty_flags_.flHighCutOff = (eax_.flHighCutOff != eax_d_.flHighCutOff);
762 void EaxEqualizerEffect::defer_all(
763 const EAXEQUALIZERPROPERTIES& all)
765 defer_low_gain(all.lLowGain);
766 defer_low_cutoff(all.flLowCutOff);
767 defer_mid1_gain(all.lMid1Gain);
768 defer_mid1_center(all.flMid1Center);
769 defer_mid1_width(all.flMid1Width);
770 defer_mid2_gain(all.lMid2Gain);
771 defer_mid2_center(all.flMid2Center);
772 defer_mid2_width(all.flMid2Width);
773 defer_high_gain(all.lHighGain);
774 defer_high_cutoff(all.flHighCutOff);
777 void EaxEqualizerEffect::defer_low_gain(
778 const EaxEaxCall& eax_call)
780 const auto& low_gain =
781 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::lLowGain)>();
783 validate_low_gain(low_gain);
784 defer_low_gain(low_gain);
787 void EaxEqualizerEffect::defer_low_cutoff(
788 const EaxEaxCall& eax_call)
790 const auto& low_cutoff =
791 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flLowCutOff)>();
793 validate_low_cutoff(low_cutoff);
794 defer_low_cutoff(low_cutoff);
797 void EaxEqualizerEffect::defer_mid1_gain(
798 const EaxEaxCall& eax_call)
800 const auto& mid1_gain =
801 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::lMid1Gain)>();
803 validate_mid1_gain(mid1_gain);
804 defer_mid1_gain(mid1_gain);
807 void EaxEqualizerEffect::defer_mid1_center(
808 const EaxEaxCall& eax_call)
810 const auto& mid1_center =
811 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flMid1Center)>();
813 validate_mid1_center(mid1_center);
814 defer_mid1_center(mid1_center);
817 void EaxEqualizerEffect::defer_mid1_width(
818 const EaxEaxCall& eax_call)
820 const auto& mid1_width =
821 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flMid1Width)>();
823 validate_mid1_width(mid1_width);
824 defer_mid1_width(mid1_width);
827 void EaxEqualizerEffect::defer_mid2_gain(
828 const EaxEaxCall& eax_call)
830 const auto& mid2_gain =
831 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::lMid2Gain)>();
833 validate_mid2_gain(mid2_gain);
834 defer_mid2_gain(mid2_gain);
837 void EaxEqualizerEffect::defer_mid2_center(
838 const EaxEaxCall& eax_call)
840 const auto& mid2_center =
841 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flMid2Center)>();
843 validate_mid2_center(mid2_center);
844 defer_mid2_center(mid2_center);
847 void EaxEqualizerEffect::defer_mid2_width(
848 const EaxEaxCall& eax_call)
850 const auto& mid2_width =
851 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flMid2Width)>();
853 validate_mid2_width(mid2_width);
854 defer_mid2_width(mid2_width);
857 void EaxEqualizerEffect::defer_high_gain(
858 const EaxEaxCall& eax_call)
860 const auto& high_gain =
861 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::lHighGain)>();
863 validate_high_gain(high_gain);
864 defer_high_gain(high_gain);
867 void EaxEqualizerEffect::defer_high_cutoff(
868 const EaxEaxCall& eax_call)
870 const auto& high_cutoff =
871 eax_call.get_value<EaxEqualizerEffectException, const decltype(EAXEQUALIZERPROPERTIES::flHighCutOff)>();
873 validate_high_cutoff(high_cutoff);
874 defer_high_cutoff(high_cutoff);
877 void EaxEqualizerEffect::defer_all(
878 const EaxEaxCall& eax_call)
880 const auto& all =
881 eax_call.get_value<EaxEqualizerEffectException, const EAXEQUALIZERPROPERTIES>();
883 validate_all(all);
884 defer_all(all);
887 // [[nodiscard]]
888 bool EaxEqualizerEffect::apply_deferred()
890 if (eax_dirty_flags_ == EaxEqualizerEffectDirtyFlags{})
892 return false;
895 eax_ = eax_d_;
897 if (eax_dirty_flags_.lLowGain)
899 set_efx_low_gain();
902 if (eax_dirty_flags_.flLowCutOff)
904 set_efx_low_cutoff();
907 if (eax_dirty_flags_.lMid1Gain)
909 set_efx_mid1_gain();
912 if (eax_dirty_flags_.flMid1Center)
914 set_efx_mid1_center();
917 if (eax_dirty_flags_.flMid1Width)
919 set_efx_mid1_width();
922 if (eax_dirty_flags_.lMid2Gain)
924 set_efx_mid2_gain();
927 if (eax_dirty_flags_.flMid2Center)
929 set_efx_mid2_center();
932 if (eax_dirty_flags_.flMid2Width)
934 set_efx_mid2_width();
937 if (eax_dirty_flags_.lHighGain)
939 set_efx_high_gain();
942 if (eax_dirty_flags_.flHighCutOff)
944 set_efx_high_cutoff();
947 eax_dirty_flags_ = EaxEqualizerEffectDirtyFlags{};
949 return true;
952 // [[nodiscard]]
953 bool EaxEqualizerEffect::set(
954 const EaxEaxCall& eax_call)
956 switch (eax_call.get_property_id())
958 case EAXEQUALIZER_NONE:
959 break;
961 case EAXEQUALIZER_ALLPARAMETERS:
962 defer_all(eax_call);
963 break;
965 case EAXEQUALIZER_LOWGAIN:
966 defer_low_gain(eax_call);
967 break;
969 case EAXEQUALIZER_LOWCUTOFF:
970 defer_low_cutoff(eax_call);
971 break;
973 case EAXEQUALIZER_MID1GAIN:
974 defer_mid1_gain(eax_call);
975 break;
977 case EAXEQUALIZER_MID1CENTER:
978 defer_mid1_center(eax_call);
979 break;
981 case EAXEQUALIZER_MID1WIDTH:
982 defer_mid1_width(eax_call);
983 break;
985 case EAXEQUALIZER_MID2GAIN:
986 defer_mid2_gain(eax_call);
987 break;
989 case EAXEQUALIZER_MID2CENTER:
990 defer_mid2_center(eax_call);
991 break;
993 case EAXEQUALIZER_MID2WIDTH:
994 defer_mid2_width(eax_call);
995 break;
997 case EAXEQUALIZER_HIGHGAIN:
998 defer_high_gain(eax_call);
999 break;
1001 case EAXEQUALIZER_HIGHCUTOFF:
1002 defer_high_cutoff(eax_call);
1003 break;
1005 default:
1006 throw EaxEqualizerEffectException{"Unsupported property id."};
1009 if (!eax_call.is_deferred())
1011 return apply_deferred();
1014 return false;
1017 } // namespace
1019 EaxEffectUPtr eax_create_eax_equalizer_effect()
1021 return std::make_unique<EaxEqualizerEffect>();
1024 #endif // ALSOFT_EAX