Don't bother with a return value that's never used
[openal-soft.git] / OpenAL32 / alEffect.c
blob39f6f33067ee80a8681ca7525cedec36343faf71
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 "alThunk.h"
32 #include "alError.h"
35 extern inline void LockEffectList(ALCdevice *device);
36 extern inline void UnlockEffectList(ALCdevice *device);
37 extern inline ALboolean IsReverbEffect(ALenum type);
39 const struct EffectList EffectList[EFFECTLIST_SIZE] = {
40 { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB },
41 { "reverb", REVERB_EFFECT, AL_EFFECT_REVERB },
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 { "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR },
49 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
50 { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_DIALOGUE },
53 ALboolean DisabledEffects[MAX_EFFECTS];
55 static ALeffect *AllocEffect(ALCcontext *context);
56 static void FreeEffect(ALCdevice *device, ALeffect *effect);
57 static void InitEffectParams(ALeffect *effect, ALenum type);
59 static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
61 EffectSubList *sublist;
62 ALuint lidx = (id-1) >> 6;
63 ALsizei slidx = (id-1) & 0x3f;
65 if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList)))
66 return NULL;
67 sublist = &VECTOR_ELEM(device->EffectList, lidx);
68 if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
69 return NULL;
70 return sublist->Effects + slidx;
74 AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
76 ALCcontext *context;
77 ALsizei cur;
79 context = GetContextRef();
80 if(!context) return;
82 if(!(n >= 0))
83 alSetError(context, AL_INVALID_VALUE, "Generating %d effects", n);
84 else for(cur = 0;cur < n;cur++)
86 ALeffect *effect = AllocEffect(context);
87 if(!effect)
89 alDeleteEffects(cur, effects);
90 break;
92 effects[cur] = effect->id;
95 ALCcontext_DecRef(context);
98 AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
100 ALCdevice *device;
101 ALCcontext *context;
102 ALeffect *effect;
103 ALsizei i;
105 context = GetContextRef();
106 if(!context) return;
108 device = context->Device;
109 LockEffectList(device);
110 if(!(n >= 0))
111 SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n);
112 for(i = 0;i < n;i++)
114 if(effects[i] && LookupEffect(device, effects[i]) == NULL)
115 SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect ID %u", effects[i]);
117 for(i = 0;i < n;i++)
119 if((effect=LookupEffect(device, effects[i])) != NULL)
120 FreeEffect(device, effect);
123 done:
124 UnlockEffectList(device);
125 ALCcontext_DecRef(context);
128 AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
130 ALCcontext *Context;
131 ALboolean result;
133 Context = GetContextRef();
134 if(!Context) return AL_FALSE;
136 LockEffectList(Context->Device);
137 result = ((!effect || LookupEffect(Context->Device, effect)) ?
138 AL_TRUE : AL_FALSE);
139 UnlockEffectList(Context->Device);
141 ALCcontext_DecRef(Context);
143 return result;
146 AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
148 ALCcontext *Context;
149 ALCdevice *Device;
150 ALeffect *ALEffect;
152 Context = GetContextRef();
153 if(!Context) return;
155 Device = Context->Device;
156 LockEffectList(Device);
157 if((ALEffect=LookupEffect(Device, effect)) == NULL)
158 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
159 else
161 if(param == AL_EFFECT_TYPE)
163 ALboolean isOk = (value == AL_EFFECT_NULL);
164 ALint i;
165 for(i = 0;!isOk && i < EFFECTLIST_SIZE;i++)
167 if(value == EffectList[i].val &&
168 !DisabledEffects[EffectList[i].type])
169 isOk = AL_TRUE;
172 if(isOk)
173 InitEffectParams(ALEffect, value);
174 else
175 alSetError(Context, AL_INVALID_VALUE, "Effect type 0x%04x not supported", value);
177 else
179 /* Call the appropriate handler */
180 V(ALEffect,setParami)(Context, param, value);
183 UnlockEffectList(Device);
185 ALCcontext_DecRef(Context);
188 AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *values)
190 ALCcontext *Context;
191 ALCdevice *Device;
192 ALeffect *ALEffect;
194 switch(param)
196 case AL_EFFECT_TYPE:
197 alEffecti(effect, param, values[0]);
198 return;
201 Context = GetContextRef();
202 if(!Context) return;
204 Device = Context->Device;
205 LockEffectList(Device);
206 if((ALEffect=LookupEffect(Device, effect)) == NULL)
207 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
208 else
210 /* Call the appropriate handler */
211 V(ALEffect,setParamiv)(Context, param, values);
213 UnlockEffectList(Device);
215 ALCcontext_DecRef(Context);
218 AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
220 ALCcontext *Context;
221 ALCdevice *Device;
222 ALeffect *ALEffect;
224 Context = GetContextRef();
225 if(!Context) return;
227 Device = Context->Device;
228 LockEffectList(Device);
229 if((ALEffect=LookupEffect(Device, effect)) == NULL)
230 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
231 else
233 /* Call the appropriate handler */
234 V(ALEffect,setParamf)(Context, param, value);
236 UnlockEffectList(Device);
238 ALCcontext_DecRef(Context);
241 AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *values)
243 ALCcontext *Context;
244 ALCdevice *Device;
245 ALeffect *ALEffect;
247 Context = GetContextRef();
248 if(!Context) return;
250 Device = Context->Device;
251 LockEffectList(Device);
252 if((ALEffect=LookupEffect(Device, effect)) == NULL)
253 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
254 else
256 /* Call the appropriate handler */
257 V(ALEffect,setParamfv)(Context, param, values);
259 UnlockEffectList(Device);
261 ALCcontext_DecRef(Context);
264 AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value)
266 ALCcontext *Context;
267 ALCdevice *Device;
268 ALeffect *ALEffect;
270 Context = GetContextRef();
271 if(!Context) return;
273 Device = Context->Device;
274 LockEffectList(Device);
275 if((ALEffect=LookupEffect(Device, effect)) == NULL)
276 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
277 else
279 if(param == AL_EFFECT_TYPE)
280 *value = ALEffect->type;
281 else
283 /* Call the appropriate handler */
284 V(ALEffect,getParami)(Context, param, value);
287 UnlockEffectList(Device);
289 ALCcontext_DecRef(Context);
292 AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *values)
294 ALCcontext *Context;
295 ALCdevice *Device;
296 ALeffect *ALEffect;
298 switch(param)
300 case AL_EFFECT_TYPE:
301 alGetEffecti(effect, param, values);
302 return;
305 Context = GetContextRef();
306 if(!Context) return;
308 Device = Context->Device;
309 LockEffectList(Device);
310 if((ALEffect=LookupEffect(Device, effect)) == NULL)
311 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
312 else
314 /* Call the appropriate handler */
315 V(ALEffect,getParamiv)(Context, param, values);
317 UnlockEffectList(Device);
319 ALCcontext_DecRef(Context);
322 AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value)
324 ALCcontext *Context;
325 ALCdevice *Device;
326 ALeffect *ALEffect;
328 Context = GetContextRef();
329 if(!Context) return;
331 Device = Context->Device;
332 LockEffectList(Device);
333 if((ALEffect=LookupEffect(Device, effect)) == NULL)
334 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
335 else
337 /* Call the appropriate handler */
338 V(ALEffect,getParamf)(Context, param, value);
340 UnlockEffectList(Device);
342 ALCcontext_DecRef(Context);
345 AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *values)
347 ALCcontext *Context;
348 ALCdevice *Device;
349 ALeffect *ALEffect;
351 Context = GetContextRef();
352 if(!Context) return;
354 Device = Context->Device;
355 LockEffectList(Device);
356 if((ALEffect=LookupEffect(Device, effect)) == NULL)
357 alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
358 else
360 /* Call the appropriate handler */
361 V(ALEffect,getParamfv)(Context, param, values);
363 UnlockEffectList(Device);
365 ALCcontext_DecRef(Context);
369 void InitEffect(ALeffect *effect)
371 InitEffectParams(effect, AL_EFFECT_NULL);
374 static ALeffect *AllocEffect(ALCcontext *context)
376 ALCdevice *device = context->Device;
377 EffectSubList *sublist, *subend;
378 ALeffect *effect = NULL;
379 ALsizei lidx = 0;
380 ALsizei slidx;
382 almtx_lock(&device->EffectLock);
383 sublist = VECTOR_BEGIN(device->EffectList);
384 subend = VECTOR_END(device->EffectList);
385 for(;sublist != subend;++sublist)
387 if(sublist->FreeMask)
389 slidx = CTZ64(sublist->FreeMask);
390 effect = sublist->Effects + slidx;
391 break;
393 ++lidx;
395 if(UNLIKELY(!effect))
397 const EffectSubList empty_sublist = { 0, NULL };
398 /* Don't allocate so many list entries that the 32-bit ID could
399 * overflow...
401 if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25))
403 almtx_unlock(&device->EffectLock);
404 alSetError(context, AL_OUT_OF_MEMORY, "Too many effects allocated");
405 return NULL;
407 lidx = (ALsizei)VECTOR_SIZE(device->EffectList);
408 VECTOR_PUSH_BACK(device->EffectList, empty_sublist);
409 sublist = &VECTOR_BACK(device->EffectList);
410 sublist->FreeMask = ~U64(0);
411 sublist->Effects = al_calloc(16, sizeof(ALeffect)*64);
412 if(UNLIKELY(!sublist->Effects))
414 VECTOR_POP_BACK(device->EffectList);
415 almtx_unlock(&device->EffectLock);
416 alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate effect batch");
417 return NULL;
420 slidx = 0;
421 effect = sublist->Effects + slidx;
424 memset(effect, 0, sizeof(*effect));
425 InitEffectParams(effect, AL_EFFECT_NULL);
427 /* Add 1 to avoid effect ID 0. */
428 effect->id = ((lidx<<6) | slidx) + 1;
430 sublist->FreeMask &= ~(U64(1)<<slidx);
431 almtx_unlock(&device->EffectLock);
433 return effect;
436 static void FreeEffect(ALCdevice *device, ALeffect *effect)
438 ALuint id = effect->id - 1;
439 ALsizei lidx = id >> 6;
440 ALsizei slidx = id & 0x3f;
442 memset(effect, 0, sizeof(*effect));
444 VECTOR_ELEM(device->EffectList, lidx).FreeMask |= U64(1) << slidx;
447 void ReleaseALEffects(ALCdevice *device)
449 EffectSubList *sublist = VECTOR_BEGIN(device->EffectList);
450 EffectSubList *subend = VECTOR_END(device->EffectList);
451 size_t leftover = 0;
452 for(;sublist != subend;++sublist)
454 ALuint64 usemask = ~sublist->FreeMask;
455 while(usemask)
457 ALsizei idx = CTZ64(usemask);
458 ALeffect *effect = sublist->Effects + idx;
460 memset(effect, 0, sizeof(*effect));
461 ++leftover;
463 usemask &= ~(U64(1) << idx);
465 sublist->FreeMask = ~usemask;
467 if(leftover > 0)
468 WARN("(%p) Deleted "SZFMT" Effect%s\n", device, leftover, (leftover==1)?"":"s");
472 static void InitEffectParams(ALeffect *effect, ALenum type)
474 switch(type)
476 case AL_EFFECT_EAXREVERB:
477 effect->Props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
478 effect->Props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
479 effect->Props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
480 effect->Props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
481 effect->Props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
482 effect->Props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
483 effect->Props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
484 effect->Props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
485 effect->Props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
486 effect->Props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
487 effect->Props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
488 effect->Props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
489 effect->Props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
490 effect->Props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
491 effect->Props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
492 effect->Props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
493 effect->Props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
494 effect->Props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
495 effect->Props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
496 effect->Props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
497 effect->Props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
498 effect->Props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
499 effect->Props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
500 effect->Props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
501 effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
502 effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
503 effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
504 effect->vtbl = &ALeaxreverb_vtable;
505 break;
506 case AL_EFFECT_REVERB:
507 effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY;
508 effect->Props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION;
509 effect->Props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN;
510 effect->Props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF;
511 effect->Props.Reverb.GainLF = 1.0f;
512 effect->Props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME;
513 effect->Props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO;
514 effect->Props.Reverb.DecayLFRatio = 1.0f;
515 effect->Props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN;
516 effect->Props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY;
517 effect->Props.Reverb.ReflectionsPan[0] = 0.0f;
518 effect->Props.Reverb.ReflectionsPan[1] = 0.0f;
519 effect->Props.Reverb.ReflectionsPan[2] = 0.0f;
520 effect->Props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN;
521 effect->Props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY;
522 effect->Props.Reverb.LateReverbPan[0] = 0.0f;
523 effect->Props.Reverb.LateReverbPan[1] = 0.0f;
524 effect->Props.Reverb.LateReverbPan[2] = 0.0f;
525 effect->Props.Reverb.EchoTime = 0.25f;
526 effect->Props.Reverb.EchoDepth = 0.0f;
527 effect->Props.Reverb.ModulationTime = 0.25f;
528 effect->Props.Reverb.ModulationDepth = 0.0f;
529 effect->Props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
530 effect->Props.Reverb.HFReference = 5000.0f;
531 effect->Props.Reverb.LFReference = 250.0f;
532 effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
533 effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT;
534 effect->vtbl = &ALreverb_vtable;
535 break;
536 case AL_EFFECT_CHORUS:
537 effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM;
538 effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE;
539 effect->Props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE;
540 effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH;
541 effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK;
542 effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY;
543 effect->vtbl = &ALchorus_vtable;
544 break;
545 case AL_EFFECT_COMPRESSOR:
546 effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF;
547 effect->vtbl = &ALcompressor_vtable;
548 break;
549 case AL_EFFECT_DISTORTION:
550 effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE;
551 effect->Props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN;
552 effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF;
553 effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER;
554 effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH;
555 effect->vtbl = &ALdistortion_vtable;
556 break;
557 case AL_EFFECT_ECHO:
558 effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY;
559 effect->Props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
560 effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
561 effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
562 effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
563 effect->vtbl = &ALecho_vtable;
564 break;
565 case AL_EFFECT_EQUALIZER:
566 effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF;
567 effect->Props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN;
568 effect->Props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER;
569 effect->Props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN;
570 effect->Props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH;
571 effect->Props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER;
572 effect->Props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN;
573 effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH;
574 effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF;
575 effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN;
576 effect->vtbl = &ALequalizer_vtable;
577 break;
578 case AL_EFFECT_FLANGER:
579 effect->Props.Chorus.Waveform = AL_FLANGER_DEFAULT_WAVEFORM;
580 effect->Props.Chorus.Phase = AL_FLANGER_DEFAULT_PHASE;
581 effect->Props.Chorus.Rate = AL_FLANGER_DEFAULT_RATE;
582 effect->Props.Chorus.Depth = AL_FLANGER_DEFAULT_DEPTH;
583 effect->Props.Chorus.Feedback = AL_FLANGER_DEFAULT_FEEDBACK;
584 effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY;
585 effect->vtbl = &ALflanger_vtable;
586 break;
587 case AL_EFFECT_RING_MODULATOR:
588 effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY;
589 effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF;
590 effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM;
591 effect->vtbl = &ALmodulator_vtable;
592 break;
593 case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT:
594 case AL_EFFECT_DEDICATED_DIALOGUE:
595 effect->Props.Dedicated.Gain = 1.0f;
596 effect->vtbl = &ALdedicated_vtable;
597 break;
598 default:
599 effect->vtbl = &ALnull_vtable;
600 break;
602 effect->type = type;
606 #include "AL/efx-presets.h"
608 #define DECL(x) { #x, EFX_REVERB_PRESET_##x }
609 static const struct {
610 const char name[32];
611 EFXEAXREVERBPROPERTIES props;
612 } reverblist[] = {
613 DECL(GENERIC),
614 DECL(PADDEDCELL),
615 DECL(ROOM),
616 DECL(BATHROOM),
617 DECL(LIVINGROOM),
618 DECL(STONEROOM),
619 DECL(AUDITORIUM),
620 DECL(CONCERTHALL),
621 DECL(CAVE),
622 DECL(ARENA),
623 DECL(HANGAR),
624 DECL(CARPETEDHALLWAY),
625 DECL(HALLWAY),
626 DECL(STONECORRIDOR),
627 DECL(ALLEY),
628 DECL(FOREST),
629 DECL(CITY),
630 DECL(MOUNTAINS),
631 DECL(QUARRY),
632 DECL(PLAIN),
633 DECL(PARKINGLOT),
634 DECL(SEWERPIPE),
635 DECL(UNDERWATER),
636 DECL(DRUGGED),
637 DECL(DIZZY),
638 DECL(PSYCHOTIC),
640 DECL(CASTLE_SMALLROOM),
641 DECL(CASTLE_SHORTPASSAGE),
642 DECL(CASTLE_MEDIUMROOM),
643 DECL(CASTLE_LARGEROOM),
644 DECL(CASTLE_LONGPASSAGE),
645 DECL(CASTLE_HALL),
646 DECL(CASTLE_CUPBOARD),
647 DECL(CASTLE_COURTYARD),
648 DECL(CASTLE_ALCOVE),
650 DECL(FACTORY_SMALLROOM),
651 DECL(FACTORY_SHORTPASSAGE),
652 DECL(FACTORY_MEDIUMROOM),
653 DECL(FACTORY_LARGEROOM),
654 DECL(FACTORY_LONGPASSAGE),
655 DECL(FACTORY_HALL),
656 DECL(FACTORY_CUPBOARD),
657 DECL(FACTORY_COURTYARD),
658 DECL(FACTORY_ALCOVE),
660 DECL(ICEPALACE_SMALLROOM),
661 DECL(ICEPALACE_SHORTPASSAGE),
662 DECL(ICEPALACE_MEDIUMROOM),
663 DECL(ICEPALACE_LARGEROOM),
664 DECL(ICEPALACE_LONGPASSAGE),
665 DECL(ICEPALACE_HALL),
666 DECL(ICEPALACE_CUPBOARD),
667 DECL(ICEPALACE_COURTYARD),
668 DECL(ICEPALACE_ALCOVE),
670 DECL(SPACESTATION_SMALLROOM),
671 DECL(SPACESTATION_SHORTPASSAGE),
672 DECL(SPACESTATION_MEDIUMROOM),
673 DECL(SPACESTATION_LARGEROOM),
674 DECL(SPACESTATION_LONGPASSAGE),
675 DECL(SPACESTATION_HALL),
676 DECL(SPACESTATION_CUPBOARD),
677 DECL(SPACESTATION_ALCOVE),
679 DECL(WOODEN_SMALLROOM),
680 DECL(WOODEN_SHORTPASSAGE),
681 DECL(WOODEN_MEDIUMROOM),
682 DECL(WOODEN_LARGEROOM),
683 DECL(WOODEN_LONGPASSAGE),
684 DECL(WOODEN_HALL),
685 DECL(WOODEN_CUPBOARD),
686 DECL(WOODEN_COURTYARD),
687 DECL(WOODEN_ALCOVE),
689 DECL(SPORT_EMPTYSTADIUM),
690 DECL(SPORT_SQUASHCOURT),
691 DECL(SPORT_SMALLSWIMMINGPOOL),
692 DECL(SPORT_LARGESWIMMINGPOOL),
693 DECL(SPORT_GYMNASIUM),
694 DECL(SPORT_FULLSTADIUM),
695 DECL(SPORT_STADIUMTANNOY),
697 DECL(PREFAB_WORKSHOP),
698 DECL(PREFAB_SCHOOLROOM),
699 DECL(PREFAB_PRACTISEROOM),
700 DECL(PREFAB_OUTHOUSE),
701 DECL(PREFAB_CARAVAN),
703 DECL(DOME_TOMB),
704 DECL(PIPE_SMALL),
705 DECL(DOME_SAINTPAULS),
706 DECL(PIPE_LONGTHIN),
707 DECL(PIPE_LARGE),
708 DECL(PIPE_RESONANT),
710 DECL(OUTDOORS_BACKYARD),
711 DECL(OUTDOORS_ROLLINGPLAINS),
712 DECL(OUTDOORS_DEEPCANYON),
713 DECL(OUTDOORS_CREEK),
714 DECL(OUTDOORS_VALLEY),
716 DECL(MOOD_HEAVEN),
717 DECL(MOOD_HELL),
718 DECL(MOOD_MEMORY),
720 DECL(DRIVING_COMMENTATOR),
721 DECL(DRIVING_PITGARAGE),
722 DECL(DRIVING_INCAR_RACER),
723 DECL(DRIVING_INCAR_SPORTS),
724 DECL(DRIVING_INCAR_LUXURY),
725 DECL(DRIVING_FULLGRANDSTAND),
726 DECL(DRIVING_EMPTYGRANDSTAND),
727 DECL(DRIVING_TUNNEL),
729 DECL(CITY_STREETS),
730 DECL(CITY_SUBWAY),
731 DECL(CITY_MUSEUM),
732 DECL(CITY_LIBRARY),
733 DECL(CITY_UNDERPASS),
734 DECL(CITY_ABANDONED),
736 DECL(DUSTYROOM),
737 DECL(CHAPEL),
738 DECL(SMALLWATERROOM),
740 #undef DECL
742 void LoadReverbPreset(const char *name, ALeffect *effect)
744 size_t i;
746 if(strcasecmp(name, "NONE") == 0)
748 InitEffectParams(effect, AL_EFFECT_NULL);
749 TRACE("Loading reverb '%s'\n", "NONE");
750 return;
753 if(!DisabledEffects[EAXREVERB_EFFECT])
754 InitEffectParams(effect, AL_EFFECT_EAXREVERB);
755 else if(!DisabledEffects[REVERB_EFFECT])
756 InitEffectParams(effect, AL_EFFECT_REVERB);
757 else
758 InitEffectParams(effect, AL_EFFECT_NULL);
759 for(i = 0;i < COUNTOF(reverblist);i++)
761 const EFXEAXREVERBPROPERTIES *props;
763 if(strcasecmp(name, reverblist[i].name) != 0)
764 continue;
766 TRACE("Loading reverb '%s'\n", reverblist[i].name);
767 props = &reverblist[i].props;
768 effect->Props.Reverb.Density = props->flDensity;
769 effect->Props.Reverb.Diffusion = props->flDiffusion;
770 effect->Props.Reverb.Gain = props->flGain;
771 effect->Props.Reverb.GainHF = props->flGainHF;
772 effect->Props.Reverb.GainLF = props->flGainLF;
773 effect->Props.Reverb.DecayTime = props->flDecayTime;
774 effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio;
775 effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio;
776 effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain;
777 effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay;
778 effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0];
779 effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1];
780 effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2];
781 effect->Props.Reverb.LateReverbGain = props->flLateReverbGain;
782 effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay;
783 effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0];
784 effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1];
785 effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2];
786 effect->Props.Reverb.EchoTime = props->flEchoTime;
787 effect->Props.Reverb.EchoDepth = props->flEchoDepth;
788 effect->Props.Reverb.ModulationTime = props->flModulationTime;
789 effect->Props.Reverb.ModulationDepth = props->flModulationDepth;
790 effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF;
791 effect->Props.Reverb.HFReference = props->flHFReference;
792 effect->Props.Reverb.LFReference = props->flLFReference;
793 effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor;
794 effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit;
795 return;
798 WARN("Reverb preset '%s' not found\n", name);