Use function-like macros to call filter and effect vtable methods
[openal-soft.git] / OpenAL32 / alEffect.c
blob6b16fc568d45df8b524ce9564f3aa74949ef53fe
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 { "chorus", CHORUS_EFFECT, AL_EFFECT_CHORUS },
42 { "compressor", COMPRESSOR_EFFECT, AL_EFFECT_COMPRESSOR },
43 { "distortion", DISTORTION_EFFECT, AL_EFFECT_DISTORTION },
44 { "echo", ECHO_EFFECT, AL_EFFECT_ECHO },
45 { "equalizer", EQUALIZER_EFFECT, AL_EFFECT_EQUALIZER },
46 { "flanger", FLANGER_EFFECT, AL_EFFECT_FLANGER },
47 { "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR },
48 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
49 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_DIALOGUE },
52 ALboolean DisabledEffects[MAX_EFFECTS];
54 static ALeffect *AllocEffect(ALCcontext *context);
55 static void FreeEffect(ALCdevice *device, ALeffect *effect);
56 static void InitEffectParams(ALeffect *effect, ALenum type);
58 static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
60 EffectSubList *sublist;
61 ALuint lidx = (id-1) >> 6;
62 ALsizei slidx = (id-1) & 0x3f;
64 if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList)))
65 return NULL;
66 sublist = &VECTOR_ELEM(device->EffectList, lidx);
67 if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
68 return NULL;
69 return sublist->Effects + slidx;
73 AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
75 ALCcontext *context;
76 ALsizei cur;
78 context = GetContextRef();
79 if(!context) return;
81 if(!(n >= 0))
82 alSetError(context, AL_INVALID_VALUE, "Generating %d effects", n);
83 else for(cur = 0;cur < n;cur++)
85 ALeffect *effect = AllocEffect(context);
86 if(!effect)
88 alDeleteEffects(cur, effects);
89 break;
91 effects[cur] = effect->id;
94 ALCcontext_DecRef(context);
97 AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
99 ALCdevice *device;
100 ALCcontext *context;
101 ALeffect *effect;
102 ALsizei i;
104 context = GetContextRef();
105 if(!context) return;
107 device = context->Device;
108 LockEffectList(device);
109 if(!(n >= 0))
110 SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n);
111 for(i = 0;i < n;i++)
113 if(effects[i] && LookupEffect(device, effects[i]) == NULL)
114 SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect ID %u", effects[i]);
116 for(i = 0;i < n;i++)
118 if((effect=LookupEffect(device, effects[i])) != NULL)
119 FreeEffect(device, effect);
122 done:
123 UnlockEffectList(device);
124 ALCcontext_DecRef(context);
127 AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
129 ALCcontext *Context;
130 ALboolean result;
132 Context = GetContextRef();
133 if(!Context) return AL_FALSE;
135 LockEffectList(Context->Device);
136 result = ((!effect || LookupEffect(Context->Device, effect)) ?
137 AL_TRUE : AL_FALSE);
138 UnlockEffectList(Context->Device);
140 ALCcontext_DecRef(Context);
142 return result;
145 AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
147 ALCcontext *Context;
148 ALCdevice *Device;
149 ALeffect *ALEffect;
151 Context = GetContextRef();
152 if(!Context) return;
154 Device = Context->Device;
155 LockEffectList(Device);
156 if((ALEffect=LookupEffect(Device, effect)) == NULL)
157 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
158 else
160 if(param == AL_EFFECT_TYPE)
162 ALboolean isOk = (value == AL_EFFECT_NULL);
163 ALint i;
164 for(i = 0;!isOk && i < EFFECTLIST_SIZE;i++)
166 if(value == EffectList[i].val &&
167 !DisabledEffects[EffectList[i].type])
168 isOk = AL_TRUE;
171 if(isOk)
172 InitEffectParams(ALEffect, value);
173 else
174 alSetError(Context, AL_INVALID_VALUE, "Effect type 0x%04x not supported", value);
176 else
178 /* Call the appropriate handler */
179 ALeffect_setParami(ALEffect, Context, param, value);
182 UnlockEffectList(Device);
184 ALCcontext_DecRef(Context);
187 AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *values)
189 ALCcontext *Context;
190 ALCdevice *Device;
191 ALeffect *ALEffect;
193 switch(param)
195 case AL_EFFECT_TYPE:
196 alEffecti(effect, param, values[0]);
197 return;
200 Context = GetContextRef();
201 if(!Context) return;
203 Device = Context->Device;
204 LockEffectList(Device);
205 if((ALEffect=LookupEffect(Device, effect)) == NULL)
206 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
207 else
209 /* Call the appropriate handler */
210 ALeffect_setParamiv(ALEffect, Context, param, values);
212 UnlockEffectList(Device);
214 ALCcontext_DecRef(Context);
217 AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
219 ALCcontext *Context;
220 ALCdevice *Device;
221 ALeffect *ALEffect;
223 Context = GetContextRef();
224 if(!Context) return;
226 Device = Context->Device;
227 LockEffectList(Device);
228 if((ALEffect=LookupEffect(Device, effect)) == NULL)
229 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
230 else
232 /* Call the appropriate handler */
233 ALeffect_setParamf(ALEffect, Context, param, value);
235 UnlockEffectList(Device);
237 ALCcontext_DecRef(Context);
240 AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *values)
242 ALCcontext *Context;
243 ALCdevice *Device;
244 ALeffect *ALEffect;
246 Context = GetContextRef();
247 if(!Context) return;
249 Device = Context->Device;
250 LockEffectList(Device);
251 if((ALEffect=LookupEffect(Device, effect)) == NULL)
252 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
253 else
255 /* Call the appropriate handler */
256 ALeffect_setParamfv(ALEffect, Context, param, values);
258 UnlockEffectList(Device);
260 ALCcontext_DecRef(Context);
263 AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value)
265 ALCcontext *Context;
266 ALCdevice *Device;
267 ALeffect *ALEffect;
269 Context = GetContextRef();
270 if(!Context) return;
272 Device = Context->Device;
273 LockEffectList(Device);
274 if((ALEffect=LookupEffect(Device, effect)) == NULL)
275 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
276 else
278 if(param == AL_EFFECT_TYPE)
279 *value = ALEffect->type;
280 else
282 /* Call the appropriate handler */
283 ALeffect_getParami(ALEffect, Context, param, value);
286 UnlockEffectList(Device);
288 ALCcontext_DecRef(Context);
291 AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *values)
293 ALCcontext *Context;
294 ALCdevice *Device;
295 ALeffect *ALEffect;
297 switch(param)
299 case AL_EFFECT_TYPE:
300 alGetEffecti(effect, param, values);
301 return;
304 Context = GetContextRef();
305 if(!Context) return;
307 Device = Context->Device;
308 LockEffectList(Device);
309 if((ALEffect=LookupEffect(Device, effect)) == NULL)
310 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
311 else
313 /* Call the appropriate handler */
314 ALeffect_getParamiv(ALEffect, Context, param, values);
316 UnlockEffectList(Device);
318 ALCcontext_DecRef(Context);
321 AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value)
323 ALCcontext *Context;
324 ALCdevice *Device;
325 ALeffect *ALEffect;
327 Context = GetContextRef();
328 if(!Context) return;
330 Device = Context->Device;
331 LockEffectList(Device);
332 if((ALEffect=LookupEffect(Device, effect)) == NULL)
333 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
334 else
336 /* Call the appropriate handler */
337 ALeffect_getParamf(ALEffect, Context, param, value);
339 UnlockEffectList(Device);
341 ALCcontext_DecRef(Context);
344 AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *values)
346 ALCcontext *Context;
347 ALCdevice *Device;
348 ALeffect *ALEffect;
350 Context = GetContextRef();
351 if(!Context) return;
353 Device = Context->Device;
354 LockEffectList(Device);
355 if((ALEffect=LookupEffect(Device, effect)) == NULL)
356 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
357 else
359 /* Call the appropriate handler */
360 ALeffect_getParamfv(ALEffect, Context, param, values);
362 UnlockEffectList(Device);
364 ALCcontext_DecRef(Context);
368 void InitEffect(ALeffect *effect)
370 InitEffectParams(effect, AL_EFFECT_NULL);
373 static ALeffect *AllocEffect(ALCcontext *context)
375 ALCdevice *device = context->Device;
376 EffectSubList *sublist, *subend;
377 ALeffect *effect = NULL;
378 ALsizei lidx = 0;
379 ALsizei slidx;
381 almtx_lock(&device->EffectLock);
382 sublist = VECTOR_BEGIN(device->EffectList);
383 subend = VECTOR_END(device->EffectList);
384 for(;sublist != subend;++sublist)
386 if(sublist->FreeMask)
388 slidx = CTZ64(sublist->FreeMask);
389 effect = sublist->Effects + slidx;
390 break;
392 ++lidx;
394 if(UNLIKELY(!effect))
396 const EffectSubList empty_sublist = { 0, NULL };
397 /* Don't allocate so many list entries that the 32-bit ID could
398 * overflow...
400 if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25))
402 almtx_unlock(&device->EffectLock);
403 alSetError(context, AL_OUT_OF_MEMORY, "Too many effects allocated");
404 return NULL;
406 lidx = (ALsizei)VECTOR_SIZE(device->EffectList);
407 VECTOR_PUSH_BACK(device->EffectList, empty_sublist);
408 sublist = &VECTOR_BACK(device->EffectList);
409 sublist->FreeMask = ~U64(0);
410 sublist->Effects = al_calloc(16, sizeof(ALeffect)*64);
411 if(UNLIKELY(!sublist->Effects))
413 VECTOR_POP_BACK(device->EffectList);
414 almtx_unlock(&device->EffectLock);
415 alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate effect batch");
416 return NULL;
419 slidx = 0;
420 effect = sublist->Effects + slidx;
423 memset(effect, 0, sizeof(*effect));
424 InitEffectParams(effect, AL_EFFECT_NULL);
426 /* Add 1 to avoid effect ID 0. */
427 effect->id = ((lidx<<6) | slidx) + 1;
429 sublist->FreeMask &= ~(U64(1)<<slidx);
430 almtx_unlock(&device->EffectLock);
432 return effect;
435 static void FreeEffect(ALCdevice *device, ALeffect *effect)
437 ALuint id = effect->id - 1;
438 ALsizei lidx = id >> 6;
439 ALsizei slidx = id & 0x3f;
441 memset(effect, 0, sizeof(*effect));
443 VECTOR_ELEM(device->EffectList, lidx).FreeMask |= U64(1) << slidx;
446 void ReleaseALEffects(ALCdevice *device)
448 EffectSubList *sublist = VECTOR_BEGIN(device->EffectList);
449 EffectSubList *subend = VECTOR_END(device->EffectList);
450 size_t leftover = 0;
451 for(;sublist != subend;++sublist)
453 ALuint64 usemask = ~sublist->FreeMask;
454 while(usemask)
456 ALsizei idx = CTZ64(usemask);
457 ALeffect *effect = sublist->Effects + idx;
459 memset(effect, 0, sizeof(*effect));
460 ++leftover;
462 usemask &= ~(U64(1) << idx);
464 sublist->FreeMask = ~usemask;
466 if(leftover > 0)
467 WARN("(%p) Deleted "SZFMT" Effect%s\n", device, leftover, (leftover==1)?"":"s");
471 static void InitEffectParams(ALeffect *effect, ALenum type)
473 switch(type)
475 case AL_EFFECT_EAXREVERB:
476 effect->Props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
477 effect->Props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
478 effect->Props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
479 effect->Props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
480 effect->Props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
481 effect->Props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
482 effect->Props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
483 effect->Props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
484 effect->Props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
485 effect->Props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
486 effect->Props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
487 effect->Props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
488 effect->Props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
489 effect->Props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
490 effect->Props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
491 effect->Props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
492 effect->Props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
493 effect->Props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
494 effect->Props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
495 effect->Props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
496 effect->Props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
497 effect->Props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
498 effect->Props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
499 effect->Props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
500 effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
501 effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
502 effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
503 effect->vtab = &ALeaxreverb_vtable;
504 break;
505 case AL_EFFECT_REVERB:
506 effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY;
507 effect->Props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
508 effect->Props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN;
509 effect->Props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF;
510 effect->Props.Reverb.GainLF = 1.0f;
511 effect->Props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
512 effect->Props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
513 effect->Props.Reverb.DecayLFRatio = 1.0f;
514 effect->Props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
515 effect->Props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
516 effect->Props.Reverb.ReflectionsPan[0] = 0.0f;
517 effect->Props.Reverb.ReflectionsPan[1] = 0.0f;
518 effect->Props.Reverb.ReflectionsPan[2] = 0.0f;
519 effect->Props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
520 effect->Props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
521 effect->Props.Reverb.LateReverbPan[0] = 0.0f;
522 effect->Props.Reverb.LateReverbPan[1] = 0.0f;
523 effect->Props.Reverb.LateReverbPan[2] = 0.0f;
524 effect->Props.Reverb.EchoTime = 0.25f;
525 effect->Props.Reverb.EchoDepth = 0.0f;
526 effect->Props.Reverb.ModulationTime = 0.25f;
527 effect->Props.Reverb.ModulationDepth = 0.0f;
528 effect->Props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
529 effect->Props.Reverb.HFReference = 5000.0f;
530 effect->Props.Reverb.LFReference = 250.0f;
531 effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
532 effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
533 effect->vtab = &ALreverb_vtable;
534 break;
535 case AL_EFFECT_CHORUS:
536 effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM;
537 effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE;
538 effect->Props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE;
539 effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH;
540 effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK;
541 effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY;
542 effect->vtab = &ALchorus_vtable;
543 break;
544 case AL_EFFECT_COMPRESSOR:
545 effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
546 effect->vtab = &ALcompressor_vtable;
547 break;
548 case AL_EFFECT_DISTORTION:
549 effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE;
550 effect->Props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN;
551 effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
552 effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
553 effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
554 effect->vtab = &ALdistortion_vtable;
555 break;
556 case AL_EFFECT_ECHO:
557 effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY;
558 effect->Props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
559 effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
560 effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
561 effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
562 effect->vtab = &ALecho_vtable;
563 break;
564 case AL_EFFECT_EQUALIZER:
565 effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
566 effect->Props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
567 effect->Props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
568 effect->Props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
569 effect->Props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
570 effect->Props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
571 effect->Props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
572 effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
573 effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
574 effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
575 effect->vtab = &ALequalizer_vtable;
576 break;
577 case AL_EFFECT_FLANGER:
578 effect->Props.Chorus.Waveform = AL_FLANGER_DEFAULT_WAVEFORM;
579 effect->Props.Chorus.Phase = AL_FLANGER_DEFAULT_PHASE;
580 effect->Props.Chorus.Rate = AL_FLANGER_DEFAULT_RATE;
581 effect->Props.Chorus.Depth = AL_FLANGER_DEFAULT_DEPTH;
582 effect->Props.Chorus.Feedback = AL_FLANGER_DEFAULT_FEEDBACK;
583 effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY;
584 effect->vtab = &ALflanger_vtable;
585 break;
586 case AL_EFFECT_RING_MODULATOR:
587 effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
588 effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
589 effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM;
590 effect->vtab = &ALmodulator_vtable;
591 break;
592 case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT:
593 case AL_EFFECT_DEDICATED_DIALOGUE:
594 effect->Props.Dedicated.Gain = 1.0f;
595 effect->vtab = &ALdedicated_vtable;
596 break;
597 default:
598 effect->vtab = &ALnull_vtable;
599 break;
601 effect->type = type;
605 #include "AL/efx-presets.h"
607 #define DECL(x) { #x, EFX_REVERB_PRESET_##x }
608 static const struct {
609 const char name[32];
610 EFXEAXREVERBPROPERTIES props;
611 } reverblist[] = {
612 DECL(GENERIC),
613 DECL(PADDEDCELL),
614 DECL(ROOM),
615 DECL(BATHROOM),
616 DECL(LIVINGROOM),
617 DECL(STONEROOM),
618 DECL(AUDITORIUM),
619 DECL(CONCERTHALL),
620 DECL(CAVE),
621 DECL(ARENA),
622 DECL(HANGAR),
623 DECL(CARPETEDHALLWAY),
624 DECL(HALLWAY),
625 DECL(STONECORRIDOR),
626 DECL(ALLEY),
627 DECL(FOREST),
628 DECL(CITY),
629 DECL(MOUNTAINS),
630 DECL(QUARRY),
631 DECL(PLAIN),
632 DECL(PARKINGLOT),
633 DECL(SEWERPIPE),
634 DECL(UNDERWATER),
635 DECL(DRUGGED),
636 DECL(DIZZY),
637 DECL(PSYCHOTIC),
639 DECL(CASTLE_SMALLROOM),
640 DECL(CASTLE_SHORTPASSAGE),
641 DECL(CASTLE_MEDIUMROOM),
642 DECL(CASTLE_LARGEROOM),
643 DECL(CASTLE_LONGPASSAGE),
644 DECL(CASTLE_HALL),
645 DECL(CASTLE_CUPBOARD),
646 DECL(CASTLE_COURTYARD),
647 DECL(CASTLE_ALCOVE),
649 DECL(FACTORY_SMALLROOM),
650 DECL(FACTORY_SHORTPASSAGE),
651 DECL(FACTORY_MEDIUMROOM),
652 DECL(FACTORY_LARGEROOM),
653 DECL(FACTORY_LONGPASSAGE),
654 DECL(FACTORY_HALL),
655 DECL(FACTORY_CUPBOARD),
656 DECL(FACTORY_COURTYARD),
657 DECL(FACTORY_ALCOVE),
659 DECL(ICEPALACE_SMALLROOM),
660 DECL(ICEPALACE_SHORTPASSAGE),
661 DECL(ICEPALACE_MEDIUMROOM),
662 DECL(ICEPALACE_LARGEROOM),
663 DECL(ICEPALACE_LONGPASSAGE),
664 DECL(ICEPALACE_HALL),
665 DECL(ICEPALACE_CUPBOARD),
666 DECL(ICEPALACE_COURTYARD),
667 DECL(ICEPALACE_ALCOVE),
669 DECL(SPACESTATION_SMALLROOM),
670 DECL(SPACESTATION_SHORTPASSAGE),
671 DECL(SPACESTATION_MEDIUMROOM),
672 DECL(SPACESTATION_LARGEROOM),
673 DECL(SPACESTATION_LONGPASSAGE),
674 DECL(SPACESTATION_HALL),
675 DECL(SPACESTATION_CUPBOARD),
676 DECL(SPACESTATION_ALCOVE),
678 DECL(WOODEN_SMALLROOM),
679 DECL(WOODEN_SHORTPASSAGE),
680 DECL(WOODEN_MEDIUMROOM),
681 DECL(WOODEN_LARGEROOM),
682 DECL(WOODEN_LONGPASSAGE),
683 DECL(WOODEN_HALL),
684 DECL(WOODEN_CUPBOARD),
685 DECL(WOODEN_COURTYARD),
686 DECL(WOODEN_ALCOVE),
688 DECL(SPORT_EMPTYSTADIUM),
689 DECL(SPORT_SQUASHCOURT),
690 DECL(SPORT_SMALLSWIMMINGPOOL),
691 DECL(SPORT_LARGESWIMMINGPOOL),
692 DECL(SPORT_GYMNASIUM),
693 DECL(SPORT_FULLSTADIUM),
694 DECL(SPORT_STADIUMTANNOY),
696 DECL(PREFAB_WORKSHOP),
697 DECL(PREFAB_SCHOOLROOM),
698 DECL(PREFAB_PRACTISEROOM),
699 DECL(PREFAB_OUTHOUSE),
700 DECL(PREFAB_CARAVAN),
702 DECL(DOME_TOMB),
703 DECL(PIPE_SMALL),
704 DECL(DOME_SAINTPAULS),
705 DECL(PIPE_LONGTHIN),
706 DECL(PIPE_LARGE),
707 DECL(PIPE_RESONANT),
709 DECL(OUTDOORS_BACKYARD),
710 DECL(OUTDOORS_ROLLINGPLAINS),
711 DECL(OUTDOORS_DEEPCANYON),
712 DECL(OUTDOORS_CREEK),
713 DECL(OUTDOORS_VALLEY),
715 DECL(MOOD_HEAVEN),
716 DECL(MOOD_HELL),
717 DECL(MOOD_MEMORY),
719 DECL(DRIVING_COMMENTATOR),
720 DECL(DRIVING_PITGARAGE),
721 DECL(DRIVING_INCAR_RACER),
722 DECL(DRIVING_INCAR_SPORTS),
723 DECL(DRIVING_INCAR_LUXURY),
724 DECL(DRIVING_FULLGRANDSTAND),
725 DECL(DRIVING_EMPTYGRANDSTAND),
726 DECL(DRIVING_TUNNEL),
728 DECL(CITY_STREETS),
729 DECL(CITY_SUBWAY),
730 DECL(CITY_MUSEUM),
731 DECL(CITY_LIBRARY),
732 DECL(CITY_UNDERPASS),
733 DECL(CITY_ABANDONED),
735 DECL(DUSTYROOM),
736 DECL(CHAPEL),
737 DECL(SMALLWATERROOM),
739 #undef DECL
741 void LoadReverbPreset(const char *name, ALeffect *effect)
743 size_t i;
745 if(strcasecmp(name, "NONE") == 0)
747 InitEffectParams(effect, AL_EFFECT_NULL);
748 TRACE("Loading reverb '%s'\n", "NONE");
749 return;
752 if(!DisabledEffects[EAXREVERB_EFFECT])
753 InitEffectParams(effect, AL_EFFECT_EAXREVERB);
754 else if(!DisabledEffects[REVERB_EFFECT])
755 InitEffectParams(effect, AL_EFFECT_REVERB);
756 else
757 InitEffectParams(effect, AL_EFFECT_NULL);
758 for(i = 0;i < COUNTOF(reverblist);i++)
760 const EFXEAXREVERBPROPERTIES *props;
762 if(strcasecmp(name, reverblist[i].name) != 0)
763 continue;
765 TRACE("Loading reverb '%s'\n", reverblist[i].name);
766 props = &reverblist[i].props;
767 effect->Props.Reverb.Density = props->flDensity;
768 effect->Props.Reverb.Diffusion = props->flDiffusion;
769 effect->Props.Reverb.Gain = props->flGain;
770 effect->Props.Reverb.GainHF = props->flGainHF;
771 effect->Props.Reverb.GainLF = props->flGainLF;
772 effect->Props.Reverb.DecayTime = props->flDecayTime;
773 effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio;
774 effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio;
775 effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain;
776 effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay;
777 effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0];
778 effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1];
779 effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2];
780 effect->Props.Reverb.LateReverbGain = props->flLateReverbGain;
781 effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay;
782 effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0];
783 effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1];
784 effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2];
785 effect->Props.Reverb.EchoTime = props->flEchoTime;
786 effect->Props.Reverb.EchoDepth = props->flEchoDepth;
787 effect->Props.Reverb.ModulationTime = props->flModulationTime;
788 effect->Props.Reverb.ModulationDepth = props->flModulationDepth;
789 effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF;
790 effect->Props.Reverb.HFReference = props->flHFReference;
791 effect->Props.Reverb.LFReference = props->flLFReference;
792 effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor;
793 effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit;
794 return;
797 WARN("Reverb preset '%s' not found\n", name);