7 #include "alc/effects/base.h"
11 #include "alnumeric.h"
12 #include "al/eax/exception.h"
13 #include "al/eax/utils.h"
19 void Distortion_setParami(EffectProps*, ALenum param, int)
20 { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
21 void Distortion_setParamiv(EffectProps*, ALenum param, const int*)
23 throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
26 void Distortion_setParamf(EffectProps *props, ALenum param, float val)
30 case AL_DISTORTION_EDGE:
31 if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE))
32 throw effect_exception{AL_INVALID_VALUE, "Distortion edge out of range"};
33 props->Distortion.Edge = val;
36 case AL_DISTORTION_GAIN:
37 if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN))
38 throw effect_exception{AL_INVALID_VALUE, "Distortion gain out of range"};
39 props->Distortion.Gain = val;
42 case AL_DISTORTION_LOWPASS_CUTOFF:
43 if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF))
44 throw effect_exception{AL_INVALID_VALUE, "Distortion low-pass cutoff out of range"};
45 props->Distortion.LowpassCutoff = val;
48 case AL_DISTORTION_EQCENTER:
49 if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER))
50 throw effect_exception{AL_INVALID_VALUE, "Distortion EQ center out of range"};
51 props->Distortion.EQCenter = val;
54 case AL_DISTORTION_EQBANDWIDTH:
55 if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH))
56 throw effect_exception{AL_INVALID_VALUE, "Distortion EQ bandwidth out of range"};
57 props->Distortion.EQBandwidth = val;
61 throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
64 void Distortion_setParamfv(EffectProps *props, ALenum param, const float *vals)
65 { Distortion_setParamf(props, param, vals[0]); }
67 void Distortion_getParami(const EffectProps*, ALenum param, int*)
68 { throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param}; }
69 void Distortion_getParamiv(const EffectProps*, ALenum param, int*)
71 throw effect_exception{AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x",
74 void Distortion_getParamf(const EffectProps *props, ALenum param, float *val)
78 case AL_DISTORTION_EDGE:
79 *val = props->Distortion.Edge;
82 case AL_DISTORTION_GAIN:
83 *val = props->Distortion.Gain;
86 case AL_DISTORTION_LOWPASS_CUTOFF:
87 *val = props->Distortion.LowpassCutoff;
90 case AL_DISTORTION_EQCENTER:
91 *val = props->Distortion.EQCenter;
94 case AL_DISTORTION_EQBANDWIDTH:
95 *val = props->Distortion.EQBandwidth;
99 throw effect_exception{AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", param};
102 void Distortion_getParamfv(const EffectProps *props, ALenum param, float *vals)
103 { Distortion_getParamf(props, param, vals); }
105 EffectProps genDefaultProps() noexcept
108 props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE;
109 props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN;
110 props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
111 props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
112 props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
118 DEFINE_ALEFFECT_VTABLE(Distortion);
120 const EffectProps DistortionEffectProps{genDefaultProps()};
125 using DistortionCommitter = EaxCommitter<EaxDistortionCommitter>;
127 struct EdgeValidator {
128 void operator()(float flEdge) const
130 eax_validate_range<DistortionCommitter::Exception>(
133 EAXDISTORTION_MINEDGE,
134 EAXDISTORTION_MAXEDGE);
138 struct GainValidator {
139 void operator()(long lGain) const
141 eax_validate_range<DistortionCommitter::Exception>(
144 EAXDISTORTION_MINGAIN,
145 EAXDISTORTION_MAXGAIN);
149 struct LowPassCutOffValidator {
150 void operator()(float flLowPassCutOff) const
152 eax_validate_range<DistortionCommitter::Exception>(
155 EAXDISTORTION_MINLOWPASSCUTOFF,
156 EAXDISTORTION_MAXLOWPASSCUTOFF);
158 }; // LowPassCutOffValidator
160 struct EqCenterValidator {
161 void operator()(float flEQCenter) const
163 eax_validate_range<DistortionCommitter::Exception>(
166 EAXDISTORTION_MINEQCENTER,
167 EAXDISTORTION_MAXEQCENTER);
169 }; // EqCenterValidator
171 struct EqBandwidthValidator {
172 void operator()(float flEQBandwidth) const
174 eax_validate_range<DistortionCommitter::Exception>(
177 EAXDISTORTION_MINEQBANDWIDTH,
178 EAXDISTORTION_MAXEQBANDWIDTH);
180 }; // EqBandwidthValidator
182 struct AllValidator {
183 void operator()(const EAXDISTORTIONPROPERTIES& all) const
185 EdgeValidator{}(all.flEdge);
186 GainValidator{}(all.lGain);
187 LowPassCutOffValidator{}(all.flLowPassCutOff);
188 EqCenterValidator{}(all.flEQCenter);
189 EqBandwidthValidator{}(all.flEQBandwidth);
196 struct DistortionCommitter::Exception : public EaxException {
197 explicit Exception(const char *message) : EaxException{"EAX_DISTORTION_EFFECT", message}
202 [[noreturn]] void DistortionCommitter::fail(const char *message)
204 throw Exception{message};
208 bool DistortionCommitter::commit(const EaxEffectProps &props)
210 if(props.mType == mEaxProps.mType && mEaxProps.mDistortion.flEdge == props.mDistortion.flEdge
211 && mEaxProps.mDistortion.lGain == props.mDistortion.lGain
212 && mEaxProps.mDistortion.flLowPassCutOff == props.mDistortion.flLowPassCutOff
213 && mEaxProps.mDistortion.flEQCenter == props.mDistortion.flEQCenter
214 && mEaxProps.mDistortion.flEQBandwidth == props.mDistortion.flEQBandwidth)
219 mAlProps.Distortion.Edge = props.mDistortion.flEdge;
220 mAlProps.Distortion.Gain = level_mb_to_gain(static_cast<float>(props.mDistortion.lGain));
221 mAlProps.Distortion.LowpassCutoff = props.mDistortion.flLowPassCutOff;
222 mAlProps.Distortion.EQCenter = props.mDistortion.flEQCenter;
223 mAlProps.Distortion.EQBandwidth = props.mDistortion.flEdge;
229 void DistortionCommitter::SetDefaults(EaxEffectProps &props)
231 props.mType = EaxEffectType::Distortion;
232 props.mDistortion.flEdge = EAXDISTORTION_DEFAULTEDGE;
233 props.mDistortion.lGain = EAXDISTORTION_DEFAULTGAIN;
234 props.mDistortion.flLowPassCutOff = EAXDISTORTION_DEFAULTLOWPASSCUTOFF;
235 props.mDistortion.flEQCenter = EAXDISTORTION_DEFAULTEQCENTER;
236 props.mDistortion.flEQBandwidth = EAXDISTORTION_DEFAULTEQBANDWIDTH;
240 void DistortionCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
242 switch(call.get_property_id())
244 case EAXDISTORTION_NONE: break;
245 case EAXDISTORTION_ALLPARAMETERS: call.set_value<Exception>(props.mDistortion); break;
246 case EAXDISTORTION_EDGE: call.set_value<Exception>(props.mDistortion.flEdge); break;
247 case EAXDISTORTION_GAIN: call.set_value<Exception>(props.mDistortion.lGain); break;
248 case EAXDISTORTION_LOWPASSCUTOFF: call.set_value<Exception>(props.mDistortion.flLowPassCutOff); break;
249 case EAXDISTORTION_EQCENTER: call.set_value<Exception>(props.mDistortion.flEQCenter); break;
250 case EAXDISTORTION_EQBANDWIDTH: call.set_value<Exception>(props.mDistortion.flEQBandwidth); break;
251 default: fail_unknown_property_id();
256 void DistortionCommitter::Set(const EaxCall &call, EaxEffectProps &props)
258 switch(call.get_property_id())
260 case EAXDISTORTION_NONE: break;
261 case EAXDISTORTION_ALLPARAMETERS: defer<AllValidator>(call, props.mDistortion); break;
262 case EAXDISTORTION_EDGE: defer<EdgeValidator>(call, props.mDistortion.flEdge); break;
263 case EAXDISTORTION_GAIN: defer<GainValidator>(call, props.mDistortion.lGain); break;
264 case EAXDISTORTION_LOWPASSCUTOFF: defer<LowPassCutOffValidator>(call, props.mDistortion.flLowPassCutOff); break;
265 case EAXDISTORTION_EQCENTER: defer<EqCenterValidator>(call, props.mDistortion.flEQCenter); break;
266 case EAXDISTORTION_EQBANDWIDTH: defer<EqBandwidthValidator>(call, props.mDistortion.flEQBandwidth); break;
267 default: fail_unknown_property_id();