Avoid some pointer arithmetic
[openal-soft.git] / al / effects / reverb.cpp
blob223dd017b9bdf21e9551b2ccb1878a5faee841b1
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 "alspan.h"
13 #include "core/effects/base.h"
14 #include "effects.h"
16 #ifdef ALSOFT_EAX
17 #include <cassert>
18 #include "alnumeric.h"
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 EffectHandler::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 EffectHandler::SetParamiv(ReverbProps &props, ALenum param, const int *vals)
111 { SetParami(props, param, *vals); }
112 void EffectHandler::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 EffectHandler::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 EffectHandler::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 EffectHandler::GetParamiv(const ReverbProps &props, ALenum param, int *vals)
276 { GetParami(props, param, vals); }
277 void EffectHandler::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 EffectHandler::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 EffectHandler::StdReverbSetParami(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 EffectHandler::StdReverbSetParamiv(ReverbProps &props, ALenum param, const int *vals)
345 { StdReverbSetParami(props, param, *vals); }
346 void EffectHandler::StdReverbSetParamf(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 EffectHandler::StdReverbSetParamfv(ReverbProps &props, ALenum param, const float *vals)
428 switch(param)
430 default:
431 StdReverbSetParamf(props, param, *vals);
432 break;
436 void EffectHandler::StdReverbGetParami(const ReverbProps &props, ALenum param, int *val)
438 switch(param)
440 case AL_REVERB_DECAY_HFLIMIT: *val = props.DecayHFLimit; break;
441 default:
442 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x",
443 param};
446 void EffectHandler::StdReverbGetParamiv(const ReverbProps &props, ALenum param, int *vals)
447 { StdReverbGetParami(props, param, vals); }
448 void EffectHandler::StdReverbGetParamf(const ReverbProps &props, ALenum param, float *val)
450 switch(param)
452 case AL_REVERB_DENSITY: *val = props.Density; break;
453 case AL_REVERB_DIFFUSION: *val = props.Diffusion; break;
454 case AL_REVERB_GAIN: *val = props.Gain; break;
455 case AL_REVERB_GAINHF: *val = props.GainHF; break;
456 case AL_REVERB_DECAY_TIME: *val = props.DecayTime; break;
457 case AL_REVERB_DECAY_HFRATIO: *val = props.DecayHFRatio; break;
458 case AL_REVERB_REFLECTIONS_GAIN: *val = props.ReflectionsGain; break;
459 case AL_REVERB_REFLECTIONS_DELAY: *val = props.ReflectionsDelay; break;
460 case AL_REVERB_LATE_REVERB_GAIN: *val = props.LateReverbGain; break;
461 case AL_REVERB_LATE_REVERB_DELAY: *val = props.LateReverbDelay; break;
462 case AL_REVERB_AIR_ABSORPTION_GAINHF: *val = props.AirAbsorptionGainHF; break;
463 case AL_REVERB_ROOM_ROLLOFF_FACTOR: *val = props.RoomRolloffFactor; break;
465 default:
466 throw effect_exception{AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", param};
469 void EffectHandler::StdReverbGetParamfv(const ReverbProps &props, ALenum param, float *vals)
471 switch(param)
473 default:
474 StdReverbGetParamf(props, param, vals);
475 break;
480 #ifdef ALSOFT_EAX
481 namespace {
483 class EaxReverbEffectException : public EaxException
485 public:
486 explicit EaxReverbEffectException(const char* message)
487 : EaxException{"EAX_REVERB_EFFECT", message}
489 }; // EaxReverbEffectException
491 struct EnvironmentValidator1 {
492 void operator()(unsigned long ulEnvironment) const
494 eax_validate_range<EaxReverbEffectException>(
495 "Environment",
496 ulEnvironment,
497 EAXREVERB_MINENVIRONMENT,
498 EAX1REVERB_MAXENVIRONMENT);
500 }; // EnvironmentValidator1
502 struct VolumeValidator {
503 void operator()(float volume) const
505 eax_validate_range<EaxReverbEffectException>(
506 "Volume",
507 volume,
508 EAX1REVERB_MINVOLUME,
509 EAX1REVERB_MAXVOLUME);
511 }; // VolumeValidator
513 struct DecayTimeValidator {
514 void operator()(float flDecayTime) const
516 eax_validate_range<EaxReverbEffectException>(
517 "Decay Time",
518 flDecayTime,
519 EAXREVERB_MINDECAYTIME,
520 EAXREVERB_MAXDECAYTIME);
522 }; // DecayTimeValidator
524 struct DampingValidator {
525 void operator()(float damping) const
527 eax_validate_range<EaxReverbEffectException>(
528 "Damping",
529 damping,
530 EAX1REVERB_MINDAMPING,
531 EAX1REVERB_MAXDAMPING);
533 }; // DampingValidator
535 struct AllValidator1 {
536 void operator()(const EAX_REVERBPROPERTIES& all) const
538 EnvironmentValidator1{}(all.environment);
539 VolumeValidator{}(all.fVolume);
540 DecayTimeValidator{}(all.fDecayTime_sec);
541 DampingValidator{}(all.fDamping);
543 }; // AllValidator1
545 struct RoomValidator {
546 void operator()(long lRoom) const
548 eax_validate_range<EaxReverbEffectException>(
549 "Room",
550 lRoom,
551 EAXREVERB_MINROOM,
552 EAXREVERB_MAXROOM);
554 }; // RoomValidator
556 struct RoomHFValidator {
557 void operator()(long lRoomHF) const
559 eax_validate_range<EaxReverbEffectException>(
560 "Room HF",
561 lRoomHF,
562 EAXREVERB_MINROOMHF,
563 EAXREVERB_MAXROOMHF);
565 }; // RoomHFValidator
567 struct RoomRolloffFactorValidator {
568 void operator()(float flRoomRolloffFactor) const
570 eax_validate_range<EaxReverbEffectException>(
571 "Room Rolloff Factor",
572 flRoomRolloffFactor,
573 EAXREVERB_MINROOMROLLOFFFACTOR,
574 EAXREVERB_MAXROOMROLLOFFFACTOR);
576 }; // RoomRolloffFactorValidator
578 struct DecayHFRatioValidator {
579 void operator()(float flDecayHFRatio) const
581 eax_validate_range<EaxReverbEffectException>(
582 "Decay HF Ratio",
583 flDecayHFRatio,
584 EAXREVERB_MINDECAYHFRATIO,
585 EAXREVERB_MAXDECAYHFRATIO);
587 }; // DecayHFRatioValidator
589 struct ReflectionsValidator {
590 void operator()(long lReflections) const
592 eax_validate_range<EaxReverbEffectException>(
593 "Reflections",
594 lReflections,
595 EAXREVERB_MINREFLECTIONS,
596 EAXREVERB_MAXREFLECTIONS);
598 }; // ReflectionsValidator
600 struct ReflectionsDelayValidator {
601 void operator()(float flReflectionsDelay) const
603 eax_validate_range<EaxReverbEffectException>(
604 "Reflections Delay",
605 flReflectionsDelay,
606 EAXREVERB_MINREFLECTIONSDELAY,
607 EAXREVERB_MAXREFLECTIONSDELAY);
609 }; // ReflectionsDelayValidator
611 struct ReverbValidator {
612 void operator()(long lReverb) const
614 eax_validate_range<EaxReverbEffectException>(
615 "Reverb",
616 lReverb,
617 EAXREVERB_MINREVERB,
618 EAXREVERB_MAXREVERB);
620 }; // ReverbValidator
622 struct ReverbDelayValidator {
623 void operator()(float flReverbDelay) const
625 eax_validate_range<EaxReverbEffectException>(
626 "Reverb Delay",
627 flReverbDelay,
628 EAXREVERB_MINREVERBDELAY,
629 EAXREVERB_MAXREVERBDELAY);
631 }; // ReverbDelayValidator
633 struct EnvironmentSizeValidator {
634 void operator()(float flEnvironmentSize) const
636 eax_validate_range<EaxReverbEffectException>(
637 "Environment Size",
638 flEnvironmentSize,
639 EAXREVERB_MINENVIRONMENTSIZE,
640 EAXREVERB_MAXENVIRONMENTSIZE);
642 }; // EnvironmentSizeValidator
644 struct EnvironmentDiffusionValidator {
645 void operator()(float flEnvironmentDiffusion) const
647 eax_validate_range<EaxReverbEffectException>(
648 "Environment Diffusion",
649 flEnvironmentDiffusion,
650 EAXREVERB_MINENVIRONMENTDIFFUSION,
651 EAXREVERB_MAXENVIRONMENTDIFFUSION);
653 }; // EnvironmentDiffusionValidator
655 struct AirAbsorptionHFValidator {
656 void operator()(float flAirAbsorptionHF) const
658 eax_validate_range<EaxReverbEffectException>(
659 "Air Absorbtion HF",
660 flAirAbsorptionHF,
661 EAXREVERB_MINAIRABSORPTIONHF,
662 EAXREVERB_MAXAIRABSORPTIONHF);
664 }; // AirAbsorptionHFValidator
666 struct FlagsValidator2 {
667 void operator()(unsigned long ulFlags) const
669 eax_validate_range<EaxReverbEffectException>(
670 "Flags",
671 ulFlags,
672 0UL,
673 ~EAX2LISTENERFLAGS_RESERVED);
675 }; // FlagsValidator2
677 struct AllValidator2 {
678 void operator()(const EAX20LISTENERPROPERTIES& all) const
680 RoomValidator{}(all.lRoom);
681 RoomHFValidator{}(all.lRoomHF);
682 RoomRolloffFactorValidator{}(all.flRoomRolloffFactor);
683 DecayTimeValidator{}(all.flDecayTime);
684 DecayHFRatioValidator{}(all.flDecayHFRatio);
685 ReflectionsValidator{}(all.lReflections);
686 ReflectionsDelayValidator{}(all.flReflectionsDelay);
687 ReverbValidator{}(all.lReverb);
688 ReverbDelayValidator{}(all.flReverbDelay);
689 EnvironmentValidator1{}(all.dwEnvironment);
690 EnvironmentSizeValidator{}(all.flEnvironmentSize);
691 EnvironmentDiffusionValidator{}(all.flEnvironmentDiffusion);
692 AirAbsorptionHFValidator{}(all.flAirAbsorptionHF);
693 FlagsValidator2{}(all.dwFlags);
695 }; // AllValidator2
697 struct EnvironmentValidator3 {
698 void operator()(unsigned long ulEnvironment) const
700 eax_validate_range<EaxReverbEffectException>(
701 "Environment",
702 ulEnvironment,
703 EAXREVERB_MINENVIRONMENT,
704 EAX30REVERB_MAXENVIRONMENT);
706 }; // EnvironmentValidator1
708 struct RoomLFValidator {
709 void operator()(long lRoomLF) const
711 eax_validate_range<EaxReverbEffectException>(
712 "Room LF",
713 lRoomLF,
714 EAXREVERB_MINROOMLF,
715 EAXREVERB_MAXROOMLF);
717 }; // RoomLFValidator
719 struct DecayLFRatioValidator {
720 void operator()(float flDecayLFRatio) const
722 eax_validate_range<EaxReverbEffectException>(
723 "Decay LF Ratio",
724 flDecayLFRatio,
725 EAXREVERB_MINDECAYLFRATIO,
726 EAXREVERB_MAXDECAYLFRATIO);
728 }; // DecayLFRatioValidator
730 struct VectorValidator {
731 void operator()(const EAXVECTOR&) const
733 }; // VectorValidator
735 struct EchoTimeValidator {
736 void operator()(float flEchoTime) const
738 eax_validate_range<EaxReverbEffectException>(
739 "Echo Time",
740 flEchoTime,
741 EAXREVERB_MINECHOTIME,
742 EAXREVERB_MAXECHOTIME);
744 }; // EchoTimeValidator
746 struct EchoDepthValidator {
747 void operator()(float flEchoDepth) const
749 eax_validate_range<EaxReverbEffectException>(
750 "Echo Depth",
751 flEchoDepth,
752 EAXREVERB_MINECHODEPTH,
753 EAXREVERB_MAXECHODEPTH);
755 }; // EchoDepthValidator
757 struct ModulationTimeValidator {
758 void operator()(float flModulationTime) const
760 eax_validate_range<EaxReverbEffectException>(
761 "Modulation Time",
762 flModulationTime,
763 EAXREVERB_MINMODULATIONTIME,
764 EAXREVERB_MAXMODULATIONTIME);
766 }; // ModulationTimeValidator
768 struct ModulationDepthValidator {
769 void operator()(float flModulationDepth) const
771 eax_validate_range<EaxReverbEffectException>(
772 "Modulation Depth",
773 flModulationDepth,
774 EAXREVERB_MINMODULATIONDEPTH,
775 EAXREVERB_MAXMODULATIONDEPTH);
777 }; // ModulationDepthValidator
779 struct HFReferenceValidator {
780 void operator()(float flHFReference) const
782 eax_validate_range<EaxReverbEffectException>(
783 "HF Reference",
784 flHFReference,
785 EAXREVERB_MINHFREFERENCE,
786 EAXREVERB_MAXHFREFERENCE);
788 }; // HFReferenceValidator
790 struct LFReferenceValidator {
791 void operator()(float flLFReference) const
793 eax_validate_range<EaxReverbEffectException>(
794 "LF Reference",
795 flLFReference,
796 EAXREVERB_MINLFREFERENCE,
797 EAXREVERB_MAXLFREFERENCE);
799 }; // LFReferenceValidator
801 struct FlagsValidator3 {
802 void operator()(unsigned long ulFlags) const
804 eax_validate_range<EaxReverbEffectException>(
805 "Flags",
806 ulFlags,
807 0UL,
808 ~EAXREVERBFLAGS_RESERVED);
810 }; // FlagsValidator3
812 struct AllValidator3 {
813 void operator()(const EAXREVERBPROPERTIES& all) const
815 EnvironmentValidator3{}(all.ulEnvironment);
816 EnvironmentSizeValidator{}(all.flEnvironmentSize);
817 EnvironmentDiffusionValidator{}(all.flEnvironmentDiffusion);
818 RoomValidator{}(all.lRoom);
819 RoomHFValidator{}(all.lRoomHF);
820 RoomLFValidator{}(all.lRoomLF);
821 DecayTimeValidator{}(all.flDecayTime);
822 DecayHFRatioValidator{}(all.flDecayHFRatio);
823 DecayLFRatioValidator{}(all.flDecayLFRatio);
824 ReflectionsValidator{}(all.lReflections);
825 ReflectionsDelayValidator{}(all.flReflectionsDelay);
826 VectorValidator{}(all.vReflectionsPan);
827 ReverbValidator{}(all.lReverb);
828 ReverbDelayValidator{}(all.flReverbDelay);
829 VectorValidator{}(all.vReverbPan);
830 EchoTimeValidator{}(all.flEchoTime);
831 EchoDepthValidator{}(all.flEchoDepth);
832 ModulationTimeValidator{}(all.flModulationTime);
833 ModulationDepthValidator{}(all.flModulationDepth);
834 AirAbsorptionHFValidator{}(all.flAirAbsorptionHF);
835 HFReferenceValidator{}(all.flHFReference);
836 LFReferenceValidator{}(all.flLFReference);
837 RoomRolloffFactorValidator{}(all.flRoomRolloffFactor);
838 FlagsValidator3{}(all.ulFlags);
840 }; // AllValidator3
842 struct EnvironmentDeferrer2 {
843 void operator()(EAX20LISTENERPROPERTIES& props, unsigned long dwEnvironment) const
845 props = EAX2REVERB_PRESETS[dwEnvironment];
847 }; // EnvironmentDeferrer2
849 struct EnvironmentSizeDeferrer2 {
850 void operator()(EAX20LISTENERPROPERTIES& props, float flEnvironmentSize) const
852 if (props.flEnvironmentSize == flEnvironmentSize)
854 return;
857 const auto scale = flEnvironmentSize / props.flEnvironmentSize;
858 props.flEnvironmentSize = flEnvironmentSize;
860 if ((props.dwFlags & EAX2LISTENERFLAGS_DECAYTIMESCALE) != 0)
862 props.flDecayTime = std::clamp(
863 props.flDecayTime * scale,
864 EAXREVERB_MINDECAYTIME,
865 EAXREVERB_MAXDECAYTIME);
868 if ((props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSSCALE) != 0 &&
869 (props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSDELAYSCALE) != 0)
871 props.lReflections = std::clamp(
872 props.lReflections - static_cast<long>(gain_to_level_mb(scale)),
873 EAXREVERB_MINREFLECTIONS,
874 EAXREVERB_MAXREFLECTIONS);
877 if ((props.dwFlags & EAX2LISTENERFLAGS_REFLECTIONSDELAYSCALE) != 0)
879 props.flReflectionsDelay = std::clamp(
880 props.flReflectionsDelay * scale,
881 EAXREVERB_MINREFLECTIONSDELAY,
882 EAXREVERB_MAXREFLECTIONSDELAY);
885 if ((props.dwFlags & EAX2LISTENERFLAGS_REVERBSCALE) != 0)
887 const auto log_scalar = ((props.dwFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0) ? 2'000.0F : 3'000.0F;
889 props.lReverb = std::clamp(
890 props.lReverb - static_cast<long>(std::log10(scale) * log_scalar),
891 EAXREVERB_MINREVERB,
892 EAXREVERB_MAXREVERB);
895 if ((props.dwFlags & EAX2LISTENERFLAGS_REVERBDELAYSCALE) != 0)
897 props.flReverbDelay = std::clamp(
898 props.flReverbDelay * scale,
899 EAXREVERB_MINREVERBDELAY,
900 EAXREVERB_MAXREVERBDELAY);
903 }; // EnvironmentSizeDeferrer2
905 struct EnvironmentDeferrer3 {
906 void operator()(EAXREVERBPROPERTIES& props, unsigned long ulEnvironment) const
908 if (ulEnvironment == EAX_ENVIRONMENT_UNDEFINED)
910 props.ulEnvironment = EAX_ENVIRONMENT_UNDEFINED;
911 return;
914 props = EAXREVERB_PRESETS[ulEnvironment];
916 }; // EnvironmentDeferrer3
918 struct EnvironmentSizeDeferrer3 {
919 void operator()(EAXREVERBPROPERTIES& props, float flEnvironmentSize) const
921 if (props.flEnvironmentSize == flEnvironmentSize)
923 return;
926 const auto scale = flEnvironmentSize / props.flEnvironmentSize;
927 props.ulEnvironment = EAX_ENVIRONMENT_UNDEFINED;
928 props.flEnvironmentSize = flEnvironmentSize;
930 if ((props.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0)
932 props.flDecayTime = std::clamp(
933 props.flDecayTime * scale,
934 EAXREVERB_MINDECAYTIME,
935 EAXREVERB_MAXDECAYTIME);
938 if ((props.ulFlags & EAXREVERBFLAGS_REFLECTIONSSCALE) != 0 &&
939 (props.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
941 props.lReflections = std::clamp(
942 props.lReflections - static_cast<long>(gain_to_level_mb(scale)),
943 EAXREVERB_MINREFLECTIONS,
944 EAXREVERB_MAXREFLECTIONS);
947 if ((props.ulFlags & EAXREVERBFLAGS_REFLECTIONSDELAYSCALE) != 0)
949 props.flReflectionsDelay = std::clamp(
950 props.flReflectionsDelay * scale,
951 EAXREVERB_MINREFLECTIONSDELAY,
952 EAXREVERB_MAXREFLECTIONSDELAY);
955 if ((props.ulFlags & EAXREVERBFLAGS_REVERBSCALE) != 0)
957 const auto log_scalar = ((props.ulFlags & EAXREVERBFLAGS_DECAYTIMESCALE) != 0) ? 2'000.0F : 3'000.0F;
958 props.lReverb = std::clamp(
959 props.lReverb - static_cast<long>(std::log10(scale) * log_scalar),
960 EAXREVERB_MINREVERB,
961 EAXREVERB_MAXREVERB);
964 if ((props.ulFlags & EAXREVERBFLAGS_REVERBDELAYSCALE) != 0)
966 props.flReverbDelay = std::clamp(
967 props.flReverbDelay * scale,
968 EAXREVERB_MINREVERBDELAY,
969 EAXREVERB_MAXREVERBDELAY);
972 if ((props.ulFlags & EAXREVERBFLAGS_ECHOTIMESCALE) != 0)
974 props.flEchoTime = std::clamp(
975 props.flEchoTime * scale,
976 EAXREVERB_MINECHOTIME,
977 EAXREVERB_MAXECHOTIME);
980 if ((props.ulFlags & EAXREVERBFLAGS_MODULATIONTIMESCALE) != 0)
982 props.flModulationTime = std::clamp(
983 props.flModulationTime * scale,
984 EAXREVERB_MINMODULATIONTIME,
985 EAXREVERB_MAXMODULATIONTIME);
988 }; // EnvironmentSizeDeferrer3
990 } // namespace
993 struct EaxReverbCommitter::Exception : public EaxReverbEffectException
995 using EaxReverbEffectException::EaxReverbEffectException;
998 [[noreturn]] void EaxReverbCommitter::fail(const char* message)
1000 throw Exception{message};
1003 void EaxReverbCommitter::translate(const EAX_REVERBPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
1005 assert(src.environment <= EAX1REVERB_MAXENVIRONMENT);
1006 dst = EAXREVERB_PRESETS[src.environment];
1007 dst.flDecayTime = src.fDecayTime_sec;
1008 dst.flDecayHFRatio = src.fDamping;
1009 dst.lReverb = static_cast<int>(std::min(gain_to_level_mb(src.fVolume), 0.0f));
1012 void EaxReverbCommitter::translate(const EAX20LISTENERPROPERTIES& src, EAXREVERBPROPERTIES& dst) noexcept
1014 assert(src.dwEnvironment <= EAX1REVERB_MAXENVIRONMENT);
1015 dst = EAXREVERB_PRESETS[src.dwEnvironment];
1016 dst.ulEnvironment = src.dwEnvironment;
1017 dst.flEnvironmentSize = src.flEnvironmentSize;
1018 dst.flEnvironmentDiffusion = src.flEnvironmentDiffusion;
1019 dst.lRoom = src.lRoom;
1020 dst.lRoomHF = src.lRoomHF;
1021 dst.flDecayTime = src.flDecayTime;
1022 dst.flDecayHFRatio = src.flDecayHFRatio;
1023 dst.lReflections = src.lReflections;
1024 dst.flReflectionsDelay = src.flReflectionsDelay;
1025 dst.lReverb = src.lReverb;
1026 dst.flReverbDelay = src.flReverbDelay;
1027 dst.flAirAbsorptionHF = src.flAirAbsorptionHF;
1028 dst.flRoomRolloffFactor = src.flRoomRolloffFactor;
1029 dst.ulFlags = src.dwFlags;
1032 bool EaxReverbCommitter::commit(const EAX_REVERBPROPERTIES &props)
1034 EAXREVERBPROPERTIES dst{};
1035 translate(props, dst);
1036 return commit(dst);
1039 bool EaxReverbCommitter::commit(const EAX20LISTENERPROPERTIES &props)
1041 EAXREVERBPROPERTIES dst{};
1042 translate(props, dst);
1043 return commit(dst);
1046 bool EaxReverbCommitter::commit(const EAXREVERBPROPERTIES &props)
1048 if(auto *cur = std::get_if<EAXREVERBPROPERTIES>(&mEaxProps); cur && *cur == props)
1049 return false;
1051 mEaxProps = props;
1053 const auto size = props.flEnvironmentSize;
1054 const auto density = (size * size * size) / 16.0f;
1055 mAlProps = [&]{
1056 ReverbProps ret{};
1057 ret.Density = std::min(density, AL_EAXREVERB_MAX_DENSITY);
1058 ret.Diffusion = props.flEnvironmentDiffusion;
1059 ret.Gain = level_mb_to_gain(static_cast<float>(props.lRoom));
1060 ret.GainHF = level_mb_to_gain(static_cast<float>(props.lRoomHF));
1061 ret.GainLF = level_mb_to_gain(static_cast<float>(props.lRoomLF));
1062 ret.DecayTime = props.flDecayTime;
1063 ret.DecayHFRatio = props.flDecayHFRatio;
1064 ret.DecayLFRatio = props.flDecayLFRatio;
1065 ret.ReflectionsGain = level_mb_to_gain(static_cast<float>(props.lReflections));
1066 ret.ReflectionsDelay = props.flReflectionsDelay;
1067 ret.ReflectionsPan = {props.vReflectionsPan.x, props.vReflectionsPan.y,
1068 props.vReflectionsPan.z};
1069 ret.LateReverbGain = level_mb_to_gain(static_cast<float>(props.lReverb));
1070 ret.LateReverbDelay = props.flReverbDelay;
1071 ret.LateReverbPan = {props.vReverbPan.x, props.vReverbPan.y, props.vReverbPan.z};
1072 ret.EchoTime = props.flEchoTime;
1073 ret.EchoDepth = props.flEchoDepth;
1074 ret.ModulationTime = props.flModulationTime;
1075 ret.ModulationDepth = props.flModulationDepth;
1076 ret.AirAbsorptionGainHF = level_mb_to_gain(props.flAirAbsorptionHF);
1077 ret.HFReference = props.flHFReference;
1078 ret.LFReference = props.flLFReference;
1079 ret.RoomRolloffFactor = props.flRoomRolloffFactor;
1080 ret.DecayHFLimit = ((props.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT) != 0);
1081 return ret;
1082 }();
1084 return true;
1087 void EaxReverbCommitter::SetDefaults(EAX_REVERBPROPERTIES &props)
1089 props = EAX1REVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
1092 void EaxReverbCommitter::SetDefaults(EAX20LISTENERPROPERTIES &props)
1094 props = EAX2REVERB_PRESETS[EAX2_ENVIRONMENT_GENERIC];
1095 props.lRoom = -10'000L;
1098 void EaxReverbCommitter::SetDefaults(EAXREVERBPROPERTIES &props)
1100 props = EAXREVERB_PRESETS[EAX_ENVIRONMENT_GENERIC];
1103 void EaxReverbCommitter::SetDefaults(EaxEffectProps &props)
1105 SetDefaults(props.emplace<EAXREVERBPROPERTIES>());
1109 void EaxReverbCommitter::Get(const EaxCall &call, const EAX_REVERBPROPERTIES &props)
1111 switch(call.get_property_id())
1113 case DSPROPERTY_EAX_ALL: call.set_value<Exception>(props); break;
1114 case DSPROPERTY_EAX_ENVIRONMENT: call.set_value<Exception>(props.environment); break;
1115 case DSPROPERTY_EAX_VOLUME: call.set_value<Exception>(props.fVolume); break;
1116 case DSPROPERTY_EAX_DECAYTIME: call.set_value<Exception>(props.fDecayTime_sec); break;
1117 case DSPROPERTY_EAX_DAMPING: call.set_value<Exception>(props.fDamping); break;
1118 default: fail_unknown_property_id();
1122 void EaxReverbCommitter::Get(const EaxCall &call, const EAX20LISTENERPROPERTIES &props)
1124 switch(call.get_property_id())
1126 case DSPROPERTY_EAX20LISTENER_NONE: break;
1127 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS: call.set_value<Exception>(props); break;
1128 case DSPROPERTY_EAX20LISTENER_ROOM: call.set_value<Exception>(props.lRoom); break;
1129 case DSPROPERTY_EAX20LISTENER_ROOMHF: call.set_value<Exception>(props.lRoomHF); break;
1130 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR: call.set_value<Exception>(props.flRoomRolloffFactor); break;
1131 case DSPROPERTY_EAX20LISTENER_DECAYTIME: call.set_value<Exception>(props.flDecayTime); break;
1132 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO: call.set_value<Exception>(props.flDecayHFRatio); break;
1133 case DSPROPERTY_EAX20LISTENER_REFLECTIONS: call.set_value<Exception>(props.lReflections); break;
1134 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY: call.set_value<Exception>(props.flReflectionsDelay); break;
1135 case DSPROPERTY_EAX20LISTENER_REVERB: call.set_value<Exception>(props.lReverb); break;
1136 case DSPROPERTY_EAX20LISTENER_REVERBDELAY: call.set_value<Exception>(props.flReverbDelay); break;
1137 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT: call.set_value<Exception>(props.dwEnvironment); break;
1138 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE: call.set_value<Exception>(props.flEnvironmentSize); break;
1139 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION: call.set_value<Exception>(props.flEnvironmentDiffusion); break;
1140 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF: call.set_value<Exception>(props.flAirAbsorptionHF); break;
1141 case DSPROPERTY_EAX20LISTENER_FLAGS: call.set_value<Exception>(props.dwFlags); break;
1142 default: fail_unknown_property_id();
1146 void EaxReverbCommitter::Get(const EaxCall &call, const EAXREVERBPROPERTIES &props)
1148 switch(call.get_property_id())
1150 case EAXREVERB_NONE: break;
1151 case EAXREVERB_ALLPARAMETERS: call.set_value<Exception>(props); break;
1152 case EAXREVERB_ENVIRONMENT: call.set_value<Exception>(props.ulEnvironment); break;
1153 case EAXREVERB_ENVIRONMENTSIZE: call.set_value<Exception>(props.flEnvironmentSize); break;
1154 case EAXREVERB_ENVIRONMENTDIFFUSION: call.set_value<Exception>(props.flEnvironmentDiffusion); break;
1155 case EAXREVERB_ROOM: call.set_value<Exception>(props.lRoom); break;
1156 case EAXREVERB_ROOMHF: call.set_value<Exception>(props.lRoomHF); break;
1157 case EAXREVERB_ROOMLF: call.set_value<Exception>(props.lRoomLF); break;
1158 case EAXREVERB_DECAYTIME: call.set_value<Exception>(props.flDecayTime); break;
1159 case EAXREVERB_DECAYHFRATIO: call.set_value<Exception>(props.flDecayHFRatio); break;
1160 case EAXREVERB_DECAYLFRATIO: call.set_value<Exception>(props.flDecayLFRatio); break;
1161 case EAXREVERB_REFLECTIONS: call.set_value<Exception>(props.lReflections); break;
1162 case EAXREVERB_REFLECTIONSDELAY: call.set_value<Exception>(props.flReflectionsDelay); break;
1163 case EAXREVERB_REFLECTIONSPAN: call.set_value<Exception>(props.vReflectionsPan); break;
1164 case EAXREVERB_REVERB: call.set_value<Exception>(props.lReverb); break;
1165 case EAXREVERB_REVERBDELAY: call.set_value<Exception>(props.flReverbDelay); break;
1166 case EAXREVERB_REVERBPAN: call.set_value<Exception>(props.vReverbPan); break;
1167 case EAXREVERB_ECHOTIME: call.set_value<Exception>(props.flEchoTime); break;
1168 case EAXREVERB_ECHODEPTH: call.set_value<Exception>(props.flEchoDepth); break;
1169 case EAXREVERB_MODULATIONTIME: call.set_value<Exception>(props.flModulationTime); break;
1170 case EAXREVERB_MODULATIONDEPTH: call.set_value<Exception>(props.flModulationDepth); break;
1171 case EAXREVERB_AIRABSORPTIONHF: call.set_value<Exception>(props.flAirAbsorptionHF); break;
1172 case EAXREVERB_HFREFERENCE: call.set_value<Exception>(props.flHFReference); break;
1173 case EAXREVERB_LFREFERENCE: call.set_value<Exception>(props.flLFReference); break;
1174 case EAXREVERB_ROOMROLLOFFFACTOR: call.set_value<Exception>(props.flRoomRolloffFactor); break;
1175 case EAXREVERB_FLAGS: call.set_value<Exception>(props.ulFlags); break;
1176 default: fail_unknown_property_id();
1181 void EaxReverbCommitter::Set(const EaxCall &call, EAX_REVERBPROPERTIES &props)
1183 switch(call.get_property_id())
1185 case DSPROPERTY_EAX_ALL: defer<AllValidator1>(call, props); break;
1186 case DSPROPERTY_EAX_ENVIRONMENT: defer<EnvironmentValidator1>(call, props.environment); break;
1187 case DSPROPERTY_EAX_VOLUME: defer<VolumeValidator>(call, props.fVolume); break;
1188 case DSPROPERTY_EAX_DECAYTIME: defer<DecayTimeValidator>(call, props.fDecayTime_sec); break;
1189 case DSPROPERTY_EAX_DAMPING: defer<DampingValidator>(call, props.fDamping); break;
1190 default: fail_unknown_property_id();
1194 void EaxReverbCommitter::Set(const EaxCall &call, EAX20LISTENERPROPERTIES &props)
1196 switch(call.get_property_id())
1198 case DSPROPERTY_EAX20LISTENER_NONE: break;
1199 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS: defer<AllValidator2>(call, props); break;
1200 case DSPROPERTY_EAX20LISTENER_ROOM: defer<RoomValidator>(call, props.lRoom); break;
1201 case DSPROPERTY_EAX20LISTENER_ROOMHF: defer<RoomHFValidator>(call, props.lRoomHF); break;
1202 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR: defer<RoomRolloffFactorValidator>(call, props.flRoomRolloffFactor); break;
1203 case DSPROPERTY_EAX20LISTENER_DECAYTIME: defer<DecayTimeValidator>(call, props.flDecayTime); break;
1204 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO: defer<DecayHFRatioValidator>(call, props.flDecayHFRatio); break;
1205 case DSPROPERTY_EAX20LISTENER_REFLECTIONS: defer<ReflectionsValidator>(call, props.lReflections); break;
1206 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY: defer<ReflectionsDelayValidator>(call, props.flReverbDelay); break;
1207 case DSPROPERTY_EAX20LISTENER_REVERB: defer<ReverbValidator>(call, props.lReverb); break;
1208 case DSPROPERTY_EAX20LISTENER_REVERBDELAY: defer<ReverbDelayValidator>(call, props.flReverbDelay); break;
1209 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT: defer<EnvironmentValidator1, EnvironmentDeferrer2>(call, props, props.dwEnvironment); break;
1210 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer2>(call, props, props.flEnvironmentSize); break;
1211 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION: defer<EnvironmentDiffusionValidator>(call, props.flEnvironmentDiffusion); break;
1212 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF: defer<AirAbsorptionHFValidator>(call, props.flAirAbsorptionHF); break;
1213 case DSPROPERTY_EAX20LISTENER_FLAGS: defer<FlagsValidator2>(call, props.dwFlags); break;
1214 default: fail_unknown_property_id();
1218 void EaxReverbCommitter::Set(const EaxCall &call, EAXREVERBPROPERTIES &props)
1220 switch(call.get_property_id())
1222 case EAXREVERB_NONE: break;
1223 case EAXREVERB_ALLPARAMETERS: defer<AllValidator3>(call, props); break;
1224 case EAXREVERB_ENVIRONMENT: defer<EnvironmentValidator3, EnvironmentDeferrer3>(call, props, props.ulEnvironment); break;
1225 case EAXREVERB_ENVIRONMENTSIZE: defer<EnvironmentSizeValidator, EnvironmentSizeDeferrer3>(call, props, props.flEnvironmentSize); break;
1226 case EAXREVERB_ENVIRONMENTDIFFUSION: defer3<EnvironmentDiffusionValidator>(call, props, props.flEnvironmentDiffusion); break;
1227 case EAXREVERB_ROOM: defer3<RoomValidator>(call, props, props.lRoom); break;
1228 case EAXREVERB_ROOMHF: defer3<RoomHFValidator>(call, props, props.lRoomHF); break;
1229 case EAXREVERB_ROOMLF: defer3<RoomLFValidator>(call, props, props.lRoomLF); break;
1230 case EAXREVERB_DECAYTIME: defer3<DecayTimeValidator>(call, props, props.flDecayTime); break;
1231 case EAXREVERB_DECAYHFRATIO: defer3<DecayHFRatioValidator>(call, props, props.flDecayHFRatio); break;
1232 case EAXREVERB_DECAYLFRATIO: defer3<DecayLFRatioValidator>(call, props, props.flDecayLFRatio); break;
1233 case EAXREVERB_REFLECTIONS: defer3<ReflectionsValidator>(call, props, props.lReflections); break;
1234 case EAXREVERB_REFLECTIONSDELAY: defer3<ReflectionsDelayValidator>(call, props, props.flReflectionsDelay); break;
1235 case EAXREVERB_REFLECTIONSPAN: defer3<VectorValidator>(call, props, props.vReflectionsPan); break;
1236 case EAXREVERB_REVERB: defer3<ReverbValidator>(call, props, props.lReverb); break;
1237 case EAXREVERB_REVERBDELAY: defer3<ReverbDelayValidator>(call, props, props.flReverbDelay); break;
1238 case EAXREVERB_REVERBPAN: defer3<VectorValidator>(call, props, props.vReverbPan); break;
1239 case EAXREVERB_ECHOTIME: defer3<EchoTimeValidator>(call, props, props.flEchoTime); break;
1240 case EAXREVERB_ECHODEPTH: defer3<EchoDepthValidator>(call, props, props.flEchoDepth); break;
1241 case EAXREVERB_MODULATIONTIME: defer3<ModulationTimeValidator>(call, props, props.flModulationTime); break;
1242 case EAXREVERB_MODULATIONDEPTH: defer3<ModulationDepthValidator>(call, props, props.flModulationDepth); break;
1243 case EAXREVERB_AIRABSORPTIONHF: defer3<AirAbsorptionHFValidator>(call, props, props.flAirAbsorptionHF); break;
1244 case EAXREVERB_HFREFERENCE: defer3<HFReferenceValidator>(call, props, props.flHFReference); break;
1245 case EAXREVERB_LFREFERENCE: defer3<LFReferenceValidator>(call, props, props.flLFReference); break;
1246 case EAXREVERB_ROOMROLLOFFFACTOR: defer3<RoomRolloffFactorValidator>(call, props, props.flRoomRolloffFactor); break;
1247 case EAXREVERB_FLAGS: defer3<FlagsValidator3>(call, props, props.ulFlags); break;
1248 default: fail_unknown_property_id();
1252 #endif // ALSOFT_EAX