Store effect slots in the context
[openal-soft.git] / OpenAL32 / alAuxEffectSlot.c
blob64ec6ef45641952ea34a4fcee8ffd57db33686af
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 <stdlib.h>
23 #include "config.h"
25 #include "AL/al.h"
26 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alAuxEffectSlot.h"
30 #include "alThunk.h"
31 #include "alError.h"
34 AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
36 ALCcontext *Context;
37 ALsizei i;
39 Context = alcGetCurrentContext();
40 if(!Context)
42 alSetError(AL_INVALID_OPERATION);
43 return;
45 SuspendContext(Context);
47 if (n > 0)
49 /* NOTE: We only support one slot currently */
50 if(n == 1 && Context->AuxiliaryEffectSlotCount == 0)
52 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
53 if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
55 ALeffectslot **list = &Context->AuxiliaryEffectSlot;
56 while(*list)
57 list = &(*list)->next;
59 i = 0;
60 while(i < n)
62 *list = calloc(1, sizeof(ALeffectslot));
63 if(!(*list))
65 // We must have run out or memory
66 alDeleteAuxiliaryEffectSlots(i, effectslots);
67 alSetError(AL_OUT_OF_MEMORY);
68 break;
71 (*list)->Gain = 1.0;
72 (*list)->AuxSendAuto = AL_TRUE;
74 effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
75 (*list)->effectslot = effectslots[i];
77 Context->AuxiliaryEffectSlotCount++;
78 i++;
82 else
83 alSetError(AL_INVALID_OPERATION);
86 ProcessContext(Context);
89 AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
91 ALCcontext *Context;
92 ALeffectslot *ALAuxiliaryEffectSlot;
93 ALsizei i;
95 Context = alcGetCurrentContext();
96 if(!Context)
98 alSetError(AL_INVALID_OPERATION);
99 return;
101 SuspendContext(Context);
103 if (n >= 0)
105 // Check that all effectslots are valid
106 for (i = 0; i < n; i++)
108 if (!alIsAuxiliaryEffectSlot(effectslots[i]))
110 alSetError(AL_INVALID_NAME);
111 break;
115 if (i == n)
117 // All effectslots are valid
118 for (i = 0; i < n; i++)
120 // Recheck that the effectslot is valid, because there could be duplicated names
121 if (alIsAuxiliaryEffectSlot(effectslots[i]))
123 ALeffectslot **list;
125 ALAuxiliaryEffectSlot = ((ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslots[i]));
127 // Remove Source from list of Sources
128 list = &Context->AuxiliaryEffectSlot;
129 while(*list && *list != ALAuxiliaryEffectSlot)
130 list = &(*list)->next;
132 if(*list)
133 *list = (*list)->next;
134 ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot);
136 memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot));
137 free(ALAuxiliaryEffectSlot);
139 Context->AuxiliaryEffectSlotCount--;
144 else
145 alSetError(AL_INVALID_VALUE);
147 ProcessContext(Context);
150 AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
152 ALCcontext *Context;
153 ALeffectslot **list;
155 Context = alcGetCurrentContext();
156 if(!Context)
158 alSetError(AL_INVALID_OPERATION);
159 return AL_FALSE;
161 SuspendContext(Context);
163 list = &Context->AuxiliaryEffectSlot;
164 while(*list && (*list)->effectslot != effectslot)
165 list = &(*list)->next;
167 ProcessContext(Context);
169 return (*list ? AL_TRUE : AL_FALSE);
172 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
174 ALCcontext *Context;
176 Context = alcGetCurrentContext();
177 if(!Context)
179 alSetError(AL_INVALID_OPERATION);
180 return;
182 SuspendContext(Context);
184 if (alIsAuxiliaryEffectSlot(effectslot))
186 ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot);
188 switch(param)
190 case AL_EFFECTSLOT_EFFECT:
191 if(alIsEffect(iValue))
193 ALeffect *effect = (ALeffect*)ALTHUNK_LOOKUPENTRY(iValue);
194 if(!effect)
196 ALEffectSlot->effect.type = AL_EFFECT_NULL;
197 ALEffectSlot->effect.effect = 0;
199 else
200 memcpy(&ALEffectSlot->effect, effect, sizeof(*effect));
202 else
203 alSetError(AL_INVALID_VALUE);
204 break;
206 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
207 if(iValue == AL_TRUE || iValue == AL_FALSE)
208 ALEffectSlot->AuxSendAuto = iValue;
209 else
210 alSetError(AL_INVALID_VALUE);
211 break;
213 default:
214 alSetError(AL_INVALID_ENUM);
215 break;
218 else
219 alSetError(AL_INVALID_NAME);
221 ProcessContext(Context);
224 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
226 ALCcontext *Context;
228 Context = alcGetCurrentContext();
229 if(!Context)
231 alSetError(AL_INVALID_OPERATION);
232 return;
234 SuspendContext(Context);
236 if (alIsAuxiliaryEffectSlot(effectslot))
238 switch(param)
240 case AL_EFFECTSLOT_EFFECT:
241 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
242 alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
243 break;
245 default:
246 alSetError(AL_INVALID_ENUM);
247 break;
250 else
251 alSetError(AL_INVALID_NAME);
253 ProcessContext(Context);
256 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue)
258 ALCcontext *Context;
260 Context = alcGetCurrentContext();
261 if(!Context)
263 alSetError(AL_INVALID_OPERATION);
264 return;
266 SuspendContext(Context);
268 if (alIsAuxiliaryEffectSlot(effectslot))
270 ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot);
272 switch(param)
274 case AL_EFFECTSLOT_GAIN:
275 if(flValue >= 0.0f && flValue <= 1.0f)
276 ALEffectSlot->Gain = flValue;
277 else
278 alSetError(AL_INVALID_VALUE);
279 break;
281 default:
282 alSetError(AL_INVALID_ENUM);
283 break;
286 else
287 alSetError(AL_INVALID_NAME);
289 ProcessContext(Context);
292 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
294 ALCcontext *Context;
296 Context = alcGetCurrentContext();
297 if(!Context)
299 alSetError(AL_INVALID_OPERATION);
300 return;
302 SuspendContext(Context);
304 if (alIsAuxiliaryEffectSlot(effectslot))
306 switch(param)
308 case AL_EFFECTSLOT_GAIN:
309 alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
310 break;
312 default:
313 alSetError(AL_INVALID_ENUM);
314 break;
317 else
318 alSetError(AL_INVALID_NAME);
320 ProcessContext(Context);
323 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
325 ALCcontext *Context;
327 Context = alcGetCurrentContext();
328 if(!Context)
330 alSetError(AL_INVALID_OPERATION);
331 return;
333 SuspendContext(Context);
335 if (alIsAuxiliaryEffectSlot(effectslot))
337 ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot);
339 switch(param)
341 case AL_EFFECTSLOT_EFFECT:
342 *piValue = ALEffectSlot->effect.effect;
343 break;
345 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
346 *piValue = ALEffectSlot->AuxSendAuto;
347 break;
349 default:
350 alSetError(AL_INVALID_ENUM);
351 break;
354 else
355 alSetError(AL_INVALID_NAME);
357 ProcessContext(Context);
360 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
362 ALCcontext *Context;
364 Context = alcGetCurrentContext();
365 if(!Context)
367 alSetError(AL_INVALID_OPERATION);
368 return;
370 SuspendContext(Context);
372 if (alIsAuxiliaryEffectSlot(effectslot))
374 switch(param)
376 case AL_EFFECTSLOT_EFFECT:
377 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
378 alGetAuxiliaryEffectSloti(effectslot, param, piValues);
379 break;
381 default:
382 alSetError(AL_INVALID_ENUM);
383 break;
386 else
387 alSetError(AL_INVALID_NAME);
389 ProcessContext(Context);
392 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
394 ALCcontext *Context;
396 Context = alcGetCurrentContext();
397 if(!Context)
399 alSetError(AL_INVALID_OPERATION);
400 return;
402 SuspendContext(Context);
404 if (alIsAuxiliaryEffectSlot(effectslot))
406 ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot);
408 switch(param)
410 case AL_EFFECTSLOT_GAIN:
411 *pflValue = ALEffectSlot->Gain;
412 break;
414 default:
415 alSetError(AL_INVALID_ENUM);
416 break;
419 else
420 alSetError(AL_INVALID_NAME);
422 ProcessContext(Context);
425 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
427 ALCcontext *Context;
429 Context = alcGetCurrentContext();
430 if(!Context)
432 alSetError(AL_INVALID_OPERATION);
433 return;
435 SuspendContext(Context);
437 if (alIsAuxiliaryEffectSlot(effectslot))
439 switch(param)
441 case AL_EFFECTSLOT_GAIN:
442 alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
443 break;
445 default:
446 alSetError(AL_INVALID_ENUM);
447 break;
450 else
451 alSetError(AL_INVALID_NAME);
453 ProcessContext(Context);
457 ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
459 #ifdef _DEBUG
460 if(Context->AuxiliaryEffectSlotCount > 0)
461 AL_PRINT("exit() %d AuxiliaryEffectSlot(s) NOT deleted\n", Context->AuxiliaryEffectSlotCount);
462 #endif
464 while(Context->AuxiliaryEffectSlot)
466 ALeffectslot *temp = Context->AuxiliaryEffectSlot;
467 Context->AuxiliaryEffectSlot = Context->AuxiliaryEffectSlot->next;
469 // Release effectslot structure
470 memset(temp, 0, sizeof(ALeffectslot));
471 free(temp);
473 Context->AuxiliaryEffectSlotCount = 0;