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
29 #include "alAuxEffectSlot.h"
35 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
);
38 ALvoid AL_APIENTRY
alGenAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
43 Context
= alcGetCurrentContext();
46 alSetError(AL_INVALID_OPERATION
);
49 SuspendContext(Context
);
53 /* NOTE: We only support one slot currently */
54 if(n
== 1 && Context
->AuxiliaryEffectSlotCount
== 0)
56 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
57 if (!IsBadWritePtr((void*)effectslots
, n
* sizeof(ALuint
)))
59 ALeffectslot
**list
= &Context
->AuxiliaryEffectSlot
;
61 list
= &(*list
)->next
;
66 *list
= calloc(1, sizeof(ALeffectslot
));
69 // We must have run out or memory
70 alDeleteAuxiliaryEffectSlots(i
, effectslots
);
71 alSetError(AL_OUT_OF_MEMORY
);
76 (*list
)->AuxSendAuto
= AL_TRUE
;
77 (*list
)->refcount
= 0;
79 effectslots
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
80 (*list
)->effectslot
= effectslots
[i
];
82 Context
->AuxiliaryEffectSlotCount
++;
85 list
= &(*list
)->next
;
90 alSetError(AL_INVALID_OPERATION
);
93 ProcessContext(Context
);
96 ALvoid AL_APIENTRY
alDeleteAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
99 ALeffectslot
*ALAuxiliaryEffectSlot
;
102 Context
= alcGetCurrentContext();
105 alSetError(AL_INVALID_OPERATION
);
108 SuspendContext(Context
);
112 // Check that all effectslots are valid
113 for (i
= 0; i
< n
; i
++)
115 if (!alIsAuxiliaryEffectSlot(effectslots
[i
]))
117 alSetError(AL_INVALID_NAME
);
122 ALAuxiliaryEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]);
123 if(ALAuxiliaryEffectSlot
->refcount
> 0)
125 alSetError(AL_INVALID_NAME
);
133 // All effectslots are valid
134 for (i
= 0; i
< n
; i
++)
136 // Recheck that the effectslot is valid, because there could be duplicated names
137 if (alIsAuxiliaryEffectSlot(effectslots
[i
]))
141 ALAuxiliaryEffectSlot
= ((ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]));
143 // Remove Source from list of Sources
144 list
= &Context
->AuxiliaryEffectSlot
;
145 while(*list
&& *list
!= ALAuxiliaryEffectSlot
)
146 list
= &(*list
)->next
;
149 *list
= (*list
)->next
;
150 ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot
->effectslot
);
152 VerbDestroy(ALAuxiliaryEffectSlot
->ReverbState
);
154 memset(ALAuxiliaryEffectSlot
, 0, sizeof(ALeffectslot
));
155 free(ALAuxiliaryEffectSlot
);
157 Context
->AuxiliaryEffectSlotCount
--;
163 alSetError(AL_INVALID_VALUE
);
165 ProcessContext(Context
);
168 ALboolean AL_APIENTRY
alIsAuxiliaryEffectSlot(ALuint effectslot
)
173 Context
= alcGetCurrentContext();
176 alSetError(AL_INVALID_OPERATION
);
179 SuspendContext(Context
);
181 list
= &Context
->AuxiliaryEffectSlot
;
182 while(*list
&& (*list
)->effectslot
!= effectslot
)
183 list
= &(*list
)->next
;
185 ProcessContext(Context
);
187 return (*list
? AL_TRUE
: AL_FALSE
);
190 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
194 Context
= alcGetCurrentContext();
197 alSetError(AL_INVALID_OPERATION
);
200 SuspendContext(Context
);
202 if (alIsAuxiliaryEffectSlot(effectslot
))
204 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
208 case AL_EFFECTSLOT_EFFECT
:
209 if(alIsEffect(iValue
))
211 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
212 InitializeEffect(Context
, ALEffectSlot
, effect
);
215 alSetError(AL_INVALID_VALUE
);
218 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
219 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
220 ALEffectSlot
->AuxSendAuto
= iValue
;
222 alSetError(AL_INVALID_VALUE
);
226 alSetError(AL_INVALID_ENUM
);
231 alSetError(AL_INVALID_NAME
);
233 ProcessContext(Context
);
236 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
240 Context
= alcGetCurrentContext();
243 alSetError(AL_INVALID_OPERATION
);
246 SuspendContext(Context
);
248 if (alIsAuxiliaryEffectSlot(effectslot
))
252 case AL_EFFECTSLOT_EFFECT
:
253 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
254 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
258 alSetError(AL_INVALID_ENUM
);
263 alSetError(AL_INVALID_NAME
);
265 ProcessContext(Context
);
268 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
272 Context
= alcGetCurrentContext();
275 alSetError(AL_INVALID_OPERATION
);
278 SuspendContext(Context
);
280 if (alIsAuxiliaryEffectSlot(effectslot
))
282 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
286 case AL_EFFECTSLOT_GAIN
:
287 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
288 ALEffectSlot
->Gain
= flValue
;
290 alSetError(AL_INVALID_VALUE
);
294 alSetError(AL_INVALID_ENUM
);
299 alSetError(AL_INVALID_NAME
);
301 ProcessContext(Context
);
304 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
308 Context
= alcGetCurrentContext();
311 alSetError(AL_INVALID_OPERATION
);
314 SuspendContext(Context
);
316 if (alIsAuxiliaryEffectSlot(effectslot
))
320 case AL_EFFECTSLOT_GAIN
:
321 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
325 alSetError(AL_INVALID_ENUM
);
330 alSetError(AL_INVALID_NAME
);
332 ProcessContext(Context
);
335 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
339 Context
= alcGetCurrentContext();
342 alSetError(AL_INVALID_OPERATION
);
345 SuspendContext(Context
);
347 if (alIsAuxiliaryEffectSlot(effectslot
))
349 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
353 case AL_EFFECTSLOT_EFFECT
:
354 *piValue
= ALEffectSlot
->effect
.effect
;
357 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
358 *piValue
= ALEffectSlot
->AuxSendAuto
;
362 alSetError(AL_INVALID_ENUM
);
367 alSetError(AL_INVALID_NAME
);
369 ProcessContext(Context
);
372 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
376 Context
= alcGetCurrentContext();
379 alSetError(AL_INVALID_OPERATION
);
382 SuspendContext(Context
);
384 if (alIsAuxiliaryEffectSlot(effectslot
))
388 case AL_EFFECTSLOT_EFFECT
:
389 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
390 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
394 alSetError(AL_INVALID_ENUM
);
399 alSetError(AL_INVALID_NAME
);
401 ProcessContext(Context
);
404 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
408 Context
= alcGetCurrentContext();
411 alSetError(AL_INVALID_OPERATION
);
414 SuspendContext(Context
);
416 if (alIsAuxiliaryEffectSlot(effectslot
))
418 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
422 case AL_EFFECTSLOT_GAIN
:
423 *pflValue
= ALEffectSlot
->Gain
;
427 alSetError(AL_INVALID_ENUM
);
432 alSetError(AL_INVALID_NAME
);
434 ProcessContext(Context
);
437 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
441 Context
= alcGetCurrentContext();
444 alSetError(AL_INVALID_OPERATION
);
447 SuspendContext(Context
);
449 if (alIsAuxiliaryEffectSlot(effectslot
))
453 case AL_EFFECTSLOT_GAIN
:
454 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
458 alSetError(AL_INVALID_ENUM
);
463 alSetError(AL_INVALID_NAME
);
465 ProcessContext(Context
);
469 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
473 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
474 VerbDestroy(ALEffectSlot
->ReverbState
);
475 ALEffectSlot
->ReverbState
= NULL
;
478 if(effect
->type
== AL_EFFECT_REVERB
)
480 if(!ALEffectSlot
->ReverbState
)
481 ALEffectSlot
->ReverbState
= VerbCreate(Context
);
482 VerbUpdate(Context
, ALEffectSlot
, effect
);
484 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
488 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
491 if(Context
->AuxiliaryEffectSlotCount
> 0)
492 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context
->AuxiliaryEffectSlotCount
);
495 while(Context
->AuxiliaryEffectSlot
)
497 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
498 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
500 // Release effectslot structure
501 VerbDestroy(temp
->ReverbState
);
502 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
504 memset(temp
, 0, sizeof(ALeffectslot
));
507 Context
->AuxiliaryEffectSlotCount
= 0;