Shorten some variable names
[openal-soft.git] / OpenAL32 / alAuxEffectSlot.c
blob3f76da2f482f7e2b0a5f46c6b3e468534987e8e0
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 "config.h"
23 #include <stdlib.h>
24 #include <math.h>
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alAuxEffectSlot.h"
30 #include "alThunk.h"
31 #include "alError.h"
32 #include "alSource.h"
35 static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect);
37 DECL_VERIFIER(EffectSlot, ALeffectslot, effectslot)
38 DECL_VERIFIER(Effect, ALeffect, effect)
40 AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
42 ALCcontext *Context;
43 ALsizei i=0, j;
45 Context = GetContextSuspended();
46 if(!Context) return;
48 if (n > 0)
50 ALCdevice *Device = Context->Device;
52 if(Context->EffectSlotCount+n <= Device->AuxiliaryEffectSlotMax)
54 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
55 if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
57 ALeffectslot *end;
58 ALeffectslot **list = &Context->EffectSlotList;
59 while(*list)
60 list = &(*list)->next;
62 end = *list;
63 while(i < n)
65 *list = calloc(1, sizeof(ALeffectslot));
66 if(!(*list) || !((*list)->EffectState=NoneCreate()))
68 // We must have run out or memory
69 free(*list); *list = NULL;
70 while(end->next)
72 ALeffectslot *temp = end->next;
73 end->next = temp->next;
75 ALEffect_Destroy(temp->EffectState);
76 ALTHUNK_REMOVEENTRY(temp->effectslot);
77 Context->EffectSlotCount--;
78 free(temp);
80 alSetError(Context, AL_OUT_OF_MEMORY);
81 break;
84 (*list)->Gain = 1.0;
85 (*list)->AuxSendAuto = AL_TRUE;
86 for(j = 0;j < BUFFERSIZE;j++)
87 (*list)->WetBuffer[j] = 0.0f;
88 (*list)->refcount = 0;
90 effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
91 (*list)->effectslot = effectslots[i];
93 Context->EffectSlotCount++;
94 i++;
96 list = &(*list)->next;
100 else
101 alSetError(Context, AL_INVALID_OPERATION);
104 ProcessContext(Context);
107 AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
109 ALCcontext *Context;
110 ALeffectslot *EffectSlot;
111 ALsizei i;
113 Context = GetContextSuspended();
114 if(!Context) return;
116 if (n >= 0)
118 // Check that all effectslots are valid
119 for (i = 0; i < n; i++)
121 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslots[i])) == NULL)
123 alSetError(Context, AL_INVALID_NAME);
124 break;
126 else
128 if(EffectSlot->refcount > 0)
130 alSetError(Context, AL_INVALID_NAME);
131 break;
136 if (i == n)
138 // All effectslots are valid
139 for (i = 0; i < n; i++)
141 // Recheck that the effectslot is valid, because there could be duplicated names
142 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslots[i])) != NULL)
144 ALeffectslot **list;
146 // Remove Source from list of Sources
147 list = &Context->EffectSlotList;
148 while(*list && *list != EffectSlot)
149 list = &(*list)->next;
151 if(*list)
152 *list = (*list)->next;
153 ALTHUNK_REMOVEENTRY(EffectSlot->effectslot);
155 ALEffect_Destroy(EffectSlot->EffectState);
157 memset(EffectSlot, 0, sizeof(ALeffectslot));
158 free(EffectSlot);
160 Context->EffectSlotCount--;
165 else
166 alSetError(Context, AL_INVALID_VALUE);
168 ProcessContext(Context);
171 AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
173 ALCcontext *Context;
174 ALboolean result;
176 Context = GetContextSuspended();
177 if(!Context) return AL_FALSE;
179 result = (VerifyEffectSlot(Context->EffectSlotList, effectslot) ?
180 AL_TRUE : AL_FALSE);
182 ProcessContext(Context);
184 return result;
187 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
189 ALCcontext *Context;
190 ALboolean updateSources = AL_FALSE;
191 ALeffectslot *EffectSlot;
193 Context = GetContextSuspended();
194 if(!Context) return;
196 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslot)) != NULL)
198 switch(param)
200 case AL_EFFECTSLOT_EFFECT: {
201 ALeffect *effect = NULL;
203 if(iValue == 0 ||
204 (effect=VerifyEffect(Context->Device->EffectList, iValue)) != NULL)
206 InitializeEffect(Context, EffectSlot, effect);
207 updateSources = AL_TRUE;
209 else
210 alSetError(Context, AL_INVALID_VALUE);
211 } break;
213 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
214 if(iValue == AL_TRUE || iValue == AL_FALSE)
216 EffectSlot->AuxSendAuto = iValue;
217 updateSources = AL_TRUE;
219 else
220 alSetError(Context, AL_INVALID_VALUE);
221 break;
223 default:
224 alSetError(Context, AL_INVALID_ENUM);
225 break;
228 else
229 alSetError(Context, AL_INVALID_NAME);
231 // Force updating the sources that use this slot, since it affects the
232 // sending parameters
233 if(updateSources)
235 ALsource *source = Context->SourceList;
236 while(source)
238 ALuint i;
239 for(i = 0;i < MAX_SENDS;i++)
241 if(!source->Send[i].Slot ||
242 source->Send[i].Slot->effectslot != effectslot)
243 continue;
244 source->NeedsUpdate = AL_TRUE;
245 break;
247 source = source->next;
251 ProcessContext(Context);
254 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
256 ALCcontext *Context;
258 Context = GetContextSuspended();
259 if(!Context) return;
261 if(VerifyEffectSlot(Context->EffectSlotList, effectslot) != NULL)
263 switch(param)
265 case AL_EFFECTSLOT_EFFECT:
266 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
267 alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
268 break;
270 default:
271 alSetError(Context, AL_INVALID_ENUM);
272 break;
275 else
276 alSetError(Context, AL_INVALID_NAME);
278 ProcessContext(Context);
281 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue)
283 ALCcontext *Context;
284 ALeffectslot *EffectSlot;
286 Context = GetContextSuspended();
287 if(!Context) return;
289 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslot)) != NULL)
291 switch(param)
293 case AL_EFFECTSLOT_GAIN:
294 if(flValue >= 0.0f && flValue <= 1.0f)
295 EffectSlot->Gain = flValue;
296 else
297 alSetError(Context, AL_INVALID_VALUE);
298 break;
300 default:
301 alSetError(Context, AL_INVALID_ENUM);
302 break;
305 else
306 alSetError(Context, AL_INVALID_NAME);
308 ProcessContext(Context);
311 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
313 ALCcontext *Context;
315 Context = GetContextSuspended();
316 if(!Context) return;
318 if(VerifyEffectSlot(Context->EffectSlotList, effectslot) != NULL)
320 switch(param)
322 case AL_EFFECTSLOT_GAIN:
323 alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
324 break;
326 default:
327 alSetError(Context, AL_INVALID_ENUM);
328 break;
331 else
332 alSetError(Context, AL_INVALID_NAME);
334 ProcessContext(Context);
337 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
339 ALCcontext *Context;
340 ALeffectslot *EffectSlot;
342 Context = GetContextSuspended();
343 if(!Context) return;
345 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslot)) != NULL)
347 switch(param)
349 case AL_EFFECTSLOT_EFFECT:
350 *piValue = EffectSlot->effect.effect;
351 break;
353 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
354 *piValue = EffectSlot->AuxSendAuto;
355 break;
357 default:
358 alSetError(Context, AL_INVALID_ENUM);
359 break;
362 else
363 alSetError(Context, AL_INVALID_NAME);
365 ProcessContext(Context);
368 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
370 ALCcontext *Context;
372 Context = GetContextSuspended();
373 if(!Context) return;
375 if(VerifyEffectSlot(Context->EffectSlotList, effectslot) != NULL)
377 switch(param)
379 case AL_EFFECTSLOT_EFFECT:
380 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
381 alGetAuxiliaryEffectSloti(effectslot, param, piValues);
382 break;
384 default:
385 alSetError(Context, AL_INVALID_ENUM);
386 break;
389 else
390 alSetError(Context, AL_INVALID_NAME);
392 ProcessContext(Context);
395 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
397 ALCcontext *Context;
398 ALeffectslot *EffectSlot;
400 Context = GetContextSuspended();
401 if(!Context) return;
403 if((EffectSlot=VerifyEffectSlot(Context->EffectSlotList, effectslot)) != NULL)
405 switch(param)
407 case AL_EFFECTSLOT_GAIN:
408 *pflValue = EffectSlot->Gain;
409 break;
411 default:
412 alSetError(Context, AL_INVALID_ENUM);
413 break;
416 else
417 alSetError(Context, AL_INVALID_NAME);
419 ProcessContext(Context);
422 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
424 ALCcontext *Context;
426 Context = GetContextSuspended();
427 if(!Context) return;
429 if(VerifyEffectSlot(Context->EffectSlotList, effectslot) != NULL)
431 switch(param)
433 case AL_EFFECTSLOT_GAIN:
434 alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
435 break;
437 default:
438 alSetError(Context, AL_INVALID_ENUM);
439 break;
442 else
443 alSetError(Context, AL_INVALID_NAME);
445 ProcessContext(Context);
449 static ALvoid NoneDestroy(ALeffectState *State)
450 { free(State); }
451 static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
453 return AL_TRUE;
454 (void)State;
455 (void)Device;
457 static ALvoid NoneUpdate(ALeffectState *State, ALCcontext *Context, const ALeffect *Effect)
459 (void)State;
460 (void)Context;
461 (void)Effect;
463 static ALvoid NoneProcess(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
465 (void)State;
466 (void)Slot;
467 (void)SamplesToDo;
468 (void)SamplesIn;
469 (void)SamplesOut;
471 ALeffectState *NoneCreate(void)
473 ALeffectState *state;
475 state = calloc(1, sizeof(*state));
476 if(!state)
477 return NULL;
479 state->Destroy = NoneDestroy;
480 state->DeviceUpdate = NoneDeviceUpdate;
481 state->Update = NoneUpdate;
482 state->Process = NoneProcess;
484 return state;
487 static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
489 if(EffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))
491 ALeffectState *NewState = NULL;
492 if(!effect || effect->type == AL_EFFECT_NULL)
493 NewState = NoneCreate();
494 else if(effect->type == AL_EFFECT_EAXREVERB)
495 NewState = EAXVerbCreate();
496 else if(effect->type == AL_EFFECT_REVERB)
497 NewState = VerbCreate();
498 else if(effect->type == AL_EFFECT_ECHO)
499 NewState = EchoCreate();
500 /* No new state? An error occured.. */
501 if(NewState == NULL ||
502 ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE)
504 if(NewState)
505 ALEffect_Destroy(NewState);
506 alSetError(Context, AL_OUT_OF_MEMORY);
507 return;
509 if(EffectSlot->EffectState)
510 ALEffect_Destroy(EffectSlot->EffectState);
511 EffectSlot->EffectState = NewState;
513 if(!effect)
514 memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
515 else
516 memcpy(&EffectSlot->effect, effect, sizeof(*effect));
517 ALEffect_Update(EffectSlot->EffectState, Context, effect);
521 ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
523 while(Context->EffectSlotList)
525 ALeffectslot *temp = Context->EffectSlotList;
526 Context->EffectSlotList = temp->next;
528 // Release effectslot structure
529 ALEffect_Destroy(temp->EffectState);
531 ALTHUNK_REMOVEENTRY(temp->effectslot);
532 memset(temp, 0, sizeof(ALeffectslot));
533 free(temp);
535 Context->EffectSlotCount = 0;