Store the effect and filter lists in the device
[openal-soft.git] / OpenAL32 / alFilter.c
blob9d32e7cf5b883efb0afbb0303b4658bc2b4ceb91
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);
36 ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
38 ALCcontext *Context;
39 ALsizei i;
41 Context = alcGetCurrentContext();
42 SuspendContext(Context);
44 if (n > 0)
46 ALCdevice *device = Context->Device;
48 // Check that enough memory has been allocted in the 'filters' array for n Filters
49 if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
51 ALfilter **list = &device->FilterList;
52 while(*list)
53 list = &(*list)->next;
55 i = 0;
56 while(i < n)
58 *list = calloc(1, sizeof(ALfilter));
59 if(!(*list))
61 // We must have run out or memory
62 alDeleteFilters(i, filters);
63 alSetError(AL_OUT_OF_MEMORY);
64 break;
67 filters[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
68 (*list)->filter = filters[i];
70 InitFilterParams(*list, AL_FILTER_NULL);
71 device->FilterCount++;
72 i++;
74 list = &(*list)->next;
79 ProcessContext(Context);
82 ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
84 ALCcontext *Context;
85 ALfilter *ALFilter;
86 ALsizei i;
88 Context = alcGetCurrentContext();
89 SuspendContext(Context);
91 if (n >= 0)
93 ALCdevice *device = Context->Device;
95 // Check that all filters are valid
96 for (i = 0; i < n; i++)
98 if (!alIsFilter(filters[i]))
100 alSetError(AL_INVALID_NAME);
101 break;
105 if (i == n)
107 // All filters are valid
108 for (i = 0; i < n; i++)
110 // Recheck that the filter is valid, because there could be duplicated names
111 if (filters[i] && alIsFilter(filters[i]))
113 ALfilter **list;
115 ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
117 // Remove Source from list of Sources
118 list = &device->FilterList;
119 while(*list && *list != ALFilter)
120 list = &(*list)->next;
122 if(*list)
123 *list = (*list)->next;
124 ALTHUNK_REMOVEENTRY(ALFilter->filter);
126 memset(ALFilter, 0, sizeof(ALfilter));
127 free(ALFilter);
129 device->FilterCount--;
134 else
135 alSetError(AL_INVALID_VALUE);
137 ProcessContext(Context);
140 ALboolean AL_APIENTRY alIsFilter(ALuint filter)
142 ALCcontext *Context;
143 ALfilter *list;
145 Context = alcGetCurrentContext();
146 SuspendContext(Context);
148 list = Context->Device->FilterList;
149 while(list && list->filter != filter)
150 list = list->next;
152 ProcessContext(Context);
154 return ((list || !filter) ? AL_TRUE : AL_FALSE);
157 ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
159 ALCcontext *Context;
161 Context = alcGetCurrentContext();
162 SuspendContext(Context);
164 if (filter && alIsFilter(filter))
166 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
168 switch(param)
170 case AL_FILTER_TYPE:
171 if(iValue == AL_FILTER_NULL ||
172 iValue == AL_FILTER_LOWPASS)
173 InitFilterParams(ALFilter, iValue);
174 else
175 alSetError(AL_INVALID_VALUE);
176 break;
178 default:
179 alSetError(AL_INVALID_ENUM);
180 break;
183 else
184 alSetError(AL_INVALID_NAME);
186 ProcessContext(Context);
189 ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
191 ALCcontext *Context;
193 Context = alcGetCurrentContext();
194 SuspendContext(Context);
196 if (filter && alIsFilter(filter))
198 switch(param)
200 case AL_FILTER_TYPE:
201 alFilteri(filter, param, piValues[0]);
202 break;
204 default:
205 alSetError(AL_INVALID_ENUM);
206 break;
209 else
210 alSetError(AL_INVALID_NAME);
212 ProcessContext(Context);
215 ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
217 ALCcontext *Context;
219 Context = alcGetCurrentContext();
220 SuspendContext(Context);
222 if (filter && alIsFilter(filter))
224 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
226 switch(ALFilter->type)
228 case AL_FILTER_LOWPASS:
229 switch(param)
231 case AL_LOWPASS_GAIN:
232 if(flValue >= 0.0f && flValue <= 1.0f)
233 ALFilter->Gain = flValue;
234 else
235 alSetError(AL_INVALID_VALUE);
236 break;
238 case AL_LOWPASS_GAINHF:
239 if(flValue >= 0.0f && flValue <= 1.0f)
240 ALFilter->GainHF = flValue;
241 else
242 alSetError(AL_INVALID_VALUE);
243 break;
245 default:
246 alSetError(AL_INVALID_ENUM);
247 break;
249 break;
251 default:
252 alSetError(AL_INVALID_ENUM);
253 break;
256 else
257 alSetError(AL_INVALID_NAME);
259 ProcessContext(Context);
262 ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
264 ALCcontext *Context;
266 Context = alcGetCurrentContext();
267 SuspendContext(Context);
269 if (filter && alIsFilter(filter))
271 switch(param)
273 default:
274 alFilterf(filter, param, pflValues[0]);
275 break;
278 else
279 alSetError(AL_INVALID_NAME);
281 ProcessContext(Context);
284 ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
286 ALCcontext *Context;
288 Context = alcGetCurrentContext();
289 SuspendContext(Context);
291 if (filter && alIsFilter(filter))
293 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
295 switch(param)
297 case AL_FILTER_TYPE:
298 *piValue = ALFilter->type;
299 break;
301 default:
302 alSetError(AL_INVALID_ENUM);
303 break;
306 else
307 alSetError(AL_INVALID_NAME);
309 ProcessContext(Context);
312 ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
314 ALCcontext *Context;
316 Context = alcGetCurrentContext();
317 SuspendContext(Context);
319 if (filter && alIsFilter(filter))
321 switch(param)
323 case AL_FILTER_TYPE:
324 alGetFilteri(filter, param, piValues);
325 break;
327 default:
328 alSetError(AL_INVALID_ENUM);
329 break;
332 else
333 alSetError(AL_INVALID_NAME);
335 ProcessContext(Context);
338 ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
340 ALCcontext *Context;
342 Context = alcGetCurrentContext();
343 SuspendContext(Context);
345 if (filter && alIsFilter(filter))
347 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
349 switch(ALFilter->type)
351 case AL_FILTER_LOWPASS:
352 switch(param)
354 case AL_LOWPASS_GAIN:
355 *pflValue = ALFilter->Gain;
356 break;
358 case AL_LOWPASS_GAINHF:
359 *pflValue = ALFilter->GainHF;
360 break;
362 default:
363 alSetError(AL_INVALID_ENUM);
364 break;
366 break;
368 default:
369 alSetError(AL_INVALID_ENUM);
370 break;
373 else
374 alSetError(AL_INVALID_NAME);
376 ProcessContext(Context);
379 ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
381 ALCcontext *Context;
383 Context = alcGetCurrentContext();
384 SuspendContext(Context);
386 if (filter && alIsFilter(filter))
388 switch(param)
390 default:
391 alGetFilterf(filter, param, pflValues);
392 break;
395 else
396 alSetError(AL_INVALID_NAME);
398 ProcessContext(Context);
402 ALvoid ReleaseALFilters(ALCdevice *device)
404 ALfilter *list = device->FilterList;
405 while(list)
407 ALfilter *temp = list;
408 list = list->next;
410 // Release filter structure
411 memset(temp, 0, sizeof(ALfilter));
412 free(temp);
414 device->FilterList = NULL;
415 device->FilterCount = 0;
419 static void InitFilterParams(ALfilter *filter, ALenum type)
421 filter->type = type;
423 filter->Gain = 1.0;
424 filter->GainHF = 1.0;