Handle AL effect properties with a variant
[openal-soft.git] / al / effects / reverb.cpp
blob7954e61790f8322e59e988cbc59c2b5f3b9a320c
2 #include "config.h"
4 #include <algorithm>
5 #include <array>
6 #include <cmath>
7 #include <variant>
9 #include "AL/al.h"
10 #include "AL/efx.h"
12 #include "alnumeric.h"
13 #include "alspan.h"
14 #include "core/effects/base.h"
15 #include "effects.h"
17 #ifdef ALSOFT_EAX
18 #include <cassert>
19 #include "al/eax/api.h"
20 #include "al/eax/call.h"
21 #include "al/eax/effect.h"
22 #include "al/eax/exception.h"
23 #include "al/eax/utils.h"
24 #endif // ALSOFT_EAX
27 namespace {
29 constexpr EffectProps genDefaultProps() noexcept
31 ReverbProps props{};
32 props.Density = AL_EAXREVERB_DEFAULT_DENSITY;
33 props.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
34 props.Gain = AL_EAXREVERB_DEFAULT_GAIN;
35 props.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
36 props.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
37 props.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
38 props.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
39 props.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
40 props.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
41 props.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
42 props.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
43 props.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
44 props.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
45 props.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
46 props.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
47 props.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
48 props.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
49 props.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
50 props.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
51 props.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
52 props.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
53 props.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
54 props.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
55 props.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
56 props.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
57 props.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
58 props.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
59 return props;
62 constexpr EffectProps genDefaultStdProps() noexcept
64 ReverbProps props{};
65 props.Density = AL_REVERB_DEFAULT_DENSITY;
66 props.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
67 props.Gain = AL_REVERB_DEFAULT_GAIN;
68 props.GainHF = AL_REVERB_DEFAULT_GAINHF;
69 props.GainLF = 1.0f;
70 props.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
71 props.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
72 props.DecayLFRatio = 1.0f;
73 props.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
74 props.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
75 props.ReflectionsPan = {0.0f, 0.0f, 0.0f};
76 props.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
77 props.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
78 props.LateReverbPan = {0.0f, 0.0f, 0.0f};
79 props.EchoTime = 0.25f;
80 props.EchoDepth = 0.0f;
81 props.ModulationTime = 0.25f;
82 props.ModulationDepth = 0.0f;
83 props.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
84 props.HFReference = 5000.0f;
85 props.LFReference = 250.0f;
86 props.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
87 props.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
88 return props;
91 } // namespace
93 const EffectProps ReverbEffectProps{genDefaultProps()};
95 void ReverbEffectHandler::SetParami(ReverbProps &props, ALenum param, int val)
97 switch(param)
99 case AL_EAXREVERB_DECAY_HFLIMIT:
100 if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT))
101 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
102 props.DecayHFLimit = val != AL_FALSE;
103 break;
105 default:
106 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
107 param};
110 void ReverbEffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
111 { SetParami(props, param, *vals); }
112 void ReverbEffectHandler::SetParamf(ReverbProps &props, ALenum param, float val)
114 switch(param)
116 case AL_EAXREVERB_DENSITY:
117 if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY))
118 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
119 props.Density = val;
120 break;
122 case AL_EAXREVERB_DIFFUSION:
123 if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION))
124 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
125 props.Diffusion = val;
126 break;
128 case AL_EAXREVERB_GAIN:
129 if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN))
130 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
131 props.Gain = val;
132 break;
134 case AL_EAXREVERB_GAINHF:
135 if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF))
136 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
137 props.GainHF = val;
138 break;
140 case AL_EAXREVERB_GAINLF:
141 if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF))
142 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainlf out of range"};
143 props.GainLF = val;
144 break;
146 case AL_EAXREVERB_DECAY_TIME:
147 if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME))
148 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
149 props.DecayTime = val;
150 break;
152 case AL_EAXREVERB_DECAY_HFRATIO:
153 if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO))
154 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
155 props.DecayHFRatio = val;
156 break;
158 case AL_EAXREVERB_DECAY_LFRATIO:
159 if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO))
160 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay lfratio out of range"};
161 props.DecayLFRatio = val;
162 break;
164 case AL_EAXREVERB_REFLECTIONS_GAIN:
165 if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN))
166 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
167 props.ReflectionsGain = val;
168 break;
170 case AL_EAXREVERB_REFLECTIONS_DELAY:
171 if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY))
172 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
173 props.ReflectionsDelay = val;
174 break;
176 case AL_EAXREVERB_LATE_REVERB_GAIN:
177 if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN))
178 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
179 props.LateReverbGain = val;
180 break;
182 case AL_EAXREVERB_LATE_REVERB_DELAY:
183 if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY))
184 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
185 props.LateReverbDelay = val;
186 break;
188 case AL_EAXREVERB_ECHO_TIME:
189 if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME))
190 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo time out of range"};
191 props.EchoTime = val;
192 break;
194 case AL_EAXREVERB_ECHO_DEPTH:
195 if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH))
196 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb echo depth out of range"};
197 props.EchoDepth = val;
198 break;
200 case AL_EAXREVERB_MODULATION_TIME:
201 if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME))
202 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation time out of range"};
203 props.ModulationTime = val;
204 break;
206 case AL_EAXREVERB_MODULATION_DEPTH:
207 if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH))
208 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb modulation depth out of range"};
209 props.ModulationDepth = val;
210 break;
212 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
213 if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF))
214 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
215 props.AirAbsorptionGainHF = val;
216 break;
218 case AL_EAXREVERB_HFREFERENCE:
219 if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE))
220 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb hfreference out of range"};
221 props.HFReference = val;
222 break;
224 case AL_EAXREVERB_LFREFERENCE:
225 if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE))
226 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb lfreference out of range"};
227 props.LFReference = val;
228 break;
230 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
231 if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR))
232 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
233 props.RoomRolloffFactor = val;
234 break;
236 default:
237 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
240 void ReverbEffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals)
242 static constexpr auto finite_checker = [](float f) -> bool { return std::isfinite(f); };
243 al::span<const float> values;
244 switch(param)
246 case AL_EAXREVERB_REFLECTIONS_PAN:
247 values = {vals, 3_uz};
248 if(!std::all_of(values.cbegin(), values.cend(), finite_checker))
249 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections pan out of range"};
250 std::copy(values.cbegin(), values.cend(), props.ReflectionsPan.begin());
251 break;
252 case AL_EAXREVERB_LATE_REVERB_PAN:
253 values = {vals, 3_uz};
254 if(!std::all_of(values.cbegin(), values.cend(), finite_checker))
255 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb pan out of range"};
256 std::copy(values.cbegin(), values.cend(), props.LateReverbPan.begin());
257 break;
259 default:
260 SetParamf(props, param, *vals);
261 break;
265 void ReverbEffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val)
267 switch(param)
269 case AL_EAXREVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; break;
270 default:
271 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
272 param};
275 void ReverbEffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
276 { GetParami(props, param, vals); }
277 void ReverbEffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val)
279 switch(param)
281 case AL_EAXREVERB_DENSITY: *val = props.Density; break;
282 case AL_EAXREVERB_DIFFUSION: *val = props.Diffusion; break;
283 case AL_EAXREVERB_GAIN: *val = props.Gain; break;
284 case AL_EAXREVERB_GAINHF: *val = props.GainHF; break;
285 case AL_EAXREVERB_GAINLF: *val = props.GainLF; break;
286 case AL_EAXREVERB_DECAY_TIME: *val = props.DecayTime; break;
287 case AL_EAXREVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
288 case AL_EAXREVERB_DECAY_LFRATIO: *val = props.DecayLFRatio; break;
289 case AL_EAXREVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
290 case AL_EAXREVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
291 case AL_EAXREVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
292 case AL_EAXREVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
293 case AL_EAXREVERB_ECHO_TIME: *val = props.EchoTime; break;
294 case AL_EAXREVERB_ECHO_DEPTH: *val = props.EchoDepth; break;
295 case AL_EAXREVERB_MODULATION_TIME: *val = props.ModulationTime; break;
296 case AL_EAXREVERB_MODULATION_DEPTH: *val = props.ModulationDepth; break;
297 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
298 case AL_EAXREVERB_HFREFERENCE: *val = props.HFReference; break;
299 case AL_EAXREVERB_LFREFERENCE: *val = props.LFReference; break;
300 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
302 default:
303 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
306 void ReverbEffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals)
308 al::span<float> values;
309 switch(param)
311 case AL_EAXREVERB_REFLECTIONS_PAN:
312 values = {vals, 3_uz};
313 std::copy(props.ReflectionsPan.cbegin(), props.ReflectionsPan.cend(), values.begin());
314 break;
315 case AL_EAXREVERB_LATE_REVERB_PAN:
316 values = {vals, 3_uz};
317 std::copy(props.LateReverbPan.cbegin(), props.LateReverbPan.cend(), values.begin());
318 break;
320 default:
321 GetParamf(props, param, vals);
322 break;
327 const EffectProps StdReverbEffectProps{genDefaultStdProps()};
329 void StdReverbEffectHandler::SetParami(ReverbProps &props, ALenum param, int val)
331 switch(param)
333 case AL_REVERB_DECAY_HFLIMIT:
334 if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT))
335 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hflimit out of range"};
336 props.DecayHFLimit = val != AL_FALSE;
337 break;
339 default:
340 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
341 param};
344 void StdReverbEffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
345 { SetParami(props, param, *vals); }
346 void StdReverbEffectHandler::SetParamf(ReverbProps &props, ALenum param, float val)
348 switch(param)
350 case AL_REVERB_DENSITY:
351 if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY))
352 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb density out of range"};
353 props.Density = val;
354 break;
356 case AL_REVERB_DIFFUSION:
357 if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION))
358 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb diffusion out of range"};
359 props.Diffusion = val;
360 break;
362 case AL_REVERB_GAIN:
363 if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN))
364 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gain out of range"};
365 props.Gain = val;
366 break;
368 case AL_REVERB_GAINHF:
369 if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF))
370 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb gainhf out of range"};
371 props.GainHF = val;
372 break;
374 case AL_REVERB_DECAY_TIME:
375 if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME))
376 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay time out of range"};
377 props.DecayTime = val;
378 break;
380 case AL_REVERB_DECAY_HFRATIO:
381 if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO))
382 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb decay hfratio out of range"};
383 props.DecayHFRatio = val;
384 break;
386 case AL_REVERB_REFLECTIONS_GAIN:
387 if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN))
388 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections gain out of range"};
389 props.ReflectionsGain = val;
390 break;
392 case AL_REVERB_REFLECTIONS_DELAY:
393 if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY))
394 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb reflections delay out of range"};
395 props.ReflectionsDelay = val;
396 break;
398 case AL_REVERB_LATE_REVERB_GAIN:
399 if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN))
400 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb gain out of range"};
401 props.LateReverbGain = val;
402 break;
404 case AL_REVERB_LATE_REVERB_DELAY:
405 if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY))
406 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb late reverb delay out of range"};
407 props.LateReverbDelay = val;
408 break;
410 case AL_REVERB_AIR_ABSORPTION_GAINHF:
411 if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF))
412 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb air absorption gainhf out of range"};
413 props.AirAbsorptionGainHF = val;
414 break;
416 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
417 if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR))
418 throw effect_exception{AL_INVALID_VALUE, "EAX Reverb room rolloff factor out of range"};
419 props.RoomRolloffFactor = val;
420 break;
422 default:
423 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
426 void StdReverbEffectHandler::SetParamfv(ReverbProps &props, ALenum param, const float *vals)
427 { SetParamf(props, param, *vals); }
429 void StdReverbEffectHandler::GetParami(const ReverbProps &props, ALenum param, int *val)
431 switch(param)
433 case AL_REVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; break;
434 default:
435 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
436 param};
439 void StdReverbEffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
440 { GetParami(props, param, vals); }
441 void StdReverbEffectHandler::GetParamf(const ReverbProps &props, ALenum param, float *val)
443 switch(param)
445 case AL_REVERB_DENSITY: *val = props.Density; break;
446 case AL_REVERB_DIFFUSION: *val = props.Diffusion; break;
447 case AL_REVERB_GAIN: *val = props.Gain; break;
448 case AL_REVERB_GAINHF: *val = props.GainHF; break;
449 case AL_REVERB_DECAY_TIME: *val = props.DecayTime; break;
450 case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
451 case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
452 case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
453 case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
454 case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
455 case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
456 case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
458 default:
459 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
462 void StdReverbEffectHandler::GetParamfv(const ReverbProps &props, ALenum param, float *vals)
463 { GetParamf(props, param, vals); }
466 #ifdef ALSOFT_EAX
467 namespace {
469 class EaxReverbEffectException : public EaxException
471 public:
472 explicit EaxReverbEffectException(const char* message)
473 : EaxException{"EAX_REVERB_EFFECT", message}
475 }; // EaxReverbEffectException
477 struct EnvironmentValidator1 {
478 void operator()(unsigned long ulEnvironment) const
480 eax_validate_range<EaxReverbEffectException>(
481 "Environment",
482 ulEnvironment,
483 EAXREVERB_MINENVIRONMENT,
484 EAX1REVERB_MAXENVIRONMENT);
486 }; // EnvironmentValidator1
488 struct VolumeValidator {
489 void operator()(float volume) const
491 eax_validate_range<EaxReverbEffectException>(
492 "Volume",
493 volume,
494 EAX1REVERB_MINVOLUME,
495 EAX1REVERB_MAXVOLUME);
497 }; // VolumeValidator
499 struct DecayTimeValidator {
500 void operator()(float flDecayTime) const
502 eax_validate_range<EaxReverbEffectException>(
503 "Decay Time",
504 flDecayTime,
505 EAXREVERB_MINDECAYTIME,
506 EAXREVERB_MAXDECAYTIME);
508 }; // DecayTimeValidator
510 struct DampingValidator {
511 void operator()(float damping) const
513 eax_validate_range<EaxReverbEffectException>(
514 "Damping",
515 damping,
516 EAX1REVERB_MINDAMPING,
517 EAX1REVERB_MAXDAMPING);
519 }; // DampingValidator
521 struct AllValidator1 {
522 void operator()(const EAX_REVERBPROPERTIES& all) const
524 EnvironmentValidator1{}(all.environment);
525 VolumeValidator{}(all.fVolume);
526 DecayTimeValidator{}(all.fDecayTime_sec);
527 DampingValidator{}(all.fDamping);
529 }; // AllValidator1
531 struct RoomValidator {
532 void operator()(long lRoom) const
534 eax_validate_range<EaxReverbEffectException>(
535 "Room",
536 lRoom,
537 EAXREVERB_MINROOM,
538 EAXREVERB_MAXROOM);
540 }; // RoomValidator
542 struct RoomHFValidator {
543 void operator()(long lRoomHF) const
545 eax_validate_range<EaxReverbEffectException>(
546 "Room HF",
547 lRoomHF,
548 EAXREVERB_MINROOMHF,
549 EAXREVERB_MAXROOMHF);
551 }; // RoomHFValidator
553 struct RoomRolloffFactorValidator {
554 void operator()(float flRoomRolloffFactor) const
556 eax_validate_range<EaxReverbEffectException>(
557 "Room Rolloff Factor",
558 flRoomRolloffFactor,
559 EAXREVERB_MINROOMROLLOFFFACTOR,
560 EAXREVERB_MAXROOMROLLOFFFACTOR);
562 }; // RoomRolloffFactorValidator
564 struct DecayHFRatioValidator {
565 void operator()(float flDecayHFRatio) const
567 eax_validate_range<EaxReverbEffectException>(
568 "Decay HF Ratio",
569 flDecayHFRatio,
570 EAXREVERB_MINDECAYHFRATIO,
571 EAXREVERB_MAXDECAYHFRATIO);
573 }; // DecayHFRatioValidator
575 struct ReflectionsValidator {
576 void operator()(long lReflections) const
578 eax_validate_range<EaxReverbEffectException>(
579 "Reflections",
580 lReflections,
581 EAXREVERB_MINREFLECTIONS,
582 EAXREVERB_MAXREFLECTIONS);
584 }; // ReflectionsValidator
586 struct ReflectionsDelayValidator {
587 void operator()(float flReflectionsDelay) const
589 eax_validate_range<EaxReverbEffectException>(
590 "Reflections Delay",
591 flReflectionsDelay,
592 EAXREVERB_MINREFLECTIONSDELAY,
593 EAXREVERB_MAXREFLECTIONSDELAY);
595 }; // ReflectionsDelayValidator
597 struct ReverbValidator {
598 void operator()(long lReverb) const
600 eax_validate_range<EaxReverbEffectException>(
601 "Reverb",
602 lReverb,
603 EAXREVERB_MINREVERB,
604 EAXREVERB_MAXREVERB);
606 }; // ReverbValidator
608 struct ReverbDelayValidator {
609 void operator()(float flReverbDelay) const
611 eax_validate_range<EaxReverbEffectException>(
612 "Reverb Delay",
613 flReverbDelay,
614 EAXREVERB_MINREVERBDELAY,
615 EAXREVERB_MAXREVERBDELAY);
617 }; // ReverbDelayValidator
619 struct EnvironmentSizeValidator {
620 void operator()(float flEnvironmentSize) const
622 eax_validate_range<EaxReverbEffectException>(
623 "Environment Size",
624 flEnvironmentSize,
625 EAXREVERB_MINENVIRONMENTSIZE,
626 EAXREVERB_MAXENVIRONMENTSIZE);
628 }; // EnvironmentSizeValidator
630 struct EnvironmentDiffusionValidator {
631 void operator()(float flEnvironmentDiffusion) const
633 eax_validate_range<EaxReverbEffectException>(
634 "Environment Diffusion",
635 flEnvironmentDiffusion,
636 EAXREVERB_MINENVIRONMENTDIFFUSION,
637 EAXREVERB_MAXENVIRONMENTDIFFUSION);
639 }; // EnvironmentDiffusionValidator
641 struct AirAbsorptionHFValidator {
642 void operator()(float flAirAbsorptionHF) const
644 eax_validate_range<EaxReverbEffectException>(
645 "Air Absorbtion HF",
646 flAirAbsorptionHF,
647 EAXREVERB_MINAIRABSORPTIONHF,
648 EAXREVERB_MAXAIRABSORPTIONHF);
650 }; // AirAbsorptionHFValidator
652 struct FlagsValidator2 {
653 void operator()(unsigned long ulFlags) const
655 eax_validate_range<EaxReverbEffectException>(
656 "Flags",
657 ulFlags,
658 0UL,
659 ~EAX2LISTENERFLAGS_RESERVED);
661 }; // FlagsValidator2
663 struct AllValidator2 {
664 void operator()(const EAX20LISTENERPROPERTIES& all) const
666 RoomValidator{}(all.lRoom);
667 RoomHFValidator{}(all.lRoomHF);
668 RoomRolloffFactorValidator{}(all.flRoomRolloffFactor);
669 DecayTimeValidator{}(all.flDecayTime);
670 DecayHFRatioValidator{}(all.flDecayHFRatio);
671 ReflectionsValidator{}(all.lReflections);
672 ReflectionsDelayValidator{}(all.flReflectionsDelay);
673 ReverbValidator{}(all.lReverb);
674 ReverbDelayValidator{}(all.flReverbDelay);
675 EnvironmentValidator1{}(all.dwEnvironment);
676 EnvironmentSizeValidator{}(all.flEnvironmentSize);
677 EnvironmentDiffusionValidator{}(all.flEnvironmentDiffusion);
678 AirAbsorptionHFValidator{}(all.flAirAbsorptionHF);
679 FlagsValidator2{}(all.dwFlags);
681 }; // AllValidator2
683 struct EnvironmentValidator3 {
684 void operator()(unsigned long ulEnvironment) const
686 eax_validate_range<EaxReverbEffectException>(
687 "Environment",
688 ulEnvironment,
689 EAXREVERB_MINENVIRONMENT,
690 EAX30REVERB_MAXENVIRONMENT);
692 }; // EnvironmentValidator1
694 struct RoomLFValidator {
695 void operator()(long lRoomLF) const
697 eax_validate_range<EaxReverbEffectException>(
698 "Room LF",
699 lRoomLF,
700 EAXREVERB_MINROOMLF,
701 EAXREVERB_MAXROOMLF);
703 }; // RoomLFValidator
705 struct DecayLFRatioValidator {
706 void operator()(float flDecayLFRatio) const
708 eax_validate_range<EaxReverbEffectException>(
709 "Decay LF Ratio",
710 flDecayLFRatio,
711 EAXREVERB_MINDECAYLFRATIO,
712 EAXREVERB_MAXDECAYLFRATIO);
714 }; // DecayLFRatioValidator
716 struct VectorValidator {
717 void operator()(const EAXVECTOR&) const
719 }; // VectorValidator
721 struct EchoTimeValidator {
722 void operator()(float flEchoTime) const
724 eax_validate_range<EaxReverbEffectException>(
725 "Echo Time",
726 flEchoTime,
727 EAXREVERB_MINECHOTIME,
728 EAXREVERB_MAXECHOTIME);
730 }; // EchoTimeValidator
732 struct EchoDepthValidator {
733 void operator()(float flEchoDepth) const
735 eax_validate_range<EaxReverbEffectException>(
736 "Echo Depth",
737 flEchoDepth,
738 EAXREVERB_MINECHODEPTH,
739 EAXREVERB_MAXECHODEPTH);
741 }; // EchoDepthValidator
743 struct ModulationTimeValidator {
744 void operator()(float flModulationTime) const
746 eax_validate_range<EaxReverbEffectException>(
747 "Modulation Time",
748 flModulationTime,
749 EAXREVERB_MINMODULATIONTIME,
750 EAXREVERB_MAXMODULATIONTIME);
752 }; // ModulationTimeValidator
754 struct ModulationDepthValidator {
755 void operator()(float flModulationDepth) const
757 eax_validate_range<EaxReverbEffectException>(
758 "Modulation Depth",
759 flModulationDepth,
760 EAXREVERB_MINMODULATIONDEPTH,
761 EAXREVERB_MAXMODULATIONDEPTH);
763 }; // ModulationDepthValidator
765 struct HFReferenceValidator {
766 void operator()(float flHFReference) const
768 eax_validate_range<EaxReverbEffectException>(
769 "HF Reference",
770 flHFReference,
771 EAXREVERB_MINHFREFERENCE,
772 EAXREVERB_MAXHFREFERENCE);
774 }; // HFReferenceValidator
776 struct LFReferenceValidator {
777 void operator()(float flLFReference) const
779 eax_validate_range<EaxReverbEffectException>(
780 "LF Reference",
781 flLFReference,
782 EAXREVERB_MINLFREFERENCE,
783 EAXREVERB_MAXLFREFERENCE);
785 }; // LFReferenceValidator
787 struct FlagsValidator3 {
788 void operator()(unsigned long ulFlags) const
790 eax_validate_range<EaxReverbEffectException>(
791 "Flags",
792 ulFlags,
793 0UL,
794 ~EAXREVERBFLAGS_RESERVED);
796 }; // FlagsValidator3
798 struct AllValidator3 {
799 void operator()(const EAXREVERBPROPERTIES& all) const
801 EnvironmentValidator3{}(all.ulEnvironment);
802 EnvironmentSizeValidator{}(all.flEnvironmentSize);
803 EnvironmentDiffusionValidator{}(all.flEnvironmentDiffusion);
804 RoomValidator{}(all.lRoom);
805 RoomHFValidator{}(all.lRoomHF);
806 RoomLFValidator{}(all.lRoomLF);
807 DecayTimeValidator{}(all.flDecayTime);
808 DecayHFRatioValidator{}(all.flDecayHFRatio);
809 DecayLFRatioValidator{}(all.flDecayLFRatio);
810 ReflectionsValidator{}(all.lReflections);
811 ReflectionsDelayValidator{}(all.flReflectionsDelay);
812 VectorValidator{}(all.vReflectionsPan);
813 ReverbValidator{}(all.lReverb);
814 ReverbDelayValidator{}(all.flReverbDelay);
815 VectorValidator{}(all.vReverbPan);
816 EchoTimeValidator{}(all.flEchoTime);
817 EchoDepthValidator{}(all.flEchoDepth);
818 ModulationTimeValidator{}(all.flModulationTime);
819 ModulationDepthValidator{}(all.flModulationDepth);
820 AirAbsorptionHFValidator{}(all.flAirAbsorptionHF);
821 HFReferenceValidator{}(all.flHFReference);
822 LFReferenceValidator{}(all.flLFReference);
823 RoomRolloffFactorValidator{}(all.flRoomRolloffFactor);
824 FlagsValidator3{}(all.ulFlags);
826 }; // AllValidator3
828 struct EnvironmentDeferrer2 {
829 void operator()(EAX20LISTENERPROPERTIES& props, unsigned long dwEnvironment) const
831 props = EAX2REVERB_PRESETS[dwEnvironment];
833 }; // EnvironmentDeferrer2
835 struct EnvironmentSizeDeferrer2 {
836 void operator()(EAX20LISTENERPROPERTIES& props, float flEnvironmentSize) const
838 if (props.flEnvironmentSize == flEnvironmentSize)
840 return;
843 const auto scale = flEnvironmentSize / props.flEnvironmentSize;
844 props.flEnvironmentSize = flEnvironmentSize;
846 if ((props.dwFlags & EAX2LISTENERFLAGS_DECAYTIMESCALE) != 0)
848 props.flDecayTime = std::clamp(
849 props.flDecayTime * scale,
850 EAXREVERB_MINDECAYTIME,
851 EAXREVERB_MAXDECAYTIME);
854 if ((props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSSCALE) != 0 &&
855 (props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSDELAYSCALE) != 0)
857 props.lReflections = std::clamp(
858 props.lReflections - static_cast<long>(gain_to_level_mb(scale)),
859 EAXREVERB_MINREFLECTIONS,
860 EAXREVERB_MAXREFLECTIONS);
863 if ((props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSDELAYSCALE) != 0)
865 props.flReflectionsDelay = std::clamp(
866 props.flReflectionsDelay * scale,
867 EAXREVERB_MINREFLECTIONSDELAY,
868 EAXREVERB_MAXREFLECTIONSDELAY);
871 if ((props.dwFlags & EAX2LISTENERFLAGS_REVERBSCALE) != 0)
873 const auto log_scalar = ((props.dwFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0) ? 2'000.0F : 3'000.0F;
875 props.lReverb = std::clamp(
876 props.lReverb - static_cast<long>(std::log10(scale) * log_scalar),
877 EAXREVERB_MINREVERB,
878 EAXREVERB_MAXREVERB);
881 if ((props.dwFlags & EAX2LISTENERFLAGS_REVERBDELAYSCALE) != 0)
883 props.flReverbDelay = std::clamp(
884 props.flReverbDelay * scale,
885 EAXREVERB_MINREVERBDELAY,
886 EAXREVERB_MAXREVERBDELAY);
889 }; // EnvironmentSizeDeferrer2
891 struct EnvironmentDeferrer3 {
892 void operator()(EAXREVERBPROPERTIES& props, unsigned long ulEnvironment) const
894 if (ulEnvironment == EAX_ENVIRONMENT_UNDEFINED)
896 props.ulEnvironment = EAX_ENVIRONMENT_UNDEFINED;
897 return;
900 props = EAXREVERB_PRESETS[ulEnvironment];
902 }; // EnvironmentDeferrer3
904 struct EnvironmentSizeDeferrer3 {
905 void operator()(EAXREVERBPROPERTIES& props, float flEnvironmentSize) const
907 if (props.flEnvironmentSize == flEnvironmentSize)
909 return;
912 const auto scale = flEnvironmentSize / props.flEnvironmentSize;
913 props.ulEnvironment = EAX_ENVIRONMENT_UNDEFINED;
914 props.flEnvironmentSize = flEnvironmentSize;
916 if ((props.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0)
918 props.flDecayTime = std::clamp(
919 props.flDecayTime * scale,
920 EAXREVERB_MINDECAYTIME,
921 EAXREVERB_MAXDECAYTIME);
924 if ((props.ulFlags & EAXREVERBFLAGS_REFLECTIONSSCALE) != 0 &&
925 (props.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
927 props.lReflections = std::clamp(
928 props.lReflections - static_cast<long>(gain_to_level_mb(scale)),
929 EAXREVERB_MINREFLECTIONS,
930 EAXREVERB_MAXREFLECTIONS);
933 if ((props.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
935 props.flReflectionsDelay = std::clamp(
936 props.flReflectionsDelay * scale,
937 EAXREVERB_MINREFLECTIONSDELAY,
938 EAXREVERB_MAXREFLECTIONSDELAY);
941 if ((props.ulFlags & EAXREVERBFLAGS_REVERBSCALE) != 0)
943 const auto log_scalar = ((props.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0) ? 2'000.0F : 3'000.0F;
944 props.lReverb = std::clamp(
945 props.lReverb - static_cast<long>(std::log10(scale) * log_scalar),
946 EAXREVERB_MINREVERB,
947 EAXREVERB_MAXREVERB);
950 if ((props.ulFlags & EAXREVERBFLAGS_REVERBDELAYSCALE) != 0)
952 props.flReverbDelay = std::clamp(
953 props.flReverbDelay * scale,
954 EAXREVERB_MINREVERBDELAY,
955 EAXREVERB_MAXREVERBDELAY);
958 if ((props.ulFlags & EAXREVERBFLAGS_ECHOTIMESCALE) != 0)
960 props.flEchoTime = std::clamp(
961 props.flEchoTime * scale,
962 EAXREVERB_MINECHOTIME,
963 EAXREVERB_MAXECHOTIME);
966 if ((props.ulFlags & EAXREVERBFLAGS_MODULATIONTIMESCALE) != 0)
968 props.flModulationTime = std::clamp(
969 props.flModulationTime * scale,
970 EAXREVERB_MINMODULATIONTIME,
971 EAXREVERB_MAXMODULATIONTIME);
974 }; // EnvironmentSizeDeferrer3
976 } // namespace
979 struct EaxReverbCommitter::Exception : public EaxReverbEffectException
981 using EaxReverbEffectException::EaxReverbEffectException;
984 [[noreturn]] void EaxReverbCommitter::fail(const char* message)
986 throw Exception{message};
989 void EaxReverbCommitter::translate(const EAX_REVERBPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
991 assert(src.environment <= EAX1REVERB_MAXENVIRONMENT);
992 dst = EAXREVERB_PRESETS[src.environment];
993 dst.flDecayTime = src.fDecayTime_sec;
994 dst.flDecayHFRatio = src.fDamping;
995 dst.lReverb = static_cast<int>(std::min(gain_to_level_mb(src.fVolume), 0.0f));
998 void EaxReverbCommitter::translate(const EAX20LISTENERPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
1000 assert(src.dwEnvironment <= EAX1REVERB_MAXENVIRONMENT);
1001 dst = EAXREVERB_PRESETS[src.dwEnvironment];
1002 dst.ulEnvironment = src.dwEnvironment;
1003 dst.flEnvironmentSize = src.flEnvironmentSize;
1004 dst.flEnvironmentDiffusion = src.flEnvironmentDiffusion;
1005 dst.lRoom = src.lRoom;
1006 dst.lRoomHF = src.lRoomHF;
1007 dst.flDecayTime = src.flDecayTime;
1008 dst.flDecayHFRatio = src.flDecayHFRatio;
1009 dst.lReflections = src.lReflections;
1010 dst.flReflectionsDelay = src.flReflectionsDelay;
1011 dst.lReverb = src.lReverb;
1012 dst.flReverbDelay = src.flReverbDelay;
1013 dst.flAirAbsorptionHF = src.flAirAbsorptionHF;
1014 dst.flRoomRolloffFactor = src.flRoomRolloffFactor;
1015 dst.ulFlags = src.dwFlags;
1018 bool EaxReverbCommitter::commit(const EAX_REVERBPROPERTIES &props)
1020 EAXREVERBPROPERTIES dst{};
1021 translate(props, dst);
1022 return commit(dst);
1025 bool EaxReverbCommitter::commit(const EAX20LISTENERPROPERTIES &props)
1027 EAXREVERBPROPERTIES dst{};
1028 translate(props, dst);
1029 return commit(dst);
1032 bool EaxReverbCommitter::commit(const EAXREVERBPROPERTIES &props)
1034 if(auto *cur = std::get_if<EAXREVERBPROPERTIES>(&mEaxProps); cur && *cur == props)
1035 return false;
1037 mEaxProps = props;
1039 const auto size = props.flEnvironmentSize;
1040 const auto density = (size * size * size) / 16.0f;
1041 mAlProps = [&]{
1042 ReverbProps ret{};
1043 ret.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY);
1044 ret.Diffusion = props.flEnvironmentDiffusion;
1045 ret.Gain = level_mb_to_gain(static_cast<float>(props.lRoom));
1046 ret.GainHF = level_mb_to_gain(static_cast<float>(props.lRoomHF));
1047 ret.GainLF = level_mb_to_gain(static_cast<float>(props.lRoomLF));
1048 ret.DecayTime = props.flDecayTime;
1049 ret.DecayHFRatio = props.flDecayHFRatio;
1050 ret.DecayLFRatio = props.flDecayLFRatio;
1051 ret.ReflectionsGain = level_mb_to_gain(static_cast<float>(props.lReflections));
1052 ret.ReflectionsDelay = props.flReflectionsDelay;
1053 ret.ReflectionsPan = {props.vReflectionsPan.x, props.vReflectionsPan.y,
1054 props.vReflectionsPan.z};
1055 ret.LateReverbGain = level_mb_to_gain(static_cast<float>(props.lReverb));
1056 ret.LateReverbDelay = props.flReverbDelay;
1057 ret.LateReverbPan = {props.vReverbPan.x, props.vReverbPan.y, props.vReverbPan.z};
1058 ret.EchoTime = props.flEchoTime;
1059 ret.EchoDepth = props.flEchoDepth;
1060 ret.ModulationTime = props.flModulationTime;
1061 ret.ModulationDepth = props.flModulationDepth;
1062 ret.AirAbsorptionGainHF = level_mb_to_gain(props.flAirAbsorptionHF);
1063 ret.HFReference = props.flHFReference;
1064 ret.LFReference = props.flLFReference;
1065 ret.RoomRolloffFactor = props.flRoomRolloffFactor;
1066 ret.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
1067 return ret;
1068 }();
1070 return true;
1073 void EaxReverbCommitter::SetDefaults(EAX_REVERBPROPERTIES &props)
1075 props = EAX1REVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
1078 void EaxReverbCommitter::SetDefaults(EAX20LISTENERPROPERTIES &props)
1080 props = EAX2REVERB_PRESETS[EAX2_ENVIRONMENT_GENERIC];
1081 props.lRoom = -10'000L;
1084 void EaxReverbCommitter::SetDefaults(EAXREVERBPROPERTIES &props)
1086 props = EAXREVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
1089 void EaxReverbCommitter::SetDefaults(EaxEffectProps &props)
1091 SetDefaults(props.emplace<EAXREVERBPROPERTIES>());
1095 void EaxReverbCommitter::Get(const EaxCall &call, const EAX_REVERBPROPERTIES &props)
1097 switch(call.get_property_id())
1099 case DSPROPERTY_EAX_ALL: call.set_value<Exception>(props); break;
1100 case DSPROPERTY_EAX_ENVIRONMENT: call.set_value<Exception>(props.environment); break;
1101 case DSPROPERTY_EAX_VOLUME: call.set_value<Exception>(props.fVolume); break;
1102 case DSPROPERTY_EAX_DECAYTIME: call.set_value<Exception>(props.fDecayTime_sec); break;
1103 case DSPROPERTY_EAX_DAMPING: call.set_value<Exception>(props.fDamping); break;
1104 default: fail_unknown_property_id();
1108 void EaxReverbCommitter::Get(const EaxCall &call, const EAX20LISTENERPROPERTIES &props)
1110 switch(call.get_property_id())
1112 case DSPROPERTY_EAX20LISTENER_NONE: break;
1113 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS: call.set_value<Exception>(props); break;
1114 case DSPROPERTY_EAX20LISTENER_ROOM: call.set_value<Exception>(props.lRoom); break;
1115 case DSPROPERTY_EAX20LISTENER_ROOMHF: call.set_value<Exception>(props.lRoomHF); break;
1116 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR: call.set_value<Exception>(props.flRoomRolloffFactor); break;
1117 case DSPROPERTY_EAX20LISTENER_DECAYTIME: call.set_value<Exception>(props.flDecayTime); break;
1118 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO: call.set_value<Exception>(props.flDecayHFRatio); break;
1119 case DSPROPERTY_EAX20LISTENER_REFLECTIONS: call.set_value<Exception>(props.lReflections); break;
1120 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY: call.set_value<Exception>(props.flReflectionsDelay); break;
1121 case DSPROPERTY_EAX20LISTENER_REVERB: call.set_value<Exception>(props.lReverb); break;
1122 case DSPROPERTY_EAX20LISTENER_REVERBDELAY: call.set_value<Exception>(props.flReverbDelay); break;
1123 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT: call.set_value<Exception>(props.dwEnvironment); break;
1124 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE: call.set_value<Exception>(props.flEnvironmentSize); break;
1125 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION: call.set_value<Exception>(props.flEnvironmentDiffusion); break;
1126 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF: call.set_value<Exception>(props.flAirAbsorptionHF); break;
1127 case DSPROPERTY_EAX20LISTENER_FLAGS: call.set_value<Exception>(props.dwFlags); break;
1128 default: fail_unknown_property_id();
1132 void EaxReverbCommitter::Get(const EaxCall &call, const EAXREVERBPROPERTIES &props)
1134 switch(call.get_property_id())
1136 case EAXREVERB_NONE: break;
1137 case EAXREVERB_ALLPARAMETERS: call.set_value<Exception>(props); break;
1138 case EAXREVERB_ENVIRONMENT: call.set_value<Exception>(props.ulEnvironment); break;
1139 case EAXREVERB_ENVIRONMENTSIZE: call.set_value<Exception>(props.flEnvironmentSize); break;
1140 case EAXREVERB_ENVIRONMENTDIFFUSION: call.set_value<Exception>(props.flEnvironmentDiffusion); break;
1141 case EAXREVERB_ROOM: call.set_value<Exception>(props.lRoom); break;
1142 case EAXREVERB_ROOMHF: call.set_value<Exception>(props.lRoomHF); break;
1143 case EAXREVERB_ROOMLF: call.set_value<Exception>(props.lRoomLF); break;
1144 case EAXREVERB_DECAYTIME: call.set_value<Exception>(props.flDecayTime); break;
1145 case EAXREVERB_DECAYHFRATIO: call.set_value<Exception>(props.flDecayHFRatio); break;
1146 case EAXREVERB_DECAYLFRATIO: call.set_value<Exception>(props.flDecayLFRatio); break;
1147 case EAXREVERB_REFLECTIONS: call.set_value<Exception>(props.lReflections); break;
1148 case EAXREVERB_REFLECTIONSDELAY: call.set_value<Exception>(props.flReflectionsDelay); break;
1149 case EAXREVERB_REFLECTIONSPAN: call.set_value<Exception>(props.vReflectionsPan); break;
1150 case EAXREVERB_REVERB: call.set_value<Exception>(props.lReverb); break;
1151 case EAXREVERB_REVERBDELAY: call.set_value<Exception>(props.flReverbDelay); break;
1152 case EAXREVERB_REVERBPAN: call.set_value<Exception>(props.vReverbPan); break;
1153 case EAXREVERB_ECHOTIME: call.set_value<Exception>(props.flEchoTime); break;
1154 case EAXREVERB_ECHODEPTH: call.set_value<Exception>(props.flEchoDepth); break;
1155 case EAXREVERB_MODULATIONTIME: call.set_value<Exception>(props.flModulationTime); break;
1156 case EAXREVERB_MODULATIONDEPTH: call.set_value<Exception>(props.flModulationDepth); break;
1157 case EAXREVERB_AIRABSORPTIONHF: call.set_value<Exception>(props.flAirAbsorptionHF); break;
1158 case EAXREVERB_HFREFERENCE: call.set_value<Exception>(props.flHFReference); break;
1159 case EAXREVERB_LFREFERENCE: call.set_value<Exception>(props.flLFReference); break;
1160 case EAXREVERB_ROOMROLLOFFFACTOR: call.set_value<Exception>(props.flRoomRolloffFactor); break;
1161 case EAXREVERB_FLAGS: call.set_value<Exception>(props.ulFlags); break;
1162 default: fail_unknown_property_id();
1167 void EaxReverbCommitter::Set(const EaxCall &call, EAX_REVERBPROPERTIES &props)
1169 switch(call.get_property_id())
1171 case DSPROPERTY_EAX_ALL: defer<AllValidator1>(call, props); break;
1172 case DSPROPERTY_EAX_ENVIRONMENT: defer<EnvironmentValidator1>(call, props.environment); break;
1173 case DSPROPERTY_EAX_VOLUME: defer<VolumeValidator>(call, props.fVolume); break;
1174 case DSPROPERTY_EAX_DECAYTIME: defer<DecayTimeValidator>(call, props.fDecayTime_sec); break;
1175 case DSPROPERTY_EAX_DAMPING: defer<DampingValidator>(call, props.fDamping); break;
1176 default: fail_unknown_property_id();
1180 void EaxReverbCommitter::Set(const EaxCall &call, EAX20LISTENERPROPERTIES &props)
1182 switch(call.get_property_id())
1184 case DSPROPERTY_EAX20LISTENER_NONE: break;
1185 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS: defer<AllValidator2>(call, props); break;
1186 case DSPROPERTY_EAX20LISTENER_ROOM: defer<RoomValidator>(call, props.lRoom); break;
1187 case DSPROPERTY_EAX20LISTENER_ROOMHF: defer<RoomHFValidator>(call, props.lRoomHF); break;
1188 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR: defer<RoomRolloffFactorValidator>(call, props.flRoomRolloffFactor); break;
1189 case DSPROPERTY_EAX20LISTENER_DECAYTIME: defer<DecayTimeValidator>(call, props.flDecayTime); break;
1190 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO: defer<DecayHFRatioValidator>(call, props.flDecayHFRatio); break;
1191 case DSPROPERTY_EAX20LISTENER_REFLECTIONS: defer<ReflectionsValidator>(call, props.lReflections); break;
1192 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY: defer<ReflectionsDelayValidator>(call, props.flReverbDelay); break;
1193 case DSPROPERTY_EAX20LISTENER_REVERB: defer<ReverbValidator>(call, props.lReverb); break;
1194 case DSPROPERTY_EAX20LISTENER_REVERBDELAY: defer<ReverbDelayValidator>(call, props.flReverbDelay); break;
1195 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT: defer<EnvironmentValidator1, EnvironmentDeferrer2>(call, props, props.dwEnvironment); break;
1196 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer2>(call, props, props.flEnvironmentSize); break;
1197 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION: defer<EnvironmentDiffusionValidator>(call, props.flEnvironmentDiffusion); break;
1198 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF: defer<AirAbsorptionHFValidator>(call, props.flAirAbsorptionHF); break;
1199 case DSPROPERTY_EAX20LISTENER_FLAGS: defer<FlagsValidator2>(call, props.dwFlags); break;
1200 default: fail_unknown_property_id();
1204 void EaxReverbCommitter::Set(const EaxCall &call, EAXREVERBPROPERTIES &props)
1206 switch(call.get_property_id())
1208 case EAXREVERB_NONE: break;
1209 case EAXREVERB_ALLPARAMETERS: defer<AllValidator3>(call, props); break;
1210 case EAXREVERB_ENVIRONMENT: defer<EnvironmentValidator3, EnvironmentDeferrer3>(call, props, props.ulEnvironment); break;
1211 case EAXREVERB_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer3>(call, props, props.flEnvironmentSize); break;
1212 case EAXREVERB_ENVIRONMENTDIFFUSION: defer3<EnvironmentDiffusionValidator>(call, props, props.flEnvironmentDiffusion); break;
1213 case EAXREVERB_ROOM: defer3<RoomValidator>(call, props, props.lRoom); break;
1214 case EAXREVERB_ROOMHF: defer3<RoomHFValidator>(call, props, props.lRoomHF); break;
1215 case EAXREVERB_ROOMLF: defer3<RoomLFValidator>(call, props, props.lRoomLF); break;
1216 case EAXREVERB_DECAYTIME: defer3<DecayTimeValidator>(call, props, props.flDecayTime); break;
1217 case EAXREVERB_DECAYHFRATIO: defer3<DecayHFRatioValidator>(call, props, props.flDecayHFRatio); break;
1218 case EAXREVERB_DECAYLFRATIO: defer3<DecayLFRatioValidator>(call, props, props.flDecayLFRatio); break;
1219 case EAXREVERB_REFLECTIONS: defer3<ReflectionsValidator>(call, props, props.lReflections); break;
1220 case EAXREVERB_REFLECTIONSDELAY: defer3<ReflectionsDelayValidator>(call, props, props.flReflectionsDelay); break;
1221 case EAXREVERB_REFLECTIONSPAN: defer3<VectorValidator>(call, props, props.vReflectionsPan); break;
1222 case EAXREVERB_REVERB: defer3<ReverbValidator>(call, props, props.lReverb); break;
1223 case EAXREVERB_REVERBDELAY: defer3<ReverbDelayValidator>(call, props, props.flReverbDelay); break;
1224 case EAXREVERB_REVERBPAN: defer3<VectorValidator>(call, props, props.vReverbPan); break;
1225 case EAXREVERB_ECHOTIME: defer3<EchoTimeValidator>(call, props, props.flEchoTime); break;
1226 case EAXREVERB_ECHODEPTH: defer3<EchoDepthValidator>(call, props, props.flEchoDepth); break;
1227 case EAXREVERB_MODULATIONTIME: defer3<ModulationTimeValidator>(call, props, props.flModulationTime); break;
1228 case EAXREVERB_MODULATIONDEPTH: defer3<ModulationDepthValidator>(call, props, props.flModulationDepth); break;
1229 case EAXREVERB_AIRABSORPTIONHF: defer3<AirAbsorptionHFValidator>(call, props, props.flAirAbsorptionHF); break;
1230 case EAXREVERB_HFREFERENCE: defer3<HFReferenceValidator>(call, props, props.flHFReference); break;
1231 case EAXREVERB_LFREFERENCE: defer3<LFReferenceValidator>(call, props, props.flLFReference); break;
1232 case EAXREVERB_ROOMROLLOFFFACTOR: defer3<RoomRolloffFactorValidator>(call, props, props.flRoomRolloffFactor); break;
1233 case EAXREVERB_FLAGS: defer3<FlagsValidator3>(call, props, props.ulFlags); break;
1234 default: fail_unknown_property_id();
1238 #endif // ALSOFT_EAX