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();
113 void dispatch(const EaxEaxCall
& eax_call
) override
;
116 bool apply_deferred() override
;
119 EAXPITCHSHIFTERPROPERTIES eax_
{};
120 EAXPITCHSHIFTERPROPERTIES eax_d_
{};
121 EaxPitchShifterEffectDirtyFlags eax_dirty_flags_
{};
123 void set_eax_defaults();
125 void set_efx_coarse_tune();
126 void set_efx_fine_tune();
127 void set_efx_defaults();
129 void get(const EaxEaxCall
& eax_call
);
131 void validate_coarse_tune(long lCoarseTune
);
132 void validate_fine_tune(long lFineTune
);
133 void validate_all(const EAXPITCHSHIFTERPROPERTIES
& all
);
135 void defer_coarse_tune(long lCoarseTune
);
136 void defer_fine_tune(long lFineTune
);
137 void defer_all(const EAXPITCHSHIFTERPROPERTIES
& all
);
139 void defer_coarse_tune(const EaxEaxCall
& eax_call
);
140 void defer_fine_tune(const EaxEaxCall
& eax_call
);
141 void defer_all(const EaxEaxCall
& eax_call
);
143 void set(const EaxEaxCall
& eax_call
);
144 }; // EaxPitchShifterEffect
147 class EaxPitchShifterEffectException
:
151 explicit EaxPitchShifterEffectException(
154 EaxException
{"EAX_PITCH_SHIFTER_EFFECT", message
}
157 }; // EaxPitchShifterEffectException
160 EaxPitchShifterEffect::EaxPitchShifterEffect()
161 : EaxEffect
{AL_EFFECT_PITCH_SHIFTER
}
167 void EaxPitchShifterEffect::dispatch(const EaxEaxCall
& eax_call
)
169 eax_call
.is_get() ? get(eax_call
) : set(eax_call
);
172 void EaxPitchShifterEffect::set_eax_defaults()
174 eax_
.lCoarseTune
= EAXPITCHSHIFTER_DEFAULTCOARSETUNE
;
175 eax_
.lFineTune
= EAXPITCHSHIFTER_DEFAULTFINETUNE
;
180 void EaxPitchShifterEffect::set_efx_coarse_tune()
182 const auto coarse_tune
= clamp(
183 static_cast<ALint
>(eax_
.lCoarseTune
),
184 AL_PITCH_SHIFTER_MIN_COARSE_TUNE
,
185 AL_PITCH_SHIFTER_MAX_COARSE_TUNE
);
187 al_effect_props_
.Pshifter
.CoarseTune
= coarse_tune
;
190 void EaxPitchShifterEffect::set_efx_fine_tune()
192 const auto fine_tune
= clamp(
193 static_cast<ALint
>(eax_
.lFineTune
),
194 AL_PITCH_SHIFTER_MIN_FINE_TUNE
,
195 AL_PITCH_SHIFTER_MAX_FINE_TUNE
);
197 al_effect_props_
.Pshifter
.FineTune
= fine_tune
;
200 void EaxPitchShifterEffect::set_efx_defaults()
202 set_efx_coarse_tune();
206 void EaxPitchShifterEffect::get(const EaxEaxCall
& eax_call
)
208 switch(eax_call
.get_property_id())
210 case EAXPITCHSHIFTER_NONE
:
213 case EAXPITCHSHIFTER_ALLPARAMETERS
:
214 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
);
217 case EAXPITCHSHIFTER_COARSETUNE
:
218 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
.lCoarseTune
);
221 case EAXPITCHSHIFTER_FINETUNE
:
222 eax_call
.set_value
<EaxPitchShifterEffectException
>(eax_
.lFineTune
);
226 throw EaxPitchShifterEffectException
{"Unsupported property id."};
230 void EaxPitchShifterEffect::validate_coarse_tune(
233 eax_validate_range
<EaxPitchShifterEffectException
>(
236 EAXPITCHSHIFTER_MINCOARSETUNE
,
237 EAXPITCHSHIFTER_MAXCOARSETUNE
);
240 void EaxPitchShifterEffect::validate_fine_tune(
243 eax_validate_range
<EaxPitchShifterEffectException
>(
246 EAXPITCHSHIFTER_MINFINETUNE
,
247 EAXPITCHSHIFTER_MAXFINETUNE
);
250 void EaxPitchShifterEffect::validate_all(
251 const EAXPITCHSHIFTERPROPERTIES
& all
)
253 validate_coarse_tune(all
.lCoarseTune
);
254 validate_fine_tune(all
.lFineTune
);
257 void EaxPitchShifterEffect::defer_coarse_tune(
260 eax_d_
.lCoarseTune
= lCoarseTune
;
261 eax_dirty_flags_
.lCoarseTune
= (eax_
.lCoarseTune
!= eax_d_
.lCoarseTune
);
264 void EaxPitchShifterEffect::defer_fine_tune(
267 eax_d_
.lFineTune
= lFineTune
;
268 eax_dirty_flags_
.lFineTune
= (eax_
.lFineTune
!= eax_d_
.lFineTune
);
271 void EaxPitchShifterEffect::defer_all(
272 const EAXPITCHSHIFTERPROPERTIES
& all
)
274 defer_coarse_tune(all
.lCoarseTune
);
275 defer_fine_tune(all
.lFineTune
);
278 void EaxPitchShifterEffect::defer_coarse_tune(
279 const EaxEaxCall
& eax_call
)
281 const auto& coarse_tune
=
282 eax_call
.get_value
<EaxPitchShifterEffectException
, const decltype(EAXPITCHSHIFTERPROPERTIES::lCoarseTune
)>();
284 validate_coarse_tune(coarse_tune
);
285 defer_coarse_tune(coarse_tune
);
288 void EaxPitchShifterEffect::defer_fine_tune(
289 const EaxEaxCall
& eax_call
)
291 const auto& fine_tune
=
292 eax_call
.get_value
<EaxPitchShifterEffectException
, const decltype(EAXPITCHSHIFTERPROPERTIES::lFineTune
)>();
294 validate_fine_tune(fine_tune
);
295 defer_fine_tune(fine_tune
);
298 void EaxPitchShifterEffect::defer_all(
299 const EaxEaxCall
& eax_call
)
302 eax_call
.get_value
<EaxPitchShifterEffectException
, const EAXPITCHSHIFTERPROPERTIES
>();
309 bool EaxPitchShifterEffect::apply_deferred()
311 if (eax_dirty_flags_
== EaxPitchShifterEffectDirtyFlags
{})
318 if (eax_dirty_flags_
.lCoarseTune
)
320 set_efx_coarse_tune();
323 if (eax_dirty_flags_
.lFineTune
)
328 eax_dirty_flags_
= EaxPitchShifterEffectDirtyFlags
{};
333 void EaxPitchShifterEffect::set(const EaxEaxCall
& eax_call
)
335 switch(eax_call
.get_property_id())
337 case EAXPITCHSHIFTER_NONE
:
340 case EAXPITCHSHIFTER_ALLPARAMETERS
:
344 case EAXPITCHSHIFTER_COARSETUNE
:
345 defer_coarse_tune(eax_call
);
348 case EAXPITCHSHIFTER_FINETUNE
:
349 defer_fine_tune(eax_call
);
353 throw EaxPitchShifterEffectException
{"Unsupported property id."};
359 EaxEffectUPtr
eax_create_eax_pitch_shifter_effect()
361 return std::make_unique
<EaxPitchShifterEffect
>();