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 static ALeffect
*g_EffectList
;
34 static ALuint g_EffectCount
;
36 static void InitEffectParams(ALeffect
*effect
, ALenum type
);
39 AL_API ALvoid AL_APIENTRY
alGenEffects(ALsizei n
, ALuint
*effects
)
44 Context
= alcGetCurrentContext();
45 SuspendContext(Context
);
49 // Check that enough memory has been allocted in the 'effects' array for n Effects
50 if (!IsBadWritePtr((void*)effects
, n
* sizeof(ALuint
)))
52 ALeffect
**list
= &g_EffectList
;
54 list
= &(*list
)->next
;
59 *list
= calloc(1, sizeof(ALeffect
));
62 // We must have run out or memory
63 alDeleteEffects(i
, effects
);
64 alSetError(AL_OUT_OF_MEMORY
);
68 effects
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
69 (*list
)->effect
= effects
[i
];
71 InitEffectParams(*list
, AL_EFFECT_NULL
);
75 list
= &(*list
)->next
;
80 ProcessContext(Context
);
83 AL_API ALvoid AL_APIENTRY
alDeleteEffects(ALsizei n
, ALuint
*effects
)
89 Context
= alcGetCurrentContext();
90 SuspendContext(Context
);
94 // Check that all effects are valid
95 for (i
= 0; i
< n
; i
++)
97 if (!alIsEffect(effects
[i
]))
99 alSetError(AL_INVALID_NAME
);
106 // All effects are valid
107 for (i
= 0; i
< n
; i
++)
109 // Recheck that the effect is valid, because there could be duplicated names
110 if (effects
[i
] && alIsEffect(effects
[i
]))
114 ALEffect
= ((ALeffect
*)ALTHUNK_LOOKUPENTRY(effects
[i
]));
116 // Remove Source from list of Sources
117 list
= &g_EffectList
;
118 while(*list
&& *list
!= ALEffect
)
119 list
= &(*list
)->next
;
122 *list
= (*list
)->next
;
123 ALTHUNK_REMOVEENTRY(ALEffect
->effect
);
125 memset(ALEffect
, 0, sizeof(ALeffect
));
134 alSetError(AL_INVALID_VALUE
);
136 ProcessContext(Context
);
139 AL_API ALboolean AL_APIENTRY
alIsEffect(ALuint effect
)
144 Context
= alcGetCurrentContext();
145 SuspendContext(Context
);
147 list
= &g_EffectList
;
148 while(*list
&& (*list
)->effect
!= effect
)
149 list
= &(*list
)->next
;
151 ProcessContext(Context
);
153 return ((*list
|| !effect
) ? AL_TRUE
: AL_FALSE
);
156 AL_API ALvoid AL_APIENTRY
alEffecti(ALuint effect
, ALenum param
, ALint iValue
)
160 Context
= alcGetCurrentContext();
161 SuspendContext(Context
);
163 if (effect
&& alIsEffect(effect
))
165 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
167 if(param
== AL_EFFECT_TYPE
)
169 if(iValue
== AL_EFFECT_NULL
||
170 iValue
== AL_EFFECT_REVERB
)
171 InitEffectParams(ALEffect
, iValue
);
173 alSetError(AL_INVALID_VALUE
);
175 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
179 case AL_REVERB_DECAY_HFLIMIT
:
180 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
181 ALEffect
->Reverb
.DecayHFLimit
= iValue
;
183 alSetError(AL_INVALID_VALUE
);
187 alSetError(AL_INVALID_ENUM
);
192 alSetError(AL_INVALID_ENUM
);
195 alSetError(AL_INVALID_NAME
);
197 ProcessContext(Context
);
200 AL_API ALvoid AL_APIENTRY
alEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
204 Context
= alcGetCurrentContext();
205 SuspendContext(Context
);
207 if (effect
&& alIsEffect(effect
))
209 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
211 if(param
== AL_EFFECT_TYPE
)
213 alEffecti(effect
, param
, piValues
[0]);
215 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
219 case AL_REVERB_DECAY_HFLIMIT
:
220 alEffecti(effect
, param
, piValues
[0]);
224 alSetError(AL_INVALID_ENUM
);
229 alSetError(AL_INVALID_ENUM
);
232 alSetError(AL_INVALID_NAME
);
234 ProcessContext(Context
);
237 AL_API ALvoid AL_APIENTRY
alEffectf(ALuint effect
, ALenum param
, ALfloat flValue
)
241 Context
= alcGetCurrentContext();
242 SuspendContext(Context
);
244 if (effect
&& alIsEffect(effect
))
246 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
248 if(ALEffect
->type
== AL_EFFECT_REVERB
)
252 case AL_REVERB_DENSITY
:
253 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
254 ALEffect
->Reverb
.Density
= flValue
;
256 alSetError(AL_INVALID_VALUE
);
259 case AL_REVERB_DIFFUSION
:
260 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
261 ALEffect
->Reverb
.Diffusion
= flValue
;
263 alSetError(AL_INVALID_VALUE
);
267 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
268 ALEffect
->Reverb
.Gain
= flValue
;
270 alSetError(AL_INVALID_VALUE
);
273 case AL_REVERB_GAINHF
:
274 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
275 ALEffect
->Reverb
.GainHF
= flValue
;
277 alSetError(AL_INVALID_VALUE
);
280 case AL_REVERB_DECAY_TIME
:
281 if(flValue
>= 0.1f
&& flValue
<= 20.0f
)
282 ALEffect
->Reverb
.DecayTime
= flValue
;
284 alSetError(AL_INVALID_VALUE
);
287 case AL_REVERB_DECAY_HFRATIO
:
288 if(flValue
>= 0.1f
&& flValue
<= 2.0f
)
289 ALEffect
->Reverb
.DecayHFRatio
= flValue
;
291 alSetError(AL_INVALID_VALUE
);
294 case AL_REVERB_REFLECTIONS_GAIN
:
295 if(flValue
>= 0.0f
&& flValue
<= 3.16f
)
296 ALEffect
->Reverb
.ReflectionsGain
= flValue
;
298 alSetError(AL_INVALID_VALUE
);
301 case AL_REVERB_REFLECTIONS_DELAY
:
302 if(flValue
>= 0.0f
&& flValue
<= 0.3f
)
303 ALEffect
->Reverb
.ReflectionsDelay
= flValue
;
305 alSetError(AL_INVALID_VALUE
);
308 case AL_REVERB_LATE_REVERB_GAIN
:
309 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
310 ALEffect
->Reverb
.LateReverbGain
= flValue
;
312 alSetError(AL_INVALID_VALUE
);
315 case AL_REVERB_LATE_REVERB_DELAY
:
316 if(flValue
>= 0.0f
&& flValue
<= 0.1f
)
317 ALEffect
->Reverb
.LateReverbDelay
= flValue
;
319 alSetError(AL_INVALID_VALUE
);
322 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
323 if(flValue
>= 0.892f
&& flValue
<= 1.0f
)
324 ALEffect
->Reverb
.AirAbsorptionGainHF
= flValue
;
326 alSetError(AL_INVALID_VALUE
);
329 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
330 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
331 ALEffect
->Reverb
.RoomRolloffFactor
= flValue
;
333 alSetError(AL_INVALID_VALUE
);
337 alSetError(AL_INVALID_ENUM
);
342 alSetError(AL_INVALID_ENUM
);
345 alSetError(AL_INVALID_NAME
);
347 ProcessContext(Context
);
350 AL_API ALvoid AL_APIENTRY
alEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
354 Context
= alcGetCurrentContext();
355 SuspendContext(Context
);
357 if (effect
&& alIsEffect(effect
))
359 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
361 if(ALEffect
->type
== AL_EFFECT_REVERB
)
365 case AL_REVERB_DENSITY
:
366 case AL_REVERB_DIFFUSION
:
368 case AL_REVERB_GAINHF
:
369 case AL_REVERB_DECAY_TIME
:
370 case AL_REVERB_DECAY_HFRATIO
:
371 case AL_REVERB_REFLECTIONS_GAIN
:
372 case AL_REVERB_REFLECTIONS_DELAY
:
373 case AL_REVERB_LATE_REVERB_GAIN
:
374 case AL_REVERB_LATE_REVERB_DELAY
:
375 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
376 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
377 alEffectf(effect
, param
, pflValues
[0]);
381 alSetError(AL_INVALID_ENUM
);
386 alSetError(AL_INVALID_ENUM
);
389 alSetError(AL_INVALID_NAME
);
391 ProcessContext(Context
);
394 AL_API ALvoid AL_APIENTRY
alGetEffecti(ALuint effect
, ALenum param
, ALint
*piValue
)
398 Context
= alcGetCurrentContext();
399 SuspendContext(Context
);
401 if (effect
&& alIsEffect(effect
))
403 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
405 if(param
== AL_EFFECT_TYPE
)
407 *piValue
= ALEffect
->type
;
409 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
413 case AL_REVERB_DECAY_HFLIMIT
:
414 *piValue
= ALEffect
->Reverb
.DecayHFLimit
;
418 alSetError(AL_INVALID_ENUM
);
423 alSetError(AL_INVALID_ENUM
);
426 alSetError(AL_INVALID_NAME
);
428 ProcessContext(Context
);
431 AL_API ALvoid AL_APIENTRY
alGetEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
435 Context
= alcGetCurrentContext();
436 SuspendContext(Context
);
438 if (effect
&& alIsEffect(effect
))
440 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
442 if(param
== AL_EFFECT_TYPE
)
444 alGetEffecti(effect
, param
, piValues
);
446 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
450 case AL_REVERB_DECAY_HFLIMIT
:
451 alGetEffecti(effect
, param
, piValues
);
455 alSetError(AL_INVALID_ENUM
);
460 alSetError(AL_INVALID_ENUM
);
463 alSetError(AL_INVALID_NAME
);
465 ProcessContext(Context
);
468 AL_API ALvoid AL_APIENTRY
alGetEffectf(ALuint effect
, ALenum param
, ALfloat
*pflValue
)
472 Context
= alcGetCurrentContext();
473 SuspendContext(Context
);
475 if (effect
&& alIsEffect(effect
))
477 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
479 if(ALEffect
->type
== AL_EFFECT_REVERB
)
483 case AL_REVERB_DENSITY
:
484 *pflValue
= ALEffect
->Reverb
.Density
;
487 case AL_REVERB_DIFFUSION
:
488 *pflValue
= ALEffect
->Reverb
.Diffusion
;
492 *pflValue
= ALEffect
->Reverb
.Gain
;
495 case AL_REVERB_GAINHF
:
496 *pflValue
= ALEffect
->Reverb
.GainHF
;
499 case AL_REVERB_DECAY_TIME
:
500 *pflValue
= ALEffect
->Reverb
.DecayTime
;
503 case AL_REVERB_DECAY_HFRATIO
:
504 *pflValue
= ALEffect
->Reverb
.DecayHFRatio
;
507 case AL_REVERB_REFLECTIONS_GAIN
:
508 *pflValue
= ALEffect
->Reverb
.ReflectionsGain
;
511 case AL_REVERB_REFLECTIONS_DELAY
:
512 *pflValue
= ALEffect
->Reverb
.ReflectionsDelay
;
515 case AL_REVERB_LATE_REVERB_GAIN
:
516 *pflValue
= ALEffect
->Reverb
.LateReverbGain
;
519 case AL_REVERB_LATE_REVERB_DELAY
:
520 *pflValue
= ALEffect
->Reverb
.LateReverbDelay
;
523 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
524 *pflValue
= ALEffect
->Reverb
.AirAbsorptionGainHF
;
527 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
528 *pflValue
= ALEffect
->Reverb
.RoomRolloffFactor
;
532 alSetError(AL_INVALID_ENUM
);
537 alSetError(AL_INVALID_ENUM
);
540 alSetError(AL_INVALID_NAME
);
542 ProcessContext(Context
);
545 AL_API ALvoid AL_APIENTRY
alGetEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
549 Context
= alcGetCurrentContext();
550 SuspendContext(Context
);
552 if (effect
&& alIsEffect(effect
))
554 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
556 if(ALEffect
->type
== AL_EFFECT_REVERB
)
560 case AL_REVERB_DENSITY
:
561 case AL_REVERB_DIFFUSION
:
563 case AL_REVERB_GAINHF
:
564 case AL_REVERB_DECAY_TIME
:
565 case AL_REVERB_DECAY_HFRATIO
:
566 case AL_REVERB_REFLECTIONS_GAIN
:
567 case AL_REVERB_REFLECTIONS_DELAY
:
568 case AL_REVERB_LATE_REVERB_GAIN
:
569 case AL_REVERB_LATE_REVERB_DELAY
:
570 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
571 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
572 alGetEffectf(effect
, param
, pflValues
);
576 alSetError(AL_INVALID_ENUM
);
581 alSetError(AL_INVALID_ENUM
);
584 alSetError(AL_INVALID_NAME
);
586 ProcessContext(Context
);
590 ALvoid
ReleaseALEffects(ALvoid
)
593 if(g_EffectCount
> 0)
594 AL_PRINT("exit() %d Effect(s) NOT deleted\n", g_EffectCount
);
599 ALeffect
*temp
= g_EffectList
;
600 g_EffectList
= g_EffectList
->next
;
602 // Release effect structure
603 memset(temp
, 0, sizeof(ALeffect
));
610 static void InitEffectParams(ALeffect
*effect
, ALenum type
)
615 case AL_EFFECT_REVERB
:
616 effect
->Reverb
.Density
= 1.0f
;
617 effect
->Reverb
.Diffusion
= 1.0f
;
618 effect
->Reverb
.Gain
= 0.32f
;
619 effect
->Reverb
.GainHF
= 0.89f
;
620 effect
->Reverb
.DecayTime
= 1.49f
;
621 effect
->Reverb
.DecayHFRatio
= 0.83f
;
622 effect
->Reverb
.ReflectionsGain
= 0.05f
;
623 effect
->Reverb
.ReflectionsDelay
= 0.007f
;
624 effect
->Reverb
.LateReverbGain
= 1.26f
;
625 effect
->Reverb
.LateReverbDelay
= 0.011f
;
626 effect
->Reverb
.AirAbsorptionGainHF
= 0.994f
;
627 effect
->Reverb
.RoomRolloffFactor
= 0.0f
;
628 effect
->Reverb
.DecayHFLimit
= AL_TRUE
;