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"
35 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
);
38 ALvoid AL_APIENTRY
alGenAuxiliaryEffectSlots(ALsizei n
, ALuint
*effectslots
)
43 Context
= alcGetCurrentContext();
46 alSetError(AL_INVALID_OPERATION
);
49 SuspendContext(Context
);
53 if(Context
->AuxiliaryEffectSlotCount
+n
<= Context
->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
= alcGetCurrentContext();
106 alSetError(AL_INVALID_OPERATION
);
109 SuspendContext(Context
);
113 // Check that all effectslots are valid
114 for (i
= 0; i
< n
; i
++)
116 if (!alIsAuxiliaryEffectSlot(effectslots
[i
]))
118 alSetError(AL_INVALID_NAME
);
123 ALAuxiliaryEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]);
124 if(ALAuxiliaryEffectSlot
->refcount
> 0)
126 alSetError(AL_INVALID_NAME
);
134 // All effectslots are valid
135 for (i
= 0; i
< n
; i
++)
137 // Recheck that the effectslot is valid, because there could be duplicated names
138 if (alIsAuxiliaryEffectSlot(effectslots
[i
]))
142 ALAuxiliaryEffectSlot
= ((ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslots
[i
]));
144 // Remove Source from list of Sources
145 list
= &Context
->AuxiliaryEffectSlot
;
146 while(*list
&& *list
!= ALAuxiliaryEffectSlot
)
147 list
= &(*list
)->next
;
150 *list
= (*list
)->next
;
151 ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot
->effectslot
);
153 VerbDestroy(ALAuxiliaryEffectSlot
->ReverbState
);
154 EchoDestroy(ALAuxiliaryEffectSlot
->EchoState
);
156 memset(ALAuxiliaryEffectSlot
, 0, sizeof(ALeffectslot
));
157 free(ALAuxiliaryEffectSlot
);
159 Context
->AuxiliaryEffectSlotCount
--;
165 alSetError(AL_INVALID_VALUE
);
167 ProcessContext(Context
);
170 ALboolean AL_APIENTRY
alIsAuxiliaryEffectSlot(ALuint effectslot
)
175 Context
= alcGetCurrentContext();
178 alSetError(AL_INVALID_OPERATION
);
181 SuspendContext(Context
);
183 list
= &Context
->AuxiliaryEffectSlot
;
184 while(*list
&& (*list
)->effectslot
!= effectslot
)
185 list
= &(*list
)->next
;
187 ProcessContext(Context
);
189 return (*list
? AL_TRUE
: AL_FALSE
);
192 ALvoid AL_APIENTRY
alAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint iValue
)
196 Context
= alcGetCurrentContext();
199 alSetError(AL_INVALID_OPERATION
);
202 SuspendContext(Context
);
204 if (alIsAuxiliaryEffectSlot(effectslot
))
206 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
210 case AL_EFFECTSLOT_EFFECT
:
211 if(alIsEffect(iValue
))
213 ALeffect
*effect
= (ALeffect
*)ALTHUNK_LOOKUPENTRY(iValue
);
214 InitializeEffect(Context
, ALEffectSlot
, effect
);
217 alSetError(AL_INVALID_VALUE
);
220 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
221 if(iValue
== AL_TRUE
|| iValue
== AL_FALSE
)
222 ALEffectSlot
->AuxSendAuto
= iValue
;
224 alSetError(AL_INVALID_VALUE
);
228 alSetError(AL_INVALID_ENUM
);
233 alSetError(AL_INVALID_NAME
);
235 ProcessContext(Context
);
238 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
242 Context
= alcGetCurrentContext();
245 alSetError(AL_INVALID_OPERATION
);
248 SuspendContext(Context
);
250 if (alIsAuxiliaryEffectSlot(effectslot
))
254 case AL_EFFECTSLOT_EFFECT
:
255 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
256 alAuxiliaryEffectSloti(effectslot
, param
, piValues
[0]);
260 alSetError(AL_INVALID_ENUM
);
265 alSetError(AL_INVALID_NAME
);
267 ProcessContext(Context
);
270 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat flValue
)
274 Context
= alcGetCurrentContext();
277 alSetError(AL_INVALID_OPERATION
);
280 SuspendContext(Context
);
282 if (alIsAuxiliaryEffectSlot(effectslot
))
284 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
288 case AL_EFFECTSLOT_GAIN
:
289 if(flValue
>= 0.0f
&& flValue
<= 1.0f
)
290 ALEffectSlot
->Gain
= flValue
;
292 alSetError(AL_INVALID_VALUE
);
296 alSetError(AL_INVALID_ENUM
);
301 alSetError(AL_INVALID_NAME
);
303 ProcessContext(Context
);
306 ALvoid AL_APIENTRY
alAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
310 Context
= alcGetCurrentContext();
313 alSetError(AL_INVALID_OPERATION
);
316 SuspendContext(Context
);
318 if (alIsAuxiliaryEffectSlot(effectslot
))
322 case AL_EFFECTSLOT_GAIN
:
323 alAuxiliaryEffectSlotf(effectslot
, param
, pflValues
[0]);
327 alSetError(AL_INVALID_ENUM
);
332 alSetError(AL_INVALID_NAME
);
334 ProcessContext(Context
);
337 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSloti(ALuint effectslot
, ALenum param
, ALint
*piValue
)
341 Context
= alcGetCurrentContext();
344 alSetError(AL_INVALID_OPERATION
);
347 SuspendContext(Context
);
349 if (alIsAuxiliaryEffectSlot(effectslot
))
351 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
355 case AL_EFFECTSLOT_EFFECT
:
356 *piValue
= ALEffectSlot
->effect
.effect
;
359 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
360 *piValue
= ALEffectSlot
->AuxSendAuto
;
364 alSetError(AL_INVALID_ENUM
);
369 alSetError(AL_INVALID_NAME
);
371 ProcessContext(Context
);
374 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotiv(ALuint effectslot
, ALenum param
, ALint
*piValues
)
378 Context
= alcGetCurrentContext();
381 alSetError(AL_INVALID_OPERATION
);
384 SuspendContext(Context
);
386 if (alIsAuxiliaryEffectSlot(effectslot
))
390 case AL_EFFECTSLOT_EFFECT
:
391 case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO
:
392 alGetAuxiliaryEffectSloti(effectslot
, param
, piValues
);
396 alSetError(AL_INVALID_ENUM
);
401 alSetError(AL_INVALID_NAME
);
403 ProcessContext(Context
);
406 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotf(ALuint effectslot
, ALenum param
, ALfloat
*pflValue
)
410 Context
= alcGetCurrentContext();
413 alSetError(AL_INVALID_OPERATION
);
416 SuspendContext(Context
);
418 if (alIsAuxiliaryEffectSlot(effectslot
))
420 ALeffectslot
*ALEffectSlot
= (ALeffectslot
*)ALTHUNK_LOOKUPENTRY(effectslot
);
424 case AL_EFFECTSLOT_GAIN
:
425 *pflValue
= ALEffectSlot
->Gain
;
429 alSetError(AL_INVALID_ENUM
);
434 alSetError(AL_INVALID_NAME
);
436 ProcessContext(Context
);
439 ALvoid AL_APIENTRY
alGetAuxiliaryEffectSlotfv(ALuint effectslot
, ALenum param
, ALfloat
*pflValues
)
443 Context
= alcGetCurrentContext();
446 alSetError(AL_INVALID_OPERATION
);
449 SuspendContext(Context
);
451 if (alIsAuxiliaryEffectSlot(effectslot
))
455 case AL_EFFECTSLOT_GAIN
:
456 alGetAuxiliaryEffectSlotf(effectslot
, param
, pflValues
);
460 alSetError(AL_INVALID_ENUM
);
465 alSetError(AL_INVALID_NAME
);
467 ProcessContext(Context
);
471 static ALvoid
InitializeEffect(ALCcontext
*Context
, ALeffectslot
*ALEffectSlot
, ALeffect
*effect
)
475 memset(&ALEffectSlot
->effect
, 0, sizeof(ALEffectSlot
->effect
));
476 VerbDestroy(ALEffectSlot
->ReverbState
);
477 ALEffectSlot
->ReverbState
= NULL
;
478 EchoDestroy(ALEffectSlot
->EchoState
);
479 ALEffectSlot
->EchoState
= NULL
;
482 if(effect
->type
== AL_EFFECT_REVERB
)
484 if(ALEffectSlot
->EchoState
)
486 EchoDestroy(ALEffectSlot
->EchoState
);
487 ALEffectSlot
->EchoState
= NULL
;
489 if(!ALEffectSlot
->ReverbState
)
490 ALEffectSlot
->ReverbState
= VerbCreate(Context
);
491 VerbUpdate(Context
, ALEffectSlot
, effect
);
493 else if(effect
->type
== AL_EFFECT_ECHO
)
495 if(ALEffectSlot
->ReverbState
)
497 VerbDestroy(ALEffectSlot
->ReverbState
);
498 ALEffectSlot
->ReverbState
= NULL
;
500 if(!ALEffectSlot
->EchoState
)
501 ALEffectSlot
->EchoState
= EchoCreate(Context
);
502 EchoUpdate(Context
, ALEffectSlot
, effect
);
504 memcpy(&ALEffectSlot
->effect
, effect
, sizeof(*effect
));
508 ALvoid
ReleaseALAuxiliaryEffectSlots(ALCcontext
*Context
)
511 if(Context
->AuxiliaryEffectSlotCount
> 0)
512 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context
->AuxiliaryEffectSlotCount
);
515 while(Context
->AuxiliaryEffectSlot
)
517 ALeffectslot
*temp
= Context
->AuxiliaryEffectSlot
;
518 Context
->AuxiliaryEffectSlot
= Context
->AuxiliaryEffectSlot
->next
;
520 // Release effectslot structure
521 VerbDestroy(temp
->ReverbState
);
522 EchoDestroy(temp
->EchoState
);
523 ALTHUNK_REMOVEENTRY(temp
->effectslot
);
525 memset(temp
, 0, sizeof(ALeffectslot
));
528 Context
->AuxiliaryEffectSlotCount
= 0;