Removed project files that are generated by "android update project" step.
[openal-soft/android.git] / OpenAL32 / alAuxEffectSlot.c
blobe8a76d3546e8917e350fc12c74c7643ab24a660c
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 #define LookupEffectSlot(m, k) ((ALeffectslot*)LookupUIntMapKey(&(m), (k)))
38 #define LookupEffect(m, k) ((ALeffect*)LookupUIntMapKey(&(m), (k)))
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->EffectSlotMap.size+n <= (ALsizei)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 ALenum err;
59 while(i < n)
61 ALeffectslot *slot = calloc(1, sizeof(ALeffectslot));
62 if(!slot || !(slot->EffectState=NoneCreate()))
64 free(slot);
65 // We must have run out or memory
66 alSetError(Context, AL_OUT_OF_MEMORY);
67 alDeleteAuxiliaryEffectSlots(i, effectslots);
68 break;
71 slot->effectslot = (ALuint)ALTHUNK_ADDENTRY(slot);
72 err = InsertUIntMapEntry(&Context->EffectSlotMap,
73 slot->effectslot, slot);
74 if(err != AL_NO_ERROR)
76 ALTHUNK_REMOVEENTRY(slot->effectslot);
77 ALEffect_Destroy(slot->EffectState);
78 free(slot);
80 alSetError(Context, err);
81 alDeleteAuxiliaryEffectSlots(i, effectslots);
82 break;
85 effectslots[i++] = slot->effectslot;
87 slot->Gain = 1.0;
88 slot->AuxSendAuto = AL_TRUE;
89 for(j = 0;j < BUFFERSIZE;j++)
90 slot->WetBuffer[j] = 0.0f;
91 slot->refcount = 0;
95 else
96 alSetError(Context, AL_INVALID_OPERATION);
99 ProcessContext(Context);
102 AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
104 ALCcontext *Context;
105 ALeffectslot *EffectSlot;
106 ALsizei i;
108 Context = GetContextSuspended();
109 if(!Context) return;
111 if (n >= 0)
113 // Check that all effectslots are valid
114 for (i = 0; i < n; i++)
116 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
118 alSetError(Context, AL_INVALID_NAME);
119 break;
121 else
123 if(EffectSlot->refcount > 0)
125 alSetError(Context, AL_INVALID_NAME);
126 break;
131 if (i == n)
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((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) != NULL)
139 ALEffect_Destroy(EffectSlot->EffectState);
141 RemoveUIntMapKey(&Context->EffectSlotMap, EffectSlot->effectslot);
142 ALTHUNK_REMOVEENTRY(EffectSlot->effectslot);
144 memset(EffectSlot, 0, sizeof(ALeffectslot));
145 free(EffectSlot);
150 else
151 alSetError(Context, AL_INVALID_VALUE);
153 ProcessContext(Context);
156 AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
158 ALCcontext *Context;
159 ALboolean result;
161 Context = GetContextSuspended();
162 if(!Context) return AL_FALSE;
164 result = (LookupEffectSlot(Context->EffectSlotMap, effectslot) ?
165 AL_TRUE : AL_FALSE);
167 ProcessContext(Context);
169 return result;
172 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
174 ALCcontext *Context;
175 ALboolean updateSources = AL_FALSE;
176 ALeffectslot *EffectSlot;
178 Context = GetContextSuspended();
179 if(!Context) return;
181 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
183 switch(param)
185 case AL_EFFECTSLOT_EFFECT: {
186 ALeffect *effect = NULL;
188 if(iValue == 0 ||
189 (effect=LookupEffect(Context->Device->EffectMap, iValue)) != NULL)
191 InitializeEffect(Context, EffectSlot, effect);
192 updateSources = AL_TRUE;
194 else
195 alSetError(Context, AL_INVALID_VALUE);
196 } break;
198 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
199 if(iValue == AL_TRUE || iValue == AL_FALSE)
201 EffectSlot->AuxSendAuto = iValue;
202 updateSources = AL_TRUE;
204 else
205 alSetError(Context, AL_INVALID_VALUE);
206 break;
208 default:
209 alSetError(Context, AL_INVALID_ENUM);
210 break;
213 else
214 alSetError(Context, AL_INVALID_NAME);
216 // Force updating the sources that use this slot, since it affects the
217 // sending parameters
218 if(updateSources)
220 ALsizei pos;
221 for(pos = 0;pos < Context->SourceMap.size;pos++)
223 ALsource *source = Context->SourceMap.array[pos].value;
224 ALuint i;
225 for(i = 0;i < MAX_SENDS;i++)
227 if(!source->Send[i].Slot ||
228 source->Send[i].Slot->effectslot != effectslot)
229 continue;
230 source->NeedsUpdate = AL_TRUE;
231 break;
236 ProcessContext(Context);
239 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
241 ALCcontext *Context;
243 Context = GetContextSuspended();
244 if(!Context) return;
246 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
248 switch(param)
250 case AL_EFFECTSLOT_EFFECT:
251 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
252 alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
253 break;
255 default:
256 alSetError(Context, AL_INVALID_ENUM);
257 break;
260 else
261 alSetError(Context, AL_INVALID_NAME);
263 ProcessContext(Context);
266 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue)
268 ALCcontext *Context;
269 ALeffectslot *EffectSlot;
271 Context = GetContextSuspended();
272 if(!Context) return;
274 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
276 switch(param)
278 case AL_EFFECTSLOT_GAIN:
279 if(flValue >= 0.0f && flValue <= 1.0f)
280 EffectSlot->Gain = flValue;
281 else
282 alSetError(Context, AL_INVALID_VALUE);
283 break;
285 default:
286 alSetError(Context, AL_INVALID_ENUM);
287 break;
290 else
291 alSetError(Context, AL_INVALID_NAME);
293 ProcessContext(Context);
296 AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
298 ALCcontext *Context;
300 Context = GetContextSuspended();
301 if(!Context) return;
303 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
305 switch(param)
307 case AL_EFFECTSLOT_GAIN:
308 alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
309 break;
311 default:
312 alSetError(Context, AL_INVALID_ENUM);
313 break;
316 else
317 alSetError(Context, AL_INVALID_NAME);
319 ProcessContext(Context);
322 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
324 ALCcontext *Context;
325 ALeffectslot *EffectSlot;
327 Context = GetContextSuspended();
328 if(!Context) return;
330 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
332 switch(param)
334 case AL_EFFECTSLOT_EFFECT:
335 *piValue = EffectSlot->effect.effect;
336 break;
338 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
339 *piValue = EffectSlot->AuxSendAuto;
340 break;
342 default:
343 alSetError(Context, AL_INVALID_ENUM);
344 break;
347 else
348 alSetError(Context, AL_INVALID_NAME);
350 ProcessContext(Context);
353 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
355 ALCcontext *Context;
357 Context = GetContextSuspended();
358 if(!Context) return;
360 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
362 switch(param)
364 case AL_EFFECTSLOT_EFFECT:
365 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
366 alGetAuxiliaryEffectSloti(effectslot, param, piValues);
367 break;
369 default:
370 alSetError(Context, AL_INVALID_ENUM);
371 break;
374 else
375 alSetError(Context, AL_INVALID_NAME);
377 ProcessContext(Context);
380 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
382 ALCcontext *Context;
383 ALeffectslot *EffectSlot;
385 Context = GetContextSuspended();
386 if(!Context) return;
388 if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
390 switch(param)
392 case AL_EFFECTSLOT_GAIN:
393 *pflValue = EffectSlot->Gain;
394 break;
396 default:
397 alSetError(Context, AL_INVALID_ENUM);
398 break;
401 else
402 alSetError(Context, AL_INVALID_NAME);
404 ProcessContext(Context);
407 AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
409 ALCcontext *Context;
411 Context = GetContextSuspended();
412 if(!Context) return;
414 if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
416 switch(param)
418 case AL_EFFECTSLOT_GAIN:
419 alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
420 break;
422 default:
423 alSetError(Context, AL_INVALID_ENUM);
424 break;
427 else
428 alSetError(Context, AL_INVALID_NAME);
430 ProcessContext(Context);
434 static ALvoid NoneDestroy(ALeffectState *State)
435 { free(State); }
436 static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
438 return AL_TRUE;
439 (void)State;
440 (void)Device;
442 static ALvoid NoneUpdate(ALeffectState *State, ALCcontext *Context, const ALeffect *Effect)
444 (void)State;
445 (void)Context;
446 (void)Effect;
448 static ALvoid NoneProcess(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
450 (void)State;
451 (void)Slot;
452 (void)SamplesToDo;
453 (void)SamplesIn;
454 (void)SamplesOut;
456 ALeffectState *NoneCreate(void)
458 ALeffectState *state;
460 state = calloc(1, sizeof(*state));
461 if(!state)
462 return NULL;
464 state->Destroy = NoneDestroy;
465 state->DeviceUpdate = NoneDeviceUpdate;
466 state->Update = NoneUpdate;
467 state->Process = NoneProcess;
469 return state;
472 static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
474 if(EffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))
476 ALeffectState *NewState = NULL;
477 if(!effect || effect->type == AL_EFFECT_NULL)
478 NewState = NoneCreate();
479 else if(effect->type == AL_EFFECT_EAXREVERB)
480 NewState = EAXVerbCreate();
481 else if(effect->type == AL_EFFECT_REVERB)
482 NewState = VerbCreate();
483 else if(effect->type == AL_EFFECT_ECHO)
484 NewState = EchoCreate();
485 else if(effect->type == AL_EFFECT_RING_MODULATOR)
486 NewState = ModulatorCreate();
487 /* No new state? An error occured.. */
488 if(NewState == NULL ||
489 ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE)
491 if(NewState)
492 ALEffect_Destroy(NewState);
493 alSetError(Context, AL_OUT_OF_MEMORY);
494 return;
496 if(EffectSlot->EffectState)
497 ALEffect_Destroy(EffectSlot->EffectState);
498 EffectSlot->EffectState = NewState;
500 if(!effect)
501 memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
502 else
503 memcpy(&EffectSlot->effect, effect, sizeof(*effect));
504 ALEffect_Update(EffectSlot->EffectState, Context, effect);
508 ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
510 ALsizei pos;
511 for(pos = 0;pos < Context->EffectSlotMap.size;pos++)
513 ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
514 Context->EffectSlotMap.array[pos].value = NULL;
516 // Release effectslot structure
517 ALEffect_Destroy(temp->EffectState);
519 ALTHUNK_REMOVEENTRY(temp->effectslot);
520 memset(temp, 0, sizeof(ALeffectslot));
521 free(temp);