Merge branch 'master' into efx-experiment
[openal-soft.git] / OpenAL32 / alFilter.c
blob0753d79914200685b44faf8cc622f419341e1dc4
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 "alFilter.h"
30 #include "alThunk.h"
31 #include "alError.h"
33 static ALfilter *g_FilterList;
34 static ALuint g_FilterCount;
36 static void InitFilterParams(ALfilter *filter, ALenum type);
39 AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
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*)filters, n * sizeof(ALuint)))
52 ALfilter **list = &g_FilterList;
53 while(*list)
54 list = &(*list)->next;
56 i = 0;
57 while(i < n)
59 *list = calloc(1, sizeof(ALfilter));
60 if(!(*list))
62 // We must have run out or memory
63 alDeleteFilters(i, filters);
64 alSetError(AL_OUT_OF_MEMORY);
65 break;
68 filters[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
69 (*list)->filter = filters[i];
71 InitFilterParams(*list, AL_FILTER_NULL);
72 g_FilterCount++;
73 i++;
78 ProcessContext(Context);
81 AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
83 ALCcontext *Context;
84 ALfilter *ALFilter;
85 ALsizei i;
87 Context = alcGetCurrentContext();
88 SuspendContext(Context);
90 if (n >= 0)
92 // Check that all filters are valid
93 for (i = 0; i < n; i++)
95 if (!alIsFilter(filters[i]))
97 alSetError(AL_INVALID_NAME);
98 break;
102 if (i == n)
104 // All filters are valid
105 for (i = 0; i < n; i++)
107 // Recheck that the filter is valid, because there could be duplicated names
108 if (filters[i] && alIsFilter(filters[i]))
110 ALfilter **list;
112 ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
114 // Remove Source from list of Sources
115 list = &g_FilterList;
116 while(*list && *list != ALFilter)
117 list = &(*list)->next;
119 if(*list)
120 *list = (*list)->next;
121 ALTHUNK_REMOVEENTRY(ALFilter->filter);
123 memset(ALFilter, 0, sizeof(ALfilter));
124 free(ALFilter);
126 g_FilterCount--;
131 else
132 alSetError(AL_INVALID_VALUE);
134 ProcessContext(Context);
137 AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
139 ALCcontext *Context;
140 ALfilter **list;
142 Context = alcGetCurrentContext();
143 SuspendContext(Context);
145 list = &g_FilterList;
146 while(*list && (*list)->filter != filter)
147 list = &(*list)->next;
149 ProcessContext(Context);
151 return ((*list || !filter) ? AL_TRUE : AL_FALSE);
154 AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
156 ALCcontext *Context;
158 Context = alcGetCurrentContext();
159 SuspendContext(Context);
161 if (filter && alIsFilter(filter))
163 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
165 switch(param)
167 case AL_FILTER_TYPE:
168 if(iValue == AL_FILTER_NULL ||
169 iValue == AL_FILTER_LOWPASS)
170 InitFilterParams(ALFilter, iValue);
171 else
172 alSetError(AL_INVALID_VALUE);
173 break;
175 default:
176 alSetError(AL_INVALID_ENUM);
177 break;
180 else
181 alSetError(AL_INVALID_NAME);
183 ProcessContext(Context);
186 AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
188 ALCcontext *Context;
190 Context = alcGetCurrentContext();
191 SuspendContext(Context);
193 if (filter && alIsFilter(filter))
195 switch(param)
197 case AL_FILTER_TYPE:
198 alFilteri(filter, param, piValues[0]);
199 break;
201 default:
202 alSetError(AL_INVALID_ENUM);
203 break;
206 else
207 alSetError(AL_INVALID_NAME);
209 ProcessContext(Context);
212 AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
214 ALCcontext *Context;
216 Context = alcGetCurrentContext();
217 SuspendContext(Context);
219 if (filter && alIsFilter(filter))
221 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
223 switch(param)
225 case AL_LOWPASS_GAIN:
226 if(ALFilter->type == AL_FILTER_LOWPASS)
228 if(flValue >= 0.0f && flValue <= 1.0f)
229 ALFilter->Gain = flValue;
231 else
232 alSetError(AL_INVALID_ENUM);
233 break;
235 case AL_LOWPASS_GAINHF:
236 if(ALFilter->type == AL_FILTER_LOWPASS)
238 if(flValue >= 0.0f && flValue <= 1.0f)
239 ALFilter->GainHF = flValue;
241 else
242 alSetError(AL_INVALID_ENUM);
243 break;
245 default:
246 alSetError(AL_INVALID_ENUM);
247 break;
250 else
251 alSetError(AL_INVALID_NAME);
253 ProcessContext(Context);
256 AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
258 ALCcontext *Context;
260 Context = alcGetCurrentContext();
261 SuspendContext(Context);
263 if (filter && alIsFilter(filter))
265 switch(param)
267 case AL_LOWPASS_GAIN:
268 case AL_LOWPASS_GAINHF:
269 alFilterf(filter, param, pflValues[0]);
270 break;
272 default:
273 alSetError(AL_INVALID_ENUM);
274 break;
277 else
278 alSetError(AL_INVALID_NAME);
280 ProcessContext(Context);
283 AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
285 ALCcontext *Context;
287 (void)piValue;
289 Context = alcGetCurrentContext();
290 SuspendContext(Context);
292 if (filter && alIsFilter(filter))
294 switch(param)
296 default:
297 alSetError(AL_INVALID_ENUM);
298 break;
301 else
302 alSetError(AL_INVALID_NAME);
304 ProcessContext(Context);
307 AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
309 ALCcontext *Context;
311 (void)piValues;
313 Context = alcGetCurrentContext();
314 SuspendContext(Context);
316 if (filter && alIsFilter(filter))
318 switch(param)
320 default:
321 alSetError(AL_INVALID_ENUM);
322 break;
325 else
326 alSetError(AL_INVALID_NAME);
328 ProcessContext(Context);
331 AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
333 ALCcontext *Context;
335 Context = alcGetCurrentContext();
336 SuspendContext(Context);
338 if (filter && alIsFilter(filter))
340 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
342 switch(param)
344 case AL_LOWPASS_GAIN:
345 if(ALFilter->type == AL_FILTER_LOWPASS)
346 *pflValue = ALFilter->Gain;
347 else
348 alSetError(AL_INVALID_ENUM);
349 break;
351 case AL_LOWPASS_GAINHF:
352 if(ALFilter->type == AL_FILTER_LOWPASS)
353 *pflValue = ALFilter->GainHF;
354 else
355 alSetError(AL_INVALID_ENUM);
356 break;
358 default:
359 alSetError(AL_INVALID_ENUM);
360 break;
363 else
364 alSetError(AL_INVALID_NAME);
366 ProcessContext(Context);
369 AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
371 ALCcontext *Context;
373 Context = alcGetCurrentContext();
374 SuspendContext(Context);
376 if (filter && alIsFilter(filter))
378 switch(param)
380 case AL_LOWPASS_GAIN:
381 case AL_LOWPASS_GAINHF:
382 alGetFilterf(filter, param, pflValues);
383 break;
385 default:
386 alSetError(AL_INVALID_ENUM);
387 break;
390 else
391 alSetError(AL_INVALID_NAME);
393 ProcessContext(Context);
397 ALvoid ReleaseALFilters(ALvoid)
399 #ifdef _DEBUG
400 if(g_FilterCount > 0)
401 AL_PRINT("exit() %d Filter(s) NOT deleted\n", g_FilterCount);
402 #endif
404 while(g_FilterList)
406 ALfilter *temp = g_FilterList;
407 g_FilterList = g_FilterList->next;
409 // Release filter structure
410 memset(temp, 0, sizeof(ALfilter));
411 free(temp);
413 g_FilterCount = 0;
417 static void InitFilterParams(ALfilter *filter, ALenum type)
419 filter->type = type;
421 filter->Gain = 1.0;
422 filter->GainHF = 1.0;