Avoid calling alDelete* from alGen*
[openal-soft.git] / OpenAL32 / alEffect.c
bloba63ea72e890e55fe699db23ebc714fa9affdd76c
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);
39 DECL_VERIFIER(Effect, ALeffect, effect)
41 ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
43 ALCcontext *Context;
44 ALsizei i=0;
46 Context = GetContextSuspended();
47 if(!Context) return;
49 if (n > 0)
51 ALCdevice *device = Context->Device;
53 // Check that enough memory has been allocted in the 'effects' array for n Effects
54 if (!IsBadWritePtr((void*)effects, n * sizeof(ALuint)))
56 ALeffect *end;
57 ALeffect **list = &device->EffectList;
58 while(*list)
59 list = &(*list)->next;
61 end = *list;
62 while(i < n)
64 *list = calloc(1, sizeof(ALeffect));
65 if(!(*list))
67 while(end->next)
69 ALeffect *temp = end->next;
70 end->next = temp->next;
72 ALTHUNK_REMOVEENTRY(temp->effect);
73 device->EffectCount--;
74 free(temp);
76 alSetError(Context, AL_OUT_OF_MEMORY);
77 break;
80 effects[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
81 (*list)->effect = effects[i];
83 InitEffectParams(*list, AL_EFFECT_NULL);
84 device->EffectCount++;
85 i++;
87 list = &(*list)->next;
92 ProcessContext(Context);
95 ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects)
97 ALCcontext *Context;
98 ALeffect *ALEffect;
99 ALsizei i;
101 Context = GetContextSuspended();
102 if(!Context) return;
104 if (n >= 0)
106 ALCdevice *device = Context->Device;
108 // Check that all effects are valid
109 for (i = 0; i < n; i++)
111 if(!effects[i])
112 continue;
114 if(!VerifyEffect(device->EffectList, effects[i]))
116 alSetError(Context, AL_INVALID_NAME);
117 break;
121 if (i == n)
123 // All effects are valid
124 for (i = 0; i < n; i++)
126 // Recheck that the effect is valid, because there could be duplicated names
127 if((ALEffect=VerifyEffect(device->EffectList, effects[i])) != NULL)
129 ALeffect **list;
131 // Remove Effect from list of effects
132 list = &device->EffectList;
133 while(*list && *list != ALEffect)
134 list = &(*list)->next;
136 if(*list)
137 *list = (*list)->next;
138 ALTHUNK_REMOVEENTRY(ALEffect->effect);
140 memset(ALEffect, 0, sizeof(ALeffect));
141 free(ALEffect);
143 device->EffectCount--;
148 else
149 alSetError(Context, AL_INVALID_VALUE);
151 ProcessContext(Context);
154 ALboolean AL_APIENTRY alIsEffect(ALuint effect)
156 ALCcontext *Context;
157 ALboolean result = AL_TRUE;
159 Context = GetContextSuspended();
160 if(!Context) return AL_FALSE;
162 if(effect)
163 result = (VerifyEffect(Context->Device->EffectList, effect) ?
164 AL_TRUE : AL_FALSE);
166 ProcessContext(Context);
168 return result;
171 ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
173 ALCcontext *Context;
174 ALCdevice *Device;
175 ALeffect *ALEffect;
177 Context = GetContextSuspended();
178 if(!Context) return;
180 Device = Context->Device;
181 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
183 if(param == AL_EFFECT_TYPE)
185 ALboolean isOk = (iValue == AL_EFFECT_NULL ||
186 (iValue == AL_EFFECT_EAXREVERB && !DisabledEffects[EAXREVERB]) ||
187 (iValue == AL_EFFECT_REVERB && !DisabledEffects[REVERB]) ||
188 (iValue == AL_EFFECT_ECHO && !DisabledEffects[ECHO]));
190 if(isOk)
191 InitEffectParams(ALEffect, iValue);
192 else
193 alSetError(Context, AL_INVALID_VALUE);
195 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
197 switch(param)
199 case AL_EAXREVERB_DECAY_HFLIMIT:
200 if(iValue >= AL_EAXREVERB_MIN_DECAY_HFLIMIT &&
201 iValue <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)
202 ALEffect->Reverb.DecayHFLimit = iValue;
203 else
204 alSetError(Context, AL_INVALID_VALUE);
205 break;
207 default:
208 alSetError(Context, AL_INVALID_ENUM);
209 break;
212 else if(ALEffect->type == AL_EFFECT_REVERB)
214 switch(param)
216 case AL_REVERB_DECAY_HFLIMIT:
217 if(iValue >= AL_REVERB_MIN_DECAY_HFLIMIT &&
218 iValue <= AL_REVERB_MAX_DECAY_HFLIMIT)
219 ALEffect->Reverb.DecayHFLimit = iValue;
220 else
221 alSetError(Context, AL_INVALID_VALUE);
222 break;
224 default:
225 alSetError(Context, AL_INVALID_ENUM);
226 break;
229 else if(ALEffect->type == AL_EFFECT_ECHO)
231 switch(param)
233 default:
234 alSetError(Context, AL_INVALID_ENUM);
235 break;
238 else
239 alSetError(Context, AL_INVALID_ENUM);
241 else
242 alSetError(Context, AL_INVALID_NAME);
244 ProcessContext(Context);
247 ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues)
249 ALCcontext *Context;
250 ALCdevice *Device;
251 ALeffect *ALEffect;
253 Context = GetContextSuspended();
254 if(!Context) return;
256 Device = Context->Device;
257 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
259 if(param == AL_EFFECT_TYPE)
261 alEffecti(effect, param, piValues[0]);
263 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
265 switch(param)
267 case AL_EAXREVERB_DECAY_HFLIMIT:
268 alEffecti(effect, param, piValues[0]);
269 break;
271 default:
272 alSetError(Context, AL_INVALID_ENUM);
273 break;
276 else if(ALEffect->type == AL_EFFECT_REVERB)
278 switch(param)
280 case AL_REVERB_DECAY_HFLIMIT:
281 alEffecti(effect, param, piValues[0]);
282 break;
284 default:
285 alSetError(Context, AL_INVALID_ENUM);
286 break;
289 else if(ALEffect->type == AL_EFFECT_ECHO)
291 switch(param)
293 default:
294 alSetError(Context, AL_INVALID_ENUM);
295 break;
298 else
299 alSetError(Context, AL_INVALID_ENUM);
301 else
302 alSetError(Context, AL_INVALID_NAME);
304 ProcessContext(Context);
307 ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue)
309 ALCcontext *Context;
310 ALCdevice *Device;
311 ALeffect *ALEffect;
313 Context = GetContextSuspended();
314 if(!Context) return;
316 Device = Context->Device;
317 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
319 if(ALEffect->type == AL_EFFECT_EAXREVERB)
321 switch(param)
323 case AL_EAXREVERB_DENSITY:
324 if(flValue >= AL_EAXREVERB_MIN_DENSITY &&
325 flValue <= AL_EAXREVERB_MAX_DENSITY)
326 ALEffect->Reverb.Density = flValue;
327 else
328 alSetError(Context, AL_INVALID_VALUE);
329 break;
331 case AL_EAXREVERB_DIFFUSION:
332 if(flValue >= AL_EAXREVERB_MIN_DIFFUSION &&
333 flValue <= AL_EAXREVERB_MAX_DIFFUSION)
334 ALEffect->Reverb.Diffusion = flValue;
335 else
336 alSetError(Context, AL_INVALID_VALUE);
337 break;
339 case AL_EAXREVERB_GAIN:
340 if(flValue >= AL_EAXREVERB_MIN_GAIN &&
341 flValue <= AL_EAXREVERB_MAX_GAIN)
342 ALEffect->Reverb.Gain = flValue;
343 else
344 alSetError(Context, AL_INVALID_VALUE);
345 break;
347 case AL_EAXREVERB_GAINHF:
348 if(flValue >= AL_EAXREVERB_MIN_GAINHF &&
349 flValue <= AL_EAXREVERB_MAX_GAIN)
350 ALEffect->Reverb.GainHF = flValue;
351 else
352 alSetError(Context, AL_INVALID_VALUE);
353 break;
355 case AL_EAXREVERB_GAINLF:
356 if(flValue >= AL_EAXREVERB_MIN_GAINLF &&
357 flValue <= AL_EAXREVERB_MAX_GAINLF)
358 ALEffect->Reverb.GainLF = flValue;
359 else
360 alSetError(Context, AL_INVALID_VALUE);
361 break;
363 case AL_EAXREVERB_DECAY_TIME:
364 if(flValue >= AL_EAXREVERB_MIN_DECAY_TIME &&
365 flValue <= AL_EAXREVERB_MAX_DECAY_TIME)
366 ALEffect->Reverb.DecayTime = flValue;
367 else
368 alSetError(Context, AL_INVALID_VALUE);
369 break;
371 case AL_EAXREVERB_DECAY_HFRATIO:
372 if(flValue >= AL_EAXREVERB_MIN_DECAY_HFRATIO &&
373 flValue <= AL_EAXREVERB_MAX_DECAY_HFRATIO)
374 ALEffect->Reverb.DecayHFRatio = flValue;
375 else
376 alSetError(Context, AL_INVALID_VALUE);
377 break;
379 case AL_EAXREVERB_DECAY_LFRATIO:
380 if(flValue >= AL_EAXREVERB_MIN_DECAY_LFRATIO &&
381 flValue <= AL_EAXREVERB_MAX_DECAY_LFRATIO)
382 ALEffect->Reverb.DecayLFRatio = flValue;
383 else
384 alSetError(Context, AL_INVALID_VALUE);
385 break;
387 case AL_EAXREVERB_REFLECTIONS_GAIN:
388 if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN &&
389 flValue <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)
390 ALEffect->Reverb.ReflectionsGain = flValue;
391 else
392 alSetError(Context, AL_INVALID_VALUE);
393 break;
395 case AL_EAXREVERB_REFLECTIONS_DELAY:
396 if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY &&
397 flValue <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)
398 ALEffect->Reverb.ReflectionsDelay = flValue;
399 else
400 alSetError(Context, AL_INVALID_VALUE);
401 break;
403 case AL_EAXREVERB_LATE_REVERB_GAIN:
404 if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN &&
405 flValue <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)
406 ALEffect->Reverb.LateReverbGain = flValue;
407 else
408 alSetError(Context, AL_INVALID_VALUE);
409 break;
411 case AL_EAXREVERB_LATE_REVERB_DELAY:
412 if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY &&
413 flValue <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)
414 ALEffect->Reverb.LateReverbDelay = flValue;
415 else
416 alSetError(Context, AL_INVALID_VALUE);
417 break;
419 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
420 if(flValue >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF &&
421 flValue <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)
422 ALEffect->Reverb.AirAbsorptionGainHF = flValue;
423 else
424 alSetError(Context, AL_INVALID_VALUE);
425 break;
427 case AL_EAXREVERB_ECHO_TIME:
428 if(flValue >= AL_EAXREVERB_MIN_ECHO_TIME &&
429 flValue <= AL_EAXREVERB_MAX_ECHO_TIME)
430 ALEffect->Reverb.EchoTime = flValue;
431 else
432 alSetError(Context, AL_INVALID_VALUE);
433 break;
435 case AL_EAXREVERB_ECHO_DEPTH:
436 if(flValue >= AL_EAXREVERB_MIN_ECHO_DEPTH &&
437 flValue <= AL_EAXREVERB_MAX_ECHO_DEPTH)
438 ALEffect->Reverb.EchoDepth = flValue;
439 else
440 alSetError(Context, AL_INVALID_VALUE);
441 break;
443 case AL_EAXREVERB_MODULATION_TIME:
444 if(flValue >= AL_EAXREVERB_MIN_MODULATION_TIME &&
445 flValue <= AL_EAXREVERB_MAX_MODULATION_TIME)
446 ALEffect->Reverb.ModulationTime = flValue;
447 else
448 alSetError(Context, AL_INVALID_VALUE);
449 break;
451 case AL_EAXREVERB_MODULATION_DEPTH:
452 if(flValue >= AL_EAXREVERB_MIN_MODULATION_DEPTH &&
453 flValue <= AL_EAXREVERB_MAX_MODULATION_DEPTH)
454 ALEffect->Reverb.ModulationDepth = flValue;
455 else
456 alSetError(Context, AL_INVALID_VALUE);
457 break;
459 case AL_EAXREVERB_HFREFERENCE:
460 if(flValue >= AL_EAXREVERB_MIN_HFREFERENCE &&
461 flValue <= AL_EAXREVERB_MAX_HFREFERENCE)
462 ALEffect->Reverb.HFReference = flValue;
463 else
464 alSetError(Context, AL_INVALID_VALUE);
465 break;
467 case AL_EAXREVERB_LFREFERENCE:
468 if(flValue >= AL_EAXREVERB_MIN_LFREFERENCE &&
469 flValue <= AL_EAXREVERB_MAX_LFREFERENCE)
470 ALEffect->Reverb.LFReference = flValue;
471 else
472 alSetError(Context, AL_INVALID_VALUE);
473 break;
475 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
476 if(flValue >= 0.0f && flValue <= 10.0f)
477 ALEffect->Reverb.RoomRolloffFactor = flValue;
478 else
479 alSetError(Context, AL_INVALID_VALUE);
480 break;
482 default:
483 alSetError(Context, AL_INVALID_ENUM);
484 break;
487 else if(ALEffect->type == AL_EFFECT_REVERB)
489 switch(param)
491 case AL_REVERB_DENSITY:
492 if(flValue >= AL_REVERB_MIN_DENSITY &&
493 flValue <= AL_REVERB_MAX_DENSITY)
494 ALEffect->Reverb.Density = flValue;
495 else
496 alSetError(Context, AL_INVALID_VALUE);
497 break;
499 case AL_REVERB_DIFFUSION:
500 if(flValue >= AL_REVERB_MIN_DIFFUSION &&
501 flValue <= AL_REVERB_MAX_DIFFUSION)
502 ALEffect->Reverb.Diffusion = flValue;
503 else
504 alSetError(Context, AL_INVALID_VALUE);
505 break;
507 case AL_REVERB_GAIN:
508 if(flValue >= AL_REVERB_MIN_GAIN &&
509 flValue <= AL_REVERB_MAX_GAIN)
510 ALEffect->Reverb.Gain = flValue;
511 else
512 alSetError(Context, AL_INVALID_VALUE);
513 break;
515 case AL_REVERB_GAINHF:
516 if(flValue >= AL_REVERB_MIN_GAINHF &&
517 flValue <= AL_REVERB_MAX_GAINHF)
518 ALEffect->Reverb.GainHF = flValue;
519 else
520 alSetError(Context, AL_INVALID_VALUE);
521 break;
523 case AL_REVERB_DECAY_TIME:
524 if(flValue >= AL_REVERB_MIN_DECAY_TIME &&
525 flValue <= AL_REVERB_MAX_DECAY_TIME)
526 ALEffect->Reverb.DecayTime = flValue;
527 else
528 alSetError(Context, AL_INVALID_VALUE);
529 break;
531 case AL_REVERB_DECAY_HFRATIO:
532 if(flValue >= AL_REVERB_MIN_DECAY_HFRATIO &&
533 flValue <= AL_REVERB_MAX_DECAY_HFRATIO)
534 ALEffect->Reverb.DecayHFRatio = flValue;
535 else
536 alSetError(Context, AL_INVALID_VALUE);
537 break;
539 case AL_REVERB_REFLECTIONS_GAIN:
540 if(flValue >= AL_REVERB_MIN_REFLECTIONS_GAIN &&
541 flValue <= AL_REVERB_MAX_REFLECTIONS_GAIN)
542 ALEffect->Reverb.ReflectionsGain = flValue;
543 else
544 alSetError(Context, AL_INVALID_VALUE);
545 break;
547 case AL_REVERB_REFLECTIONS_DELAY:
548 if(flValue >= AL_REVERB_MIN_REFLECTIONS_DELAY &&
549 flValue <= AL_REVERB_MAX_REFLECTIONS_DELAY)
550 ALEffect->Reverb.ReflectionsDelay = flValue;
551 else
552 alSetError(Context, AL_INVALID_VALUE);
553 break;
555 case AL_REVERB_LATE_REVERB_GAIN:
556 if(flValue >= AL_REVERB_MIN_LATE_REVERB_GAIN &&
557 flValue <= AL_REVERB_MAX_LATE_REVERB_GAIN)
558 ALEffect->Reverb.LateReverbGain = flValue;
559 else
560 alSetError(Context, AL_INVALID_VALUE);
561 break;
563 case AL_REVERB_LATE_REVERB_DELAY:
564 if(flValue >= AL_REVERB_MIN_LATE_REVERB_DELAY &&
565 flValue <= AL_REVERB_MAX_LATE_REVERB_DELAY)
566 ALEffect->Reverb.LateReverbDelay = flValue;
567 else
568 alSetError(Context, AL_INVALID_VALUE);
569 break;
571 case AL_REVERB_AIR_ABSORPTION_GAINHF:
572 if(flValue >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF &&
573 flValue <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)
574 ALEffect->Reverb.AirAbsorptionGainHF = flValue;
575 else
576 alSetError(Context, AL_INVALID_VALUE);
577 break;
579 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
580 if(flValue >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR &&
581 flValue <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)
582 ALEffect->Reverb.RoomRolloffFactor = flValue;
583 else
584 alSetError(Context, AL_INVALID_VALUE);
585 break;
587 default:
588 alSetError(Context, AL_INVALID_ENUM);
589 break;
592 else if(ALEffect->type == AL_EFFECT_ECHO)
594 switch(param)
596 case AL_ECHO_DELAY:
597 if(flValue >= AL_ECHO_MIN_DELAY && flValue <= AL_ECHO_MAX_DELAY)
598 ALEffect->Echo.Delay = flValue;
599 else
600 alSetError(Context, AL_INVALID_VALUE);
601 break;
603 case AL_ECHO_LRDELAY:
604 if(flValue >= AL_ECHO_MIN_LRDELAY && flValue <= AL_ECHO_MAX_LRDELAY)
605 ALEffect->Echo.LRDelay = flValue;
606 else
607 alSetError(Context, AL_INVALID_VALUE);
608 break;
610 case AL_ECHO_DAMPING:
611 if(flValue >= AL_ECHO_MIN_DAMPING && flValue <= AL_ECHO_MAX_DAMPING)
612 ALEffect->Echo.Damping = flValue;
613 else
614 alSetError(Context, AL_INVALID_VALUE);
615 break;
617 case AL_ECHO_FEEDBACK:
618 if(flValue >= AL_ECHO_MIN_FEEDBACK && flValue <= AL_ECHO_MAX_FEEDBACK)
619 ALEffect->Echo.Feedback = flValue;
620 else
621 alSetError(Context, AL_INVALID_VALUE);
622 break;
624 case AL_ECHO_SPREAD:
625 if(flValue >= AL_ECHO_MIN_SPREAD && flValue <= AL_ECHO_MAX_SPREAD)
626 ALEffect->Echo.Spread = flValue;
627 else
628 alSetError(Context, AL_INVALID_VALUE);
629 break;
631 default:
632 alSetError(Context, AL_INVALID_ENUM);
633 break;
636 else
637 alSetError(Context, AL_INVALID_ENUM);
639 else
640 alSetError(Context, AL_INVALID_NAME);
642 ProcessContext(Context);
645 ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
647 ALCcontext *Context;
648 ALCdevice *Device;
649 ALeffect *ALEffect;
651 Context = GetContextSuspended();
652 if(!Context) return;
654 Device = Context->Device;
655 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
657 if(ALEffect->type == AL_EFFECT_EAXREVERB)
659 switch(param)
661 case AL_EAXREVERB_DENSITY:
662 case AL_EAXREVERB_DIFFUSION:
663 case AL_EAXREVERB_GAIN:
664 case AL_EAXREVERB_GAINHF:
665 case AL_EAXREVERB_GAINLF:
666 case AL_EAXREVERB_DECAY_TIME:
667 case AL_EAXREVERB_DECAY_HFRATIO:
668 case AL_EAXREVERB_DECAY_LFRATIO:
669 case AL_EAXREVERB_REFLECTIONS_GAIN:
670 case AL_EAXREVERB_REFLECTIONS_DELAY:
671 case AL_EAXREVERB_LATE_REVERB_GAIN:
672 case AL_EAXREVERB_LATE_REVERB_DELAY:
673 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
674 case AL_EAXREVERB_ECHO_TIME:
675 case AL_EAXREVERB_ECHO_DEPTH:
676 case AL_EAXREVERB_MODULATION_TIME:
677 case AL_EAXREVERB_MODULATION_DEPTH:
678 case AL_EAXREVERB_HFREFERENCE:
679 case AL_EAXREVERB_LFREFERENCE:
680 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
681 alEffectf(effect, param, pflValues[0]);
682 break;
684 case AL_EAXREVERB_REFLECTIONS_PAN:
685 if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2]))
687 ALEffect->Reverb.ReflectionsPan[0] = pflValues[0];
688 ALEffect->Reverb.ReflectionsPan[1] = pflValues[1];
689 ALEffect->Reverb.ReflectionsPan[2] = pflValues[2];
691 else
692 alSetError(Context, AL_INVALID_VALUE);
693 break;
694 case AL_EAXREVERB_LATE_REVERB_PAN:
695 if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2]))
697 ALEffect->Reverb.LateReverbPan[0] = pflValues[0];
698 ALEffect->Reverb.LateReverbPan[1] = pflValues[1];
699 ALEffect->Reverb.LateReverbPan[2] = pflValues[2];
701 else
702 alSetError(Context, AL_INVALID_VALUE);
703 break;
705 default:
706 alSetError(Context, AL_INVALID_ENUM);
707 break;
710 else if(ALEffect->type == AL_EFFECT_REVERB)
712 switch(param)
714 case AL_REVERB_DENSITY:
715 case AL_REVERB_DIFFUSION:
716 case AL_REVERB_GAIN:
717 case AL_REVERB_GAINHF:
718 case AL_REVERB_DECAY_TIME:
719 case AL_REVERB_DECAY_HFRATIO:
720 case AL_REVERB_REFLECTIONS_GAIN:
721 case AL_REVERB_REFLECTIONS_DELAY:
722 case AL_REVERB_LATE_REVERB_GAIN:
723 case AL_REVERB_LATE_REVERB_DELAY:
724 case AL_REVERB_AIR_ABSORPTION_GAINHF:
725 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
726 alEffectf(effect, param, pflValues[0]);
727 break;
729 default:
730 alSetError(Context, AL_INVALID_ENUM);
731 break;
734 else if(ALEffect->type == AL_EFFECT_ECHO)
736 switch(param)
738 case AL_ECHO_DELAY:
739 case AL_ECHO_LRDELAY:
740 case AL_ECHO_DAMPING:
741 case AL_ECHO_FEEDBACK:
742 case AL_ECHO_SPREAD:
743 alEffectf(effect, param, pflValues[0]);
744 break;
746 default:
747 alSetError(Context, AL_INVALID_ENUM);
748 break;
751 else
752 alSetError(Context, AL_INVALID_ENUM);
754 else
755 alSetError(Context, AL_INVALID_NAME);
757 ProcessContext(Context);
760 ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue)
762 ALCcontext *Context;
763 ALCdevice *Device;
764 ALeffect *ALEffect;
766 Context = GetContextSuspended();
767 if(!Context) return;
769 Device = Context->Device;
770 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
772 if(param == AL_EFFECT_TYPE)
774 *piValue = ALEffect->type;
776 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
778 switch(param)
780 case AL_EAXREVERB_DECAY_HFLIMIT:
781 *piValue = ALEffect->Reverb.DecayHFLimit;
782 break;
784 default:
785 alSetError(Context, AL_INVALID_ENUM);
786 break;
789 else if(ALEffect->type == AL_EFFECT_REVERB)
791 switch(param)
793 case AL_REVERB_DECAY_HFLIMIT:
794 *piValue = ALEffect->Reverb.DecayHFLimit;
795 break;
797 default:
798 alSetError(Context, AL_INVALID_ENUM);
799 break;
802 else if(ALEffect->type == AL_EFFECT_ECHO)
804 switch(param)
806 default:
807 alSetError(Context, AL_INVALID_ENUM);
808 break;
811 else
812 alSetError(Context, AL_INVALID_ENUM);
814 else
815 alSetError(Context, AL_INVALID_NAME);
817 ProcessContext(Context);
820 ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues)
822 ALCcontext *Context;
823 ALCdevice *Device;
824 ALeffect *ALEffect;
826 Context = GetContextSuspended();
827 if(!Context) return;
829 Device = Context->Device;
830 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
832 if(param == AL_EFFECT_TYPE)
834 alGetEffecti(effect, param, piValues);
836 else if(ALEffect->type == AL_EFFECT_EAXREVERB)
838 switch(param)
840 case AL_EAXREVERB_DECAY_HFLIMIT:
841 alGetEffecti(effect, param, piValues);
842 break;
844 default:
845 alSetError(Context, AL_INVALID_ENUM);
846 break;
849 else if(ALEffect->type == AL_EFFECT_REVERB)
851 switch(param)
853 case AL_REVERB_DECAY_HFLIMIT:
854 alGetEffecti(effect, param, piValues);
855 break;
857 default:
858 alSetError(Context, AL_INVALID_ENUM);
859 break;
862 else if(ALEffect->type == AL_EFFECT_ECHO)
864 switch(param)
866 default:
867 alSetError(Context, AL_INVALID_ENUM);
868 break;
871 else
872 alSetError(Context, AL_INVALID_ENUM);
874 else
875 alSetError(Context, AL_INVALID_NAME);
877 ProcessContext(Context);
880 ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue)
882 ALCcontext *Context;
883 ALCdevice *Device;
884 ALeffect *ALEffect;
886 Context = GetContextSuspended();
887 if(!Context) return;
889 Device = Context->Device;
890 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
892 if(ALEffect->type == AL_EFFECT_EAXREVERB)
894 switch(param)
896 case AL_EAXREVERB_DENSITY:
897 *pflValue = ALEffect->Reverb.Density;
898 break;
900 case AL_EAXREVERB_DIFFUSION:
901 *pflValue = ALEffect->Reverb.Diffusion;
902 break;
904 case AL_EAXREVERB_GAIN:
905 *pflValue = ALEffect->Reverb.Gain;
906 break;
908 case AL_EAXREVERB_GAINHF:
909 *pflValue = ALEffect->Reverb.GainHF;
910 break;
912 case AL_EAXREVERB_GAINLF:
913 *pflValue = ALEffect->Reverb.GainLF;
914 break;
916 case AL_EAXREVERB_DECAY_TIME:
917 *pflValue = ALEffect->Reverb.DecayTime;
918 break;
920 case AL_EAXREVERB_DECAY_HFRATIO:
921 *pflValue = ALEffect->Reverb.DecayHFRatio;
922 break;
924 case AL_EAXREVERB_DECAY_LFRATIO:
925 *pflValue = ALEffect->Reverb.DecayLFRatio;
926 break;
928 case AL_EAXREVERB_REFLECTIONS_GAIN:
929 *pflValue = ALEffect->Reverb.ReflectionsGain;
930 break;
932 case AL_EAXREVERB_REFLECTIONS_DELAY:
933 *pflValue = ALEffect->Reverb.ReflectionsDelay;
934 break;
936 case AL_EAXREVERB_LATE_REVERB_GAIN:
937 *pflValue = ALEffect->Reverb.LateReverbGain;
938 break;
940 case AL_EAXREVERB_LATE_REVERB_DELAY:
941 *pflValue = ALEffect->Reverb.LateReverbDelay;
942 break;
944 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
945 *pflValue = ALEffect->Reverb.AirAbsorptionGainHF;
946 break;
948 case AL_EAXREVERB_ECHO_TIME:
949 *pflValue = ALEffect->Reverb.EchoTime;
950 break;
952 case AL_EAXREVERB_ECHO_DEPTH:
953 *pflValue = ALEffect->Reverb.EchoDepth;
954 break;
956 case AL_EAXREVERB_MODULATION_TIME:
957 *pflValue = ALEffect->Reverb.ModulationTime;
958 break;
960 case AL_EAXREVERB_MODULATION_DEPTH:
961 *pflValue = ALEffect->Reverb.ModulationDepth;
962 break;
964 case AL_EAXREVERB_HFREFERENCE:
965 *pflValue = ALEffect->Reverb.HFReference;
966 break;
968 case AL_EAXREVERB_LFREFERENCE:
969 *pflValue = ALEffect->Reverb.LFReference;
970 break;
972 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
973 *pflValue = ALEffect->Reverb.RoomRolloffFactor;
974 break;
976 default:
977 alSetError(Context, AL_INVALID_ENUM);
978 break;
981 else if(ALEffect->type == AL_EFFECT_REVERB)
983 switch(param)
985 case AL_REVERB_DENSITY:
986 *pflValue = ALEffect->Reverb.Density;
987 break;
989 case AL_REVERB_DIFFUSION:
990 *pflValue = ALEffect->Reverb.Diffusion;
991 break;
993 case AL_REVERB_GAIN:
994 *pflValue = ALEffect->Reverb.Gain;
995 break;
997 case AL_REVERB_GAINHF:
998 *pflValue = ALEffect->Reverb.GainHF;
999 break;
1001 case AL_REVERB_DECAY_TIME:
1002 *pflValue = ALEffect->Reverb.DecayTime;
1003 break;
1005 case AL_REVERB_DECAY_HFRATIO:
1006 *pflValue = ALEffect->Reverb.DecayHFRatio;
1007 break;
1009 case AL_REVERB_REFLECTIONS_GAIN:
1010 *pflValue = ALEffect->Reverb.ReflectionsGain;
1011 break;
1013 case AL_REVERB_REFLECTIONS_DELAY:
1014 *pflValue = ALEffect->Reverb.ReflectionsDelay;
1015 break;
1017 case AL_REVERB_LATE_REVERB_GAIN:
1018 *pflValue = ALEffect->Reverb.LateReverbGain;
1019 break;
1021 case AL_REVERB_LATE_REVERB_DELAY:
1022 *pflValue = ALEffect->Reverb.LateReverbDelay;
1023 break;
1025 case AL_REVERB_AIR_ABSORPTION_GAINHF:
1026 *pflValue = ALEffect->Reverb.AirAbsorptionGainHF;
1027 break;
1029 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
1030 *pflValue = ALEffect->Reverb.RoomRolloffFactor;
1031 break;
1033 default:
1034 alSetError(Context, AL_INVALID_ENUM);
1035 break;
1038 else if(ALEffect->type == AL_EFFECT_ECHO)
1040 switch(param)
1042 case AL_ECHO_DELAY:
1043 *pflValue = ALEffect->Echo.Delay;
1044 break;
1046 case AL_ECHO_LRDELAY:
1047 *pflValue = ALEffect->Echo.LRDelay;
1048 break;
1050 case AL_ECHO_DAMPING:
1051 *pflValue = ALEffect->Echo.Damping;
1052 break;
1054 case AL_ECHO_FEEDBACK:
1055 *pflValue = ALEffect->Echo.Feedback;
1056 break;
1058 case AL_ECHO_SPREAD:
1059 *pflValue = ALEffect->Echo.Spread;
1060 break;
1062 default:
1063 alSetError(Context, AL_INVALID_ENUM);
1064 break;
1067 else
1068 alSetError(Context, AL_INVALID_ENUM);
1070 else
1071 alSetError(Context, AL_INVALID_NAME);
1073 ProcessContext(Context);
1076 ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
1078 ALCcontext *Context;
1079 ALCdevice *Device;
1080 ALeffect *ALEffect;
1082 Context = GetContextSuspended();
1083 if(!Context) return;
1085 Device = Context->Device;
1086 if((ALEffect=VerifyEffect(Device->EffectList, effect)) != NULL)
1088 if(ALEffect->type == AL_EFFECT_EAXREVERB)
1090 switch(param)
1092 case AL_EAXREVERB_DENSITY:
1093 case AL_EAXREVERB_DIFFUSION:
1094 case AL_EAXREVERB_GAIN:
1095 case AL_EAXREVERB_GAINHF:
1096 case AL_EAXREVERB_GAINLF:
1097 case AL_EAXREVERB_DECAY_TIME:
1098 case AL_EAXREVERB_DECAY_HFRATIO:
1099 case AL_EAXREVERB_DECAY_LFRATIO:
1100 case AL_EAXREVERB_REFLECTIONS_GAIN:
1101 case AL_EAXREVERB_REFLECTIONS_DELAY:
1102 case AL_EAXREVERB_LATE_REVERB_GAIN:
1103 case AL_EAXREVERB_LATE_REVERB_DELAY:
1104 case AL_EAXREVERB_AIR_ABSORPTION_GAINHF:
1105 case AL_EAXREVERB_ECHO_TIME:
1106 case AL_EAXREVERB_ECHO_DEPTH:
1107 case AL_EAXREVERB_MODULATION_TIME:
1108 case AL_EAXREVERB_MODULATION_DEPTH:
1109 case AL_EAXREVERB_HFREFERENCE:
1110 case AL_EAXREVERB_LFREFERENCE:
1111 case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR:
1112 alGetEffectf(effect, param, pflValues);
1113 break;
1115 case AL_EAXREVERB_REFLECTIONS_PAN:
1116 pflValues[0] = ALEffect->Reverb.ReflectionsPan[0];
1117 pflValues[1] = ALEffect->Reverb.ReflectionsPan[1];
1118 pflValues[2] = ALEffect->Reverb.ReflectionsPan[2];
1119 break;
1120 case AL_EAXREVERB_LATE_REVERB_PAN:
1121 pflValues[0] = ALEffect->Reverb.LateReverbPan[0];
1122 pflValues[1] = ALEffect->Reverb.LateReverbPan[1];
1123 pflValues[2] = ALEffect->Reverb.LateReverbPan[2];
1124 break;
1126 default:
1127 alSetError(Context, AL_INVALID_ENUM);
1128 break;
1131 else if(ALEffect->type == AL_EFFECT_REVERB)
1133 switch(param)
1135 case AL_REVERB_DENSITY:
1136 case AL_REVERB_DIFFUSION:
1137 case AL_REVERB_GAIN:
1138 case AL_REVERB_GAINHF:
1139 case AL_REVERB_DECAY_TIME:
1140 case AL_REVERB_DECAY_HFRATIO:
1141 case AL_REVERB_REFLECTIONS_GAIN:
1142 case AL_REVERB_REFLECTIONS_DELAY:
1143 case AL_REVERB_LATE_REVERB_GAIN:
1144 case AL_REVERB_LATE_REVERB_DELAY:
1145 case AL_REVERB_AIR_ABSORPTION_GAINHF:
1146 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
1147 alGetEffectf(effect, param, pflValues);
1148 break;
1150 default:
1151 alSetError(Context, AL_INVALID_ENUM);
1152 break;
1155 else if(ALEffect->type == AL_EFFECT_ECHO)
1157 switch(param)
1159 case AL_ECHO_DELAY:
1160 case AL_ECHO_LRDELAY:
1161 case AL_ECHO_DAMPING:
1162 case AL_ECHO_FEEDBACK:
1163 case AL_ECHO_SPREAD:
1164 alGetEffectf(effect, param, pflValues);
1165 break;
1167 default:
1168 alSetError(Context, AL_INVALID_ENUM);
1169 break;
1172 else
1173 alSetError(Context, AL_INVALID_ENUM);
1175 else
1176 alSetError(Context, AL_INVALID_NAME);
1178 ProcessContext(Context);
1182 ALvoid ReleaseALEffects(ALCdevice *device)
1184 ALeffect *list = device->EffectList;
1185 while(list)
1187 ALeffect *temp = list;
1188 list = list->next;
1190 // Release effect structure
1191 memset(temp, 0, sizeof(ALeffect));
1192 free(temp);
1194 device->EffectList = NULL;
1195 device->EffectCount = 0;
1199 static void InitEffectParams(ALeffect *effect, ALenum type)
1201 effect->type = type;
1202 switch(type)
1204 /* NOTE: Standard reverb and EAX reverb use the same defaults for the
1205 * shared parameters, and EAX's additional parameters default to
1206 * values assumed by standard reverb.
1208 case AL_EFFECT_EAXREVERB:
1209 case AL_EFFECT_REVERB:
1210 effect->Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY;
1211 effect->Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION;
1212 effect->Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN;
1213 effect->Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF;
1214 effect->Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF;
1215 effect->Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME;
1216 effect->Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO;
1217 effect->Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO;
1218 effect->Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN;
1219 effect->Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY;
1220 effect->Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1221 effect->Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1222 effect->Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ;
1223 effect->Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN;
1224 effect->Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY;
1225 effect->Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1226 effect->Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1227 effect->Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ;
1228 effect->Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME;
1229 effect->Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH;
1230 effect->Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME;
1231 effect->Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH;
1232 effect->Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF;
1233 effect->Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE;
1234 effect->Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE;
1235 effect->Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR;
1236 effect->Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT;
1237 break;
1238 case AL_EFFECT_ECHO:
1239 effect->Echo.Delay = AL_ECHO_DEFAULT_DELAY;
1240 effect->Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY;
1241 effect->Echo.Damping = AL_ECHO_DEFAULT_DAMPING;
1242 effect->Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK;
1243 effect->Echo.Spread = AL_ECHO_DEFAULT_SPREAD;
1244 break;