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> &params)
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