Define the CoreAudio default name only when needed
[openal-soft.git] / al / effects / pshifter.cpp
blob6c45ab4e0a0fbff10f9b4f21fe03771bc4e10a86
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 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",
25 param};
28 void Pshifter_setParami(EffectProps *props, ALenum param, int val)
30 switch(param)
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;
36 break;
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;
42 break;
44 default:
45 throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
46 param};
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)
54 switch(param)
56 case AL_PITCH_SHIFTER_COARSE_TUNE:
57 *val = props->Pshifter.CoarseTune;
58 break;
59 case AL_PITCH_SHIFTER_FINE_TUNE:
60 *val = props->Pshifter.FineTune;
61 break;
63 default:
64 throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
65 param};
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",
76 param};
79 EffectProps genDefaultProps() noexcept
81 EffectProps props{};
82 props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
83 props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
84 return props;
87 } // namespace
89 DEFINE_ALEFFECT_VTABLE(Pshifter);
91 const EffectProps PshifterEffectProps{genDefaultProps()};
93 #ifdef ALSOFT_EAX
94 namespace {
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 :
108 public EaxEffect
110 public:
111 EaxPitchShifterEffect();
113 // [[nodiscard]]
114 bool dispatch(
115 const EaxEaxCall& eax_call) override;
117 private:
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();
133 // [[nodiscard]]
134 bool get(
135 const EaxEaxCall& eax_call);
138 void validate_coarse_tune(
139 long lCoarseTune);
141 void validate_fine_tune(
142 long lFineTune);
144 void validate_all(
145 const EAXPITCHSHIFTERPROPERTIES& all);
148 void defer_coarse_tune(
149 long lCoarseTune);
151 void defer_fine_tune(
152 long lFineTune);
154 void defer_all(
155 const EAXPITCHSHIFTERPROPERTIES& all);
158 void defer_coarse_tune(
159 const EaxEaxCall& eax_call);
161 void defer_fine_tune(
162 const EaxEaxCall& eax_call);
164 void defer_all(
165 const EaxEaxCall& eax_call);
168 // [[nodiscard]]
169 bool apply_deferred();
171 // [[nodiscard]]
172 bool set(
173 const EaxEaxCall& eax_call);
174 }; // EaxPitchShifterEffect
177 class EaxPitchShifterEffectException :
178 public EaxException
180 public:
181 explicit EaxPitchShifterEffectException(
182 const char* message)
184 EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
187 }; // EaxPitchShifterEffectException
190 EaxPitchShifterEffect::EaxPitchShifterEffect()
191 : EaxEffect{AL_EFFECT_PITCH_SHIFTER}
193 set_eax_defaults();
194 set_efx_defaults();
197 // [[nodiscard]]
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;
209 eax_d_ = eax_;
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();
235 set_efx_fine_tune();
238 // [[nodiscard]]
239 bool EaxPitchShifterEffect::get(
240 const EaxEaxCall& eax_call)
242 switch (eax_call.get_property_id())
244 case EAXPITCHSHIFTER_NONE:
245 break;
247 case EAXPITCHSHIFTER_ALLPARAMETERS:
248 eax_call.set_value<EaxPitchShifterEffectException>(eax_);
249 break;
251 case EAXPITCHSHIFTER_COARSETUNE:
252 eax_call.set_value<EaxPitchShifterEffectException>(eax_.lCoarseTune);
253 break;
255 case EAXPITCHSHIFTER_FINETUNE:
256 eax_call.set_value<EaxPitchShifterEffectException>(eax_.lFineTune);
257 break;
259 default:
260 throw EaxPitchShifterEffectException{"Unsupported property id."};
263 return false;
266 void EaxPitchShifterEffect::validate_coarse_tune(
267 long lCoarseTune)
269 eax_validate_range<EaxPitchShifterEffectException>(
270 "Coarse Tune",
271 lCoarseTune,
272 EAXPITCHSHIFTER_MINCOARSETUNE,
273 EAXPITCHSHIFTER_MAXCOARSETUNE);
276 void EaxPitchShifterEffect::validate_fine_tune(
277 long lFineTune)
279 eax_validate_range<EaxPitchShifterEffectException>(
280 "Fine Tune",
281 lFineTune,
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(
294 long lCoarseTune)
296 eax_d_.lCoarseTune = lCoarseTune;
297 eax_dirty_flags_.lCoarseTune = (eax_.lCoarseTune != eax_d_.lCoarseTune);
300 void EaxPitchShifterEffect::defer_fine_tune(
301 long lFineTune)
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)
337 const auto& all =
338 eax_call.get_value<EaxPitchShifterEffectException, const EAXPITCHSHIFTERPROPERTIES>();
340 validate_all(all);
341 defer_all(all);
344 // [[nodiscard]]
345 bool EaxPitchShifterEffect::apply_deferred()
347 if (eax_dirty_flags_ == EaxPitchShifterEffectDirtyFlags{})
349 return false;
352 eax_ = eax_d_;
354 if (eax_dirty_flags_.lCoarseTune)
356 set_efx_coarse_tune();
359 if (eax_dirty_flags_.lFineTune)
361 set_efx_fine_tune();
364 eax_dirty_flags_ = EaxPitchShifterEffectDirtyFlags{};
366 return true;
369 // [[nodiscard]]
370 bool EaxPitchShifterEffect::set(
371 const EaxEaxCall& eax_call)
373 switch (eax_call.get_property_id())
375 case EAXPITCHSHIFTER_NONE:
376 break;
378 case EAXPITCHSHIFTER_ALLPARAMETERS:
379 defer_all(eax_call);
380 break;
382 case EAXPITCHSHIFTER_COARSETUNE:
383 defer_coarse_tune(eax_call);
384 break;
386 case EAXPITCHSHIFTER_FINETUNE:
387 defer_fine_tune(eax_call);
388 break;
390 default:
391 throw EaxPitchShifterEffectException{"Unsupported property id."};
394 if (!eax_call.is_deferred())
396 return apply_deferred();
399 return false;
402 } // namespace
404 EaxEffectUPtr eax_create_eax_pitch_shifter_effect()
406 return std::make_unique<EaxPitchShifterEffect>();
409 #endif // ALSOFT_EAX