7 #include "alc/effects/base.h"
11 #include "alnumeric.h"
12 #include "al/eax/exception.h"
13 #include "al/eax/utils.h"
19 static_assert(EchoMaxDelay >= AL_ECHO_MAX_DELAY, "Echo max delay too short");
20 static_assert(EchoMaxLRDelay >= AL_ECHO_MAX_LRDELAY, "Echo max left-right delay too short");
22 void Echo_setParami(EffectProps*, ALenum param, int)
23 { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
24 void Echo_setParamiv(EffectProps*, ALenum param, const int*)
25 { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
26 void Echo_setParamf(EffectProps *props, ALenum param, float val)
31 if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY))
32 throw effect_exception{AL_INVALID_VALUE, "Echo delay out of range"};
33 props->Echo.Delay = val;
37 if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY))
38 throw effect_exception{AL_INVALID_VALUE, "Echo LR delay out of range"};
39 props->Echo.LRDelay = val;
43 if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING))
44 throw effect_exception{AL_INVALID_VALUE, "Echo damping out of range"};
45 props->Echo.Damping = val;
48 case AL_ECHO_FEEDBACK:
49 if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK))
50 throw effect_exception{AL_INVALID_VALUE, "Echo feedback out of range"};
51 props->Echo.Feedback = val;
55 if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD))
56 throw effect_exception{AL_INVALID_VALUE, "Echo spread out of range"};
57 props->Echo.Spread = val;
61 throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
64 void Echo_setParamfv(EffectProps *props, ALenum param, const float *vals)
65 { Echo_setParamf(props, param, vals[0]); }
67 void Echo_getParami(const EffectProps*, ALenum param, int*)
68 { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param}; }
69 void Echo_getParamiv(const EffectProps*, ALenum param, int*)
70 { throw effect_exception{AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param}; }
71 void Echo_getParamf(const EffectProps *props, ALenum param, float *val)
76 *val = props->Echo.Delay;
80 *val = props->Echo.LRDelay;
84 *val = props->Echo.Damping;
87 case AL_ECHO_FEEDBACK:
88 *val = props->Echo.Feedback;
92 *val = props->Echo.Spread;
96 throw effect_exception{AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param};
99 void Echo_getParamfv(const EffectProps *props, ALenum param, float *vals)
100 { Echo_getParamf(props, param, vals); }
102 EffectProps genDefaultProps() noexcept
105 props.Echo.Delay = AL_ECHO_DEFAULT_DELAY;
106 props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
107 props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
108 props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
109 props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
115 DEFINE_ALEFFECT_VTABLE(Echo);
117 const EffectProps EchoEffectProps{genDefaultProps()};
122 using EchoCommitter = EaxCommitter<EaxEchoCommitter>;
124 struct DelayValidator {
125 void operator()(float flDelay) const
127 eax_validate_range<EchoCommitter::Exception>(
135 struct LrDelayValidator {
136 void operator()(float flLRDelay) const
138 eax_validate_range<EchoCommitter::Exception>(
144 }; // LrDelayValidator
146 struct DampingValidator {
147 void operator()(float flDamping) const
149 eax_validate_range<EchoCommitter::Exception>(
155 }; // DampingValidator
157 struct FeedbackValidator {
158 void operator()(float flFeedback) const
160 eax_validate_range<EchoCommitter::Exception>(
164 EAXECHO_MAXFEEDBACK);
166 }; // FeedbackValidator
168 struct SpreadValidator {
169 void operator()(float flSpread) const
171 eax_validate_range<EchoCommitter::Exception>(
177 }; // SpreadValidator
179 struct AllValidator {
180 void operator()(const EAXECHOPROPERTIES& all) const
182 DelayValidator{}(all.flDelay);
183 LrDelayValidator{}(all.flLRDelay);
184 DampingValidator{}(all.flDamping);
185 FeedbackValidator{}(all.flFeedback);
186 SpreadValidator{}(all.flSpread);
193 struct EchoCommitter::Exception : public EaxException {
194 explicit Exception(const char* message) : EaxException{"EAX_ECHO_EFFECT", message}
199 [[noreturn]] void EchoCommitter::fail(const char *message)
201 throw Exception{message};
205 bool EchoCommitter::commit(const EaxEffectProps &props)
207 if(props.mType == mEaxProps.mType && mEaxProps.mEcho.flDelay == props.mEcho.flDelay
208 && mEaxProps.mEcho.flLRDelay == props.mEcho.flLRDelay
209 && mEaxProps.mEcho.flDamping == props.mEcho.flDamping
210 && mEaxProps.mEcho.flFeedback == props.mEcho.flFeedback
211 && mEaxProps.mEcho.flSpread == props.mEcho.flSpread)
216 mAlProps.Echo.Delay = props.mEcho.flDelay;
217 mAlProps.Echo.LRDelay = props.mEcho.flLRDelay;
218 mAlProps.Echo.Damping = props.mEcho.flDamping;
219 mAlProps.Echo.Feedback = props.mEcho.flFeedback;
220 mAlProps.Echo.Spread = props.mEcho.flSpread;
226 void EchoCommitter::SetDefaults(EaxEffectProps &props)
228 props.mType = EaxEffectType::Echo;
229 props.mEcho.flDelay = EAXECHO_DEFAULTDELAY;
230 props.mEcho.flLRDelay = EAXECHO_DEFAULTLRDELAY;
231 props.mEcho.flDamping = EAXECHO_DEFAULTDAMPING;
232 props.mEcho.flFeedback = EAXECHO_DEFAULTFEEDBACK;
233 props.mEcho.flSpread = EAXECHO_DEFAULTSPREAD;
237 void EchoCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
239 switch(call.get_property_id())
241 case EAXECHO_NONE: break;
242 case EAXECHO_ALLPARAMETERS: call.set_value<Exception>(props.mEcho); break;
243 case EAXECHO_DELAY: call.set_value<Exception>(props.mEcho.flDelay); break;
244 case EAXECHO_LRDELAY: call.set_value<Exception>(props.mEcho.flLRDelay); break;
245 case EAXECHO_DAMPING: call.set_value<Exception>(props.mEcho.flDamping); break;
246 case EAXECHO_FEEDBACK: call.set_value<Exception>(props.mEcho.flFeedback); break;
247 case EAXECHO_SPREAD: call.set_value<Exception>(props.mEcho.flSpread); break;
248 default: fail_unknown_property_id();
253 void EchoCommitter::Set(const EaxCall &call, EaxEffectProps &props)
255 switch(call.get_property_id())
257 case EAXECHO_NONE: break;
258 case EAXECHO_ALLPARAMETERS: defer<AllValidator>(call, props.mEcho); break;
259 case EAXECHO_DELAY: defer<DelayValidator>(call, props.mEcho.flDelay); break;
260 case EAXECHO_LRDELAY: defer<LrDelayValidator>(call, props.mEcho.flLRDelay); break;
261 case EAXECHO_DAMPING: defer<DampingValidator>(call, props.mEcho.flDamping); break;
262 case EAXECHO_FEEDBACK: defer<FeedbackValidator>(call, props.mEcho.flFeedback); break;
263 case EAXECHO_SPREAD: defer<SpreadValidator>(call, props.mEcho.flSpread); break;
264 default: fail_unknown_property_id();