Add base support for ALC_EXT_disconnect
[openal-soft.git] / OpenAL32 / alEffect.c
blob0c2d129f447965ff4d0bb1003312bf7108e947ae
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include <math.h>
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alEffect.h"
30 #include "alThunk.h"
31 #include "alError.h"
34 ALboolean DisabledEffects[MAX_EFFECTS];
37 static void InitEffectParams(ALeffect *effect, ALenum type);
40 ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
42 ALCcontext *Context;
43 ALsizei i;
45 Context = GetContextSuspended();
47 if (n > 0)
49 ALCdevice *device = Context->Device;
51 // Check that enough memory has been allocted in the 'effects' array for n Effects
52 if (!IsBadWritePtr((void*)effects, n * sizeof(ALuint)))
54 ALeffect **list = &device->EffectList;
55 while(*list)
56 list = &(*list)->next;
58 i = 0;
59 while(i < n)
61 *list = calloc(1, sizeof(ALeffect));
62 if(!(*list))
64 // We must have run out or memory
65 alDeleteEffects(i, effects);
66 alSetError(AL_OUT_OF_MEMORY);
67 break;
70 effects[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
71 (*list)->effect = effects[i];
73 InitEffectParams(*list, AL_EFFECT_NULL);
74 device->EffectCount++;
75 i++;
77 list = &(*list)->next;
82 ProcessContext(Context);
85 ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects)
87 ALCcontext *Context;
88 ALeffect *ALEffect;
89 ALsizei i;
91 Context = GetContextSuspended();
93 if (n >= 0)
95 ALCdevice *device = Context->Device;
97 // Check that all effects are valid
98 for (i = 0; i < n; i++)
100 if (!alIsEffect(effects[i]))
102 alSetError(AL_INVALID_NAME);
103 break;
107 if (i == n)
109 // All effects are valid
110 for (i = 0; i < n; i++)
112 // Recheck that the effect is valid, because there could be duplicated names
113 if (effects[i] && alIsEffect(effects[i]))
115 ALeffect **list;
117 ALEffect = ((ALeffect*)ALTHUNK_LOOKUPENTRY(effects[i]));
119 // Remove Source from list of Sources
120 list = &device->EffectList;
121 while(*list && *list != ALEffect)
122 list = &(*list)->next;
124 if(*list)
125 *list = (*list)->next;
126 ALTHUNK_REMOVEENTRY(ALEffect->effect);
128 memset(ALEffect, 0, sizeof(ALeffect));
129 free(ALEffect);
131 device->EffectCount--;
136 else
137 alSetError(AL_INVALID_VALUE);
139 ProcessContext(Context);
142 ALboolean AL_APIENTRY alIsEffect(ALuint effect)
144 ALCcontext *Context;
145 ALeffect *list;
147 Context = GetContextSuspended();
149 list = Context->Device->EffectList;
150 while(list && list->effect != effect)
151 list = list->next;
153 ProcessContext(Context);
155 return ((list || !effect) ? AL_TRUE : AL_FALSE);
158 ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
160 ALCcontext *Context;
162 Context = GetContextSuspended();
164 if (effect && alIsEffect(effect))
166 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
168 if(param == AL_EFFECT_TYPE)
170 ALboolean isOk = (iValue == AL_EFFECT_NULL ||
171 (iValue == AL_EFFECT_EAXREVERB && !DisabledEffects[EAXREVERB]) ||
172 (iValue == AL_EFFECT_REVERB && !DisabledEffects[REVERB]) ||
173 (iValue == AL_EFFECT_ECHO && !DisabledEffects[ECHO]));
175 if(isOk)
176 InitEffectParams(ALEffect, iValue);
177 else
178 alSetError(AL_INVALID_VALUE);
180 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
182 switch(param)
184 case AL_EAXREVERB_DECAY_HFLIMIT:
185 if(iValue >= AL_EAXREVERB_MIN_DECAY_HFLIMIT &&
186 iValue <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)
187 ALEffect->Reverb.DecayHFLimit = iValue;
188 else
189 alSetError(AL_INVALID_VALUE);
190 break;
192 default:
193 alSetError(AL_INVALID_ENUM);
194 break;
197 else if(ALEffect->type == AL_EFFECT_REVERB)
199 switch(param)
201 case AL_REVERB_DECAY_HFLIMIT:
202 if(iValue >= AL_REVERB_MIN_DECAY_HFLIMIT &&
203 iValue <= AL_REVERB_MAX_DECAY_HFLIMIT)
204 ALEffect->Reverb.DecayHFLimit = iValue;
205 else
206 alSetError(AL_INVALID_VALUE);
207 break;
209 default:
210 alSetError(AL_INVALID_ENUM);
211 break;
214 else if(ALEffect->type == AL_EFFECT_ECHO)
216 switch(param)
218 default:
219 alSetError(AL_INVALID_ENUM);
220 break;
223 else
224 alSetError(AL_INVALID_ENUM);
226 else
227 alSetError(AL_INVALID_NAME);
229 ProcessContext(Context);
232 ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues)
234 ALCcontext *Context;
236 Context = GetContextSuspended();
238 if (effect && alIsEffect(effect))
240 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
242 if(param == AL_EFFECT_TYPE)
244 alEffecti(effect, param, piValues[0]);
246 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
248 switch(param)
250 case AL_EAXREVERB_DECAY_HFLIMIT:
251 alEffecti(effect, param, piValues[0]);
252 break;
254 default:
255 alSetError(AL_INVALID_ENUM);
256 break;
259 else if(ALEffect->type == AL_EFFECT_REVERB)
261 switch(param)
263 case AL_REVERB_DECAY_HFLIMIT:
264 alEffecti(effect, param, piValues[0]);
265 break;
267 default:
268 alSetError(AL_INVALID_ENUM);
269 break;
272 else if(ALEffect->type == AL_EFFECT_ECHO)
274 switch(param)
276 default:
277 alSetError(AL_INVALID_ENUM);
278 break;
281 else
282 alSetError(AL_INVALID_ENUM);
284 else
285 alSetError(AL_INVALID_NAME);
287 ProcessContext(Context);
290 ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue)
292 ALCcontext *Context;
294 Context = GetContextSuspended();
296 if (effect && alIsEffect(effect))
298 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
300 if(ALEffect->type == AL_EFFECT_EAXREVERB)
302 switch(param)
304 case AL_EAXREVERB_DENSITY:
305 if(flValue >= AL_EAXREVERB_MIN_DENSITY &&
306 flValue <= AL_EAXREVERB_MAX_DENSITY)
307 ALEffect->Reverb.Density = flValue;
308 else
309 alSetError(AL_INVALID_VALUE);
310 break;
312 case AL_EAXREVERB_DIFFUSION:
313 if(flValue >= AL_EAXREVERB_MIN_DIFFUSION &&
314 flValue <= AL_EAXREVERB_MAX_DIFFUSION)
315 ALEffect->Reverb.Diffusion = flValue;
316 else
317 alSetError(AL_INVALID_VALUE);
318 break;
320 case AL_EAXREVERB_GAIN:
321 if(flValue >= AL_EAXREVERB_MIN_GAIN &&
322 flValue <= AL_EAXREVERB_MAX_GAIN)
323 ALEffect->Reverb.Gain = flValue;
324 else
325 alSetError(AL_INVALID_VALUE);
326 break;
328 case AL_EAXREVERB_GAINHF:
329 if(flValue >= AL_EAXREVERB_MIN_GAINHF &&
330 flValue <= AL_EAXREVERB_MAX_GAIN)
331 ALEffect->Reverb.GainHF = flValue;
332 else
333 alSetError(AL_INVALID_VALUE);
334 break;
336 case AL_EAXREVERB_GAINLF:
337 if(flValue >= AL_EAXREVERB_MIN_GAINLF &&
338 flValue <= AL_EAXREVERB_MAX_GAINLF)
339 ALEffect->Reverb.GainLF = flValue;
340 else
341 alSetError(AL_INVALID_VALUE);
342 break;
344 case AL_EAXREVERB_DECAY_TIME:
345 if(flValue >= AL_EAXREVERB_MIN_DECAY_TIME &&
346 flValue <= AL_EAXREVERB_MAX_DECAY_TIME)
347 ALEffect->Reverb.DecayTime = flValue;
348 else
349 alSetError(AL_INVALID_VALUE);
350 break;
352 case AL_EAXREVERB_DECAY_HFRATIO:
353 if(flValue >= AL_EAXREVERB_MIN_DECAY_HFRATIO &&
354 flValue <= AL_EAXREVERB_MAX_DECAY_HFRATIO)
355 ALEffect->Reverb.DecayHFRatio = flValue;
356 else
357 alSetError(AL_INVALID_VALUE);
358 break;
360 case AL_EAXREVERB_DECAY_LFRATIO:
361 if(flValue >= AL_EAXREVERB_MIN_DECAY_LFRATIO &&
362 flValue <= AL_EAXREVERB_MAX_DECAY_LFRATIO)
363 ALEffect->Reverb.DecayLFRatio = flValue;
364 else
365 alSetError(AL_INVALID_VALUE);
366 break;
368 case AL_EAXREVERB_REFLECTIONS_GAIN:
369 if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN &&
370 flValue <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)
371 ALEffect->Reverb.ReflectionsGain = flValue;
372 else
373 alSetError(AL_INVALID_VALUE);
374 break;
376 case AL_EAXREVERB_REFLECTIONS_DELAY:
377 if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY &&
378 flValue <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)
379 ALEffect->Reverb.ReflectionsDelay = flValue;
380 else
381 alSetError(AL_INVALID_VALUE);
382 break;
384 case AL_EAXREVERB_LATE_REVERB_GAIN:
385 if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN &&
386 flValue <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)
387 ALEffect->Reverb.LateReverbGain = flValue;
388 else
389 alSetError(AL_INVALID_VALUE);
390 break;
392 case AL_EAXREVERB_LATE_REVERB_DELAY:
393 if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY &&
394 flValue <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)
395 ALEffect->Reverb.LateReverbDelay = flValue;
396 else
397 alSetError(AL_INVALID_VALUE);
398 break;
400 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
401 if(flValue >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF &&
402 flValue <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)
403 ALEffect->Reverb.AirAbsorptionGainHF = flValue;
404 else
405 alSetError(AL_INVALID_VALUE);
406 break;
408 case AL_EAXREVERB_ECHO_TIME:
409 if(flValue >= AL_EAXREVERB_MIN_ECHO_TIME &&
410 flValue <= AL_EAXREVERB_MAX_ECHO_TIME)
411 ALEffect->Reverb.EchoTime = flValue;
412 else
413 alSetError(AL_INVALID_VALUE);
414 break;
416 case AL_EAXREVERB_ECHO_DEPTH:
417 if(flValue >= AL_EAXREVERB_MIN_ECHO_DEPTH &&
418 flValue <= AL_EAXREVERB_MAX_ECHO_DEPTH)
419 ALEffect->Reverb.EchoDepth = flValue;
420 else
421 alSetError(AL_INVALID_VALUE);
422 break;
424 case AL_EAXREVERB_MODULATION_TIME:
425 if(flValue >= AL_EAXREVERB_MIN_MODULATION_TIME &&
426 flValue <= AL_EAXREVERB_MAX_MODULATION_TIME)
427 ALEffect->Reverb.ModulationTime = flValue;
428 else
429 alSetError(AL_INVALID_VALUE);
430 break;
432 case AL_EAXREVERB_MODULATION_DEPTH:
433 if(flValue >= AL_EAXREVERB_MIN_MODULATION_DEPTH &&
434 flValue <= AL_EAXREVERB_MAX_MODULATION_DEPTH)
435 ALEffect->Reverb.ModulationDepth = flValue;
436 else
437 alSetError(AL_INVALID_VALUE);
438 break;
440 case AL_EAXREVERB_HFREFERENCE:
441 if(flValue >= AL_EAXREVERB_MIN_HFREFERENCE &&
442 flValue <= AL_EAXREVERB_MAX_HFREFERENCE)
443 ALEffect->Reverb.HFReference = flValue;
444 else
445 alSetError(AL_INVALID_VALUE);
446 break;
448 case AL_EAXREVERB_LFREFERENCE:
449 if(flValue >= AL_EAXREVERB_MIN_LFREFERENCE &&
450 flValue <= AL_EAXREVERB_MAX_LFREFERENCE)
451 ALEffect->Reverb.LFReference = flValue;
452 else
453 alSetError(AL_INVALID_VALUE);
454 break;
456 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
457 if(flValue >= 0.0f && flValue <= 10.0f)
458 ALEffect->Reverb.RoomRolloffFactor = flValue;
459 else
460 alSetError(AL_INVALID_VALUE);
461 break;
463 default:
464 alSetError(AL_INVALID_ENUM);
465 break;
468 else if(ALEffect->type == AL_EFFECT_REVERB)
470 switch(param)
472 case AL_REVERB_DENSITY:
473 if(flValue >= AL_REVERB_MIN_DENSITY &&
474 flValue <= AL_REVERB_MAX_DENSITY)
475 ALEffect->Reverb.Density = flValue;
476 else
477 alSetError(AL_INVALID_VALUE);
478 break;
480 case AL_REVERB_DIFFUSION:
481 if(flValue >= AL_REVERB_MIN_DIFFUSION &&
482 flValue <= AL_REVERB_MAX_DIFFUSION)
483 ALEffect->Reverb.Diffusion = flValue;
484 else
485 alSetError(AL_INVALID_VALUE);
486 break;
488 case AL_REVERB_GAIN:
489 if(flValue >= AL_REVERB_MIN_GAIN &&
490 flValue <= AL_REVERB_MAX_GAIN)
491 ALEffect->Reverb.Gain = flValue;
492 else
493 alSetError(AL_INVALID_VALUE);
494 break;
496 case AL_REVERB_GAINHF:
497 if(flValue >= AL_REVERB_MIN_GAINHF &&
498 flValue <= AL_REVERB_MAX_GAINHF)
499 ALEffect->Reverb.GainHF = flValue;
500 else
501 alSetError(AL_INVALID_VALUE);
502 break;
504 case AL_REVERB_DECAY_TIME:
505 if(flValue >= AL_REVERB_MIN_DECAY_TIME &&
506 flValue <= AL_REVERB_MAX_DECAY_TIME)
507 ALEffect->Reverb.DecayTime = flValue;
508 else
509 alSetError(AL_INVALID_VALUE);
510 break;
512 case AL_REVERB_DECAY_HFRATIO:
513 if(flValue >= AL_REVERB_MIN_DECAY_HFRATIO &&
514 flValue <= AL_REVERB_MAX_DECAY_HFRATIO)
515 ALEffect->Reverb.DecayHFRatio = flValue;
516 else
517 alSetError(AL_INVALID_VALUE);
518 break;
520 case AL_REVERB_REFLECTIONS_GAIN:
521 if(flValue >= AL_REVERB_MIN_REFLECTIONS_GAIN &&
522 flValue <= AL_REVERB_MAX_REFLECTIONS_GAIN)
523 ALEffect->Reverb.ReflectionsGain = flValue;
524 else
525 alSetError(AL_INVALID_VALUE);
526 break;
528 case AL_REVERB_REFLECTIONS_DELAY:
529 if(flValue >= AL_REVERB_MIN_REFLECTIONS_DELAY &&
530 flValue <= AL_REVERB_MAX_REFLECTIONS_DELAY)
531 ALEffect->Reverb.ReflectionsDelay = flValue;
532 else
533 alSetError(AL_INVALID_VALUE);
534 break;
536 case AL_REVERB_LATE_REVERB_GAIN:
537 if(flValue >= AL_REVERB_MIN_LATE_REVERB_GAIN &&
538 flValue <= AL_REVERB_MAX_LATE_REVERB_GAIN)
539 ALEffect->Reverb.LateReverbGain = flValue;
540 else
541 alSetError(AL_INVALID_VALUE);
542 break;
544 case AL_REVERB_LATE_REVERB_DELAY:
545 if(flValue >= AL_REVERB_MIN_LATE_REVERB_DELAY &&
546 flValue <= AL_REVERB_MAX_LATE_REVERB_DELAY)
547 ALEffect->Reverb.LateReverbDelay = flValue;
548 else
549 alSetError(AL_INVALID_VALUE);
550 break;
552 case AL_REVERB_AIR_ABSORPTION_GAINHF:
553 if(flValue >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF &&
554 flValue <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)
555 ALEffect->Reverb.AirAbsorptionGainHF = flValue;
556 else
557 alSetError(AL_INVALID_VALUE);
558 break;
560 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
561 if(flValue >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR &&
562 flValue <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)
563 ALEffect->Reverb.RoomRolloffFactor = flValue;
564 else
565 alSetError(AL_INVALID_VALUE);
566 break;
568 default:
569 alSetError(AL_INVALID_ENUM);
570 break;
573 else if(ALEffect->type == AL_EFFECT_ECHO)
575 switch(param)
577 case AL_ECHO_DELAY:
578 if(flValue >= AL_ECHO_MIN_DELAY && flValue <= AL_ECHO_MAX_DELAY)
579 ALEffect->Echo.Delay = flValue;
580 else
581 alSetError(AL_INVALID_VALUE);
582 break;
584 case AL_ECHO_LRDELAY:
585 if(flValue >= AL_ECHO_MIN_LRDELAY && flValue <= AL_ECHO_MAX_LRDELAY)
586 ALEffect->Echo.LRDelay = flValue;
587 else
588 alSetError(AL_INVALID_VALUE);
589 break;
591 case AL_ECHO_DAMPING:
592 if(flValue >= AL_ECHO_MIN_DAMPING && flValue <= AL_ECHO_MAX_DAMPING)
593 ALEffect->Echo.Damping = flValue;
594 else
595 alSetError(AL_INVALID_VALUE);
596 break;
598 case AL_ECHO_FEEDBACK:
599 if(flValue >= AL_ECHO_MIN_FEEDBACK && flValue <= AL_ECHO_MAX_FEEDBACK)
600 ALEffect->Echo.Feedback = flValue;
601 else
602 alSetError(AL_INVALID_VALUE);
603 break;
605 case AL_ECHO_SPREAD:
606 if(flValue >= AL_ECHO_MIN_SPREAD && flValue <= AL_ECHO_MAX_SPREAD)
607 ALEffect->Echo.Spread = flValue;
608 else
609 alSetError(AL_INVALID_VALUE);
610 break;
612 default:
613 alSetError(AL_INVALID_ENUM);
614 break;
617 else
618 alSetError(AL_INVALID_ENUM);
620 else
621 alSetError(AL_INVALID_NAME);
623 ProcessContext(Context);
626 ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
628 ALCcontext *Context;
630 Context = GetContextSuspended();
632 if (effect && alIsEffect(effect))
634 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
636 if(ALEffect->type == AL_EFFECT_EAXREVERB)
638 switch(param)
640 case AL_EAXREVERB_DENSITY:
641 case AL_EAXREVERB_DIFFUSION:
642 case AL_EAXREVERB_GAIN:
643 case AL_EAXREVERB_GAINHF:
644 case AL_EAXREVERB_GAINLF:
645 case AL_EAXREVERB_DECAY_TIME:
646 case AL_EAXREVERB_DECAY_HFRATIO:
647 case AL_EAXREVERB_DECAY_LFRATIO:
648 case AL_EAXREVERB_REFLECTIONS_GAIN:
649 case AL_EAXREVERB_REFLECTIONS_DELAY:
650 case AL_EAXREVERB_LATE_REVERB_GAIN:
651 case AL_EAXREVERB_LATE_REVERB_DELAY:
652 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
653 case AL_EAXREVERB_ECHO_TIME:
654 case AL_EAXREVERB_ECHO_DEPTH:
655 case AL_EAXREVERB_MODULATION_TIME:
656 case AL_EAXREVERB_MODULATION_DEPTH:
657 case AL_EAXREVERB_HFREFERENCE:
658 case AL_EAXREVERB_LFREFERENCE:
659 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
660 alEffectf(effect, param, pflValues[0]);
661 break;
663 case AL_EAXREVERB_REFLECTIONS_PAN:
664 if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2]))
666 ALEffect->Reverb.ReflectionsPan[0] = pflValues[0];
667 ALEffect->Reverb.ReflectionsPan[1] = pflValues[1];
668 ALEffect->Reverb.ReflectionsPan[2] = pflValues[2];
670 else
671 alSetError(AL_INVALID_VALUE);
672 break;
673 case AL_EAXREVERB_LATE_REVERB_PAN:
674 if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2]))
676 ALEffect->Reverb.LateReverbPan[0] = pflValues[0];
677 ALEffect->Reverb.LateReverbPan[1] = pflValues[1];
678 ALEffect->Reverb.LateReverbPan[2] = pflValues[2];
680 else
681 alSetError(AL_INVALID_VALUE);
682 break;
684 default:
685 alSetError(AL_INVALID_ENUM);
686 break;
689 else if(ALEffect->type == AL_EFFECT_REVERB)
691 switch(param)
693 case AL_REVERB_DENSITY:
694 case AL_REVERB_DIFFUSION:
695 case AL_REVERB_GAIN:
696 case AL_REVERB_GAINHF:
697 case AL_REVERB_DECAY_TIME:
698 case AL_REVERB_DECAY_HFRATIO:
699 case AL_REVERB_REFLECTIONS_GAIN:
700 case AL_REVERB_REFLECTIONS_DELAY:
701 case AL_REVERB_LATE_REVERB_GAIN:
702 case AL_REVERB_LATE_REVERB_DELAY:
703 case AL_REVERB_AIR_ABSORPTION_GAINHF:
704 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
705 alEffectf(effect, param, pflValues[0]);
706 break;
708 default:
709 alSetError(AL_INVALID_ENUM);
710 break;
713 else if(ALEffect->type == AL_EFFECT_ECHO)
715 switch(param)
717 case AL_ECHO_DELAY:
718 case AL_ECHO_LRDELAY:
719 case AL_ECHO_DAMPING:
720 case AL_ECHO_FEEDBACK:
721 case AL_ECHO_SPREAD:
722 alEffectf(effect, param, pflValues[0]);
723 break;
725 default:
726 alSetError(AL_INVALID_ENUM);
727 break;
730 else
731 alSetError(AL_INVALID_ENUM);
733 else
734 alSetError(AL_INVALID_NAME);
736 ProcessContext(Context);
739 ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue)
741 ALCcontext *Context;
743 Context = GetContextSuspended();
745 if (effect && alIsEffect(effect))
747 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
749 if(param == AL_EFFECT_TYPE)
751 *piValue = ALEffect->type;
753 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
755 switch(param)
757 case AL_EAXREVERB_DECAY_HFLIMIT:
758 *piValue = ALEffect->Reverb.DecayHFLimit;
759 break;
761 default:
762 alSetError(AL_INVALID_ENUM);
763 break;
766 else if(ALEffect->type == AL_EFFECT_REVERB)
768 switch(param)
770 case AL_REVERB_DECAY_HFLIMIT:
771 *piValue = ALEffect->Reverb.DecayHFLimit;
772 break;
774 default:
775 alSetError(AL_INVALID_ENUM);
776 break;
779 else if(ALEffect->type == AL_EFFECT_ECHO)
781 switch(param)
783 default:
784 alSetError(AL_INVALID_ENUM);
785 break;
788 else
789 alSetError(AL_INVALID_ENUM);
791 else
792 alSetError(AL_INVALID_NAME);
794 ProcessContext(Context);
797 ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues)
799 ALCcontext *Context;
801 Context = GetContextSuspended();
803 if (effect && alIsEffect(effect))
805 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
807 if(param == AL_EFFECT_TYPE)
809 alGetEffecti(effect, param, piValues);
811 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
813 switch(param)
815 case AL_EAXREVERB_DECAY_HFLIMIT:
816 alGetEffecti(effect, param, piValues);
817 break;
819 default:
820 alSetError(AL_INVALID_ENUM);
821 break;
824 else if(ALEffect->type == AL_EFFECT_REVERB)
826 switch(param)
828 case AL_REVERB_DECAY_HFLIMIT:
829 alGetEffecti(effect, param, piValues);
830 break;
832 default:
833 alSetError(AL_INVALID_ENUM);
834 break;
837 else if(ALEffect->type == AL_EFFECT_ECHO)
839 switch(param)
841 default:
842 alSetError(AL_INVALID_ENUM);
843 break;
846 else
847 alSetError(AL_INVALID_ENUM);
849 else
850 alSetError(AL_INVALID_NAME);
852 ProcessContext(Context);
855 ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue)
857 ALCcontext *Context;
859 Context = GetContextSuspended();
861 if (effect && alIsEffect(effect))
863 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
865 if(ALEffect->type == AL_EFFECT_EAXREVERB)
867 switch(param)
869 case AL_EAXREVERB_DENSITY:
870 *pflValue = ALEffect->Reverb.Density;
871 break;
873 case AL_EAXREVERB_DIFFUSION:
874 *pflValue = ALEffect->Reverb.Diffusion;
875 break;
877 case AL_EAXREVERB_GAIN:
878 *pflValue = ALEffect->Reverb.Gain;
879 break;
881 case AL_EAXREVERB_GAINHF:
882 *pflValue = ALEffect->Reverb.GainHF;
883 break;
885 case AL_EAXREVERB_GAINLF:
886 *pflValue = ALEffect->Reverb.GainLF;
887 break;
889 case AL_EAXREVERB_DECAY_TIME:
890 *pflValue = ALEffect->Reverb.DecayTime;
891 break;
893 case AL_EAXREVERB_DECAY_HFRATIO:
894 *pflValue = ALEffect->Reverb.DecayHFRatio;
895 break;
897 case AL_EAXREVERB_DECAY_LFRATIO:
898 *pflValue = ALEffect->Reverb.DecayLFRatio;
899 break;
901 case AL_EAXREVERB_REFLECTIONS_GAIN:
902 *pflValue = ALEffect->Reverb.ReflectionsGain;
903 break;
905 case AL_EAXREVERB_REFLECTIONS_DELAY:
906 *pflValue = ALEffect->Reverb.ReflectionsDelay;
907 break;
909 case AL_EAXREVERB_LATE_REVERB_GAIN:
910 *pflValue = ALEffect->Reverb.LateReverbGain;
911 break;
913 case AL_EAXREVERB_LATE_REVERB_DELAY:
914 *pflValue = ALEffect->Reverb.LateReverbDelay;
915 break;
917 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
918 *pflValue = ALEffect->Reverb.AirAbsorptionGainHF;
919 break;
921 case AL_EAXREVERB_ECHO_TIME:
922 *pflValue = ALEffect->Reverb.EchoTime;
923 break;
925 case AL_EAXREVERB_ECHO_DEPTH:
926 *pflValue = ALEffect->Reverb.EchoDepth;
927 break;
929 case AL_EAXREVERB_MODULATION_TIME:
930 *pflValue = ALEffect->Reverb.ModulationTime;
931 break;
933 case AL_EAXREVERB_MODULATION_DEPTH:
934 *pflValue = ALEffect->Reverb.ModulationDepth;
935 break;
937 case AL_EAXREVERB_HFREFERENCE:
938 *pflValue = ALEffect->Reverb.HFReference;
939 break;
941 case AL_EAXREVERB_LFREFERENCE:
942 *pflValue = ALEffect->Reverb.LFReference;
943 break;
945 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
946 *pflValue = ALEffect->Reverb.RoomRolloffFactor;
947 break;
949 default:
950 alSetError(AL_INVALID_ENUM);
951 break;
954 else if(ALEffect->type == AL_EFFECT_REVERB)
956 switch(param)
958 case AL_REVERB_DENSITY:
959 *pflValue = ALEffect->Reverb.Density;
960 break;
962 case AL_REVERB_DIFFUSION:
963 *pflValue = ALEffect->Reverb.Diffusion;
964 break;
966 case AL_REVERB_GAIN:
967 *pflValue = ALEffect->Reverb.Gain;
968 break;
970 case AL_REVERB_GAINHF:
971 *pflValue = ALEffect->Reverb.GainHF;
972 break;
974 case AL_REVERB_DECAY_TIME:
975 *pflValue = ALEffect->Reverb.DecayTime;
976 break;
978 case AL_REVERB_DECAY_HFRATIO:
979 *pflValue = ALEffect->Reverb.DecayHFRatio;
980 break;
982 case AL_REVERB_REFLECTIONS_GAIN:
983 *pflValue = ALEffect->Reverb.ReflectionsGain;
984 break;
986 case AL_REVERB_REFLECTIONS_DELAY:
987 *pflValue = ALEffect->Reverb.ReflectionsDelay;
988 break;
990 case AL_REVERB_LATE_REVERB_GAIN:
991 *pflValue = ALEffect->Reverb.LateReverbGain;
992 break;
994 case AL_REVERB_LATE_REVERB_DELAY:
995 *pflValue = ALEffect->Reverb.LateReverbDelay;
996 break;
998 case AL_REVERB_AIR_ABSORPTION_GAINHF:
999 *pflValue = ALEffect->Reverb.AirAbsorptionGainHF;
1000 break;
1002 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
1003 *pflValue = ALEffect->Reverb.RoomRolloffFactor;
1004 break;
1006 default:
1007 alSetError(AL_INVALID_ENUM);
1008 break;
1011 else if(ALEffect->type == AL_EFFECT_ECHO)
1013 switch(param)
1015 case AL_ECHO_DELAY:
1016 *pflValue = ALEffect->Echo.Delay;
1017 break;
1019 case AL_ECHO_LRDELAY:
1020 *pflValue = ALEffect->Echo.LRDelay;
1021 break;
1023 case AL_ECHO_DAMPING:
1024 *pflValue = ALEffect->Echo.Damping;
1025 break;
1027 case AL_ECHO_FEEDBACK:
1028 *pflValue = ALEffect->Echo.Feedback;
1029 break;
1031 case AL_ECHO_SPREAD:
1032 *pflValue = ALEffect->Echo.Spread;
1033 break;
1035 default:
1036 alSetError(AL_INVALID_ENUM);
1037 break;
1040 else
1041 alSetError(AL_INVALID_ENUM);
1043 else
1044 alSetError(AL_INVALID_NAME);
1046 ProcessContext(Context);
1049 ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
1051 ALCcontext *Context;
1053 Context = GetContextSuspended();
1055 if (effect && alIsEffect(effect))
1057 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
1059 if(ALEffect->type == AL_EFFECT_EAXREVERB)
1061 switch(param)
1063 case AL_EAXREVERB_DENSITY:
1064 case AL_EAXREVERB_DIFFUSION:
1065 case AL_EAXREVERB_GAIN:
1066 case AL_EAXREVERB_GAINHF:
1067 case AL_EAXREVERB_GAINLF:
1068 case AL_EAXREVERB_DECAY_TIME:
1069 case AL_EAXREVERB_DECAY_HFRATIO:
1070 case AL_EAXREVERB_DECAY_LFRATIO:
1071 case AL_EAXREVERB_REFLECTIONS_GAIN:
1072 case AL_EAXREVERB_REFLECTIONS_DELAY:
1073 case AL_EAXREVERB_LATE_REVERB_GAIN:
1074 case AL_EAXREVERB_LATE_REVERB_DELAY:
1075 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
1076 case AL_EAXREVERB_ECHO_TIME:
1077 case AL_EAXREVERB_ECHO_DEPTH:
1078 case AL_EAXREVERB_MODULATION_TIME:
1079 case AL_EAXREVERB_MODULATION_DEPTH:
1080 case AL_EAXREVERB_HFREFERENCE:
1081 case AL_EAXREVERB_LFREFERENCE:
1082 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
1083 alGetEffectf(effect, param, pflValues);
1084 break;
1086 case AL_EAXREVERB_REFLECTIONS_PAN:
1087 pflValues[0] = ALEffect->Reverb.ReflectionsPan[0];
1088 pflValues[1] = ALEffect->Reverb.ReflectionsPan[1];
1089 pflValues[2] = ALEffect->Reverb.ReflectionsPan[2];
1090 break;
1091 case AL_EAXREVERB_LATE_REVERB_PAN:
1092 pflValues[0] = ALEffect->Reverb.LateReverbPan[0];
1093 pflValues[1] = ALEffect->Reverb.LateReverbPan[1];
1094 pflValues[2] = ALEffect->Reverb.LateReverbPan[2];
1095 break;
1097 default:
1098 alSetError(AL_INVALID_ENUM);
1099 break;
1102 else if(ALEffect->type == AL_EFFECT_REVERB)
1104 switch(param)
1106 case AL_REVERB_DENSITY:
1107 case AL_REVERB_DIFFUSION:
1108 case AL_REVERB_GAIN:
1109 case AL_REVERB_GAINHF:
1110 case AL_REVERB_DECAY_TIME:
1111 case AL_REVERB_DECAY_HFRATIO:
1112 case AL_REVERB_REFLECTIONS_GAIN:
1113 case AL_REVERB_REFLECTIONS_DELAY:
1114 case AL_REVERB_LATE_REVERB_GAIN:
1115 case AL_REVERB_LATE_REVERB_DELAY:
1116 case AL_REVERB_AIR_ABSORPTION_GAINHF:
1117 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
1118 alGetEffectf(effect, param, pflValues);
1119 break;
1121 default:
1122 alSetError(AL_INVALID_ENUM);
1123 break;
1126 else if(ALEffect->type == AL_EFFECT_ECHO)
1128 switch(param)
1130 case AL_ECHO_DELAY:
1131 case AL_ECHO_LRDELAY:
1132 case AL_ECHO_DAMPING:
1133 case AL_ECHO_FEEDBACK:
1134 case AL_ECHO_SPREAD:
1135 alGetEffectf(effect, param, pflValues);
1136 break;
1138 default:
1139 alSetError(AL_INVALID_ENUM);
1140 break;
1143 else
1144 alSetError(AL_INVALID_ENUM);
1146 else
1147 alSetError(AL_INVALID_NAME);
1149 ProcessContext(Context);
1153 ALvoid ReleaseALEffects(ALCdevice *device)
1155 ALeffect *list = device->EffectList;
1156 while(list)
1158 ALeffect *temp = list;
1159 list = list->next;
1161 // Release effect structure
1162 memset(temp, 0, sizeof(ALeffect));
1163 free(temp);
1165 device->EffectList = NULL;
1166 device->EffectCount = 0;
1170 static void InitEffectParams(ALeffect *effect, ALenum type)
1172 effect->type = type;
1173 switch(type)
1175 /* NOTE: Standard reverb and EAX reverb use the same defaults for the
1176 * shared parameters, and EAX's additional parameters default to
1177 * values assumed by standard reverb.
1179 case AL_EFFECT_EAXREVERB:
1180 case AL_EFFECT_REVERB:
1181 effect->Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
1182 effect->Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
1183 effect->Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
1184 effect->Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
1185 effect->Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
1186 effect->Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
1187 effect->Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
1188 effect->Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
1189 effect->Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
1190 effect->Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
1191 effect->Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1192 effect->Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1193 effect->Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1194 effect->Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
1195 effect->Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
1196 effect->Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1197 effect->Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1198 effect->Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1199 effect->Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
1200 effect->Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
1201 effect->Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
1202 effect->Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
1203 effect->Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
1204 effect->Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
1205 effect->Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
1206 effect->Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
1207 effect->Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
1208 break;
1209 case AL_EFFECT_ECHO:
1210 effect->Echo.Delay = AL_ECHO_DEFAULT_DELAY;
1211 effect->Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
1212 effect->Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
1213 effect->Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
1214 effect->Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
1215 break;