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"
34 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
);
37 ALvoid AL_APIENTRY
alGenAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
42 Context
= GetContextSuspended();
47 ALCdevice
*Device
= Context
->Device
;
49 if(Context
->AuxiliaryEffectSlotCount
+n
<= Device
->AuxiliaryEffectSlotMax
)
51 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
52 if (!IsBadWritePtr((void*)effectslots
, n
* sizeof(ALuint
)))
54 ALeffectslot
**list
= &Context
->AuxiliaryEffectSlot
;
56 list
= &(*list
)->next
;
61 *list
= calloc(1, sizeof(ALeffectslot
));
64 // We must have run out or memory
65 alDeleteAuxiliaryEffectSlots(i
, effectslots
);
66 alSetError(AL_OUT_OF_MEMORY
);
71 (*list
)->AuxSendAuto
= AL_TRUE
;
72 for(j
= 0;j
< BUFFERSIZE
;j
++)
73 (*list
)->WetBuffer
[j
] = 0.0f
;
74 (*list
)->refcount
= 0;
76 effectslots
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
77 (*list
)->effectslot
= effectslots
[i
];
79 Context
->AuxiliaryEffectSlotCount
++;
82 list
= &(*list
)->next
;
87 alSetError(AL_INVALID_OPERATION
);
90 ProcessContext(Context
);
93 ALvoid AL_APIENTRY
alDeleteAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
96 ALeffectslot
*ALAuxiliaryEffectSlot
;
99 Context
= GetContextSuspended();
104 // Check that all effectslots are valid
105 for (i
= 0; i
< n
; i
++)
107 if (!alIsAuxiliaryEffectSlot(effectslots
[i
]))
109 alSetError(AL_INVALID_NAME
);
114 ALAuxiliaryEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]);
115 if(ALAuxiliaryEffectSlot
->refcount
> 0)
117 alSetError(AL_INVALID_NAME
);
125 // All effectslots are valid
126 for (i
= 0; i
< n
; i
++)
128 // Recheck that the effectslot is valid, because there could be duplicated names
129 if (alIsAuxiliaryEffectSlot(effectslots
[i
]))
133 ALAuxiliaryEffectSlot
= ((ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]));
135 // Remove Source from list of Sources
136 list
= &Context
->AuxiliaryEffectSlot
;
137 while(*list
&& *list
!= ALAuxiliaryEffectSlot
)
138 list
= &(*list
)->next
;
141 *list
= (*list
)->next
;
142 ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot
->effectslot
);
144 if(ALAuxiliaryEffectSlot
->EffectState
)
145 ALEffect_Destroy(ALAuxiliaryEffectSlot
->EffectState
);
147 memset(ALAuxiliaryEffectSlot
, 0, sizeof(ALeffectslot
));
148 free(ALAuxiliaryEffectSlot
);
150 Context
->AuxiliaryEffectSlotCount
--;
156 alSetError(AL_INVALID_VALUE
);
158 ProcessContext(Context
);
161 ALboolean AL_APIENTRY
alIsAuxiliaryEffectSlot(ALuint effectslot
)
166 Context
= GetContextSuspended();
167 if(!Context
) return AL_FALSE
;
169 list
= &Context
->AuxiliaryEffectSlot
;
170 while(*list
&& (*list
)->effectslot
!= effectslot
)
171 list
= &(*list
)->next
;
173 ProcessContext(Context
);
175 return (*list
? AL_TRUE
: AL_FALSE
);
178 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
182 Context
= GetContextSuspended();
185 if (alIsAuxiliaryEffectSlot(effectslot
))
187 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
191 case AL_EFFECTSLOT_EFFECT
:
192 if(alIsEffect(iValue
))
194 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
195 InitializeEffect(Context
, ALEffectSlot
, effect
);
198 alSetError(AL_INVALID_VALUE
);
201 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
202 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
203 ALEffectSlot
->AuxSendAuto
= iValue
;
205 alSetError(AL_INVALID_VALUE
);
209 alSetError(AL_INVALID_ENUM
);
214 alSetError(AL_INVALID_NAME
);
216 ProcessContext(Context
);
219 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
223 Context
= GetContextSuspended();
226 if (alIsAuxiliaryEffectSlot(effectslot
))
230 case AL_EFFECTSLOT_EFFECT
:
231 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
232 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
236 alSetError(AL_INVALID_ENUM
);
241 alSetError(AL_INVALID_NAME
);
243 ProcessContext(Context
);
246 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
250 Context
= GetContextSuspended();
253 if (alIsAuxiliaryEffectSlot(effectslot
))
255 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
259 case AL_EFFECTSLOT_GAIN
:
260 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
261 ALEffectSlot
->Gain
= flValue
;
263 alSetError(AL_INVALID_VALUE
);
267 alSetError(AL_INVALID_ENUM
);
272 alSetError(AL_INVALID_NAME
);
274 ProcessContext(Context
);
277 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
281 Context
= GetContextSuspended();
284 if (alIsAuxiliaryEffectSlot(effectslot
))
288 case AL_EFFECTSLOT_GAIN
:
289 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
293 alSetError(AL_INVALID_ENUM
);
298 alSetError(AL_INVALID_NAME
);
300 ProcessContext(Context
);
303 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
307 Context
= GetContextSuspended();
310 if (alIsAuxiliaryEffectSlot(effectslot
))
312 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
316 case AL_EFFECTSLOT_EFFECT
:
317 *piValue
= ALEffectSlot
->effect
.effect
;
320 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
321 *piValue
= ALEffectSlot
->AuxSendAuto
;
325 alSetError(AL_INVALID_ENUM
);
330 alSetError(AL_INVALID_NAME
);
332 ProcessContext(Context
);
335 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
339 Context
= GetContextSuspended();
342 if (alIsAuxiliaryEffectSlot(effectslot
))
346 case AL_EFFECTSLOT_EFFECT
:
347 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
348 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
352 alSetError(AL_INVALID_ENUM
);
357 alSetError(AL_INVALID_NAME
);
359 ProcessContext(Context
);
362 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
366 Context
= GetContextSuspended();
369 if (alIsAuxiliaryEffectSlot(effectslot
))
371 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
375 case AL_EFFECTSLOT_GAIN
:
376 *pflValue
= ALEffectSlot
->Gain
;
380 alSetError(AL_INVALID_ENUM
);
385 alSetError(AL_INVALID_NAME
);
387 ProcessContext(Context
);
390 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
394 Context
= GetContextSuspended();
397 if (alIsAuxiliaryEffectSlot(effectslot
))
401 case AL_EFFECTSLOT_GAIN
:
402 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
406 alSetError(AL_INVALID_ENUM
);
411 alSetError(AL_INVALID_NAME
);
413 ProcessContext(Context
);
417 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
419 if((!effect
) || (effect
->type
!= ALEffectSlot
->effect
.type
))
421 ALeffectState
*NewState
= NULL
;
424 if(effect
->type
== AL_EFFECT_EAXREVERB
)
425 NewState
= EAXVerbCreate();
426 else if(effect
->type
== AL_EFFECT_REVERB
)
427 NewState
= VerbCreate();
428 else if(effect
->type
== AL_EFFECT_ECHO
)
429 NewState
= EchoCreate();
430 /* No new state? An error occured.. */
431 if(NewState
== NULL
||
432 ALEffect_DeviceUpdate(NewState
, Context
->Device
) == AL_FALSE
)
435 ALEffect_Destroy(NewState
);
439 if(ALEffectSlot
->EffectState
)
440 ALEffect_Destroy(ALEffectSlot
->EffectState
);
441 ALEffectSlot
->EffectState
= NewState
;
445 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
448 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
449 ALEffect_Update(ALEffectSlot
->EffectState
, Context
, effect
);
453 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
455 while(Context
->AuxiliaryEffectSlot
)
457 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
458 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
460 // Release effectslot structure
461 if(temp
->EffectState
)
462 ALEffect_Destroy(temp
->EffectState
);
463 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
465 memset(temp
, 0, sizeof(ALeffectslot
));
468 Context
->AuxiliaryEffectSlotCount
= 0;