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
= alcGetCurrentContext();
45 alSetError(AL_INVALID_OPERATION
);
48 SuspendContext(Context
);
52 if(Context
->AuxiliaryEffectSlotCount
+n
<= Context
->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
**list
= &Context
->AuxiliaryEffectSlot
;
59 list
= &(*list
)->next
;
64 *list
= calloc(1, sizeof(ALeffectslot
));
67 // We must have run out or memory
68 alDeleteAuxiliaryEffectSlots(i
, effectslots
);
69 alSetError(AL_OUT_OF_MEMORY
);
74 (*list
)->AuxSendAuto
= AL_TRUE
;
75 for(j
= 0;j
< BUFFERSIZE
;j
++)
76 (*list
)->WetBuffer
[j
] = 0.0f
;
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 if(ALAuxiliaryEffectSlot
->EffectState
)
153 ALEffect_Destroy(ALAuxiliaryEffectSlot
->EffectState
);
155 memset(ALAuxiliaryEffectSlot
, 0, sizeof(ALeffectslot
));
156 free(ALAuxiliaryEffectSlot
);
158 Context
->AuxiliaryEffectSlotCount
--;
164 alSetError(AL_INVALID_VALUE
);
166 ProcessContext(Context
);
169 ALboolean AL_APIENTRY
alIsAuxiliaryEffectSlot(ALuint effectslot
)
174 Context
= alcGetCurrentContext();
177 alSetError(AL_INVALID_OPERATION
);
180 SuspendContext(Context
);
182 list
= &Context
->AuxiliaryEffectSlot
;
183 while(*list
&& (*list
)->effectslot
!= effectslot
)
184 list
= &(*list
)->next
;
186 ProcessContext(Context
);
188 return (*list
? AL_TRUE
: AL_FALSE
);
191 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
195 Context
= alcGetCurrentContext();
198 alSetError(AL_INVALID_OPERATION
);
201 SuspendContext(Context
);
203 if (alIsAuxiliaryEffectSlot(effectslot
))
205 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
209 case AL_EFFECTSLOT_EFFECT
:
210 if(alIsEffect(iValue
))
212 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
213 InitializeEffect(Context
, ALEffectSlot
, effect
);
216 alSetError(AL_INVALID_VALUE
);
219 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
220 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
221 ALEffectSlot
->AuxSendAuto
= iValue
;
223 alSetError(AL_INVALID_VALUE
);
227 alSetError(AL_INVALID_ENUM
);
232 alSetError(AL_INVALID_NAME
);
234 ProcessContext(Context
);
237 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
241 Context
= alcGetCurrentContext();
244 alSetError(AL_INVALID_OPERATION
);
247 SuspendContext(Context
);
249 if (alIsAuxiliaryEffectSlot(effectslot
))
253 case AL_EFFECTSLOT_EFFECT
:
254 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
255 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
259 alSetError(AL_INVALID_ENUM
);
264 alSetError(AL_INVALID_NAME
);
266 ProcessContext(Context
);
269 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
273 Context
= alcGetCurrentContext();
276 alSetError(AL_INVALID_OPERATION
);
279 SuspendContext(Context
);
281 if (alIsAuxiliaryEffectSlot(effectslot
))
283 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
287 case AL_EFFECTSLOT_GAIN
:
288 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
289 ALEffectSlot
->Gain
= flValue
;
291 alSetError(AL_INVALID_VALUE
);
295 alSetError(AL_INVALID_ENUM
);
300 alSetError(AL_INVALID_NAME
);
302 ProcessContext(Context
);
305 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
309 Context
= alcGetCurrentContext();
312 alSetError(AL_INVALID_OPERATION
);
315 SuspendContext(Context
);
317 if (alIsAuxiliaryEffectSlot(effectslot
))
321 case AL_EFFECTSLOT_GAIN
:
322 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
326 alSetError(AL_INVALID_ENUM
);
331 alSetError(AL_INVALID_NAME
);
333 ProcessContext(Context
);
336 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
340 Context
= alcGetCurrentContext();
343 alSetError(AL_INVALID_OPERATION
);
346 SuspendContext(Context
);
348 if (alIsAuxiliaryEffectSlot(effectslot
))
350 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
354 case AL_EFFECTSLOT_EFFECT
:
355 *piValue
= ALEffectSlot
->effect
.effect
;
358 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
359 *piValue
= ALEffectSlot
->AuxSendAuto
;
363 alSetError(AL_INVALID_ENUM
);
368 alSetError(AL_INVALID_NAME
);
370 ProcessContext(Context
);
373 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
377 Context
= alcGetCurrentContext();
380 alSetError(AL_INVALID_OPERATION
);
383 SuspendContext(Context
);
385 if (alIsAuxiliaryEffectSlot(effectslot
))
389 case AL_EFFECTSLOT_EFFECT
:
390 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
391 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
395 alSetError(AL_INVALID_ENUM
);
400 alSetError(AL_INVALID_NAME
);
402 ProcessContext(Context
);
405 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
409 Context
= alcGetCurrentContext();
412 alSetError(AL_INVALID_OPERATION
);
415 SuspendContext(Context
);
417 if (alIsAuxiliaryEffectSlot(effectslot
))
419 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
423 case AL_EFFECTSLOT_GAIN
:
424 *pflValue
= ALEffectSlot
->Gain
;
428 alSetError(AL_INVALID_ENUM
);
433 alSetError(AL_INVALID_NAME
);
435 ProcessContext(Context
);
438 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
442 Context
= alcGetCurrentContext();
445 alSetError(AL_INVALID_OPERATION
);
448 SuspendContext(Context
);
450 if (alIsAuxiliaryEffectSlot(effectslot
))
454 case AL_EFFECTSLOT_GAIN
:
455 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
459 alSetError(AL_INVALID_ENUM
);
464 alSetError(AL_INVALID_NAME
);
466 ProcessContext(Context
);
470 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
472 if((!effect
) || (effect
->type
!= ALEffectSlot
->effect
.type
))
474 ALeffectState
*NewState
= NULL
;
477 if(effect
->type
== AL_EFFECT_EAXREVERB
)
478 NewState
= EAXVerbCreate(Context
);
479 else if(effect
->type
== AL_EFFECT_REVERB
)
480 NewState
= VerbCreate(Context
);
481 else if(effect
->type
== AL_EFFECT_ECHO
)
482 NewState
= EchoCreate(Context
);
483 /* No new state? An error occured.. */
487 if(ALEffectSlot
->EffectState
)
488 ALEffect_Destroy(ALEffectSlot
->EffectState
);
489 ALEffectSlot
->EffectState
= NewState
;
493 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
496 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
497 ALEffect_Update(ALEffectSlot
->EffectState
, Context
, effect
);
501 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
504 if(Context
->AuxiliaryEffectSlotCount
> 0)
505 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context
->AuxiliaryEffectSlotCount
);
508 while(Context
->AuxiliaryEffectSlot
)
510 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
511 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
513 // Release effectslot structure
514 if(temp
->EffectState
)
515 ALEffect_Destroy(temp
->EffectState
);
516 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
518 memset(temp
, 0, sizeof(ALeffectslot
));
521 Context
->AuxiliaryEffectSlotCount
= 0;