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 ALCdevice
*Device
= alcGetContextsDevice(Context
);
54 if(Context
->AuxiliaryEffectSlotCount
+n
<= Device
->AuxiliaryEffectSlotMax
)
56 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
57 if (!IsBadWritePtr((void*)effectslots
, n
* sizeof(ALuint
)))
59 ALeffectslot
**list
= &Context
->AuxiliaryEffectSlot
;
61 list
= &(*list
)->next
;
66 *list
= calloc(1, sizeof(ALeffectslot
));
69 // We must have run out or memory
70 alDeleteAuxiliaryEffectSlots(i
, effectslots
);
71 alSetError(AL_OUT_OF_MEMORY
);
76 (*list
)->AuxSendAuto
= AL_TRUE
;
77 for(j
= 0;j
< BUFFERSIZE
;j
++)
78 (*list
)->WetBuffer
[j
] = 0.0f
;
79 (*list
)->refcount
= 0;
81 effectslots
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
82 (*list
)->effectslot
= effectslots
[i
];
84 Context
->AuxiliaryEffectSlotCount
++;
87 list
= &(*list
)->next
;
92 alSetError(AL_INVALID_OPERATION
);
95 ProcessContext(Context
);
98 ALvoid AL_APIENTRY
alDeleteAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
101 ALeffectslot
*ALAuxiliaryEffectSlot
;
104 Context
= alcGetCurrentContext();
107 alSetError(AL_INVALID_OPERATION
);
110 SuspendContext(Context
);
114 // Check that all effectslots are valid
115 for (i
= 0; i
< n
; i
++)
117 if (!alIsAuxiliaryEffectSlot(effectslots
[i
]))
119 alSetError(AL_INVALID_NAME
);
124 ALAuxiliaryEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]);
125 if(ALAuxiliaryEffectSlot
->refcount
> 0)
127 alSetError(AL_INVALID_NAME
);
135 // All effectslots are valid
136 for (i
= 0; i
< n
; i
++)
138 // Recheck that the effectslot is valid, because there could be duplicated names
139 if (alIsAuxiliaryEffectSlot(effectslots
[i
]))
143 ALAuxiliaryEffectSlot
= ((ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]));
145 // Remove Source from list of Sources
146 list
= &Context
->AuxiliaryEffectSlot
;
147 while(*list
&& *list
!= ALAuxiliaryEffectSlot
)
148 list
= &(*list
)->next
;
151 *list
= (*list
)->next
;
152 ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot
->effectslot
);
154 if(ALAuxiliaryEffectSlot
->EffectState
)
155 ALEffect_Destroy(ALAuxiliaryEffectSlot
->EffectState
);
157 memset(ALAuxiliaryEffectSlot
, 0, sizeof(ALeffectslot
));
158 free(ALAuxiliaryEffectSlot
);
160 Context
->AuxiliaryEffectSlotCount
--;
166 alSetError(AL_INVALID_VALUE
);
168 ProcessContext(Context
);
171 ALboolean AL_APIENTRY
alIsAuxiliaryEffectSlot(ALuint effectslot
)
176 Context
= alcGetCurrentContext();
179 alSetError(AL_INVALID_OPERATION
);
182 SuspendContext(Context
);
184 list
= &Context
->AuxiliaryEffectSlot
;
185 while(*list
&& (*list
)->effectslot
!= effectslot
)
186 list
= &(*list
)->next
;
188 ProcessContext(Context
);
190 return (*list
? AL_TRUE
: AL_FALSE
);
193 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
197 Context
= alcGetCurrentContext();
200 alSetError(AL_INVALID_OPERATION
);
203 SuspendContext(Context
);
205 if (alIsAuxiliaryEffectSlot(effectslot
))
207 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
211 case AL_EFFECTSLOT_EFFECT
:
212 if(alIsEffect(iValue
))
214 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
215 InitializeEffect(Context
, ALEffectSlot
, effect
);
218 alSetError(AL_INVALID_VALUE
);
221 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
222 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
223 ALEffectSlot
->AuxSendAuto
= iValue
;
225 alSetError(AL_INVALID_VALUE
);
229 alSetError(AL_INVALID_ENUM
);
234 alSetError(AL_INVALID_NAME
);
236 ProcessContext(Context
);
239 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
243 Context
= alcGetCurrentContext();
246 alSetError(AL_INVALID_OPERATION
);
249 SuspendContext(Context
);
251 if (alIsAuxiliaryEffectSlot(effectslot
))
255 case AL_EFFECTSLOT_EFFECT
:
256 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
257 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
261 alSetError(AL_INVALID_ENUM
);
266 alSetError(AL_INVALID_NAME
);
268 ProcessContext(Context
);
271 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
275 Context
= alcGetCurrentContext();
278 alSetError(AL_INVALID_OPERATION
);
281 SuspendContext(Context
);
283 if (alIsAuxiliaryEffectSlot(effectslot
))
285 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
289 case AL_EFFECTSLOT_GAIN
:
290 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
291 ALEffectSlot
->Gain
= flValue
;
293 alSetError(AL_INVALID_VALUE
);
297 alSetError(AL_INVALID_ENUM
);
302 alSetError(AL_INVALID_NAME
);
304 ProcessContext(Context
);
307 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
311 Context
= alcGetCurrentContext();
314 alSetError(AL_INVALID_OPERATION
);
317 SuspendContext(Context
);
319 if (alIsAuxiliaryEffectSlot(effectslot
))
323 case AL_EFFECTSLOT_GAIN
:
324 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
328 alSetError(AL_INVALID_ENUM
);
333 alSetError(AL_INVALID_NAME
);
335 ProcessContext(Context
);
338 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
342 Context
= alcGetCurrentContext();
345 alSetError(AL_INVALID_OPERATION
);
348 SuspendContext(Context
);
350 if (alIsAuxiliaryEffectSlot(effectslot
))
352 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
356 case AL_EFFECTSLOT_EFFECT
:
357 *piValue
= ALEffectSlot
->effect
.effect
;
360 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
361 *piValue
= ALEffectSlot
->AuxSendAuto
;
365 alSetError(AL_INVALID_ENUM
);
370 alSetError(AL_INVALID_NAME
);
372 ProcessContext(Context
);
375 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
379 Context
= alcGetCurrentContext();
382 alSetError(AL_INVALID_OPERATION
);
385 SuspendContext(Context
);
387 if (alIsAuxiliaryEffectSlot(effectslot
))
391 case AL_EFFECTSLOT_EFFECT
:
392 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
393 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
397 alSetError(AL_INVALID_ENUM
);
402 alSetError(AL_INVALID_NAME
);
404 ProcessContext(Context
);
407 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
411 Context
= alcGetCurrentContext();
414 alSetError(AL_INVALID_OPERATION
);
417 SuspendContext(Context
);
419 if (alIsAuxiliaryEffectSlot(effectslot
))
421 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
425 case AL_EFFECTSLOT_GAIN
:
426 *pflValue
= ALEffectSlot
->Gain
;
430 alSetError(AL_INVALID_ENUM
);
435 alSetError(AL_INVALID_NAME
);
437 ProcessContext(Context
);
440 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
444 Context
= alcGetCurrentContext();
447 alSetError(AL_INVALID_OPERATION
);
450 SuspendContext(Context
);
452 if (alIsAuxiliaryEffectSlot(effectslot
))
456 case AL_EFFECTSLOT_GAIN
:
457 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
461 alSetError(AL_INVALID_ENUM
);
466 alSetError(AL_INVALID_NAME
);
468 ProcessContext(Context
);
472 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
474 if((!effect
) || (effect
->type
!= ALEffectSlot
->effect
.type
))
476 ALeffectState
*NewState
= NULL
;
479 if(effect
->type
== AL_EFFECT_EAXREVERB
)
480 NewState
= EAXVerbCreate(Context
);
481 else if(effect
->type
== AL_EFFECT_REVERB
)
482 NewState
= VerbCreate(Context
);
483 else if(effect
->type
== AL_EFFECT_ECHO
)
484 NewState
= EchoCreate(Context
);
485 /* No new state? An error occured.. */
489 if(ALEffectSlot
->EffectState
)
490 ALEffect_Destroy(ALEffectSlot
->EffectState
);
491 ALEffectSlot
->EffectState
= NewState
;
495 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
498 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
499 ALEffect_Update(ALEffectSlot
->EffectState
, Context
, effect
);
503 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
506 if(Context
->AuxiliaryEffectSlotCount
> 0)
507 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context
->AuxiliaryEffectSlotCount
);
510 while(Context
->AuxiliaryEffectSlot
)
512 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
513 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
515 // Release effectslot structure
516 if(temp
->EffectState
)
517 ALEffect_Destroy(temp
->EffectState
);
518 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
520 memset(temp
, 0, sizeof(ALeffectslot
));
523 Context
->AuxiliaryEffectSlotCount
= 0;