7 #include "alc/effects/base.h"
11 #include "alnumeric.h"
12 #include "al/eax/effect.h"
13 #include "al/eax/exception.h"
14 #include "al/eax/utils.h"
20 static_assert(EchoMaxDelay
>= AL_ECHO_MAX_DELAY
, "Echo max delay too short");
21 static_assert(EchoMaxLRDelay
>= AL_ECHO_MAX_LRDELAY
, "Echo max left-right delay too short");
23 constexpr EffectProps
genDefaultProps() noexcept
26 props
.Delay
= AL_ECHO_DEFAULT_DELAY
;
27 props
.LRDelay
= AL_ECHO_DEFAULT_LRDELAY
;
28 props
.Damping
= AL_ECHO_DEFAULT_DAMPING
;
29 props
.Feedback
= AL_ECHO_DEFAULT_FEEDBACK
;
30 props
.Spread
= AL_ECHO_DEFAULT_SPREAD
;
36 const EffectProps EchoEffectProps
{genDefaultProps()};
38 void EchoEffectHandler::SetParami(EchoProps
&, ALenum param
, int)
39 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo integer property 0x%04x", param
}; }
40 void EchoEffectHandler::SetParamiv(EchoProps
&, ALenum param
, const int*)
41 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo integer-vector property 0x%04x", param
}; }
42 void EchoEffectHandler::SetParamf(EchoProps
&props
, ALenum param
, float val
)
47 if(!(val
>= AL_ECHO_MIN_DELAY
&& val
<= AL_ECHO_MAX_DELAY
))
48 throw effect_exception
{AL_INVALID_VALUE
, "Echo delay out of range"};
53 if(!(val
>= AL_ECHO_MIN_LRDELAY
&& val
<= AL_ECHO_MAX_LRDELAY
))
54 throw effect_exception
{AL_INVALID_VALUE
, "Echo LR delay out of range"};
59 if(!(val
>= AL_ECHO_MIN_DAMPING
&& val
<= AL_ECHO_MAX_DAMPING
))
60 throw effect_exception
{AL_INVALID_VALUE
, "Echo damping out of range"};
64 case AL_ECHO_FEEDBACK
:
65 if(!(val
>= AL_ECHO_MIN_FEEDBACK
&& val
<= AL_ECHO_MAX_FEEDBACK
))
66 throw effect_exception
{AL_INVALID_VALUE
, "Echo feedback out of range"};
71 if(!(val
>= AL_ECHO_MIN_SPREAD
&& val
<= AL_ECHO_MAX_SPREAD
))
72 throw effect_exception
{AL_INVALID_VALUE
, "Echo spread out of range"};
77 throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo float property 0x%04x", param
};
80 void EchoEffectHandler::SetParamfv(EchoProps
&props
, ALenum param
, const float *vals
)
81 { SetParamf(props
, param
, *vals
); }
83 void EchoEffectHandler::GetParami(const EchoProps
&, ALenum param
, int*)
84 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo integer property 0x%04x", param
}; }
85 void EchoEffectHandler::GetParamiv(const EchoProps
&, ALenum param
, int*)
86 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo integer-vector property 0x%04x", param
}; }
87 void EchoEffectHandler::GetParamf(const EchoProps
&props
, ALenum param
, float *val
)
91 case AL_ECHO_DELAY
: *val
= props
.Delay
; break;
92 case AL_ECHO_LRDELAY
: *val
= props
.LRDelay
; break;
93 case AL_ECHO_DAMPING
: *val
= props
.Damping
; break;
94 case AL_ECHO_FEEDBACK
: *val
= props
.Feedback
; break;
95 case AL_ECHO_SPREAD
: *val
= props
.Spread
; break;
98 throw effect_exception
{AL_INVALID_ENUM
, "Invalid echo float property 0x%04x", param
};
101 void EchoEffectHandler::GetParamfv(const EchoProps
&props
, ALenum param
, float *vals
)
102 { GetParamf(props
, param
, vals
); }
108 using EchoCommitter
= EaxCommitter
<EaxEchoCommitter
>;
110 struct DelayValidator
{
111 void operator()(float flDelay
) const
113 eax_validate_range
<EchoCommitter::Exception
>(
121 struct LrDelayValidator
{
122 void operator()(float flLRDelay
) const
124 eax_validate_range
<EchoCommitter::Exception
>(
130 }; // LrDelayValidator
132 struct DampingValidator
{
133 void operator()(float flDamping
) const
135 eax_validate_range
<EchoCommitter::Exception
>(
141 }; // DampingValidator
143 struct FeedbackValidator
{
144 void operator()(float flFeedback
) const
146 eax_validate_range
<EchoCommitter::Exception
>(
150 EAXECHO_MAXFEEDBACK
);
152 }; // FeedbackValidator
154 struct SpreadValidator
{
155 void operator()(float flSpread
) const
157 eax_validate_range
<EchoCommitter::Exception
>(
163 }; // SpreadValidator
165 struct AllValidator
{
166 void operator()(const EAXECHOPROPERTIES
& all
) const
168 DelayValidator
{}(all
.flDelay
);
169 LrDelayValidator
{}(all
.flLRDelay
);
170 DampingValidator
{}(all
.flDamping
);
171 FeedbackValidator
{}(all
.flFeedback
);
172 SpreadValidator
{}(all
.flSpread
);
179 struct EchoCommitter::Exception
: public EaxException
{
180 explicit Exception(const char* message
) : EaxException
{"EAX_ECHO_EFFECT", message
}
185 [[noreturn
]] void EchoCommitter::fail(const char *message
)
187 throw Exception
{message
};
190 bool EaxEchoCommitter::commit(const EAXECHOPROPERTIES
&props
)
192 if(auto *cur
= std::get_if
<EAXECHOPROPERTIES
>(&mEaxProps
); cur
&& *cur
== props
)
198 ret
.Delay
= props
.flDelay
;
199 ret
.LRDelay
= props
.flLRDelay
;
200 ret
.Damping
= props
.flDamping
;
201 ret
.Feedback
= props
.flFeedback
;
202 ret
.Spread
= props
.flSpread
;
209 void EaxEchoCommitter::SetDefaults(EaxEffectProps
&props
)
211 static constexpr EAXECHOPROPERTIES defprops
{[]
213 EAXECHOPROPERTIES ret
{};
214 ret
.flDelay
= EAXECHO_DEFAULTDELAY
;
215 ret
.flLRDelay
= EAXECHO_DEFAULTLRDELAY
;
216 ret
.flDamping
= EAXECHO_DEFAULTDAMPING
;
217 ret
.flFeedback
= EAXECHO_DEFAULTFEEDBACK
;
218 ret
.flSpread
= EAXECHO_DEFAULTSPREAD
;
224 void EaxEchoCommitter::Get(const EaxCall
&call
, const EAXECHOPROPERTIES
&props
)
226 switch(call
.get_property_id())
228 case EAXECHO_NONE
: break;
229 case EAXECHO_ALLPARAMETERS
: call
.set_value
<Exception
>(props
); break;
230 case EAXECHO_DELAY
: call
.set_value
<Exception
>(props
.flDelay
); break;
231 case EAXECHO_LRDELAY
: call
.set_value
<Exception
>(props
.flLRDelay
); break;
232 case EAXECHO_DAMPING
: call
.set_value
<Exception
>(props
.flDamping
); break;
233 case EAXECHO_FEEDBACK
: call
.set_value
<Exception
>(props
.flFeedback
); break;
234 case EAXECHO_SPREAD
: call
.set_value
<Exception
>(props
.flSpread
); break;
235 default: fail_unknown_property_id();
239 void EaxEchoCommitter::Set(const EaxCall
&call
, EAXECHOPROPERTIES
&props
)
241 switch(call
.get_property_id())
243 case EAXECHO_NONE
: break;
244 case EAXECHO_ALLPARAMETERS
: defer
<AllValidator
>(call
, props
); break;
245 case EAXECHO_DELAY
: defer
<DelayValidator
>(call
, props
.flDelay
); break;
246 case EAXECHO_LRDELAY
: defer
<LrDelayValidator
>(call
, props
.flLRDelay
); break;
247 case EAXECHO_DAMPING
: defer
<DampingValidator
>(call
, props
.flDamping
); break;
248 case EAXECHO_FEEDBACK
: defer
<FeedbackValidator
>(call
, props
.flFeedback
); break;
249 case EAXECHO_SPREAD
: defer
<SpreadValidator
>(call
, props
.flSpread
); break;
250 default: fail_unknown_property_id();