7 #include "alc/effects/base.h"
11 #include "alnumeric.h"
13 #include "al/eax_exception.h"
14 #include "al/eax_utils.h"
20 void Pshifter_setParamf(EffectProps
*, ALenum param
, float)
21 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter float property 0x%04x", param
}; }
22 void Pshifter_setParamfv(EffectProps
*, ALenum param
, const float*)
24 throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter float-vector property 0x%04x",
28 void Pshifter_setParami(EffectProps
*props
, ALenum param
, int val
)
32 case AL_PITCH_SHIFTER_COARSE_TUNE
:
33 if(!(val
>= AL_PITCH_SHIFTER_MIN_COARSE_TUNE
&& val
<= AL_PITCH_SHIFTER_MAX_COARSE_TUNE
))
34 throw effect_exception
{AL_INVALID_VALUE
, "Pitch shifter coarse tune out of range"};
35 props
->Pshifter
.CoarseTune
= val
;
38 case AL_PITCH_SHIFTER_FINE_TUNE
:
39 if(!(val
>= AL_PITCH_SHIFTER_MIN_FINE_TUNE
&& val
<= AL_PITCH_SHIFTER_MAX_FINE_TUNE
))
40 throw effect_exception
{AL_INVALID_VALUE
, "Pitch shifter fine tune out of range"};
41 props
->Pshifter
.FineTune
= val
;
45 throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter integer property 0x%04x",
49 void Pshifter_setParamiv(EffectProps
*props
, ALenum param
, const int *vals
)
50 { Pshifter_setParami(props
, param
, vals
[0]); }
52 void Pshifter_getParami(const EffectProps
*props
, ALenum param
, int *val
)
56 case AL_PITCH_SHIFTER_COARSE_TUNE
:
57 *val
= props
->Pshifter
.CoarseTune
;
59 case AL_PITCH_SHIFTER_FINE_TUNE
:
60 *val
= props
->Pshifter
.FineTune
;
64 throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter integer property 0x%04x",
68 void Pshifter_getParamiv(const EffectProps
*props
, ALenum param
, int *vals
)
69 { Pshifter_getParami(props
, param
, vals
); }
71 void Pshifter_getParamf(const EffectProps
*, ALenum param
, float*)
72 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter float property 0x%04x", param
}; }
73 void Pshifter_getParamfv(const EffectProps
*, ALenum param
, float*)
75 throw effect_exception
{AL_INVALID_ENUM
, "Invalid pitch shifter float vector-property 0x%04x",
79 EffectProps
genDefaultProps() noexcept
82 props
.Pshifter
.CoarseTune
= AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE
;
83 props
.Pshifter
.FineTune
= AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE
;
89 DEFINE_ALEFFECT_VTABLE(Pshifter
);
91 const EffectProps PshifterEffectProps
{genDefaultProps()};
96 using EaxPitchShifterEffectDirtyFlagsValue
= std::uint_least8_t;
98 struct EaxPitchShifterEffectDirtyFlags
100 using EaxIsBitFieldStruct
= bool;
102 EaxPitchShifterEffectDirtyFlagsValue lCoarseTune
: 1;
103 EaxPitchShifterEffectDirtyFlagsValue lFineTune
: 1;
104 }; // EaxPitchShifterEffectDirtyFlags
107 class EaxPitchShifterEffect final
:
111 EaxPitchShifterEffect();
115 const EaxEaxCall
& eax_call
) override
;
118 EAXPITCHSHIFTERPROPERTIES eax_
{};
119 EAXPITCHSHIFTERPROPERTIES eax_d_
{};
120 EaxPitchShifterEffectDirtyFlags eax_dirty_flags_
{};
123 void set_eax_defaults();
126 void set_efx_coarse_tune();
128 void set_efx_fine_tune();
130 void set_efx_defaults();
135 const EaxEaxCall
& eax_call
);
138 void validate_coarse_tune(
141 void validate_fine_tune(
145 const EAXPITCHSHIFTERPROPERTIES
& all
);
148 void defer_coarse_tune(
151 void defer_fine_tune(
155 const EAXPITCHSHIFTERPROPERTIES
& all
);
158 void defer_coarse_tune(
159 const EaxEaxCall
& eax_call
);
161 void defer_fine_tune(
162 const EaxEaxCall
& eax_call
);
165 const EaxEaxCall
& eax_call
);
169 bool apply_deferred();
173 const EaxEaxCall
& eax_call
);
174 }; // EaxPitchShifterEffect
177 class EaxPitchShifterEffectException
:
181 explicit EaxPitchShifterEffectException(
184 EaxException
{"EAX_PITCH_SHIFTER_EFFECT", message
}
187 }; // EaxPitchShifterEffectException
190 EaxPitchShifterEffect::EaxPitchShifterEffect()
191 : EaxEffect
{AL_EFFECT_PITCH_SHIFTER
}
198 bool EaxPitchShifterEffect::dispatch(
199 const EaxEaxCall
& eax_call
)
201 return eax_call
.is_get() ? get(eax_call
) : set(eax_call
);
204 void EaxPitchShifterEffect::set_eax_defaults()
206 eax_
.lCoarseTune
= EAXPITCHSHIFTER_DEFAULTCOARSETUNE
;
207 eax_
.lFineTune
= EAXPITCHSHIFTER_DEFAULTFINETUNE
;
212 void EaxPitchShifterEffect::set_efx_coarse_tune()
214 const auto coarse_tune
= clamp(
215 static_cast<ALint
>(eax_
.lCoarseTune
),
216 AL_PITCH_SHIFTER_MIN_COARSE_TUNE
,
217 AL_PITCH_SHIFTER_MAX_COARSE_TUNE
);
219 al_effect_props_
.Pshifter
.CoarseTune
= coarse_tune
;
222 void EaxPitchShifterEffect::set_efx_fine_tune()
224 const auto fine_tune
= clamp(
225 static_cast<ALint
>(eax_
.lFineTune
),
226 AL_PITCH_SHIFTER_MIN_FINE_TUNE
,
227 AL_PITCH_SHIFTER_MAX_FINE_TUNE
);
229 al_effect_props_
.Pshifter
.FineTune
= fine_tune
;
232 void EaxPitchShifterEffect::set_efx_defaults()
234 set_efx_coarse_tune();
239 bool EaxPitchShifterEffect::get(
240 const EaxEaxCall
& eax_call
)
242 switch (eax_call
.get_property_id())
244 case EAXPITCHSHIFTER_NONE
:
247 case EAXPITCHSHIFTER_ALLPARAMETERS
:
248 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
);
251 case EAXPITCHSHIFTER_COARSETUNE
:
252 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
.lCoarseTune
);
255 case EAXPITCHSHIFTER_FINETUNE
:
256 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
.lFineTune
);
260 throw EaxPitchShifterEffectException
{"Unsupported property id."};
266 void EaxPitchShifterEffect::validate_coarse_tune(
269 eax_validate_range
<EaxPitchShifterEffectException
>(
272 EAXPITCHSHIFTER_MINCOARSETUNE
,
273 EAXPITCHSHIFTER_MAXCOARSETUNE
);
276 void EaxPitchShifterEffect::validate_fine_tune(
279 eax_validate_range
<EaxPitchShifterEffectException
>(
282 EAXPITCHSHIFTER_MINFINETUNE
,
283 EAXPITCHSHIFTER_MAXFINETUNE
);
286 void EaxPitchShifterEffect::validate_all(
287 const EAXPITCHSHIFTERPROPERTIES
& all
)
289 validate_coarse_tune(all
.lCoarseTune
);
290 validate_fine_tune(all
.lFineTune
);
293 void EaxPitchShifterEffect::defer_coarse_tune(
296 eax_d_
.lCoarseTune
= lCoarseTune
;
297 eax_dirty_flags_
.lCoarseTune
= (eax_
.lCoarseTune
!= eax_d_
.lCoarseTune
);
300 void EaxPitchShifterEffect::defer_fine_tune(
303 eax_d_
.lFineTune
= lFineTune
;
304 eax_dirty_flags_
.lFineTune
= (eax_
.lFineTune
!= eax_d_
.lFineTune
);
307 void EaxPitchShifterEffect::defer_all(
308 const EAXPITCHSHIFTERPROPERTIES
& all
)
310 defer_coarse_tune(all
.lCoarseTune
);
311 defer_fine_tune(all
.lFineTune
);
314 void EaxPitchShifterEffect::defer_coarse_tune(
315 const EaxEaxCall
& eax_call
)
317 const auto& coarse_tune
=
318 eax_call
.get_value
<EaxPitchShifterEffectException
, const decltype(EAXPITCHSHIFTERPROPERTIES::lCoarseTune
)>();
320 validate_coarse_tune(coarse_tune
);
321 defer_coarse_tune(coarse_tune
);
324 void EaxPitchShifterEffect::defer_fine_tune(
325 const EaxEaxCall
& eax_call
)
327 const auto& fine_tune
=
328 eax_call
.get_value
<EaxPitchShifterEffectException
, const decltype(EAXPITCHSHIFTERPROPERTIES::lFineTune
)>();
330 validate_fine_tune(fine_tune
);
331 defer_fine_tune(fine_tune
);
334 void EaxPitchShifterEffect::defer_all(
335 const EaxEaxCall
& eax_call
)
338 eax_call
.get_value
<EaxPitchShifterEffectException
, const EAXPITCHSHIFTERPROPERTIES
>();
345 bool EaxPitchShifterEffect::apply_deferred()
347 if (eax_dirty_flags_
== EaxPitchShifterEffectDirtyFlags
{})
354 if (eax_dirty_flags_
.lCoarseTune
)
356 set_efx_coarse_tune();
359 if (eax_dirty_flags_
.lFineTune
)
364 eax_dirty_flags_
= EaxPitchShifterEffectDirtyFlags
{};
370 bool EaxPitchShifterEffect::set(
371 const EaxEaxCall
& eax_call
)
373 switch (eax_call
.get_property_id())
375 case EAXPITCHSHIFTER_NONE
:
378 case EAXPITCHSHIFTER_ALLPARAMETERS
:
382 case EAXPITCHSHIFTER_COARSETUNE
:
383 defer_coarse_tune(eax_call
);
386 case EAXPITCHSHIFTER_FINETUNE
:
387 defer_fine_tune(eax_call
);
391 throw EaxPitchShifterEffectException
{"Unsupported property id."};
394 if (!eax_call
.is_deferred())
396 return apply_deferred();
404 EaxEffectUPtr
eax_create_eax_pitch_shifter_effect()
406 return std::make_unique
<EaxPitchShifterEffect
>();