1 /**
2 * Copyright (c) 2006-2016 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21 #include "Effect.h"
22 #include "common/Exception.h"
23
24 #include <cmath>
25 #include <iostream>
26
27 namespace love
28 {
29 namespace audio
30 {
31 namespace openal
32 {
33
34 //base class
Effect()35 Effect::Effect()
36 {
37 generateEffect();
38 }
39
Effect(const Effect & s)40 Effect::Effect(const Effect &s)
41 : Effect()
42 {
43 setParams(s.getParams());
44 }
45
~Effect()46 Effect::~Effect()
47 {
48 deleteEffect();
49 }
50
clone()51 Effect *Effect::clone()
52 {
53 return new Effect(*this);
54 }
55
generateEffect()56 bool Effect::generateEffect()
57 {
58 #ifdef ALC_EXT_EFX
59 if (!alGenEffects)
60 return false;
61
62 if (effect != AL_EFFECT_NULL)
63 return true;
64
65 alGenEffects(1, &effect);
66 if (alGetError() != AL_NO_ERROR)
67 throw love::Exception("Failed to create sound Effect.");
68
69 return true;
70 #else
71 return false;
72 #endif
73 }
74
deleteEffect()75 void Effect::deleteEffect()
76 {
77 #ifdef ALC_EXT_EFX
78 if (effect != AL_EFFECT_NULL)
79 alDeleteEffects(1, &effect);
80 #endif
81 effect = AL_EFFECT_NULL;
82 }
83
getEffect() const84 ALuint Effect::getEffect() const
85 {
86 return effect;
87 }
88
setParams(const std::map<Parameter,float> & params)89 bool Effect::setParams(const std::map<Parameter, float> ¶ms)
90 {
91 this->params = params;
92 type = (Type)(int) this->params[EFFECT_TYPE];
93
94 if (!generateEffect())
95 return false;
96
97 #ifdef ALC_EXT_EFX
98 //parameter table without EFFECT_TYPE entry is illegal
99 switch (type)
100 {
101 case TYPE_REVERB:
102 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
103 break;
104 case TYPE_CHORUS:
105 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS);
106 break;
107 case TYPE_DISTORTION:
108 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION);
109 break;
110 case TYPE_ECHO:
111 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO);
112 break;
113 case TYPE_FLANGER:
114 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER);
115 break;
116 /*
117 case TYPE_FREQSHIFTER:
118 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER);
119 break;
120 case TYPE_MORPHER:
121 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER);
122 break;
123 case TYPE_PITCHSHIFTER:
124 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
125 break;
126 */
127 case TYPE_MODULATOR:
128 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR);
129 break;
130 /*
131 case TYPE_AUTOWAH:
132 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH);
133 break;
134 */
135 case TYPE_COMPRESSOR:
136 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR);
137 break;
138 case TYPE_EQUALIZER:
139 alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
140 break;
141 case TYPE_BASIC:
142 case TYPE_MAX_ENUM:
143 break;
144 }
145
146 //failed to make effect specific type - not supported etc.
147 if (alGetError() != AL_NO_ERROR)
148 {
149 deleteEffect();
150 return false;
151 }
152
153 #define clampf(v,l,h) fmax(fmin((v),(h)),(l))
154 #define PARAMSTR(i,e,v) effect,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v)
155 switch (type)
156 {
157 case TYPE_REVERB:
158 {
159 alEffectf(PARAMSTR(REVERB_GAIN,REVERB,GAIN));
160 alEffectf(PARAMSTR(REVERB_HFGAIN,REVERB,GAINHF));
161 alEffectf(PARAMSTR(REVERB_DENSITY,REVERB,DENSITY));
162 alEffectf(PARAMSTR(REVERB_DIFFUSION,REVERB,DIFFUSION));
163 alEffectf(PARAMSTR(REVERB_DECAY,REVERB,DECAY_TIME));
164 alEffectf(PARAMSTR(REVERB_HFDECAY,REVERB,DECAY_HFRATIO));
165 alEffectf(PARAMSTR(REVERB_EARLYGAIN,REVERB,REFLECTIONS_GAIN));
166 alEffectf(PARAMSTR(REVERB_EARLYDELAY,REVERB,REFLECTIONS_DELAY));
167 alEffectf(PARAMSTR(REVERB_LATEGAIN,REVERB,LATE_REVERB_GAIN));
168 alEffectf(PARAMSTR(REVERB_LATEDELAY,REVERB,LATE_REVERB_DELAY));;
169 alEffectf(PARAMSTR(REVERB_ROLLOFF,REVERB,ROOM_ROLLOFF_FACTOR));
170 alEffectf(PARAMSTR(REVERB_AIRHFGAIN,REVERB,AIR_ABSORPTION_GAINHF));
171 alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, getValue(REVERB_HFLIMITER, 0));
172 break;
173 }
174 case TYPE_CHORUS:
175 {
176 Waveform wave = static_cast<Waveform>(getValue(CHORUS_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
177 if (wave == WAVE_SINE)
178 alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_SINUSOID);
179 else if (wave == WAVE_TRIANGLE)
180 alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_TRIANGLE);
181 else
182 alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_DEFAULT_WAVEFORM);
183
184 alEffecti(PARAMSTR(CHORUS_PHASE,CHORUS,PHASE));
185 alEffectf(PARAMSTR(CHORUS_RATE,CHORUS,RATE));
186 alEffectf(PARAMSTR(CHORUS_DEPTH,CHORUS,DEPTH));
187 alEffectf(PARAMSTR(CHORUS_FEEDBACK,CHORUS,FEEDBACK));
188 alEffectf(PARAMSTR(CHORUS_DELAY,CHORUS,DELAY));
189 break;
190 }
191 case TYPE_DISTORTION:
192 alEffectf(PARAMSTR(DISTORTION_GAIN,DISTORTION,GAIN));
193 alEffectf(PARAMSTR(DISTORTION_EDGE,DISTORTION,EDGE));
194 alEffectf(PARAMSTR(DISTORTION_LOWCUT,DISTORTION,LOWPASS_CUTOFF));
195 alEffectf(PARAMSTR(DISTORTION_EQCENTER,DISTORTION,EQCENTER));
196 alEffectf(PARAMSTR(DISTORTION_EQBAND,DISTORTION,EQBANDWIDTH));
197 break;
198
199 case TYPE_ECHO:
200 alEffectf(PARAMSTR(ECHO_DELAY,ECHO,DELAY));
201 alEffectf(PARAMSTR(ECHO_LRDELAY,ECHO,LRDELAY));
202 alEffectf(PARAMSTR(ECHO_DAMPING,ECHO,DAMPING));
203 alEffectf(PARAMSTR(ECHO_FEEDBACK,ECHO,FEEDBACK));
204 alEffectf(PARAMSTR(ECHO_SPREAD,ECHO,SPREAD));
205 break;
206
207 case TYPE_FLANGER:
208 {
209 Waveform wave = static_cast<Waveform>(getValue(FLANGER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
210 if (wave == WAVE_SINE)
211 alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_SINUSOID);
212 else if (wave == WAVE_TRIANGLE)
213 alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_TRIANGLE);
214 else
215 alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_DEFAULT_WAVEFORM);
216
217 alEffecti(PARAMSTR(FLANGER_PHASE,FLANGER,PHASE));
218 alEffectf(PARAMSTR(FLANGER_RATE,FLANGER,RATE));
219 alEffectf(PARAMSTR(FLANGER_DEPTH,FLANGER,DEPTH));
220 alEffectf(PARAMSTR(FLANGER_FEEDBACK,FLANGER,FEEDBACK));
221 alEffectf(PARAMSTR(FLANGER_DELAY,FLANGER,DELAY));
222 break;
223 }
224 /*
225 case TYPE_FREQSHIFTER:
226 {
227 alEffectf(PARAMSTR(FREQSHIFTER_FREQ,FREQUENCY_SHIFTER,FREQUENCY));
228
229 Direction dir = static_cast<Direction>(getValue(FREQSHIFTER_LEFTDIR, static_cast<int>(DIR_MAX_ENUM)));
230 if (dir == DIR_NONE)
231 alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF);
232 else if(dir == DIR_UP)
233 alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP);
234 else if(dir == DIR_DOWN)
235 alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN);
236 else
237 alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION);
238
239 dir = static_cast<Direction>(getValue(FREQSHIFTER_RIGHTDIR, static_cast<int>(DIR_MAX_ENUM)));
240 if (dir == DIR_NONE)
241 alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF);
242 else if(dir == DIR_UP)
243 alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP);
244 else if(dir == DIR_DOWN)
245 alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN);
246 else
247 alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION);
248 break;
249 }
250 case TYPE_MORPHER:
251 {
252 Waveform wave = static_cast<Waveform>(getValue(MORPHER_WAVEFORM, static_cast<int>(WAVE_MAX_ENUM)));
253 if (wave == WAVE_SINE)
254 alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SINUSOID);
255 else if (wave == WAVE_TRIANGLE)
256 alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE);
257 else if (wave == WAVE_SAWTOOTH)
258 alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH);
259 else
260 alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_DEFAULT_WAVEFORM);
261
262 Phoneme phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEA, static_cast<int>(PHONEME_MAX_ENUM)));
263 if (phoneme == PHONEME_MAX_ENUM)
264 alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, AL_VOCAL_MORPHER_DEFAULT_PHONEMEA);
265 else
266 alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, phonemeMap[phoneme]);
267
268 phoneme = static_cast<Phoneme>(getValue(MORPHER_PHONEMEB, static_cast<int>(PHONEME_MAX_ENUM)));
269 if (phoneme == PHONEME_MAX_ENUM)
270 alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, AL_VOCAL_MORPHER_DEFAULT_PHONEMEB);
271 else
272 alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, phonemeMap[phoneme]);
273
274 alEffectf(PARAMSTR(MORPHER_RATE,VOCAL_MORPHER,RATE));
275 alEffecti(PARAMSTR(MORPHER_TUNEA,VOCAL_MORPHER,PHONEMEA_COARSE_TUNING));
276 alEffecti(PARAMSTR(MORPHER_TUNEB,VOCAL_MORPHER,PHONEMEB_COARSE_TUNING));
277 break;
278 }
279 case TYPE_PITCHSHIFTER:
280 {
281 float tune = getValue(PITCHSHIFTER_PITCH, (float)AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE + (float)(AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE - 50) / 100.0 );
282
283 int coarse = (int)floor(tune);
284 int fine = (int)(fmod(tune, 1.0)*100.0);
285 if (fine > 50)
286 {
287 fine -= 100;
288 coarse += 1;
289 }
290 else if (fine < -50)
291 {
292 fine += 100;
293 coarse -= 1;
294 }
295 if (coarse > AL_PITCH_SHIFTER_MAX_COARSE_TUNE)
296 {
297 coarse = AL_PITCH_SHIFTER_MAX_COARSE_TUNE;
298 fine = AL_PITCH_SHIFTER_MAX_FINE_TUNE;
299 }
300 else if (coarse < AL_PITCH_SHIFTER_MIN_COARSE_TUNE)
301 {
302 coarse = AL_PITCH_SHIFTER_MIN_COARSE_TUNE;
303 fine = AL_PITCH_SHIFTER_MIN_FINE_TUNE;
304 }
305 alEffecti(effect, AL_PITCH_SHIFTER_COARSE_TUNE, coarse);
306 alEffecti(effect, AL_PITCH_SHIFTER_FINE_TUNE, fine);
307 break;
308 }
309 */
310 case TYPE_MODULATOR:
311 {
312 Waveform wave = static_cast<Waveform>(getValue(MODULATOR_WAVEFORM,static_cast<int>(WAVE_MAX_ENUM)));
313 if (wave == WAVE_SINE)
314 alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SINUSOID);
315 else if (wave == WAVE_SAWTOOTH)
316 alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SAWTOOTH);
317 else if (wave == WAVE_SQUARE)
318 alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SQUARE);
319 else
320 alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_DEFAULT_WAVEFORM);
321
322 alEffectf(PARAMSTR(MODULATOR_FREQ,RING_MODULATOR,FREQUENCY));
323 alEffectf(PARAMSTR(MODULATOR_HIGHCUT,RING_MODULATOR,HIGHPASS_CUTOFF));
324 break;
325 }
326 /*
327 case TYPE_AUTOWAH:
328 alEffectf(PARAMSTR(AUTOWAH_ATTACK,AUTOWAH,ATTACK_TIME));
329 alEffectf(PARAMSTR(AUTOWAH_RELEASE,AUTOWAH,RELEASE_TIME));
330 alEffectf(PARAMSTR(AUTOWAH_RESONANCE,AUTOWAH,RESONANCE));
331 alEffectf(PARAMSTR(AUTOWAH_PEAKGAIN,AUTOWAH,PEAK_GAIN));
332 break;
333 */
334 case TYPE_COMPRESSOR:
335 alEffecti(effect, AL_COMPRESSOR_ONOFF, getValue(COMPRESSOR_ENABLE,static_cast<int>(AL_COMPRESSOR_DEFAULT_ONOFF)));
336 break;
337
338 case TYPE_EQUALIZER:
339 alEffectf(PARAMSTR(EQUALIZER_LOWGAIN,EQUALIZER,LOW_GAIN));
340 alEffectf(PARAMSTR(EQUALIZER_LOWCUT,EQUALIZER,LOW_CUTOFF));
341 alEffectf(PARAMSTR(EQUALIZER_MID1GAIN,EQUALIZER,MID1_GAIN));
342 alEffectf(PARAMSTR(EQUALIZER_MID1FREQ,EQUALIZER,MID1_CENTER));
343 alEffectf(PARAMSTR(EQUALIZER_MID1BAND,EQUALIZER,MID1_WIDTH));
344 alEffectf(PARAMSTR(EQUALIZER_MID2GAIN,EQUALIZER,MID2_GAIN));
345 alEffectf(PARAMSTR(EQUALIZER_MID2FREQ,EQUALIZER,MID2_CENTER));
346 alEffectf(PARAMSTR(EQUALIZER_MID2BAND,EQUALIZER,MID2_WIDTH));
347 alEffectf(PARAMSTR(EQUALIZER_HIGHGAIN,EQUALIZER,HIGH_GAIN));
348 alEffectf(PARAMSTR(EQUALIZER_HIGHCUT,EQUALIZER,HIGH_CUTOFF));
349 break;
350 case TYPE_BASIC:
351 case TYPE_MAX_ENUM:
352 break;
353 }
354 #undef PARAMSTR
355 #undef clampf
356 //alGetError();
357
358 return true;
359 #else
360 return false;
361 #endif //ALC_EXT_EFX
362 }
363
getParams() const364 const std::map<Effect::Parameter, float> &Effect::getParams() const
365 {
366 return params;
367 }
368
getValue(Parameter in,float def) const369 float Effect::getValue(Parameter in, float def) const
370 {
371 return params.find(in) == params.end() ? def : params.at(in);
372 }
373
getValue(Parameter in,int def) const374 int Effect::getValue(Parameter in, int def) const
375 {
376 return params.find(in) == params.end() ? def : static_cast<int>(params.at(in));
377 }
378
379 /*
380 std::map<Effect::Phoneme, ALint> Effect::phonemeMap =
381 {
382 {Effect::PHONEME_A, AL_VOCAL_MORPHER_PHONEME_A},
383 {Effect::PHONEME_E, AL_VOCAL_MORPHER_PHONEME_E},
384 {Effect::PHONEME_I, AL_VOCAL_MORPHER_PHONEME_I},
385 {Effect::PHONEME_O, AL_VOCAL_MORPHER_PHONEME_O},
386 {Effect::PHONEME_U, AL_VOCAL_MORPHER_PHONEME_U},
387 {Effect::PHONEME_AA, AL_VOCAL_MORPHER_PHONEME_AA},
388 {Effect::PHONEME_AE, AL_VOCAL_MORPHER_PHONEME_AE},
389 {Effect::PHONEME_AH, AL_VOCAL_MORPHER_PHONEME_AH},
390 {Effect::PHONEME_AO, AL_VOCAL_MORPHER_PHONEME_AO},
391 {Effect::PHONEME_EH, AL_VOCAL_MORPHER_PHONEME_EH},
392 {Effect::PHONEME_ER, AL_VOCAL_MORPHER_PHONEME_ER},
393 {Effect::PHONEME_IH, AL_VOCAL_MORPHER_PHONEME_IH},
394 {Effect::PHONEME_IY, AL_VOCAL_MORPHER_PHONEME_IY},
395 {Effect::PHONEME_UH, AL_VOCAL_MORPHER_PHONEME_UH},
396 {Effect::PHONEME_UW, AL_VOCAL_MORPHER_PHONEME_UW},
397 {Effect::PHONEME_B, AL_VOCAL_MORPHER_PHONEME_B},
398 {Effect::PHONEME_D, AL_VOCAL_MORPHER_PHONEME_D},
399 {Effect::PHONEME_F, AL_VOCAL_MORPHER_PHONEME_F},
400 {Effect::PHONEME_G, AL_VOCAL_MORPHER_PHONEME_G},
401 {Effect::PHONEME_J, AL_VOCAL_MORPHER_PHONEME_J},
402 {Effect::PHONEME_K, AL_VOCAL_MORPHER_PHONEME_K},
403 {Effect::PHONEME_L, AL_VOCAL_MORPHER_PHONEME_L},
404 {Effect::PHONEME_M, AL_VOCAL_MORPHER_PHONEME_M},
405 {Effect::PHONEME_N, AL_VOCAL_MORPHER_PHONEME_N},
406 {Effect::PHONEME_P, AL_VOCAL_MORPHER_PHONEME_P},
407 {Effect::PHONEME_R, AL_VOCAL_MORPHER_PHONEME_R},
408 {Effect::PHONEME_S, AL_VOCAL_MORPHER_PHONEME_S},
409 {Effect::PHONEME_T, AL_VOCAL_MORPHER_PHONEME_T},
410 {Effect::PHONEME_V, AL_VOCAL_MORPHER_PHONEME_V},
411 {Effect::PHONEME_Z, AL_VOCAL_MORPHER_PHONEME_Z}
412 };
413 */
414
415 } //openal
416 } //audio
417 } //love
418