]> git.tdb.fi Git - ext/openal.git/blob - al/effects/autowah.cpp
Import OpenAL Soft 1.23.1 sources
[ext/openal.git] / al / effects / autowah.cpp
1
2 #include "config.h"
3
4 #include <cmath>
5 #include <cstdlib>
6
7 #include <algorithm>
8
9 #include "AL/efx.h"
10
11 #include "alc/effects/base.h"
12 #include "effects.h"
13
14 #ifdef ALSOFT_EAX
15 #include "alnumeric.h"
16 #include "al/eax/exception.h"
17 #include "al/eax/utils.h"
18 #endif // ALSOFT_EAX
19
20
21 namespace {
22
23 void Autowah_setParamf(EffectProps *props, ALenum param, float val)
24 {
25     switch(param)
26     {
27     case AL_AUTOWAH_ATTACK_TIME:
28         if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME))
29             throw effect_exception{AL_INVALID_VALUE, "Autowah attack time out of range"};
30         props->Autowah.AttackTime = val;
31         break;
32
33     case AL_AUTOWAH_RELEASE_TIME:
34         if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME))
35             throw effect_exception{AL_INVALID_VALUE, "Autowah release time out of range"};
36         props->Autowah.ReleaseTime = val;
37         break;
38
39     case AL_AUTOWAH_RESONANCE:
40         if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE))
41             throw effect_exception{AL_INVALID_VALUE, "Autowah resonance out of range"};
42         props->Autowah.Resonance = val;
43         break;
44
45     case AL_AUTOWAH_PEAK_GAIN:
46         if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN))
47             throw effect_exception{AL_INVALID_VALUE, "Autowah peak gain out of range"};
48         props->Autowah.PeakGain = val;
49         break;
50
51     default:
52         throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
53     }
54 }
55 void Autowah_setParamfv(EffectProps *props,  ALenum param, const float *vals)
56 { Autowah_setParamf(props, param, vals[0]); }
57
58 void Autowah_setParami(EffectProps*, ALenum param, int)
59 { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
60 void Autowah_setParamiv(EffectProps*, ALenum param, const int*)
61 {
62     throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
63         param};
64 }
65
66 void Autowah_getParamf(const EffectProps *props, ALenum param, float *val)
67 {
68     switch(param)
69     {
70     case AL_AUTOWAH_ATTACK_TIME:
71         *val = props->Autowah.AttackTime;
72         break;
73
74     case AL_AUTOWAH_RELEASE_TIME:
75         *val = props->Autowah.ReleaseTime;
76         break;
77
78     case AL_AUTOWAH_RESONANCE:
79         *val = props->Autowah.Resonance;
80         break;
81
82     case AL_AUTOWAH_PEAK_GAIN:
83         *val = props->Autowah.PeakGain;
84         break;
85
86     default:
87         throw effect_exception{AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param};
88     }
89
90 }
91 void Autowah_getParamfv(const EffectProps *props, ALenum param, float *vals)
92 { Autowah_getParamf(props, param, vals); }
93
94 void Autowah_getParami(const EffectProps*, ALenum param, int*)
95 { throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param}; }
96 void Autowah_getParamiv(const EffectProps*, ALenum param, int*)
97 {
98     throw effect_exception{AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x",
99         param};
100 }
101
102 EffectProps genDefaultProps() noexcept
103 {
104     EffectProps props{};
105     props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
106     props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
107     props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
108     props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
109     return props;
110 }
111
112 } // namespace
113
114 DEFINE_ALEFFECT_VTABLE(Autowah);
115
116 const EffectProps AutowahEffectProps{genDefaultProps()};
117
118 #ifdef ALSOFT_EAX
119 namespace {
120
121 using AutowahCommitter = EaxCommitter<EaxAutowahCommitter>;
122
123 struct AttackTimeValidator {
124     void operator()(float flAttackTime) const
125     {
126         eax_validate_range<AutowahCommitter::Exception>(
127             "Attack Time",
128             flAttackTime,
129             EAXAUTOWAH_MINATTACKTIME,
130             EAXAUTOWAH_MAXATTACKTIME);
131     }
132 }; // AttackTimeValidator
133
134 struct ReleaseTimeValidator {
135     void operator()(float flReleaseTime) const
136     {
137         eax_validate_range<AutowahCommitter::Exception>(
138             "Release Time",
139             flReleaseTime,
140             EAXAUTOWAH_MINRELEASETIME,
141             EAXAUTOWAH_MAXRELEASETIME);
142     }
143 }; // ReleaseTimeValidator
144
145 struct ResonanceValidator {
146     void operator()(long lResonance) const
147     {
148         eax_validate_range<AutowahCommitter::Exception>(
149             "Resonance",
150             lResonance,
151             EAXAUTOWAH_MINRESONANCE,
152             EAXAUTOWAH_MAXRESONANCE);
153     }
154 }; // ResonanceValidator
155
156 struct PeakLevelValidator {
157     void operator()(long lPeakLevel) const
158     {
159         eax_validate_range<AutowahCommitter::Exception>(
160             "Peak Level",
161             lPeakLevel,
162             EAXAUTOWAH_MINPEAKLEVEL,
163             EAXAUTOWAH_MAXPEAKLEVEL);
164     }
165 }; // PeakLevelValidator
166
167 struct AllValidator {
168     void operator()(const EAXAUTOWAHPROPERTIES& all) const
169     {
170         AttackTimeValidator{}(all.flAttackTime);
171         ReleaseTimeValidator{}(all.flReleaseTime);
172         ResonanceValidator{}(all.lResonance);
173         PeakLevelValidator{}(all.lPeakLevel);
174     }
175 }; // AllValidator
176
177 } // namespace
178
179 template<>
180 struct AutowahCommitter::Exception : public EaxException
181 {
182     explicit Exception(const char *message) : EaxException{"EAX_AUTOWAH_EFFECT", message}
183     { }
184 };
185
186 template<>
187 [[noreturn]] void AutowahCommitter::fail(const char *message)
188 {
189     throw Exception{message};
190 }
191
192 template<>
193 bool AutowahCommitter::commit(const EaxEffectProps &props)
194 {
195     if(props.mType == mEaxProps.mType
196         && mEaxProps.mAutowah.flAttackTime == props.mAutowah.flAttackTime
197         && mEaxProps.mAutowah.flReleaseTime == props.mAutowah.flReleaseTime
198         && mEaxProps.mAutowah.lResonance == props.mAutowah.lResonance
199         && mEaxProps.mAutowah.lPeakLevel == props.mAutowah.lPeakLevel)
200         return false;
201
202     mEaxProps = props;
203
204     mAlProps.Autowah.AttackTime = props.mAutowah.flAttackTime;
205     mAlProps.Autowah.ReleaseTime = props.mAutowah.flReleaseTime;
206     mAlProps.Autowah.Resonance = level_mb_to_gain(static_cast<float>(props.mAutowah.lResonance));
207     mAlProps.Autowah.PeakGain = level_mb_to_gain(static_cast<float>(props.mAutowah.lPeakLevel));
208
209     return true;
210 }
211
212 template<>
213 void AutowahCommitter::SetDefaults(EaxEffectProps &props)
214 {
215     props.mType = EaxEffectType::Autowah;
216     props.mAutowah.flAttackTime = EAXAUTOWAH_DEFAULTATTACKTIME;
217     props.mAutowah.flReleaseTime = EAXAUTOWAH_DEFAULTRELEASETIME;
218     props.mAutowah.lResonance = EAXAUTOWAH_DEFAULTRESONANCE;
219     props.mAutowah.lPeakLevel = EAXAUTOWAH_DEFAULTPEAKLEVEL;
220 }
221
222 template<>
223 void AutowahCommitter::Get(const EaxCall &call, const EaxEffectProps &props)
224 {
225     switch(call.get_property_id())
226     {
227     case EAXAUTOWAH_NONE: break;
228     case EAXAUTOWAH_ALLPARAMETERS: call.set_value<Exception>(props.mAutowah); break;
229     case EAXAUTOWAH_ATTACKTIME: call.set_value<Exception>(props.mAutowah.flAttackTime); break;
230     case EAXAUTOWAH_RELEASETIME: call.set_value<Exception>(props.mAutowah.flReleaseTime); break;
231     case EAXAUTOWAH_RESONANCE: call.set_value<Exception>(props.mAutowah.lResonance); break;
232     case EAXAUTOWAH_PEAKLEVEL: call.set_value<Exception>(props.mAutowah.lPeakLevel); break;
233     default: fail_unknown_property_id();
234     }
235 }
236
237 template<>
238 void AutowahCommitter::Set(const EaxCall &call, EaxEffectProps &props)
239 {
240     switch(call.get_property_id())
241     {
242     case EAXAUTOWAH_NONE: break;
243     case EAXAUTOWAH_ALLPARAMETERS: defer<AllValidator>(call, props.mAutowah); break;
244     case EAXAUTOWAH_ATTACKTIME: defer<AttackTimeValidator>(call, props.mAutowah.flAttackTime); break;
245     case EAXAUTOWAH_RELEASETIME: defer<ReleaseTimeValidator>(call, props.mAutowah.flReleaseTime); break;
246     case EAXAUTOWAH_RESONANCE: defer<ResonanceValidator>(call, props.mAutowah.lResonance); break;
247     case EAXAUTOWAH_PEAKLEVEL: defer<PeakLevelValidator>(call, props.mAutowah.lPeakLevel); break;
248     default: fail_unknown_property_id();
249     }
250 }
251
252 #endif // ALSOFT_EAX