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
32 static ALeffect
*g_EffectList
;
33 static ALuint g_EffectCount
;
35 static void InitEffectParams(ALeffect
*effect
, ALenum type
);
38 ALvoid AL_APIENTRY
alGenEffects(ALsizei n
, ALuint
*effects
)
43 Context
= alcGetCurrentContext();
44 SuspendContext(Context
);
48 // Check that enough memory has been allocted in the 'effects' array for n Effects
49 if (!IsBadWritePtr((void*)effects
, n
* sizeof(ALuint
)))
51 ALeffect
**list
= &g_EffectList
;
53 list
= &(*list
)->next
;
58 *list
= calloc(1, sizeof(ALeffect
));
61 // We must have run out or memory
62 alDeleteEffects(i
, effects
);
63 alSetError(AL_OUT_OF_MEMORY
);
67 effects
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
68 (*list
)->effect
= effects
[i
];
70 InitEffectParams(*list
, AL_EFFECT_NULL
);
74 list
= &(*list
)->next
;
79 ProcessContext(Context
);
82 ALvoid AL_APIENTRY
alDeleteEffects(ALsizei n
, ALuint
*effects
)
88 Context
= alcGetCurrentContext();
89 SuspendContext(Context
);
93 // Check that all effects are valid
94 for (i
= 0; i
< n
; i
++)
96 if (!alIsEffect(effects
[i
]))
98 alSetError(AL_INVALID_NAME
);
105 // All effects are valid
106 for (i
= 0; i
< n
; i
++)
108 // Recheck that the effect is valid, because there could be duplicated names
109 if (effects
[i
] && alIsEffect(effects
[i
]))
113 ALEffect
= ((ALeffect
*)ALTHUNK_LOOKUPENTRY(effects
[i
]));
115 // Remove Source from list of Sources
116 list
= &g_EffectList
;
117 while(*list
&& *list
!= ALEffect
)
118 list
= &(*list
)->next
;
121 *list
= (*list
)->next
;
122 ALTHUNK_REMOVEENTRY(ALEffect
->effect
);
124 memset(ALEffect
, 0, sizeof(ALeffect
));
133 alSetError(AL_INVALID_VALUE
);
135 ProcessContext(Context
);
138 ALboolean AL_APIENTRY
alIsEffect(ALuint effect
)
143 Context
= alcGetCurrentContext();
144 SuspendContext(Context
);
146 list
= &g_EffectList
;
147 while(*list
&& (*list
)->effect
!= effect
)
148 list
= &(*list
)->next
;
150 ProcessContext(Context
);
152 return ((*list
|| !effect
) ? AL_TRUE
: AL_FALSE
);
155 ALvoid AL_APIENTRY
alEffecti(ALuint effect
, ALenum param
, ALint iValue
)
159 Context
= alcGetCurrentContext();
160 SuspendContext(Context
);
162 if (effect
&& alIsEffect(effect
))
164 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
166 if(param
== AL_EFFECT_TYPE
)
168 if(iValue
== AL_EFFECT_NULL
||
169 iValue
== AL_EFFECT_REVERB
)
170 InitEffectParams(ALEffect
, iValue
);
172 alSetError(AL_INVALID_VALUE
);
174 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
178 case AL_REVERB_DECAY_HFLIMIT
:
179 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
180 ALEffect
->Reverb
.DecayHFLimit
= iValue
;
182 alSetError(AL_INVALID_VALUE
);
186 alSetError(AL_INVALID_ENUM
);
191 alSetError(AL_INVALID_ENUM
);
194 alSetError(AL_INVALID_NAME
);
196 ProcessContext(Context
);
199 ALvoid AL_APIENTRY
alEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
203 Context
= alcGetCurrentContext();
204 SuspendContext(Context
);
206 if (effect
&& alIsEffect(effect
))
208 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
210 if(param
== AL_EFFECT_TYPE
)
212 alEffecti(effect
, param
, piValues
[0]);
214 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
218 case AL_REVERB_DECAY_HFLIMIT
:
219 alEffecti(effect
, param
, piValues
[0]);
223 alSetError(AL_INVALID_ENUM
);
228 alSetError(AL_INVALID_ENUM
);
231 alSetError(AL_INVALID_NAME
);
233 ProcessContext(Context
);
236 ALvoid AL_APIENTRY
alEffectf(ALuint effect
, ALenum param
, ALfloat flValue
)
240 Context
= alcGetCurrentContext();
241 SuspendContext(Context
);
243 if (effect
&& alIsEffect(effect
))
245 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
247 if(ALEffect
->type
== AL_EFFECT_REVERB
)
251 case AL_REVERB_DENSITY
:
252 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
253 ALEffect
->Reverb
.Density
= flValue
;
255 alSetError(AL_INVALID_VALUE
);
258 case AL_REVERB_DIFFUSION
:
259 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
260 ALEffect
->Reverb
.Diffusion
= flValue
;
262 alSetError(AL_INVALID_VALUE
);
266 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
267 ALEffect
->Reverb
.Gain
= flValue
;
269 alSetError(AL_INVALID_VALUE
);
272 case AL_REVERB_GAINHF
:
273 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
274 ALEffect
->Reverb
.GainHF
= flValue
;
276 alSetError(AL_INVALID_VALUE
);
279 case AL_REVERB_DECAY_TIME
:
280 if(flValue
>= 0.1f
&& flValue
<= 20.0f
)
281 ALEffect
->Reverb
.DecayTime
= flValue
;
283 alSetError(AL_INVALID_VALUE
);
286 case AL_REVERB_DECAY_HFRATIO
:
287 if(flValue
>= 0.1f
&& flValue
<= 2.0f
)
288 ALEffect
->Reverb
.DecayHFRatio
= flValue
;
290 alSetError(AL_INVALID_VALUE
);
293 case AL_REVERB_REFLECTIONS_GAIN
:
294 if(flValue
>= 0.0f
&& flValue
<= 3.16f
)
295 ALEffect
->Reverb
.ReflectionsGain
= flValue
;
297 alSetError(AL_INVALID_VALUE
);
300 case AL_REVERB_REFLECTIONS_DELAY
:
301 if(flValue
>= 0.0f
&& flValue
<= 0.3f
)
302 ALEffect
->Reverb
.ReflectionsDelay
= flValue
;
304 alSetError(AL_INVALID_VALUE
);
307 case AL_REVERB_LATE_REVERB_GAIN
:
308 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
309 ALEffect
->Reverb
.LateReverbGain
= flValue
;
311 alSetError(AL_INVALID_VALUE
);
314 case AL_REVERB_LATE_REVERB_DELAY
:
315 if(flValue
>= 0.0f
&& flValue
<= 0.1f
)
316 ALEffect
->Reverb
.LateReverbDelay
= flValue
;
318 alSetError(AL_INVALID_VALUE
);
321 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
322 if(flValue
>= 0.892f
&& flValue
<= 1.0f
)
323 ALEffect
->Reverb
.AirAbsorptionGainHF
= flValue
;
325 alSetError(AL_INVALID_VALUE
);
328 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
329 if(flValue
>= 0.0f
&& flValue
<= 10.0f
)
330 ALEffect
->Reverb
.RoomRolloffFactor
= flValue
;
332 alSetError(AL_INVALID_VALUE
);
336 alSetError(AL_INVALID_ENUM
);
341 alSetError(AL_INVALID_ENUM
);
344 alSetError(AL_INVALID_NAME
);
346 ProcessContext(Context
);
349 ALvoid AL_APIENTRY
alEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
353 Context
= alcGetCurrentContext();
354 SuspendContext(Context
);
356 if (effect
&& alIsEffect(effect
))
358 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
360 if(ALEffect
->type
== AL_EFFECT_REVERB
)
364 case AL_REVERB_DENSITY
:
365 case AL_REVERB_DIFFUSION
:
367 case AL_REVERB_GAINHF
:
368 case AL_REVERB_DECAY_TIME
:
369 case AL_REVERB_DECAY_HFRATIO
:
370 case AL_REVERB_REFLECTIONS_GAIN
:
371 case AL_REVERB_REFLECTIONS_DELAY
:
372 case AL_REVERB_LATE_REVERB_GAIN
:
373 case AL_REVERB_LATE_REVERB_DELAY
:
374 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
375 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
376 alEffectf(effect
, param
, pflValues
[0]);
380 alSetError(AL_INVALID_ENUM
);
385 alSetError(AL_INVALID_ENUM
);
388 alSetError(AL_INVALID_NAME
);
390 ProcessContext(Context
);
393 ALvoid AL_APIENTRY
alGetEffecti(ALuint effect
, ALenum param
, ALint
*piValue
)
397 Context
= alcGetCurrentContext();
398 SuspendContext(Context
);
400 if (effect
&& alIsEffect(effect
))
402 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
404 if(param
== AL_EFFECT_TYPE
)
406 *piValue
= ALEffect
->type
;
408 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
412 case AL_REVERB_DECAY_HFLIMIT
:
413 *piValue
= ALEffect
->Reverb
.DecayHFLimit
;
417 alSetError(AL_INVALID_ENUM
);
422 alSetError(AL_INVALID_ENUM
);
425 alSetError(AL_INVALID_NAME
);
427 ProcessContext(Context
);
430 ALvoid AL_APIENTRY
alGetEffectiv(ALuint effect
, ALenum param
, ALint
*piValues
)
434 Context
= alcGetCurrentContext();
435 SuspendContext(Context
);
437 if (effect
&& alIsEffect(effect
))
439 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
441 if(param
== AL_EFFECT_TYPE
)
443 alGetEffecti(effect
, param
, piValues
);
445 else if(ALEffect
->type
== AL_EFFECT_REVERB
)
449 case AL_REVERB_DECAY_HFLIMIT
:
450 alGetEffecti(effect
, param
, piValues
);
454 alSetError(AL_INVALID_ENUM
);
459 alSetError(AL_INVALID_ENUM
);
462 alSetError(AL_INVALID_NAME
);
464 ProcessContext(Context
);
467 ALvoid AL_APIENTRY
alGetEffectf(ALuint effect
, ALenum param
, ALfloat
*pflValue
)
471 Context
= alcGetCurrentContext();
472 SuspendContext(Context
);
474 if (effect
&& alIsEffect(effect
))
476 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
478 if(ALEffect
->type
== AL_EFFECT_REVERB
)
482 case AL_REVERB_DENSITY
:
483 *pflValue
= ALEffect
->Reverb
.Density
;
486 case AL_REVERB_DIFFUSION
:
487 *pflValue
= ALEffect
->Reverb
.Diffusion
;
491 *pflValue
= ALEffect
->Reverb
.Gain
;
494 case AL_REVERB_GAINHF
:
495 *pflValue
= ALEffect
->Reverb
.GainHF
;
498 case AL_REVERB_DECAY_TIME
:
499 *pflValue
= ALEffect
->Reverb
.DecayTime
;
502 case AL_REVERB_DECAY_HFRATIO
:
503 *pflValue
= ALEffect
->Reverb
.DecayHFRatio
;
506 case AL_REVERB_REFLECTIONS_GAIN
:
507 *pflValue
= ALEffect
->Reverb
.ReflectionsGain
;
510 case AL_REVERB_REFLECTIONS_DELAY
:
511 *pflValue
= ALEffect
->Reverb
.ReflectionsDelay
;
514 case AL_REVERB_LATE_REVERB_GAIN
:
515 *pflValue
= ALEffect
->Reverb
.LateReverbGain
;
518 case AL_REVERB_LATE_REVERB_DELAY
:
519 *pflValue
= ALEffect
->Reverb
.LateReverbDelay
;
522 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
523 *pflValue
= ALEffect
->Reverb
.AirAbsorptionGainHF
;
526 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
527 *pflValue
= ALEffect
->Reverb
.RoomRolloffFactor
;
531 alSetError(AL_INVALID_ENUM
);
536 alSetError(AL_INVALID_ENUM
);
539 alSetError(AL_INVALID_NAME
);
541 ProcessContext(Context
);
544 ALvoid AL_APIENTRY
alGetEffectfv(ALuint effect
, ALenum param
, ALfloat
*pflValues
)
548 Context
= alcGetCurrentContext();
549 SuspendContext(Context
);
551 if (effect
&& alIsEffect(effect
))
553 ALeffect
*ALEffect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(effect
);
555 if(ALEffect
->type
== AL_EFFECT_REVERB
)
559 case AL_REVERB_DENSITY
:
560 case AL_REVERB_DIFFUSION
:
562 case AL_REVERB_GAINHF
:
563 case AL_REVERB_DECAY_TIME
:
564 case AL_REVERB_DECAY_HFRATIO
:
565 case AL_REVERB_REFLECTIONS_GAIN
:
566 case AL_REVERB_REFLECTIONS_DELAY
:
567 case AL_REVERB_LATE_REVERB_GAIN
:
568 case AL_REVERB_LATE_REVERB_DELAY
:
569 case AL_REVERB_AIR_ABSORPTION_GAINHF
:
570 case AL_REVERB_ROOM_ROLLOFF_FACTOR
:
571 alGetEffectf(effect
, param
, pflValues
);
575 alSetError(AL_INVALID_ENUM
);
580 alSetError(AL_INVALID_ENUM
);
583 alSetError(AL_INVALID_NAME
);
585 ProcessContext(Context
);
589 ALvoid
ReleaseALEffects(ALvoid
)
592 if(g_EffectCount
> 0)
593 AL_PRINT("exit(): deleting %d Effect(s)\n", g_EffectCount
);
598 ALeffect
*temp
= g_EffectList
;
599 g_EffectList
= g_EffectList
->next
;
601 // Release effect structure
602 memset(temp
, 0, sizeof(ALeffect
));
609 static void InitEffectParams(ALeffect
*effect
, ALenum type
)
614 case AL_EFFECT_REVERB
:
615 effect
->Reverb
.Density
= 1.0f
;
616 effect
->Reverb
.Diffusion
= 1.0f
;
617 effect
->Reverb
.Gain
= 0.32f
;
618 effect
->Reverb
.GainHF
= 0.89f
;
619 effect
->Reverb
.DecayTime
= 1.49f
;
620 effect
->Reverb
.DecayHFRatio
= 0.83f
;
621 effect
->Reverb
.ReflectionsGain
= 0.05f
;
622 effect
->Reverb
.ReflectionsDelay
= 0.007f
;
623 effect
->Reverb
.LateReverbGain
= 1.26f
;
624 effect
->Reverb
.LateReverbDelay
= 0.011f
;
625 effect
->Reverb
.AirAbsorptionGainHF
= 0.994f
;
626 effect
->Reverb
.RoomRolloffFactor
= 0.0f
;
627 effect
->Reverb
.DecayHFLimit
= AL_TRUE
;