Merge branch 'master' into efx-experiment
[openal-soft.git] / OpenAL32 / alEffect.c
blob97778f9e2b304b938105f223e0a2ccd56e240ce7
1 /**
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
21 #include <stdlib.h>
23 #include "config.h"
25 #include "AL/al.h"
26 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alEffect.h"
30 #include "alThunk.h"
31 #include "alError.h"
33 static ALeffect *g_EffectList;
34 static ALuint g_EffectCount;
36 static void InitEffectParams(ALeffect *effect, ALenum type);
39 AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
41 ALCcontext *Context;
42 ALsizei i;
44 Context = alcGetCurrentContext();
45 SuspendContext(Context);
47 if (n > 0)
49 // Check that enough memory has been allocted in the 'sources' array for n Sources
50 if (!IsBadWritePtr((void*)effects, n * sizeof(ALuint)))
52 ALeffect **list = &g_EffectList;
53 while(*list)
54 list = &(*list)->next;
56 i = 0;
57 while(i < n)
59 *list = calloc(1, sizeof(ALeffect));
60 if(!(*list))
62 // We must have run out or memory
63 alDeleteEffects(i, effects);
64 alSetError(AL_OUT_OF_MEMORY);
65 break;
68 effects[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
69 (*list)->effect = effects[i];
71 InitEffectParams(*list, AL_EFFECT_NULL);
72 g_EffectCount++;
73 i++;
78 ProcessContext(Context);
81 AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects)
83 ALCcontext *Context;
84 ALeffect *ALEffect;
85 ALsizei i;
87 Context = alcGetCurrentContext();
88 SuspendContext(Context);
90 if (n >= 0)
92 // Check that all effects are valid
93 for (i = 0; i < n; i++)
95 if (!alIsEffect(effects[i]))
97 alSetError(AL_INVALID_NAME);
98 break;
102 if (i == n)
104 // All effects are valid
105 for (i = 0; i < n; i++)
107 // Recheck that the effect is valid, because there could be duplicated names
108 if (effects[i] && alIsEffect(effects[i]))
110 ALeffect **list;
112 ALEffect = ((ALeffect*)ALTHUNK_LOOKUPENTRY(effects[i]));
114 // Remove Source from list of Sources
115 list = &g_EffectList;
116 while(*list && *list != ALEffect)
117 list = &(*list)->next;
119 if(*list)
120 *list = (*list)->next;
121 ALTHUNK_REMOVEENTRY(ALEffect->effect);
123 memset(ALEffect, 0, sizeof(ALeffect));
124 free(ALEffect);
126 g_EffectCount--;
131 else
132 alSetError(AL_INVALID_VALUE);
134 ProcessContext(Context);
137 AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
139 ALCcontext *Context;
140 ALeffect **list;
142 Context = alcGetCurrentContext();
143 SuspendContext(Context);
145 list = &g_EffectList;
146 while(*list && (*list)->effect != effect)
147 list = &(*list)->next;
149 ProcessContext(Context);
151 return ((*list || !effect) ? AL_TRUE : AL_FALSE);
154 AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
156 ALCcontext *Context;
158 Context = alcGetCurrentContext();
159 SuspendContext(Context);
161 if (effect && alIsEffect(effect))
163 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
165 switch(param)
167 case AL_EFFECT_TYPE:
168 if(iValue == AL_EFFECT_NULL)
169 InitEffectParams(ALEffect, iValue);
170 else
171 alSetError(AL_INVALID_VALUE);
172 break;
174 default:
175 alSetError(AL_INVALID_ENUM);
176 break;
179 else
180 alSetError(AL_INVALID_NAME);
182 ProcessContext(Context);
185 AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues)
187 ALCcontext *Context;
189 Context = alcGetCurrentContext();
190 SuspendContext(Context);
192 if (effect && alIsEffect(effect))
194 switch(param)
196 case AL_EFFECT_TYPE:
197 alEffecti(effect, param, piValues[0]);
198 break;
200 default:
201 alSetError(AL_INVALID_ENUM);
202 break;
205 else
206 alSetError(AL_INVALID_NAME);
208 ProcessContext(Context);
211 AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue)
213 ALCcontext *Context;
215 (void)flValue;
217 Context = alcGetCurrentContext();
218 SuspendContext(Context);
220 if (effect && alIsEffect(effect))
222 switch(param)
224 default:
225 alSetError(AL_INVALID_ENUM);
226 break;
229 else
230 alSetError(AL_INVALID_NAME);
232 ProcessContext(Context);
235 AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
237 ALCcontext *Context;
239 (void)pflValues;
241 Context = alcGetCurrentContext();
242 SuspendContext(Context);
244 if (effect && alIsEffect(effect))
246 switch(param)
248 default:
249 alSetError(AL_INVALID_ENUM);
250 break;
253 else
254 alSetError(AL_INVALID_NAME);
256 ProcessContext(Context);
259 AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue)
261 ALCcontext *Context;
263 Context = alcGetCurrentContext();
264 SuspendContext(Context);
266 if (effect && alIsEffect(effect))
268 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
270 switch(param)
272 case AL_EFFECT_TYPE:
273 *piValue = ALEffect->type;
274 break;
276 default:
277 alSetError(AL_INVALID_ENUM);
278 break;
281 else
282 alSetError(AL_INVALID_NAME);
284 ProcessContext(Context);
287 AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues)
289 ALCcontext *Context;
291 Context = alcGetCurrentContext();
292 SuspendContext(Context);
294 if (effect && alIsEffect(effect))
296 switch(param)
298 case AL_EFFECT_TYPE:
299 alGetEffecti(effect, param, piValues);
300 break;
302 default:
303 alSetError(AL_INVALID_ENUM);
304 break;
307 else
308 alSetError(AL_INVALID_NAME);
310 ProcessContext(Context);
313 AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue)
315 ALCcontext *Context;
317 (void)pflValue;
319 Context = alcGetCurrentContext();
320 SuspendContext(Context);
322 if (effect && alIsEffect(effect))
324 switch(param)
326 default:
327 alSetError(AL_INVALID_ENUM);
328 break;
331 else
332 alSetError(AL_INVALID_NAME);
334 ProcessContext(Context);
337 AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
339 ALCcontext *Context;
341 (void)pflValues;
343 Context = alcGetCurrentContext();
344 SuspendContext(Context);
346 if (effect && alIsEffect(effect))
348 switch(param)
350 default:
351 alSetError(AL_INVALID_ENUM);
352 break;
355 else
356 alSetError(AL_INVALID_NAME);
358 ProcessContext(Context);
362 ALvoid ReleaseALEffects(ALvoid)
364 #ifdef _DEBUG
365 if(g_EffectCount > 0)
366 AL_PRINT("exit() %d Effect(s) NOT deleted\n", g_EffectCount);
367 #endif
369 while(g_EffectList)
371 ALeffect *temp = g_EffectList;
372 g_EffectList = g_EffectList->next;
374 // Release effect structure
375 memset(temp, 0, sizeof(ALeffect));
376 free(temp);
378 g_EffectCount = 0;
382 static void InitEffectParams(ALeffect *effect, ALenum type)
384 effect->type = type;