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
33 ALboolean DisabledEffects
[MAX_EFFECTS
];
36 static ALeffect
*g_EffectList
;
37 static ALuint g_EffectCount
;
39 static void InitEffectParams(ALeffect
*effect
, ALenum type
);
42 ALvoid AL_APIENTRY
alGenEffects(ALsizei n
, ALuint
*effects
)
47 Context
= alcGetCurrentContext();
48 SuspendContext(Context
);
52 // Check that enough memory has been allocted in the 'effects' array for n Effects
53 if (!IsBadWritePtr((void*)effects
, n
* sizeof(ALuint
)))
55 ALeffect
**list
= &g_EffectList
;
57 list
= &(*list
)->next
;
62 *list
= calloc(1, sizeof(ALeffect
));
65 // We must have run out or memory
66 alDeleteEffects(i
, effects
);
67 alSetError(AL_OUT_OF_MEMORY
);
71 effects
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
72 (*list
)->effect
= effects
[i
];
74 InitEffectParams(*list
, AL_EFFECT_NULL
);
78 list
= &(*list
)->next
;
83 ProcessContext(Context
);
86 ALvoid AL_APIENTRY
alDeleteEffects(ALsizei n
, ALuint
*effects
)
92 Context
= alcGetCurrentContext();
93 SuspendContext(Context
);
97 // Check that all effects are valid
98 for (i
= 0; i
< n
; i
++)
100 if (!alIsEffect(effects
[i
]))
102 alSetError(AL_INVALID_NAME
);
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
]))
117 ALEffect
= ((ALeffect
*)ALTHUNK_LOOKUPENTRY(effects
[i
]));
119 // Remove Source from list of Sources
120 list
= &g_EffectList
;
121 while(*list
&& *list
!= ALEffect
)
122 list
= &(*list
)->next
;
125 *list
= (*list
)->next
;
126 ALTHUNK_REMOVEENTRY(ALEffect
->effect
);
128 memset(ALEffect
, 0, sizeof(ALeffect
));
137 alSetError(AL_INVALID_VALUE
);
139 ProcessContext(Context
);
142 ALboolean AL_APIENTRY
alIsEffect(ALuint effect
)
147 Context
= alcGetCurrentContext();
148 SuspendContext(Context
);
150 list
= &g_EffectList
;
151 while(*list
&& (*list
)->effect
!= effect
)
152 list
= &(*list
)->next
;
154 ProcessContext(Context
);
156 return ((*list
|| !effect
) ? AL_TRUE
: AL_FALSE
);
159 ALvoid AL_APIENTRY
alEffecti(ALuint effect
, ALenum param
, ALint iValue
)
163 Context
= alcGetCurrentContext();
164 SuspendContext(Context
);
166 if (effect
&& alIsEffect(effect
))
168 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
170 if(param
== AL_EFFECT_TYPE
)
172 ALboolean isOk
= (iValue
== AL_EFFECT_NULL
||
173 (iValue
== AL_EFFECT_REVERB
&& !DisabledEffects
[REVERB
]));
176 InitEffectParams(ALEffect
, iValue
);
178 alSetError(AL_INVALID_VALUE
);
180 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
184 case AL_REVERB_DECAY_HFLIMIT
:
185 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
186 ALEffect
->Reverb
.DecayHFLimit
= iValue
;
188 alSetError(AL_INVALID_VALUE
);
192 alSetError(AL_INVALID_ENUM
);
197 alSetError(AL_INVALID_ENUM
);
200 alSetError(AL_INVALID_NAME
);
202 ProcessContext(Context
);
205 ALvoid AL_APIENTRY
alEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
209 Context
= alcGetCurrentContext();
210 SuspendContext(Context
);
212 if (effect
&& alIsEffect(effect
))
214 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
216 if(param
== AL_EFFECT_TYPE
)
218 alEffecti(effect
, param
, piValues
[0]);
220 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
224 case AL_REVERB_DECAY_HFLIMIT
:
225 alEffecti(effect
, param
, piValues
[0]);
229 alSetError(AL_INVALID_ENUM
);
234 alSetError(AL_INVALID_ENUM
);
237 alSetError(AL_INVALID_NAME
);
239 ProcessContext(Context
);
242 ALvoid AL_APIENTRY
alEffectf(ALuint effect
, ALenum param
, ALfloat flValue
)
246 Context
= alcGetCurrentContext();
247 SuspendContext(Context
);
249 if (effect
&& alIsEffect(effect
))
251 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
253 if(ALEffect
->type
== AL_EFFECT_REVERB
)
257 case AL_REVERB_DENSITY
:
258 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
259 ALEffect
->Reverb
.Density
= flValue
;
261 alSetError(AL_INVALID_VALUE
);
264 case AL_REVERB_DIFFUSION
:
265 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
266 ALEffect
->Reverb
.Diffusion
= flValue
;
268 alSetError(AL_INVALID_VALUE
);
272 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
273 ALEffect
->Reverb
.Gain
= flValue
;
275 alSetError(AL_INVALID_VALUE
);
278 case AL_REVERB_GAINHF
:
279 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
280 ALEffect
->Reverb
.GainHF
= flValue
;
282 alSetError(AL_INVALID_VALUE
);
285 case AL_REVERB_DECAY_TIME
:
286 if(flValue
>= 0.1f
&& flValue
<= 20.0f
)
287 ALEffect
->Reverb
.DecayTime
= flValue
;
289 alSetError(AL_INVALID_VALUE
);
292 case AL_REVERB_DECAY_HFRATIO
:
293 if(flValue
>= 0.1f
&& flValue
<= 2.0f
)
294 ALEffect
->Reverb
.DecayHFRatio
= flValue
;
296 alSetError(AL_INVALID_VALUE
);
299 case AL_REVERB_REFLECTIONS_GAIN
:
300 if(flValue
>= 0.0f
&& flValue
<= 3.16f
)
301 ALEffect
->Reverb
.ReflectionsGain
= flValue
;
303 alSetError(AL_INVALID_VALUE
);
306 case AL_REVERB_REFLECTIONS_DELAY
:
307 if(flValue
>= 0.0f
&& flValue
<= 0.3f
)
308 ALEffect
->Reverb
.ReflectionsDelay
= flValue
;
310 alSetError(AL_INVALID_VALUE
);
313 case AL_REVERB_LATE_REVERB_GAIN
:
314 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
315 ALEffect
->Reverb
.LateReverbGain
= flValue
;
317 alSetError(AL_INVALID_VALUE
);
320 case AL_REVERB_LATE_REVERB_DELAY
:
321 if(flValue
>= 0.0f
&& flValue
<= 0.1f
)
322 ALEffect
->Reverb
.LateReverbDelay
= flValue
;
324 alSetError(AL_INVALID_VALUE
);
327 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
328 if(flValue
>= 0.892f
&& flValue
<= 1.0f
)
329 ALEffect
->Reverb
.AirAbsorptionGainHF
= flValue
;
331 alSetError(AL_INVALID_VALUE
);
334 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
335 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
336 ALEffect
->Reverb
.RoomRolloffFactor
= flValue
;
338 alSetError(AL_INVALID_VALUE
);
342 alSetError(AL_INVALID_ENUM
);
347 alSetError(AL_INVALID_ENUM
);
350 alSetError(AL_INVALID_NAME
);
352 ProcessContext(Context
);
355 ALvoid AL_APIENTRY
alEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
359 Context
= alcGetCurrentContext();
360 SuspendContext(Context
);
362 if (effect
&& alIsEffect(effect
))
364 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
366 if(ALEffect
->type
== AL_EFFECT_REVERB
)
370 case AL_REVERB_DENSITY
:
371 case AL_REVERB_DIFFUSION
:
373 case AL_REVERB_GAINHF
:
374 case AL_REVERB_DECAY_TIME
:
375 case AL_REVERB_DECAY_HFRATIO
:
376 case AL_REVERB_REFLECTIONS_GAIN
:
377 case AL_REVERB_REFLECTIONS_DELAY
:
378 case AL_REVERB_LATE_REVERB_GAIN
:
379 case AL_REVERB_LATE_REVERB_DELAY
:
380 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
381 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
382 alEffectf(effect
, param
, pflValues
[0]);
386 alSetError(AL_INVALID_ENUM
);
391 alSetError(AL_INVALID_ENUM
);
394 alSetError(AL_INVALID_NAME
);
396 ProcessContext(Context
);
399 ALvoid AL_APIENTRY
alGetEffecti(ALuint effect
, ALenum param
, ALint
*piValue
)
403 Context
= alcGetCurrentContext();
404 SuspendContext(Context
);
406 if (effect
&& alIsEffect(effect
))
408 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
410 if(param
== AL_EFFECT_TYPE
)
412 *piValue
= ALEffect
->type
;
414 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
418 case AL_REVERB_DECAY_HFLIMIT
:
419 *piValue
= ALEffect
->Reverb
.DecayHFLimit
;
423 alSetError(AL_INVALID_ENUM
);
428 alSetError(AL_INVALID_ENUM
);
431 alSetError(AL_INVALID_NAME
);
433 ProcessContext(Context
);
436 ALvoid AL_APIENTRY
alGetEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
440 Context
= alcGetCurrentContext();
441 SuspendContext(Context
);
443 if (effect
&& alIsEffect(effect
))
445 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
447 if(param
== AL_EFFECT_TYPE
)
449 alGetEffecti(effect
, param
, piValues
);
451 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
455 case AL_REVERB_DECAY_HFLIMIT
:
456 alGetEffecti(effect
, param
, piValues
);
460 alSetError(AL_INVALID_ENUM
);
465 alSetError(AL_INVALID_ENUM
);
468 alSetError(AL_INVALID_NAME
);
470 ProcessContext(Context
);
473 ALvoid AL_APIENTRY
alGetEffectf(ALuint effect
, ALenum param
, ALfloat
*pflValue
)
477 Context
= alcGetCurrentContext();
478 SuspendContext(Context
);
480 if (effect
&& alIsEffect(effect
))
482 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
484 if(ALEffect
->type
== AL_EFFECT_REVERB
)
488 case AL_REVERB_DENSITY
:
489 *pflValue
= ALEffect
->Reverb
.Density
;
492 case AL_REVERB_DIFFUSION
:
493 *pflValue
= ALEffect
->Reverb
.Diffusion
;
497 *pflValue
= ALEffect
->Reverb
.Gain
;
500 case AL_REVERB_GAINHF
:
501 *pflValue
= ALEffect
->Reverb
.GainHF
;
504 case AL_REVERB_DECAY_TIME
:
505 *pflValue
= ALEffect
->Reverb
.DecayTime
;
508 case AL_REVERB_DECAY_HFRATIO
:
509 *pflValue
= ALEffect
->Reverb
.DecayHFRatio
;
512 case AL_REVERB_REFLECTIONS_GAIN
:
513 *pflValue
= ALEffect
->Reverb
.ReflectionsGain
;
516 case AL_REVERB_REFLECTIONS_DELAY
:
517 *pflValue
= ALEffect
->Reverb
.ReflectionsDelay
;
520 case AL_REVERB_LATE_REVERB_GAIN
:
521 *pflValue
= ALEffect
->Reverb
.LateReverbGain
;
524 case AL_REVERB_LATE_REVERB_DELAY
:
525 *pflValue
= ALEffect
->Reverb
.LateReverbDelay
;
528 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
529 *pflValue
= ALEffect
->Reverb
.AirAbsorptionGainHF
;
532 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
533 *pflValue
= ALEffect
->Reverb
.RoomRolloffFactor
;
537 alSetError(AL_INVALID_ENUM
);
542 alSetError(AL_INVALID_ENUM
);
545 alSetError(AL_INVALID_NAME
);
547 ProcessContext(Context
);
550 ALvoid AL_APIENTRY
alGetEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
554 Context
= alcGetCurrentContext();
555 SuspendContext(Context
);
557 if (effect
&& alIsEffect(effect
))
559 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
561 if(ALEffect
->type
== AL_EFFECT_REVERB
)
565 case AL_REVERB_DENSITY
:
566 case AL_REVERB_DIFFUSION
:
568 case AL_REVERB_GAINHF
:
569 case AL_REVERB_DECAY_TIME
:
570 case AL_REVERB_DECAY_HFRATIO
:
571 case AL_REVERB_REFLECTIONS_GAIN
:
572 case AL_REVERB_REFLECTIONS_DELAY
:
573 case AL_REVERB_LATE_REVERB_GAIN
:
574 case AL_REVERB_LATE_REVERB_DELAY
:
575 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
576 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
577 alGetEffectf(effect
, param
, pflValues
);
581 alSetError(AL_INVALID_ENUM
);
586 alSetError(AL_INVALID_ENUM
);
589 alSetError(AL_INVALID_NAME
);
591 ProcessContext(Context
);
595 ALvoid
ReleaseALEffects(ALvoid
)
598 if(g_EffectCount
> 0)
599 AL_PRINT("exit(): deleting %d Effect(s)\n", g_EffectCount
);
604 ALeffect
*temp
= g_EffectList
;
605 g_EffectList
= g_EffectList
->next
;
607 // Release effect structure
608 memset(temp
, 0, sizeof(ALeffect
));
615 static void InitEffectParams(ALeffect
*effect
, ALenum type
)
620 case AL_EFFECT_REVERB
:
621 effect
->Reverb
.Density
= 1.0f
;
622 effect
->Reverb
.Diffusion
= 1.0f
;
623 effect
->Reverb
.Gain
= 0.32f
;
624 effect
->Reverb
.GainHF
= 0.89f
;
625 effect
->Reverb
.DecayTime
= 1.49f
;
626 effect
->Reverb
.DecayHFRatio
= 0.83f
;
627 effect
->Reverb
.ReflectionsGain
= 0.05f
;
628 effect
->Reverb
.ReflectionsDelay
= 0.007f
;
629 effect
->Reverb
.LateReverbGain
= 1.26f
;
630 effect
->Reverb
.LateReverbDelay
= 0.011f
;
631 effect
->Reverb
.AirAbsorptionGainHF
= 0.994f
;
632 effect
->Reverb
.RoomRolloffFactor
= 0.0f
;
633 effect
->Reverb
.DecayHFLimit
= AL_TRUE
;