Avoid calling alDelete* from alGen*
[openal-soft.git] / OpenAL32 / alFilter.c
blob1e8ada32c1db176b98f1731d6f2477935740c65d
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 "config.h"
23 #include <stdlib.h>
25 #include "AL/al.h"
26 #include "AL/alc.h"
27 #include "alMain.h"
28 #include "alFilter.h"
29 #include "alThunk.h"
30 #include "alError.h"
33 static void InitFilterParams(ALfilter *filter, ALenum type);
35 DECL_VERIFIER(Filter, ALfilter, filter)
37 ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
39 ALCcontext *Context;
40 ALsizei i=0;
42 Context = GetContextSuspended();
43 if(!Context) return;
45 if (n > 0)
47 ALCdevice *device = Context->Device;
49 // Check that enough memory has been allocted in the 'filters' array for n Filters
50 if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
52 ALfilter *end;
53 ALfilter **list = &device->FilterList;
54 while(*list)
55 list = &(*list)->next;
57 end = *list;
58 while(i < n)
60 *list = calloc(1, sizeof(ALfilter));
61 if(!(*list))
63 while(end->next)
65 ALfilter *temp = end->next;
66 end->next = temp->next;
68 ALTHUNK_REMOVEENTRY(temp->filter);
69 device->FilterCount--;
70 free(temp);
72 alSetError(Context, AL_OUT_OF_MEMORY);
73 break;
76 filters[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
77 (*list)->filter = filters[i];
79 InitFilterParams(*list, AL_FILTER_NULL);
80 device->FilterCount++;
81 i++;
83 list = &(*list)->next;
88 ProcessContext(Context);
91 ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
93 ALCcontext *Context;
94 ALfilter *ALFilter;
95 ALsizei i;
97 Context = GetContextSuspended();
98 if(!Context) return;
100 if (n >= 0)
102 ALCdevice *device = Context->Device;
104 // Check that all filters are valid
105 for (i = 0; i < n; i++)
107 if(!filters[i])
108 continue;
110 if(!VerifyFilter(device->FilterList, filters[i]))
112 alSetError(Context, AL_INVALID_NAME);
113 break;
117 if (i == n)
119 // All filters are valid
120 for (i = 0; i < n; i++)
122 // Recheck that the filter is valid, because there could be duplicated names
123 if((ALFilter=VerifyFilter(device->FilterList, filters[i])) != NULL)
125 ALfilter **list;
127 // Remove Source from list of Sources
128 list = &device->FilterList;
129 while(*list && *list != ALFilter)
130 list = &(*list)->next;
132 if(*list)
133 *list = (*list)->next;
134 ALTHUNK_REMOVEENTRY(ALFilter->filter);
136 memset(ALFilter, 0, sizeof(ALfilter));
137 free(ALFilter);
139 device->FilterCount--;
144 else
145 alSetError(Context, AL_INVALID_VALUE);
147 ProcessContext(Context);
150 ALboolean AL_APIENTRY alIsFilter(ALuint filter)
152 ALCcontext *Context;
153 ALboolean result = AL_TRUE;
155 Context = GetContextSuspended();
156 if(!Context) return AL_FALSE;
158 if(filter)
159 result = (VerifyFilter(Context->Device->FilterList, filter) ?
160 AL_TRUE : AL_FALSE);
162 ProcessContext(Context);
164 return result;
167 ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
169 ALCcontext *Context;
170 ALCdevice *Device;
171 ALfilter *ALFilter;
173 Context = GetContextSuspended();
174 if(!Context) return;
176 Device = Context->Device;
177 if((ALFilter=VerifyFilter(Device->FilterList, filter)) != NULL)
179 switch(param)
181 case AL_FILTER_TYPE:
182 if(iValue == AL_FILTER_NULL ||
183 iValue == AL_FILTER_LOWPASS)
184 InitFilterParams(ALFilter, iValue);
185 else
186 alSetError(Context, AL_INVALID_VALUE);
187 break;
189 default:
190 alSetError(Context, AL_INVALID_ENUM);
191 break;
194 else
195 alSetError(Context, AL_INVALID_NAME);
197 ProcessContext(Context);
200 ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
202 ALCcontext *Context;
203 ALCdevice *Device;
205 Context = GetContextSuspended();
206 if(!Context) return;
208 Device = Context->Device;
209 if(VerifyFilter(Device->FilterList, filter) != NULL)
211 switch(param)
213 case AL_FILTER_TYPE:
214 alFilteri(filter, param, piValues[0]);
215 break;
217 default:
218 alSetError(Context, AL_INVALID_ENUM);
219 break;
222 else
223 alSetError(Context, AL_INVALID_NAME);
225 ProcessContext(Context);
228 ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
230 ALCcontext *Context;
231 ALCdevice *Device;
232 ALfilter *ALFilter;
234 Context = GetContextSuspended();
235 if(!Context) return;
237 Device = Context->Device;
238 if((ALFilter=VerifyFilter(Device->FilterList, filter)) != NULL)
240 switch(ALFilter->type)
242 case AL_FILTER_LOWPASS:
243 switch(param)
245 case AL_LOWPASS_GAIN:
246 if(flValue >= 0.0f && flValue <= 1.0f)
247 ALFilter->Gain = flValue;
248 else
249 alSetError(Context, AL_INVALID_VALUE);
250 break;
252 case AL_LOWPASS_GAINHF:
253 if(flValue >= 0.0f && flValue <= 1.0f)
254 ALFilter->GainHF = flValue;
255 else
256 alSetError(Context, AL_INVALID_VALUE);
257 break;
259 default:
260 alSetError(Context, AL_INVALID_ENUM);
261 break;
263 break;
265 default:
266 alSetError(Context, AL_INVALID_ENUM);
267 break;
270 else
271 alSetError(Context, AL_INVALID_NAME);
273 ProcessContext(Context);
276 ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
278 ALCcontext *Context;
279 ALCdevice *Device;
281 Context = GetContextSuspended();
282 if(!Context) return;
284 Device = Context->Device;
285 if(VerifyFilter(Device->FilterList, filter) != NULL)
287 switch(param)
289 default:
290 alFilterf(filter, param, pflValues[0]);
291 break;
294 else
295 alSetError(Context, AL_INVALID_NAME);
297 ProcessContext(Context);
300 ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
302 ALCcontext *Context;
303 ALCdevice *Device;
304 ALfilter *ALFilter;
306 Context = GetContextSuspended();
307 if(!Context) return;
309 Device = Context->Device;
310 if((ALFilter=VerifyFilter(Device->FilterList, filter)) != NULL)
312 switch(param)
314 case AL_FILTER_TYPE:
315 *piValue = ALFilter->type;
316 break;
318 default:
319 alSetError(Context, AL_INVALID_ENUM);
320 break;
323 else
324 alSetError(Context, AL_INVALID_NAME);
326 ProcessContext(Context);
329 ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
331 ALCcontext *Context;
332 ALCdevice *Device;
334 Context = GetContextSuspended();
335 if(!Context) return;
337 Device = Context->Device;
338 if(VerifyFilter(Device->FilterList, filter) != NULL)
340 switch(param)
342 case AL_FILTER_TYPE:
343 alGetFilteri(filter, param, piValues);
344 break;
346 default:
347 alSetError(Context, AL_INVALID_ENUM);
348 break;
351 else
352 alSetError(Context, AL_INVALID_NAME);
354 ProcessContext(Context);
357 ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
359 ALCcontext *Context;
360 ALCdevice *Device;
361 ALfilter *ALFilter;
363 Context = GetContextSuspended();
364 if(!Context) return;
366 Device = Context->Device;
367 if((ALFilter=VerifyFilter(Device->FilterList, filter)) != NULL)
369 switch(ALFilter->type)
371 case AL_FILTER_LOWPASS:
372 switch(param)
374 case AL_LOWPASS_GAIN:
375 *pflValue = ALFilter->Gain;
376 break;
378 case AL_LOWPASS_GAINHF:
379 *pflValue = ALFilter->GainHF;
380 break;
382 default:
383 alSetError(Context, AL_INVALID_ENUM);
384 break;
386 break;
388 default:
389 alSetError(Context, AL_INVALID_ENUM);
390 break;
393 else
394 alSetError(Context, AL_INVALID_NAME);
396 ProcessContext(Context);
399 ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
401 ALCcontext *Context;
402 ALCdevice *Device;
404 Context = GetContextSuspended();
405 if(!Context) return;
407 Device = Context->Device;
408 if(VerifyFilter(Device->FilterList, filter) != NULL)
410 switch(param)
412 default:
413 alGetFilterf(filter, param, pflValues);
414 break;
417 else
418 alSetError(Context, AL_INVALID_NAME);
420 ProcessContext(Context);
424 ALvoid ReleaseALFilters(ALCdevice *device)
426 ALfilter *list = device->FilterList;
427 while(list)
429 ALfilter *temp = list;
430 list = list->next;
432 // Release filter structure
433 memset(temp, 0, sizeof(ALfilter));
434 free(temp);
436 device->FilterList = NULL;
437 device->FilterCount = 0;
441 static void InitFilterParams(ALfilter *filter, ALenum type)
443 filter->type = type;
445 filter->Gain = 1.0;
446 filter->GainHF = 1.0;