Combine nearly-duplicate structures
[openal-soft.git] / OpenAL32 / alEffect.c
blobc2a78a0ca9509ed423ccb3c999f26d78ccdc2c9c
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include <math.h>
25 #include <float.h>
27 #include "AL/al.h"
28 #include "AL/alc.h"
29 #include "alMain.h"
30 #include "alEffect.h"
31 #include "alError.h"
34 extern inline void LockEffectList(ALCdevice *device);
35 extern inline void UnlockEffectList(ALCdevice *device);
36 extern inline ALboolean IsReverbEffect(ALenum type);
38 const struct EffectList EffectList[EFFECTLIST_SIZE] = {
39 { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB },
40 { "reverb", REVERB_EFFECT, AL_EFFECT_REVERB },
41 { "autowah", AUTOWAH_EFFECT, AL_EFFECT_AUTOWAH },
42 { "chorus", CHORUS_EFFECT, AL_EFFECT_CHORUS },
43 { "compressor", COMPRESSOR_EFFECT, AL_EFFECT_COMPRESSOR },
44 { "distortion", DISTORTION_EFFECT, AL_EFFECT_DISTORTION },
45 { "echo", ECHO_EFFECT, AL_EFFECT_ECHO },
46 { "equalizer", EQUALIZER_EFFECT, AL_EFFECT_EQUALIZER },
47 { "flanger", FLANGER_EFFECT, AL_EFFECT_FLANGER },
48 { "fshifter", FSHIFTER_EFFECT, AL_EFFECT_FREQUENCY_SHIFTER },
49 { "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR },
50 { "pshifter", PSHIFTER_EFFECT, AL_EFFECT_PITCH_SHIFTER },
51 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
52 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_DIALOGUE },
55 ALboolean DisabledEffects[MAX_EFFECTS];
57 static ALeffect *AllocEffect(ALCcontext *context);
58 static void FreeEffect(ALCdevice *device, ALeffect *effect);
59 static void InitEffectParams(ALeffect *effect, ALenum type);
61 static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
63 EffectSubList *sublist;
64 ALuint lidx = (id-1) >> 6;
65 ALsizei slidx = (id-1) & 0x3f;
67 if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList)))
68 return NULL;
69 sublist = &VECTOR_ELEM(device->EffectList, lidx);
70 if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
71 return NULL;
72 return sublist->Effects + slidx;
76 AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
78 ALCcontext *context;
79 ALsizei cur;
81 context = GetContextRef();
82 if(!context) return;
84 if(!(n >= 0))
85 alSetError(context, AL_INVALID_VALUE, "Generating %d effects", n);
86 else for(cur = 0;cur < n;cur++)
88 ALeffect *effect = AllocEffect(context);
89 if(!effect)
91 alDeleteEffects(cur, effects);
92 break;
94 effects[cur] = effect->id;
97 ALCcontext_DecRef(context);
100 AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
102 ALCdevice *device;
103 ALCcontext *context;
104 ALeffect *effect;
105 ALsizei i;
107 context = GetContextRef();
108 if(!context) return;
110 device = context->Device;
111 LockEffectList(device);
112 if(!(n >= 0))
113 SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n);
114 for(i = 0;i < n;i++)
116 if(effects[i] && LookupEffect(device, effects[i]) == NULL)
117 SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect ID %u", effects[i]);
119 for(i = 0;i < n;i++)
121 if((effect=LookupEffect(device, effects[i])) != NULL)
122 FreeEffect(device, effect);
125 done:
126 UnlockEffectList(device);
127 ALCcontext_DecRef(context);
130 AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
132 ALCcontext *Context;
133 ALboolean result;
135 Context = GetContextRef();
136 if(!Context) return AL_FALSE;
138 LockEffectList(Context->Device);
139 result = ((!effect || LookupEffect(Context->Device, effect)) ?
140 AL_TRUE : AL_FALSE);
141 UnlockEffectList(Context->Device);
143 ALCcontext_DecRef(Context);
145 return result;
148 AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
150 ALCcontext *Context;
151 ALCdevice *Device;
152 ALeffect *ALEffect;
154 Context = GetContextRef();
155 if(!Context) return;
157 Device = Context->Device;
158 LockEffectList(Device);
159 if((ALEffect=LookupEffect(Device, effect)) == NULL)
160 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
161 else
163 if(param == AL_EFFECT_TYPE)
165 ALboolean isOk = (value == AL_EFFECT_NULL);
166 ALint i;
167 for(i = 0;!isOk && i < EFFECTLIST_SIZE;i++)
169 if(value == EffectList[i].val &&
170 !DisabledEffects[EffectList[i].type])
171 isOk = AL_TRUE;
174 if(isOk)
175 InitEffectParams(ALEffect, value);
176 else
177 alSetError(Context, AL_INVALID_VALUE, "Effect type 0x%04x not supported", value);
179 else
181 /* Call the appropriate handler */
182 ALeffect_setParami(ALEffect, Context, param, value);
185 UnlockEffectList(Device);
187 ALCcontext_DecRef(Context);
190 AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *values)
192 ALCcontext *Context;
193 ALCdevice *Device;
194 ALeffect *ALEffect;
196 switch(param)
198 case AL_EFFECT_TYPE:
199 alEffecti(effect, param, values[0]);
200 return;
203 Context = GetContextRef();
204 if(!Context) return;
206 Device = Context->Device;
207 LockEffectList(Device);
208 if((ALEffect=LookupEffect(Device, effect)) == NULL)
209 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
210 else
212 /* Call the appropriate handler */
213 ALeffect_setParamiv(ALEffect, Context, param, values);
215 UnlockEffectList(Device);
217 ALCcontext_DecRef(Context);
220 AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
222 ALCcontext *Context;
223 ALCdevice *Device;
224 ALeffect *ALEffect;
226 Context = GetContextRef();
227 if(!Context) return;
229 Device = Context->Device;
230 LockEffectList(Device);
231 if((ALEffect=LookupEffect(Device, effect)) == NULL)
232 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
233 else
235 /* Call the appropriate handler */
236 ALeffect_setParamf(ALEffect, Context, param, value);
238 UnlockEffectList(Device);
240 ALCcontext_DecRef(Context);
243 AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *values)
245 ALCcontext *Context;
246 ALCdevice *Device;
247 ALeffect *ALEffect;
249 Context = GetContextRef();
250 if(!Context) return;
252 Device = Context->Device;
253 LockEffectList(Device);
254 if((ALEffect=LookupEffect(Device, effect)) == NULL)
255 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
256 else
258 /* Call the appropriate handler */
259 ALeffect_setParamfv(ALEffect, Context, param, values);
261 UnlockEffectList(Device);
263 ALCcontext_DecRef(Context);
266 AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value)
268 ALCcontext *Context;
269 ALCdevice *Device;
270 ALeffect *ALEffect;
272 Context = GetContextRef();
273 if(!Context) return;
275 Device = Context->Device;
276 LockEffectList(Device);
277 if((ALEffect=LookupEffect(Device, effect)) == NULL)
278 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
279 else
281 if(param == AL_EFFECT_TYPE)
282 *value = ALEffect->type;
283 else
285 /* Call the appropriate handler */
286 ALeffect_getParami(ALEffect, Context, param, value);
289 UnlockEffectList(Device);
291 ALCcontext_DecRef(Context);
294 AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *values)
296 ALCcontext *Context;
297 ALCdevice *Device;
298 ALeffect *ALEffect;
300 switch(param)
302 case AL_EFFECT_TYPE:
303 alGetEffecti(effect, param, values);
304 return;
307 Context = GetContextRef();
308 if(!Context) return;
310 Device = Context->Device;
311 LockEffectList(Device);
312 if((ALEffect=LookupEffect(Device, effect)) == NULL)
313 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
314 else
316 /* Call the appropriate handler */
317 ALeffect_getParamiv(ALEffect, Context, param, values);
319 UnlockEffectList(Device);
321 ALCcontext_DecRef(Context);
324 AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value)
326 ALCcontext *Context;
327 ALCdevice *Device;
328 ALeffect *ALEffect;
330 Context = GetContextRef();
331 if(!Context) return;
333 Device = Context->Device;
334 LockEffectList(Device);
335 if((ALEffect=LookupEffect(Device, effect)) == NULL)
336 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
337 else
339 /* Call the appropriate handler */
340 ALeffect_getParamf(ALEffect, Context, param, value);
342 UnlockEffectList(Device);
344 ALCcontext_DecRef(Context);
347 AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *values)
349 ALCcontext *Context;
350 ALCdevice *Device;
351 ALeffect *ALEffect;
353 Context = GetContextRef();
354 if(!Context) return;
356 Device = Context->Device;
357 LockEffectList(Device);
358 if((ALEffect=LookupEffect(Device, effect)) == NULL)
359 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
360 else
362 /* Call the appropriate handler */
363 ALeffect_getParamfv(ALEffect, Context, param, values);
365 UnlockEffectList(Device);
367 ALCcontext_DecRef(Context);
371 void InitEffect(ALeffect *effect)
373 InitEffectParams(effect, AL_EFFECT_NULL);
376 static ALeffect *AllocEffect(ALCcontext *context)
378 ALCdevice *device = context->Device;
379 EffectSubList *sublist, *subend;
380 ALeffect *effect = NULL;
381 ALsizei lidx = 0;
382 ALsizei slidx;
384 almtx_lock(&device->EffectLock);
385 sublist = VECTOR_BEGIN(device->EffectList);
386 subend = VECTOR_END(device->EffectList);
387 for(;sublist != subend;++sublist)
389 if(sublist->FreeMask)
391 slidx = CTZ64(sublist->FreeMask);
392 effect = sublist->Effects + slidx;
393 break;
395 ++lidx;
397 if(UNLIKELY(!effect))
399 const EffectSubList empty_sublist = { 0, NULL };
400 /* Don't allocate so many list entries that the 32-bit ID could
401 * overflow...
403 if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25))
405 almtx_unlock(&device->EffectLock);
406 alSetError(context, AL_OUT_OF_MEMORY, "Too many effects allocated");
407 return NULL;
409 lidx = (ALsizei)VECTOR_SIZE(device->EffectList);
410 VECTOR_PUSH_BACK(device->EffectList, empty_sublist);
411 sublist = &VECTOR_BACK(device->EffectList);
412 sublist->FreeMask = ~U64(0);
413 sublist->Effects = al_calloc(16, sizeof(ALeffect)*64);
414 if(UNLIKELY(!sublist->Effects))
416 VECTOR_POP_BACK(device->EffectList);
417 almtx_unlock(&device->EffectLock);
418 alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate effect batch");
419 return NULL;
422 slidx = 0;
423 effect = sublist->Effects + slidx;
426 memset(effect, 0, sizeof(*effect));
427 InitEffectParams(effect, AL_EFFECT_NULL);
429 /* Add 1 to avoid effect ID 0. */
430 effect->id = ((lidx<<6) | slidx) + 1;
432 sublist->FreeMask &= ~(U64(1)<<slidx);
433 almtx_unlock(&device->EffectLock);
435 return effect;
438 static void FreeEffect(ALCdevice *device, ALeffect *effect)
440 ALuint id = effect->id - 1;
441 ALsizei lidx = id >> 6;
442 ALsizei slidx = id & 0x3f;
444 memset(effect, 0, sizeof(*effect));
446 VECTOR_ELEM(device->EffectList, lidx).FreeMask |= U64(1) << slidx;
449 void ReleaseALEffects(ALCdevice *device)
451 EffectSubList *sublist = VECTOR_BEGIN(device->EffectList);
452 EffectSubList *subend = VECTOR_END(device->EffectList);
453 size_t leftover = 0;
454 for(;sublist != subend;++sublist)
456 ALuint64 usemask = ~sublist->FreeMask;
457 while(usemask)
459 ALsizei idx = CTZ64(usemask);
460 ALeffect *effect = sublist->Effects + idx;
462 memset(effect, 0, sizeof(*effect));
463 ++leftover;
465 usemask &= ~(U64(1) << idx);
467 sublist->FreeMask = ~usemask;
469 if(leftover > 0)
470 WARN("(%p) Deleted "SZFMT" Effect%s\n", device, leftover, (leftover==1)?"":"s");
474 static void InitEffectParams(ALeffect *effect, ALenum type)
476 switch(type)
478 case AL_EFFECT_EAXREVERB:
479 effect->Props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
480 effect->Props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
481 effect->Props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
482 effect->Props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
483 effect->Props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
484 effect->Props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
485 effect->Props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
486 effect->Props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
487 effect->Props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
488 effect->Props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
489 effect->Props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
490 effect->Props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
491 effect->Props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
492 effect->Props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
493 effect->Props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
494 effect->Props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
495 effect->Props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
496 effect->Props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
497 effect->Props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
498 effect->Props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
499 effect->Props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
500 effect->Props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
501 effect->Props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
502 effect->Props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
503 effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
504 effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
505 effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
506 effect->vtab = &ALeaxreverb_vtable;
507 break;
508 case AL_EFFECT_REVERB:
509 effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY;
510 effect->Props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
511 effect->Props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN;
512 effect->Props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF;
513 effect->Props.Reverb.GainLF = 1.0f;
514 effect->Props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
515 effect->Props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
516 effect->Props.Reverb.DecayLFRatio = 1.0f;
517 effect->Props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
518 effect->Props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
519 effect->Props.Reverb.ReflectionsPan[0] = 0.0f;
520 effect->Props.Reverb.ReflectionsPan[1] = 0.0f;
521 effect->Props.Reverb.ReflectionsPan[2] = 0.0f;
522 effect->Props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
523 effect->Props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
524 effect->Props.Reverb.LateReverbPan[0] = 0.0f;
525 effect->Props.Reverb.LateReverbPan[1] = 0.0f;
526 effect->Props.Reverb.LateReverbPan[2] = 0.0f;
527 effect->Props.Reverb.EchoTime = 0.25f;
528 effect->Props.Reverb.EchoDepth = 0.0f;
529 effect->Props.Reverb.ModulationTime = 0.25f;
530 effect->Props.Reverb.ModulationDepth = 0.0f;
531 effect->Props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
532 effect->Props.Reverb.HFReference = 5000.0f;
533 effect->Props.Reverb.LFReference = 250.0f;
534 effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
535 effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
536 effect->vtab = &ALreverb_vtable;
537 break;
538 case AL_EFFECT_AUTOWAH:
539 effect->Props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
540 effect->Props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
541 effect->Props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
542 effect->Props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
543 effect->vtab = &ALautowah_vtable;
544 break;
545 case AL_EFFECT_CHORUS:
546 effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM;
547 effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE;
548 effect->Props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE;
549 effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH;
550 effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK;
551 effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY;
552 effect->vtab = &ALchorus_vtable;
553 break;
554 case AL_EFFECT_COMPRESSOR:
555 effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
556 effect->vtab = &ALcompressor_vtable;
557 break;
558 case AL_EFFECT_DISTORTION:
559 effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE;
560 effect->Props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN;
561 effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
562 effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
563 effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
564 effect->vtab = &ALdistortion_vtable;
565 break;
566 case AL_EFFECT_ECHO:
567 effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY;
568 effect->Props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
569 effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
570 effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
571 effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
572 effect->vtab = &ALecho_vtable;
573 break;
574 case AL_EFFECT_EQUALIZER:
575 effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
576 effect->Props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
577 effect->Props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
578 effect->Props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
579 effect->Props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
580 effect->Props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
581 effect->Props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
582 effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
583 effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
584 effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
585 effect->vtab = &ALequalizer_vtable;
586 break;
587 case AL_EFFECT_FLANGER:
588 effect->Props.Chorus.Waveform = AL_FLANGER_DEFAULT_WAVEFORM;
589 effect->Props.Chorus.Phase = AL_FLANGER_DEFAULT_PHASE;
590 effect->Props.Chorus.Rate = AL_FLANGER_DEFAULT_RATE;
591 effect->Props.Chorus.Depth = AL_FLANGER_DEFAULT_DEPTH;
592 effect->Props.Chorus.Feedback = AL_FLANGER_DEFAULT_FEEDBACK;
593 effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY;
594 effect->vtab = &ALflanger_vtable;
595 break;
596 case AL_EFFECT_FREQUENCY_SHIFTER:
597 effect->Props.Fshifter.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY;
598 effect->Props.Fshifter.LeftDirection = AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION;
599 effect->Props.Fshifter.RightDirection = AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION;
600 effect->vtab = &ALfshifter_vtable;
601 break;
602 case AL_EFFECT_RING_MODULATOR:
603 effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
604 effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
605 effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM;
606 effect->vtab = &ALmodulator_vtable;
607 break;
608 case AL_EFFECT_PITCH_SHIFTER:
609 effect->Props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
610 effect->Props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
611 effect->vtab = &ALpshifter_vtable;
612 break;
613 case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT:
614 case AL_EFFECT_DEDICATED_DIALOGUE:
615 effect->Props.Dedicated.Gain = 1.0f;
616 effect->vtab = &ALdedicated_vtable;
617 break;
618 default:
619 effect->vtab = &ALnull_vtable;
620 break;
622 effect->type = type;
626 #include "AL/efx-presets.h"
628 #define DECL(x) { #x, EFX_REVERB_PRESET_##x }
629 static const struct {
630 const char name[32];
631 EFXEAXREVERBPROPERTIES props;
632 } reverblist[] = {
633 DECL(GENERIC),
634 DECL(PADDEDCELL),
635 DECL(ROOM),
636 DECL(BATHROOM),
637 DECL(LIVINGROOM),
638 DECL(STONEROOM),
639 DECL(AUDITORIUM),
640 DECL(CONCERTHALL),
641 DECL(CAVE),
642 DECL(ARENA),
643 DECL(HANGAR),
644 DECL(CARPETEDHALLWAY),
645 DECL(HALLWAY),
646 DECL(STONECORRIDOR),
647 DECL(ALLEY),
648 DECL(FOREST),
649 DECL(CITY),
650 DECL(MOUNTAINS),
651 DECL(QUARRY),
652 DECL(PLAIN),
653 DECL(PARKINGLOT),
654 DECL(SEWERPIPE),
655 DECL(UNDERWATER),
656 DECL(DRUGGED),
657 DECL(DIZZY),
658 DECL(PSYCHOTIC),
660 DECL(CASTLE_SMALLROOM),
661 DECL(CASTLE_SHORTPASSAGE),
662 DECL(CASTLE_MEDIUMROOM),
663 DECL(CASTLE_LARGEROOM),
664 DECL(CASTLE_LONGPASSAGE),
665 DECL(CASTLE_HALL),
666 DECL(CASTLE_CUPBOARD),
667 DECL(CASTLE_COURTYARD),
668 DECL(CASTLE_ALCOVE),
670 DECL(FACTORY_SMALLROOM),
671 DECL(FACTORY_SHORTPASSAGE),
672 DECL(FACTORY_MEDIUMROOM),
673 DECL(FACTORY_LARGEROOM),
674 DECL(FACTORY_LONGPASSAGE),
675 DECL(FACTORY_HALL),
676 DECL(FACTORY_CUPBOARD),
677 DECL(FACTORY_COURTYARD),
678 DECL(FACTORY_ALCOVE),
680 DECL(ICEPALACE_SMALLROOM),
681 DECL(ICEPALACE_SHORTPASSAGE),
682 DECL(ICEPALACE_MEDIUMROOM),
683 DECL(ICEPALACE_LARGEROOM),
684 DECL(ICEPALACE_LONGPASSAGE),
685 DECL(ICEPALACE_HALL),
686 DECL(ICEPALACE_CUPBOARD),
687 DECL(ICEPALACE_COURTYARD),
688 DECL(ICEPALACE_ALCOVE),
690 DECL(SPACESTATION_SMALLROOM),
691 DECL(SPACESTATION_SHORTPASSAGE),
692 DECL(SPACESTATION_MEDIUMROOM),
693 DECL(SPACESTATION_LARGEROOM),
694 DECL(SPACESTATION_LONGPASSAGE),
695 DECL(SPACESTATION_HALL),
696 DECL(SPACESTATION_CUPBOARD),
697 DECL(SPACESTATION_ALCOVE),
699 DECL(WOODEN_SMALLROOM),
700 DECL(WOODEN_SHORTPASSAGE),
701 DECL(WOODEN_MEDIUMROOM),
702 DECL(WOODEN_LARGEROOM),
703 DECL(WOODEN_LONGPASSAGE),
704 DECL(WOODEN_HALL),
705 DECL(WOODEN_CUPBOARD),
706 DECL(WOODEN_COURTYARD),
707 DECL(WOODEN_ALCOVE),
709 DECL(SPORT_EMPTYSTADIUM),
710 DECL(SPORT_SQUASHCOURT),
711 DECL(SPORT_SMALLSWIMMINGPOOL),
712 DECL(SPORT_LARGESWIMMINGPOOL),
713 DECL(SPORT_GYMNASIUM),
714 DECL(SPORT_FULLSTADIUM),
715 DECL(SPORT_STADIUMTANNOY),
717 DECL(PREFAB_WORKSHOP),
718 DECL(PREFAB_SCHOOLROOM),
719 DECL(PREFAB_PRACTISEROOM),
720 DECL(PREFAB_OUTHOUSE),
721 DECL(PREFAB_CARAVAN),
723 DECL(DOME_TOMB),
724 DECL(PIPE_SMALL),
725 DECL(DOME_SAINTPAULS),
726 DECL(PIPE_LONGTHIN),
727 DECL(PIPE_LARGE),
728 DECL(PIPE_RESONANT),
730 DECL(OUTDOORS_BACKYARD),
731 DECL(OUTDOORS_ROLLINGPLAINS),
732 DECL(OUTDOORS_DEEPCANYON),
733 DECL(OUTDOORS_CREEK),
734 DECL(OUTDOORS_VALLEY),
736 DECL(MOOD_HEAVEN),
737 DECL(MOOD_HELL),
738 DECL(MOOD_MEMORY),
740 DECL(DRIVING_COMMENTATOR),
741 DECL(DRIVING_PITGARAGE),
742 DECL(DRIVING_INCAR_RACER),
743 DECL(DRIVING_INCAR_SPORTS),
744 DECL(DRIVING_INCAR_LUXURY),
745 DECL(DRIVING_FULLGRANDSTAND),
746 DECL(DRIVING_EMPTYGRANDSTAND),
747 DECL(DRIVING_TUNNEL),
749 DECL(CITY_STREETS),
750 DECL(CITY_SUBWAY),
751 DECL(CITY_MUSEUM),
752 DECL(CITY_LIBRARY),
753 DECL(CITY_UNDERPASS),
754 DECL(CITY_ABANDONED),
756 DECL(DUSTYROOM),
757 DECL(CHAPEL),
758 DECL(SMALLWATERROOM),
760 #undef DECL
762 void LoadReverbPreset(const char *name, ALeffect *effect)
764 size_t i;
766 if(strcasecmp(name, "NONE") == 0)
768 InitEffectParams(effect, AL_EFFECT_NULL);
769 TRACE("Loading reverb '%s'\n", "NONE");
770 return;
773 if(!DisabledEffects[EAXREVERB_EFFECT])
774 InitEffectParams(effect, AL_EFFECT_EAXREVERB);
775 else if(!DisabledEffects[REVERB_EFFECT])
776 InitEffectParams(effect, AL_EFFECT_REVERB);
777 else
778 InitEffectParams(effect, AL_EFFECT_NULL);
779 for(i = 0;i < COUNTOF(reverblist);i++)
781 const EFXEAXREVERBPROPERTIES *props;
783 if(strcasecmp(name, reverblist[i].name) != 0)
784 continue;
786 TRACE("Loading reverb '%s'\n", reverblist[i].name);
787 props = &reverblist[i].props;
788 effect->Props.Reverb.Density = props->flDensity;
789 effect->Props.Reverb.Diffusion = props->flDiffusion;
790 effect->Props.Reverb.Gain = props->flGain;
791 effect->Props.Reverb.GainHF = props->flGainHF;
792 effect->Props.Reverb.GainLF = props->flGainLF;
793 effect->Props.Reverb.DecayTime = props->flDecayTime;
794 effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio;
795 effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio;
796 effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain;
797 effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay;
798 effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0];
799 effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1];
800 effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2];
801 effect->Props.Reverb.LateReverbGain = props->flLateReverbGain;
802 effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay;
803 effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0];
804 effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1];
805 effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2];
806 effect->Props.Reverb.EchoTime = props->flEchoTime;
807 effect->Props.Reverb.EchoDepth = props->flEchoDepth;
808 effect->Props.Reverb.ModulationTime = props->flModulationTime;
809 effect->Props.Reverb.ModulationDepth = props->flModulationDepth;
810 effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF;
811 effect->Props.Reverb.HFReference = props->flHFReference;
812 effect->Props.Reverb.LFReference = props->flLFReference;
813 effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor;
814 effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit;
815 return;
818 WARN("Reverb preset '%s' not found\n", name);