Define the CoreAudio default name only when needed
[openal-soft.git] / al / effects / compressor.cpp
blobd4a8e9c2c3bad5c8f75443fafd48b822c741d153
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 Compressor_setParami(EffectProps *props, ALenum param, int val)
22 switch(param)
24 case AL_COMPRESSOR_ONOFF:
25 if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF))
26 throw effect_exception{AL_INVALID_VALUE, "Compressor state out of range"};
27 props->Compressor.OnOff = (val != AL_FALSE);
28 break;
30 default:
31 throw effect_exception{AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x",
32 param};
35 void Compressor_setParamiv(EffectProps *props, ALenum param, const int *vals)
36 { Compressor_setParami(props, param, vals[0]); }
37 void Compressor_setParamf(EffectProps*, ALenum param, float)
38 { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
39 void Compressor_setParamfv(EffectProps*, ALenum param, const float*)
41 throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
42 param};
45 void Compressor_getParami(const EffectProps *props, ALenum param, int *val)
47 switch(param)
49 case AL_COMPRESSOR_ONOFF:
50 *val = props->Compressor.OnOff;
51 break;
53 default:
54 throw effect_exception{AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x",
55 param};
58 void Compressor_getParamiv(const EffectProps *props, ALenum param, int *vals)
59 { Compressor_getParami(props, param, vals); }
60 void Compressor_getParamf(const EffectProps*, ALenum param, float*)
61 { throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param}; }
62 void Compressor_getParamfv(const EffectProps*, ALenum param, float*)
64 throw effect_exception{AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x",
65 param};
68 EffectProps genDefaultProps() noexcept
70 EffectProps props{};
71 props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
72 return props;
75 } // namespace
77 DEFINE_ALEFFECT_VTABLE(Compressor);
79 const EffectProps CompressorEffectProps{genDefaultProps()};
81 #ifdef ALSOFT_EAX
82 namespace {
84 using EaxCompressorEffectDirtyFlagsValue = std::uint_least8_t;
86 struct EaxCompressorEffectDirtyFlags
88 using EaxIsBitFieldStruct = bool;
90 EaxCompressorEffectDirtyFlagsValue ulOnOff : 1;
91 }; // EaxCompressorEffectDirtyFlags
94 class EaxCompressorEffect final :
95 public EaxEffect
97 public:
98 EaxCompressorEffect();
101 // [[nodiscard]]
102 bool dispatch(
103 const EaxEaxCall& eax_call) override;
106 private:
107 EAXAGCCOMPRESSORPROPERTIES eax_{};
108 EAXAGCCOMPRESSORPROPERTIES eax_d_{};
109 EaxCompressorEffectDirtyFlags eax_dirty_flags_{};
112 void set_eax_defaults();
115 void set_efx_on_off();
117 void set_efx_defaults();
120 // [[nodiscard]]
121 bool get(
122 const EaxEaxCall& eax_call);
125 void validate_on_off(
126 unsigned long ulOnOff);
128 void validate_all(
129 const EAXAGCCOMPRESSORPROPERTIES& eax_all);
132 void defer_on_off(
133 unsigned long ulOnOff);
135 void defer_all(
136 const EAXAGCCOMPRESSORPROPERTIES& eax_all);
139 void defer_on_off(
140 const EaxEaxCall& eax_call);
142 void defer_all(
143 const EaxEaxCall& eax_call);
146 // [[nodiscard]]
147 bool apply_deferred();
149 // [[nodiscard]]
150 bool set(
151 const EaxEaxCall& eax_call);
152 }; // EaxCompressorEffect
155 class EaxCompressorEffectException :
156 public EaxException
158 public:
159 explicit EaxCompressorEffectException(
160 const char* message)
162 EaxException{"EAX_COMPRESSOR_EFFECT", message}
165 }; // EaxCompressorEffectException
168 EaxCompressorEffect::EaxCompressorEffect()
169 : EaxEffect{AL_EFFECT_COMPRESSOR}
171 set_eax_defaults();
172 set_efx_defaults();
175 // [[nodiscard]]
176 bool EaxCompressorEffect::dispatch(
177 const EaxEaxCall& eax_call)
179 return eax_call.is_get() ? get(eax_call) : set(eax_call);
182 void EaxCompressorEffect::set_eax_defaults()
184 eax_.ulOnOff = EAXAGCCOMPRESSOR_DEFAULTONOFF;
186 eax_d_ = eax_;
189 void EaxCompressorEffect::set_efx_on_off()
191 const auto on_off = clamp(
192 static_cast<ALint>(eax_.ulOnOff),
193 AL_COMPRESSOR_MIN_ONOFF,
194 AL_COMPRESSOR_MAX_ONOFF);
196 al_effect_props_.Compressor.OnOff = (on_off != AL_FALSE);
199 void EaxCompressorEffect::set_efx_defaults()
201 set_efx_on_off();
204 // [[nodiscard]]
205 bool EaxCompressorEffect::get(
206 const EaxEaxCall& eax_call)
208 switch (eax_call.get_property_id())
210 case EAXAGCCOMPRESSOR_NONE:
211 break;
213 case EAXAGCCOMPRESSOR_ALLPARAMETERS:
214 eax_call.set_value<EaxCompressorEffectException>(eax_);
215 break;
217 case EAXAGCCOMPRESSOR_ONOFF:
218 eax_call.set_value<EaxCompressorEffectException>(eax_.ulOnOff);
219 break;
221 default:
222 throw EaxCompressorEffectException{"Unsupported property id."};
225 return false;
228 void EaxCompressorEffect::validate_on_off(
229 unsigned long ulOnOff)
231 eax_validate_range<EaxCompressorEffectException>(
232 "On-Off",
233 ulOnOff,
234 EAXAGCCOMPRESSOR_MINONOFF,
235 EAXAGCCOMPRESSOR_MAXONOFF);
238 void EaxCompressorEffect::validate_all(
239 const EAXAGCCOMPRESSORPROPERTIES& eax_all)
241 validate_on_off(eax_all.ulOnOff);
244 void EaxCompressorEffect::defer_on_off(
245 unsigned long ulOnOff)
247 eax_d_.ulOnOff = ulOnOff;
248 eax_dirty_flags_.ulOnOff = (eax_.ulOnOff != eax_d_.ulOnOff);
251 void EaxCompressorEffect::defer_all(
252 const EAXAGCCOMPRESSORPROPERTIES& eax_all)
254 defer_on_off(eax_all.ulOnOff);
257 void EaxCompressorEffect::defer_on_off(
258 const EaxEaxCall& eax_call)
260 const auto& on_off =
261 eax_call.get_value<EaxCompressorEffectException, const decltype(EAXAGCCOMPRESSORPROPERTIES::ulOnOff)>();
263 validate_on_off(on_off);
264 defer_on_off(on_off);
267 void EaxCompressorEffect::defer_all(
268 const EaxEaxCall& eax_call)
270 const auto& all =
271 eax_call.get_value<EaxCompressorEffectException, const EAXAGCCOMPRESSORPROPERTIES>();
273 validate_all(all);
274 defer_all(all);
277 // [[nodiscard]]
278 bool EaxCompressorEffect::apply_deferred()
280 if (eax_dirty_flags_ == EaxCompressorEffectDirtyFlags{})
282 return false;
285 eax_ = eax_d_;
287 if (eax_dirty_flags_.ulOnOff)
289 set_efx_on_off();
292 eax_dirty_flags_ = EaxCompressorEffectDirtyFlags{};
294 return true;
297 // [[nodiscard]]
298 bool EaxCompressorEffect::set(
299 const EaxEaxCall& eax_call)
301 switch (eax_call.get_property_id())
303 case EAXAGCCOMPRESSOR_NONE:
304 break;
306 case EAXAGCCOMPRESSOR_ALLPARAMETERS:
307 defer_all(eax_call);
308 break;
310 case EAXAGCCOMPRESSOR_ONOFF:
311 defer_on_off(eax_call);
312 break;
314 default:
315 throw EaxCompressorEffectException{"Unsupported property id."};
318 if (!eax_call.is_deferred())
320 return apply_deferred();
323 return false;
326 } // namespace
328 EaxEffectUPtr eax_create_eax_compressor_effect()
330 return std::make_unique<EaxCompressorEffect>();
333 #endif // ALSOFT_EAX