Install openal-info if it is built
[openal-soft.git] / OpenAL32 / alFilter.c
blob2a0e6973e1f7668801573da1f7abdb8901cb73a8
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"
32 static ALfilter *g_FilterList;
33 static ALuint g_FilterCount;
35 static void InitFilterParams(ALfilter *filter, ALenum type);
38 AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
40 ALCcontext *Context;
41 ALsizei i;
43 Context = alcGetCurrentContext();
44 SuspendContext(Context);
46 if (n > 0)
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 = &g_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 g_FilterCount++;
72 i++;
74 list = &(*list)->next;
79 ProcessContext(Context);
82 AL_API 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 // Check that all filters are valid
94 for (i = 0; i < n; i++)
96 if (!alIsFilter(filters[i]))
98 alSetError(AL_INVALID_NAME);
99 break;
103 if (i == n)
105 // All filters are valid
106 for (i = 0; i < n; i++)
108 // Recheck that the filter is valid, because there could be duplicated names
109 if (filters[i] && alIsFilter(filters[i]))
111 ALfilter **list;
113 ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
115 // Remove Source from list of Sources
116 list = &g_FilterList;
117 while(*list && *list != ALFilter)
118 list = &(*list)->next;
120 if(*list)
121 *list = (*list)->next;
122 ALTHUNK_REMOVEENTRY(ALFilter->filter);
124 memset(ALFilter, 0, sizeof(ALfilter));
125 free(ALFilter);
127 g_FilterCount--;
132 else
133 alSetError(AL_INVALID_VALUE);
135 ProcessContext(Context);
138 AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
140 ALCcontext *Context;
141 ALfilter **list;
143 Context = alcGetCurrentContext();
144 SuspendContext(Context);
146 list = &g_FilterList;
147 while(*list && (*list)->filter != filter)
148 list = &(*list)->next;
150 ProcessContext(Context);
152 return ((*list || !filter) ? AL_TRUE : AL_FALSE);
155 AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
157 ALCcontext *Context;
159 Context = alcGetCurrentContext();
160 SuspendContext(Context);
162 if (filter && alIsFilter(filter))
164 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
166 switch(param)
168 case AL_FILTER_TYPE:
169 if(iValue == AL_FILTER_NULL ||
170 iValue == AL_FILTER_LOWPASS)
171 InitFilterParams(ALFilter, iValue);
172 else
173 alSetError(AL_INVALID_VALUE);
174 break;
176 default:
177 alSetError(AL_INVALID_ENUM);
178 break;
181 else
182 alSetError(AL_INVALID_NAME);
184 ProcessContext(Context);
187 AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
189 ALCcontext *Context;
191 Context = alcGetCurrentContext();
192 SuspendContext(Context);
194 if (filter && alIsFilter(filter))
196 switch(param)
198 case AL_FILTER_TYPE:
199 alFilteri(filter, param, piValues[0]);
200 break;
202 default:
203 alSetError(AL_INVALID_ENUM);
204 break;
207 else
208 alSetError(AL_INVALID_NAME);
210 ProcessContext(Context);
213 AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
215 ALCcontext *Context;
217 Context = alcGetCurrentContext();
218 SuspendContext(Context);
220 if (filter && alIsFilter(filter))
222 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
224 switch(param)
226 case AL_LOWPASS_GAIN:
227 if(ALFilter->type == AL_FILTER_LOWPASS)
229 if(flValue >= 0.0f && flValue <= 1.0f)
230 ALFilter->Gain = flValue;
232 else
233 alSetError(AL_INVALID_ENUM);
234 break;
236 case AL_LOWPASS_GAINHF:
237 if(ALFilter->type == AL_FILTER_LOWPASS)
239 if(flValue >= 0.0f && flValue <= 1.0f)
240 ALFilter->GainHF = flValue;
242 else
243 alSetError(AL_INVALID_ENUM);
244 break;
246 default:
247 alSetError(AL_INVALID_ENUM);
248 break;
251 else
252 alSetError(AL_INVALID_NAME);
254 ProcessContext(Context);
257 AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
259 ALCcontext *Context;
261 Context = alcGetCurrentContext();
262 SuspendContext(Context);
264 if (filter && alIsFilter(filter))
266 switch(param)
268 case AL_LOWPASS_GAIN:
269 case AL_LOWPASS_GAINHF:
270 alFilterf(filter, param, pflValues[0]);
271 break;
273 default:
274 alSetError(AL_INVALID_ENUM);
275 break;
278 else
279 alSetError(AL_INVALID_NAME);
281 ProcessContext(Context);
284 AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
286 ALCcontext *Context;
288 (void)piValue;
290 Context = alcGetCurrentContext();
291 SuspendContext(Context);
293 if (filter && alIsFilter(filter))
295 switch(param)
297 default:
298 alSetError(AL_INVALID_ENUM);
299 break;
302 else
303 alSetError(AL_INVALID_NAME);
305 ProcessContext(Context);
308 AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
310 ALCcontext *Context;
312 (void)piValues;
314 Context = alcGetCurrentContext();
315 SuspendContext(Context);
317 if (filter && alIsFilter(filter))
319 switch(param)
321 default:
322 alSetError(AL_INVALID_ENUM);
323 break;
326 else
327 alSetError(AL_INVALID_NAME);
329 ProcessContext(Context);
332 AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
334 ALCcontext *Context;
336 Context = alcGetCurrentContext();
337 SuspendContext(Context);
339 if (filter && alIsFilter(filter))
341 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
343 switch(param)
345 case AL_LOWPASS_GAIN:
346 if(ALFilter->type == AL_FILTER_LOWPASS)
347 *pflValue = ALFilter->Gain;
348 else
349 alSetError(AL_INVALID_ENUM);
350 break;
352 case AL_LOWPASS_GAINHF:
353 if(ALFilter->type == AL_FILTER_LOWPASS)
354 *pflValue = ALFilter->GainHF;
355 else
356 alSetError(AL_INVALID_ENUM);
357 break;
359 default:
360 alSetError(AL_INVALID_ENUM);
361 break;
364 else
365 alSetError(AL_INVALID_NAME);
367 ProcessContext(Context);
370 AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
372 ALCcontext *Context;
374 Context = alcGetCurrentContext();
375 SuspendContext(Context);
377 if (filter && alIsFilter(filter))
379 switch(param)
381 case AL_LOWPASS_GAIN:
382 case AL_LOWPASS_GAINHF:
383 alGetFilterf(filter, param, pflValues);
384 break;
386 default:
387 alSetError(AL_INVALID_ENUM);
388 break;
391 else
392 alSetError(AL_INVALID_NAME);
394 ProcessContext(Context);
398 ALvoid ReleaseALFilters(ALvoid)
400 #ifdef _DEBUG
401 if(g_FilterCount > 0)
402 AL_PRINT("exit() %d Filter(s) NOT deleted\n", g_FilterCount);
403 #endif
405 while(g_FilterList)
407 ALfilter *temp = g_FilterList;
408 g_FilterList = g_FilterList->next;
410 // Release filter structure
411 memset(temp, 0, sizeof(ALfilter));
412 free(temp);
414 g_FilterCount = 0;
418 static void InitFilterParams(ALfilter *filter, ALenum type)
420 filter->type = type;
422 filter->Gain = 1.0;
423 filter->GainHF = 1.0;