9 #include "alc/effects/base.h"
10 #include "aloptional.h"
16 #include "alnumeric.h"
18 #include "al/eax_exception.h"
19 #include "al/eax_utils.h"
25 al::optional
<VMorpherPhenome
> PhenomeFromEnum(ALenum val
)
27 #define HANDLE_PHENOME(x) case AL_VOCAL_MORPHER_PHONEME_ ## x: \
28 return al::make_optional(VMorpherPhenome::x)
65 ALenum
EnumFromPhenome(VMorpherPhenome phenome
)
67 #define HANDLE_PHENOME(x) case VMorpherPhenome::x: return AL_VOCAL_MORPHER_PHONEME_ ## x
101 throw std::runtime_error
{"Invalid phenome: "+std::to_string(static_cast<int>(phenome
))};
102 #undef HANDLE_PHENOME
105 al::optional
<VMorpherWaveform
> WaveformFromEmum(ALenum value
)
109 case AL_VOCAL_MORPHER_WAVEFORM_SINUSOID
: return al::make_optional(VMorpherWaveform::Sinusoid
);
110 case AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE
: return al::make_optional(VMorpherWaveform::Triangle
);
111 case AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH
: return al::make_optional(VMorpherWaveform::Sawtooth
);
115 ALenum
EnumFromWaveform(VMorpherWaveform type
)
119 case VMorpherWaveform::Sinusoid
: return AL_VOCAL_MORPHER_WAVEFORM_SINUSOID
;
120 case VMorpherWaveform::Triangle
: return AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE
;
121 case VMorpherWaveform::Sawtooth
: return AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH
;
123 throw std::runtime_error
{"Invalid vocal morpher waveform: " +
124 std::to_string(static_cast<int>(type
))};
127 void Vmorpher_setParami(EffectProps
*props
, ALenum param
, int val
)
131 case AL_VOCAL_MORPHER_PHONEMEA
:
132 if(auto phenomeopt
= PhenomeFromEnum(val
))
133 props
->Vmorpher
.PhonemeA
= *phenomeopt
;
135 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher phoneme-a out of range: 0x%04x", val
};
138 case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING
:
139 if(!(val
>= AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING
&& val
<= AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING
))
140 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher phoneme-a coarse tuning out of range"};
141 props
->Vmorpher
.PhonemeACoarseTuning
= val
;
144 case AL_VOCAL_MORPHER_PHONEMEB
:
145 if(auto phenomeopt
= PhenomeFromEnum(val
))
146 props
->Vmorpher
.PhonemeB
= *phenomeopt
;
148 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher phoneme-b out of range: 0x%04x", val
};
151 case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING
:
152 if(!(val
>= AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING
&& val
<= AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING
))
153 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher phoneme-b coarse tuning out of range"};
154 props
->Vmorpher
.PhonemeBCoarseTuning
= val
;
157 case AL_VOCAL_MORPHER_WAVEFORM
:
158 if(auto formopt
= WaveformFromEmum(val
))
159 props
->Vmorpher
.Waveform
= *formopt
;
161 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher waveform out of range: 0x%04x", val
};
165 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher integer property 0x%04x",
169 void Vmorpher_setParamiv(EffectProps
*, ALenum param
, const int*)
171 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher integer-vector property 0x%04x",
174 void Vmorpher_setParamf(EffectProps
*props
, ALenum param
, float val
)
178 case AL_VOCAL_MORPHER_RATE
:
179 if(!(val
>= AL_VOCAL_MORPHER_MIN_RATE
&& val
<= AL_VOCAL_MORPHER_MAX_RATE
))
180 throw effect_exception
{AL_INVALID_VALUE
, "Vocal morpher rate out of range"};
181 props
->Vmorpher
.Rate
= val
;
185 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher float property 0x%04x",
189 void Vmorpher_setParamfv(EffectProps
*props
, ALenum param
, const float *vals
)
190 { Vmorpher_setParamf(props
, param
, vals
[0]); }
192 void Vmorpher_getParami(const EffectProps
*props
, ALenum param
, int* val
)
196 case AL_VOCAL_MORPHER_PHONEMEA
:
197 *val
= EnumFromPhenome(props
->Vmorpher
.PhonemeA
);
200 case AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING
:
201 *val
= props
->Vmorpher
.PhonemeACoarseTuning
;
204 case AL_VOCAL_MORPHER_PHONEMEB
:
205 *val
= EnumFromPhenome(props
->Vmorpher
.PhonemeB
);
208 case AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING
:
209 *val
= props
->Vmorpher
.PhonemeBCoarseTuning
;
212 case AL_VOCAL_MORPHER_WAVEFORM
:
213 *val
= EnumFromWaveform(props
->Vmorpher
.Waveform
);
217 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher integer property 0x%04x",
221 void Vmorpher_getParamiv(const EffectProps
*, ALenum param
, int*)
223 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher integer-vector property 0x%04x",
226 void Vmorpher_getParamf(const EffectProps
*props
, ALenum param
, float *val
)
230 case AL_VOCAL_MORPHER_RATE
:
231 *val
= props
->Vmorpher
.Rate
;
235 throw effect_exception
{AL_INVALID_ENUM
, "Invalid vocal morpher float property 0x%04x",
239 void Vmorpher_getParamfv(const EffectProps
*props
, ALenum param
, float *vals
)
240 { Vmorpher_getParamf(props
, param
, vals
); }
242 EffectProps
genDefaultProps() noexcept
245 props
.Vmorpher
.Rate
= AL_VOCAL_MORPHER_DEFAULT_RATE
;
246 props
.Vmorpher
.PhonemeA
= *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEA
);
247 props
.Vmorpher
.PhonemeB
= *PhenomeFromEnum(AL_VOCAL_MORPHER_DEFAULT_PHONEMEB
);
248 props
.Vmorpher
.PhonemeACoarseTuning
= AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING
;
249 props
.Vmorpher
.PhonemeBCoarseTuning
= AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING
;
250 props
.Vmorpher
.Waveform
= *WaveformFromEmum(AL_VOCAL_MORPHER_DEFAULT_WAVEFORM
);
256 DEFINE_ALEFFECT_VTABLE(Vmorpher
);
258 const EffectProps VmorpherEffectProps
{genDefaultProps()};
263 using EaxVocalMorpherEffectDirtyFlagsValue
= std::uint_least8_t;
265 struct EaxVocalMorpherEffectDirtyFlags
267 using EaxIsBitFieldStruct
= bool;
269 EaxVocalMorpherEffectDirtyFlagsValue ulPhonemeA
: 1;
270 EaxVocalMorpherEffectDirtyFlagsValue lPhonemeACoarseTuning
: 1;
271 EaxVocalMorpherEffectDirtyFlagsValue ulPhonemeB
: 1;
272 EaxVocalMorpherEffectDirtyFlagsValue lPhonemeBCoarseTuning
: 1;
273 EaxVocalMorpherEffectDirtyFlagsValue ulWaveform
: 1;
274 EaxVocalMorpherEffectDirtyFlagsValue flRate
: 1;
275 }; // EaxPitchShifterEffectDirtyFlags
278 class EaxVocalMorpherEffect final
:
282 EaxVocalMorpherEffect();
284 void dispatch(const EaxEaxCall
& eax_call
) override
;
287 bool apply_deferred() override
;
290 EAXVOCALMORPHERPROPERTIES eax_
{};
291 EAXVOCALMORPHERPROPERTIES eax_d_
{};
292 EaxVocalMorpherEffectDirtyFlags eax_dirty_flags_
{};
294 void set_eax_defaults();
296 void set_efx_phoneme_a();
297 void set_efx_phoneme_a_coarse_tuning();
298 void set_efx_phoneme_b();
299 void set_efx_phoneme_b_coarse_tuning();
300 void set_efx_waveform();
302 void set_efx_defaults();
304 void get(const EaxEaxCall
& eax_call
);
306 void validate_phoneme_a(unsigned long ulPhonemeA
);
307 void validate_phoneme_a_coarse_tuning(long lPhonemeACoarseTuning
);
308 void validate_phoneme_b(unsigned long ulPhonemeB
);
309 void validate_phoneme_b_coarse_tuning(long lPhonemeBCoarseTuning
);
310 void validate_waveform(unsigned long ulWaveform
);
311 void validate_rate(float flRate
);
312 void validate_all(const EAXVOCALMORPHERPROPERTIES
& all
);
314 void defer_phoneme_a(unsigned long ulPhonemeA
);
315 void defer_phoneme_a_coarse_tuning(long lPhonemeACoarseTuning
);
316 void defer_phoneme_b(unsigned long ulPhonemeB
);
317 void defer_phoneme_b_coarse_tuning(long lPhonemeBCoarseTuning
);
318 void defer_waveform(unsigned long ulWaveform
);
319 void defer_rate(float flRate
);
320 void defer_all(const EAXVOCALMORPHERPROPERTIES
& all
);
322 void defer_phoneme_a(const EaxEaxCall
& eax_call
);
323 void defer_phoneme_a_coarse_tuning(const EaxEaxCall
& eax_call
);
324 void defer_phoneme_b(const EaxEaxCall
& eax_call
);
325 void defer_phoneme_b_coarse_tuning(const EaxEaxCall
& eax_call
);
326 void defer_waveform(const EaxEaxCall
& eax_call
);
327 void defer_rate(const EaxEaxCall
& eax_call
);
328 void defer_all(const EaxEaxCall
& eax_call
);
330 void set(const EaxEaxCall
& eax_call
);
331 }; // EaxVocalMorpherEffect
334 class EaxVocalMorpherEffectException
:
338 explicit EaxVocalMorpherEffectException(
341 EaxException
{"EAX_VOCAL_MORPHER_EFFECT", message
}
344 }; // EaxVocalMorpherEffectException
347 EaxVocalMorpherEffect::EaxVocalMorpherEffect()
348 : EaxEffect
{AL_EFFECT_VOCAL_MORPHER
}
354 void EaxVocalMorpherEffect::dispatch(const EaxEaxCall
& eax_call
)
356 eax_call
.is_get() ? get(eax_call
) : set(eax_call
);
359 void EaxVocalMorpherEffect::set_eax_defaults()
361 eax_
.ulPhonemeA
= EAXVOCALMORPHER_DEFAULTPHONEMEA
;
362 eax_
.lPhonemeACoarseTuning
= EAXVOCALMORPHER_DEFAULTPHONEMEACOARSETUNING
;
363 eax_
.ulPhonemeB
= EAXVOCALMORPHER_DEFAULTPHONEMEB
;
364 eax_
.lPhonemeBCoarseTuning
= EAXVOCALMORPHER_DEFAULTPHONEMEBCOARSETUNING
;
365 eax_
.ulWaveform
= EAXVOCALMORPHER_DEFAULTWAVEFORM
;
366 eax_
.flRate
= EAXVOCALMORPHER_DEFAULTRATE
;
371 void EaxVocalMorpherEffect::set_efx_phoneme_a()
373 const auto phoneme_a
= clamp(
374 static_cast<ALint
>(eax_
.ulPhonemeA
),
375 AL_VOCAL_MORPHER_MIN_PHONEMEA
,
376 AL_VOCAL_MORPHER_MAX_PHONEMEA
);
378 const auto efx_phoneme_a
= PhenomeFromEnum(phoneme_a
);
379 assert(efx_phoneme_a
.has_value());
380 al_effect_props_
.Vmorpher
.PhonemeA
= *efx_phoneme_a
;
383 void EaxVocalMorpherEffect::set_efx_phoneme_a_coarse_tuning()
385 const auto phoneme_a_coarse_tuning
= clamp(
386 static_cast<ALint
>(eax_
.lPhonemeACoarseTuning
),
387 AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING
,
388 AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING
);
390 al_effect_props_
.Vmorpher
.PhonemeACoarseTuning
= phoneme_a_coarse_tuning
;
393 void EaxVocalMorpherEffect::set_efx_phoneme_b()
395 const auto phoneme_b
= clamp(
396 static_cast<ALint
>(eax_
.ulPhonemeB
),
397 AL_VOCAL_MORPHER_MIN_PHONEMEB
,
398 AL_VOCAL_MORPHER_MAX_PHONEMEB
);
400 const auto efx_phoneme_b
= PhenomeFromEnum(phoneme_b
);
401 assert(efx_phoneme_b
.has_value());
402 al_effect_props_
.Vmorpher
.PhonemeB
= *efx_phoneme_b
;
405 void EaxVocalMorpherEffect::set_efx_phoneme_b_coarse_tuning()
407 const auto phoneme_b_coarse_tuning
= clamp(
408 static_cast<ALint
>(eax_
.lPhonemeBCoarseTuning
),
409 AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING
,
410 AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING
);
412 al_effect_props_
.Vmorpher
.PhonemeBCoarseTuning
= phoneme_b_coarse_tuning
;
415 void EaxVocalMorpherEffect::set_efx_waveform()
417 const auto waveform
= clamp(
418 static_cast<ALint
>(eax_
.ulWaveform
),
419 AL_VOCAL_MORPHER_MIN_WAVEFORM
,
420 AL_VOCAL_MORPHER_MAX_WAVEFORM
);
422 const auto wfx_waveform
= WaveformFromEmum(waveform
);
423 assert(wfx_waveform
.has_value());
424 al_effect_props_
.Vmorpher
.Waveform
= *wfx_waveform
;
427 void EaxVocalMorpherEffect::set_efx_rate()
429 const auto rate
= clamp(
431 AL_VOCAL_MORPHER_MIN_RATE
,
432 AL_VOCAL_MORPHER_MAX_RATE
);
434 al_effect_props_
.Vmorpher
.Rate
= rate
;
437 void EaxVocalMorpherEffect::set_efx_defaults()
440 set_efx_phoneme_a_coarse_tuning();
442 set_efx_phoneme_b_coarse_tuning();
447 void EaxVocalMorpherEffect::get(const EaxEaxCall
& eax_call
)
449 switch(eax_call
.get_property_id())
451 case EAXVOCALMORPHER_NONE
:
454 case EAXVOCALMORPHER_ALLPARAMETERS
:
455 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
);
458 case EAXVOCALMORPHER_PHONEMEA
:
459 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.ulPhonemeA
);
462 case EAXVOCALMORPHER_PHONEMEACOARSETUNING
:
463 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.lPhonemeACoarseTuning
);
466 case EAXVOCALMORPHER_PHONEMEB
:
467 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.ulPhonemeB
);
470 case EAXVOCALMORPHER_PHONEMEBCOARSETUNING
:
471 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.lPhonemeBCoarseTuning
);
474 case EAXVOCALMORPHER_WAVEFORM
:
475 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.ulWaveform
);
478 case EAXVOCALMORPHER_RATE
:
479 eax_call
.set_value
<EaxVocalMorpherEffectException
>(eax_
.flRate
);
483 throw EaxVocalMorpherEffectException
{"Unsupported property id."};
487 void EaxVocalMorpherEffect::validate_phoneme_a(
488 unsigned long ulPhonemeA
)
490 eax_validate_range
<EaxVocalMorpherEffectException
>(
493 EAXVOCALMORPHER_MINPHONEMEA
,
494 EAXVOCALMORPHER_MAXPHONEMEA
);
497 void EaxVocalMorpherEffect::validate_phoneme_a_coarse_tuning(
498 long lPhonemeACoarseTuning
)
500 eax_validate_range
<EaxVocalMorpherEffectException
>(
501 "Phoneme A Coarse Tuning",
502 lPhonemeACoarseTuning
,
503 EAXVOCALMORPHER_MINPHONEMEACOARSETUNING
,
504 EAXVOCALMORPHER_MAXPHONEMEACOARSETUNING
);
507 void EaxVocalMorpherEffect::validate_phoneme_b(
508 unsigned long ulPhonemeB
)
510 eax_validate_range
<EaxVocalMorpherEffectException
>(
513 EAXVOCALMORPHER_MINPHONEMEB
,
514 EAXVOCALMORPHER_MAXPHONEMEB
);
517 void EaxVocalMorpherEffect::validate_phoneme_b_coarse_tuning(
518 long lPhonemeBCoarseTuning
)
520 eax_validate_range
<EaxVocalMorpherEffectException
>(
521 "Phoneme B Coarse Tuning",
522 lPhonemeBCoarseTuning
,
523 EAXVOCALMORPHER_MINPHONEMEBCOARSETUNING
,
524 EAXVOCALMORPHER_MAXPHONEMEBCOARSETUNING
);
527 void EaxVocalMorpherEffect::validate_waveform(
528 unsigned long ulWaveform
)
530 eax_validate_range
<EaxVocalMorpherEffectException
>(
533 EAXVOCALMORPHER_MINWAVEFORM
,
534 EAXVOCALMORPHER_MAXWAVEFORM
);
537 void EaxVocalMorpherEffect::validate_rate(
540 eax_validate_range
<EaxVocalMorpherEffectException
>(
543 EAXVOCALMORPHER_MINRATE
,
544 EAXVOCALMORPHER_MAXRATE
);
547 void EaxVocalMorpherEffect::validate_all(
548 const EAXVOCALMORPHERPROPERTIES
& all
)
550 validate_phoneme_a(all
.ulPhonemeA
);
551 validate_phoneme_a_coarse_tuning(all
.lPhonemeACoarseTuning
);
552 validate_phoneme_b(all
.ulPhonemeB
);
553 validate_phoneme_b_coarse_tuning(all
.lPhonemeBCoarseTuning
);
554 validate_waveform(all
.ulWaveform
);
555 validate_rate(all
.flRate
);
558 void EaxVocalMorpherEffect::defer_phoneme_a(
559 unsigned long ulPhonemeA
)
561 eax_d_
.ulPhonemeA
= ulPhonemeA
;
562 eax_dirty_flags_
.ulPhonemeA
= (eax_
.ulPhonemeA
!= eax_d_
.ulPhonemeA
);
565 void EaxVocalMorpherEffect::defer_phoneme_a_coarse_tuning(
566 long lPhonemeACoarseTuning
)
568 eax_d_
.lPhonemeACoarseTuning
= lPhonemeACoarseTuning
;
569 eax_dirty_flags_
.lPhonemeACoarseTuning
= (eax_
.lPhonemeACoarseTuning
!= eax_d_
.lPhonemeACoarseTuning
);
572 void EaxVocalMorpherEffect::defer_phoneme_b(
573 unsigned long ulPhonemeB
)
575 eax_d_
.ulPhonemeB
= ulPhonemeB
;
576 eax_dirty_flags_
.ulPhonemeB
= (eax_
.ulPhonemeB
!= eax_d_
.ulPhonemeB
);
579 void EaxVocalMorpherEffect::defer_phoneme_b_coarse_tuning(
580 long lPhonemeBCoarseTuning
)
582 eax_d_
.lPhonemeBCoarseTuning
= lPhonemeBCoarseTuning
;
583 eax_dirty_flags_
.lPhonemeBCoarseTuning
= (eax_
.lPhonemeBCoarseTuning
!= eax_d_
.lPhonemeBCoarseTuning
);
586 void EaxVocalMorpherEffect::defer_waveform(
587 unsigned long ulWaveform
)
589 eax_d_
.ulWaveform
= ulWaveform
;
590 eax_dirty_flags_
.ulWaveform
= (eax_
.ulWaveform
!= eax_d_
.ulWaveform
);
593 void EaxVocalMorpherEffect::defer_rate(
596 eax_d_
.flRate
= flRate
;
597 eax_dirty_flags_
.flRate
= (eax_
.flRate
!= eax_d_
.flRate
);
600 void EaxVocalMorpherEffect::defer_all(
601 const EAXVOCALMORPHERPROPERTIES
& all
)
603 defer_phoneme_a(all
.ulPhonemeA
);
604 defer_phoneme_a_coarse_tuning(all
.lPhonemeACoarseTuning
);
605 defer_phoneme_b(all
.ulPhonemeB
);
606 defer_phoneme_b_coarse_tuning(all
.lPhonemeBCoarseTuning
);
607 defer_waveform(all
.ulWaveform
);
608 defer_rate(all
.flRate
);
611 void EaxVocalMorpherEffect::defer_phoneme_a(
612 const EaxEaxCall
& eax_call
)
614 const auto& phoneme_a
= eax_call
.get_value
<EaxVocalMorpherEffectException
,
615 const decltype(EAXVOCALMORPHERPROPERTIES::ulPhonemeA
)>();
617 validate_phoneme_a(phoneme_a
);
618 defer_phoneme_a(phoneme_a
);
621 void EaxVocalMorpherEffect::defer_phoneme_a_coarse_tuning(
622 const EaxEaxCall
& eax_call
)
624 const auto& phoneme_a_coarse_tuning
= eax_call
.get_value
<
625 EaxVocalMorpherEffectException
,
626 const decltype(EAXVOCALMORPHERPROPERTIES::lPhonemeACoarseTuning
)
629 validate_phoneme_a_coarse_tuning(phoneme_a_coarse_tuning
);
630 defer_phoneme_a_coarse_tuning(phoneme_a_coarse_tuning
);
633 void EaxVocalMorpherEffect::defer_phoneme_b(
634 const EaxEaxCall
& eax_call
)
636 const auto& phoneme_b
= eax_call
.get_value
<
637 EaxVocalMorpherEffectException
,
638 const decltype(EAXVOCALMORPHERPROPERTIES::ulPhonemeB
)
641 validate_phoneme_b(phoneme_b
);
642 defer_phoneme_b(phoneme_b
);
645 void EaxVocalMorpherEffect::defer_phoneme_b_coarse_tuning(
646 const EaxEaxCall
& eax_call
)
648 const auto& phoneme_b_coarse_tuning
= eax_call
.get_value
<
649 EaxVocalMorpherEffectException
,
650 const decltype(EAXVOCALMORPHERPROPERTIES::lPhonemeBCoarseTuning
)
653 validate_phoneme_b_coarse_tuning(phoneme_b_coarse_tuning
);
654 defer_phoneme_b_coarse_tuning(phoneme_b_coarse_tuning
);
657 void EaxVocalMorpherEffect::defer_waveform(
658 const EaxEaxCall
& eax_call
)
660 const auto& waveform
= eax_call
.get_value
<
661 EaxVocalMorpherEffectException
,
662 const decltype(EAXVOCALMORPHERPROPERTIES::ulWaveform
)
665 validate_waveform(waveform
);
666 defer_waveform(waveform
);
669 void EaxVocalMorpherEffect::defer_rate(
670 const EaxEaxCall
& eax_call
)
672 const auto& rate
= eax_call
.get_value
<
673 EaxVocalMorpherEffectException
,
674 const decltype(EAXVOCALMORPHERPROPERTIES::flRate
)
681 void EaxVocalMorpherEffect::defer_all(
682 const EaxEaxCall
& eax_call
)
684 const auto& all
= eax_call
.get_value
<
685 EaxVocalMorpherEffectException
,
686 const EAXVOCALMORPHERPROPERTIES
694 bool EaxVocalMorpherEffect::apply_deferred()
696 if (eax_dirty_flags_
== EaxVocalMorpherEffectDirtyFlags
{})
703 if (eax_dirty_flags_
.ulPhonemeA
)
708 if (eax_dirty_flags_
.lPhonemeACoarseTuning
)
710 set_efx_phoneme_a_coarse_tuning();
713 if (eax_dirty_flags_
.ulPhonemeB
)
718 if (eax_dirty_flags_
.lPhonemeBCoarseTuning
)
720 set_efx_phoneme_b_coarse_tuning();
723 if (eax_dirty_flags_
.ulWaveform
)
728 if (eax_dirty_flags_
.flRate
)
733 eax_dirty_flags_
= EaxVocalMorpherEffectDirtyFlags
{};
738 void EaxVocalMorpherEffect::set(const EaxEaxCall
& eax_call
)
740 switch(eax_call
.get_property_id())
742 case EAXVOCALMORPHER_NONE
:
745 case EAXVOCALMORPHER_ALLPARAMETERS
:
749 case EAXVOCALMORPHER_PHONEMEA
:
750 defer_phoneme_a(eax_call
);
753 case EAXVOCALMORPHER_PHONEMEACOARSETUNING
:
754 defer_phoneme_a_coarse_tuning(eax_call
);
757 case EAXVOCALMORPHER_PHONEMEB
:
758 defer_phoneme_b(eax_call
);
761 case EAXVOCALMORPHER_PHONEMEBCOARSETUNING
:
762 defer_phoneme_b_coarse_tuning(eax_call
);
765 case EAXVOCALMORPHER_WAVEFORM
:
766 defer_waveform(eax_call
);
769 case EAXVOCALMORPHER_RATE
:
770 defer_rate(eax_call
);
774 throw EaxVocalMorpherEffectException
{"Unsupported property id."};
781 EaxEffectUPtr
eax_create_eax_vocal_morpher_effect()
783 return std::make_unique
<EaxVocalMorpherEffect
>();