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();
45 alSetError(AL_INVALID_OPERATION
);
51 ALCdevice
*Device
= alcGetContextsDevice(Context
);
53 if(Context
->AuxiliaryEffectSlotCount
+n
<= Device
->AuxiliaryEffectSlotMax
)
55 // Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
56 if (!IsBadWritePtr((void*)effectslots
, n
* sizeof(ALuint
)))
58 ALeffectslot
**list
= &Context
->AuxiliaryEffectSlot
;
60 list
= &(*list
)->next
;
65 *list
= calloc(1, sizeof(ALeffectslot
));
68 // We must have run out or memory
69 alDeleteAuxiliaryEffectSlots(i
, effectslots
);
70 alSetError(AL_OUT_OF_MEMORY
);
75 (*list
)->AuxSendAuto
= AL_TRUE
;
76 for(j
= 0;j
< BUFFERSIZE
;j
++)
77 (*list
)->WetBuffer
[j
] = 0.0f
;
78 (*list
)->refcount
= 0;
80 effectslots
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
81 (*list
)->effectslot
= effectslots
[i
];
83 Context
->AuxiliaryEffectSlotCount
++;
86 list
= &(*list
)->next
;
91 alSetError(AL_INVALID_OPERATION
);
94 ProcessContext(Context
);
97 ALvoid AL_APIENTRY
alDeleteAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
100 ALeffectslot
*ALAuxiliaryEffectSlot
;
103 Context
= GetContextSuspended();
106 alSetError(AL_INVALID_OPERATION
);
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
= GetContextSuspended();
177 alSetError(AL_INVALID_OPERATION
);
181 list
= &Context
->AuxiliaryEffectSlot
;
182 while(*list
&& (*list
)->effectslot
!= effectslot
)
183 list
= &(*list
)->next
;
185 ProcessContext(Context
);
187 return (*list
? AL_TRUE
: AL_FALSE
);
190 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
194 Context
= GetContextSuspended();
197 alSetError(AL_INVALID_OPERATION
);
201 if (alIsAuxiliaryEffectSlot(effectslot
))
203 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
207 case AL_EFFECTSLOT_EFFECT
:
208 if(alIsEffect(iValue
))
210 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
211 InitializeEffect(Context
, ALEffectSlot
, effect
);
214 alSetError(AL_INVALID_VALUE
);
217 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
218 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
219 ALEffectSlot
->AuxSendAuto
= iValue
;
221 alSetError(AL_INVALID_VALUE
);
225 alSetError(AL_INVALID_ENUM
);
230 alSetError(AL_INVALID_NAME
);
232 ProcessContext(Context
);
235 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
239 Context
= GetContextSuspended();
242 alSetError(AL_INVALID_OPERATION
);
246 if (alIsAuxiliaryEffectSlot(effectslot
))
250 case AL_EFFECTSLOT_EFFECT
:
251 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
252 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
256 alSetError(AL_INVALID_ENUM
);
261 alSetError(AL_INVALID_NAME
);
263 ProcessContext(Context
);
266 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
270 Context
= GetContextSuspended();
273 alSetError(AL_INVALID_OPERATION
);
277 if (alIsAuxiliaryEffectSlot(effectslot
))
279 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
283 case AL_EFFECTSLOT_GAIN
:
284 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
285 ALEffectSlot
->Gain
= flValue
;
287 alSetError(AL_INVALID_VALUE
);
291 alSetError(AL_INVALID_ENUM
);
296 alSetError(AL_INVALID_NAME
);
298 ProcessContext(Context
);
301 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
305 Context
= GetContextSuspended();
308 alSetError(AL_INVALID_OPERATION
);
312 if (alIsAuxiliaryEffectSlot(effectslot
))
316 case AL_EFFECTSLOT_GAIN
:
317 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
321 alSetError(AL_INVALID_ENUM
);
326 alSetError(AL_INVALID_NAME
);
328 ProcessContext(Context
);
331 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
335 Context
= GetContextSuspended();
338 alSetError(AL_INVALID_OPERATION
);
342 if (alIsAuxiliaryEffectSlot(effectslot
))
344 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
348 case AL_EFFECTSLOT_EFFECT
:
349 *piValue
= ALEffectSlot
->effect
.effect
;
352 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
353 *piValue
= ALEffectSlot
->AuxSendAuto
;
357 alSetError(AL_INVALID_ENUM
);
362 alSetError(AL_INVALID_NAME
);
364 ProcessContext(Context
);
367 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
371 Context
= GetContextSuspended();
374 alSetError(AL_INVALID_OPERATION
);
378 if (alIsAuxiliaryEffectSlot(effectslot
))
382 case AL_EFFECTSLOT_EFFECT
:
383 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
384 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
388 alSetError(AL_INVALID_ENUM
);
393 alSetError(AL_INVALID_NAME
);
395 ProcessContext(Context
);
398 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
402 Context
= GetContextSuspended();
405 alSetError(AL_INVALID_OPERATION
);
409 if (alIsAuxiliaryEffectSlot(effectslot
))
411 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
415 case AL_EFFECTSLOT_GAIN
:
416 *pflValue
= ALEffectSlot
->Gain
;
420 alSetError(AL_INVALID_ENUM
);
425 alSetError(AL_INVALID_NAME
);
427 ProcessContext(Context
);
430 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
434 Context
= GetContextSuspended();
437 alSetError(AL_INVALID_OPERATION
);
441 if (alIsAuxiliaryEffectSlot(effectslot
))
445 case AL_EFFECTSLOT_GAIN
:
446 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
450 alSetError(AL_INVALID_ENUM
);
455 alSetError(AL_INVALID_NAME
);
457 ProcessContext(Context
);
461 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
463 if((!effect
) || (effect
->type
!= ALEffectSlot
->effect
.type
))
465 ALeffectState
*NewState
= NULL
;
468 if(effect
->type
== AL_EFFECT_EAXREVERB
)
469 NewState
= EAXVerbCreate(Context
);
470 else if(effect
->type
== AL_EFFECT_REVERB
)
471 NewState
= VerbCreate(Context
);
472 else if(effect
->type
== AL_EFFECT_ECHO
)
473 NewState
= EchoCreate(Context
);
474 /* No new state? An error occured.. */
478 if(ALEffectSlot
->EffectState
)
479 ALEffect_Destroy(ALEffectSlot
->EffectState
);
480 ALEffectSlot
->EffectState
= NewState
;
484 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
487 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
488 ALEffect_Update(ALEffectSlot
->EffectState
, Context
, effect
);
492 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
495 if(Context
->AuxiliaryEffectSlotCount
> 0)
496 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context
->AuxiliaryEffectSlotCount
);
499 while(Context
->AuxiliaryEffectSlot
)
501 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
502 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
504 // Release effectslot structure
505 if(temp
->EffectState
)
506 ALEffect_Destroy(temp
->EffectState
);
507 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
509 memset(temp
, 0, sizeof(ALeffectslot
));
512 Context
->AuxiliaryEffectSlotCount
= 0;