Allow auxiliary effect slot 0 when (un)setting the source auxiliary send
[openal-soft.git] / OpenAL32 / alFilter.c
blob80da100adb994197c67776703b5d737a5787b5d0
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"
31 static ALfilter *g_FilterList;
32 static ALuint g_FilterCount;
34 static void InitFilterParams(ALfilter *filter, ALenum type);
37 AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
39 ALCcontext *Context;
40 ALsizei i;
42 Context = alcGetCurrentContext();
43 SuspendContext(Context);
45 if (n > 0)
47 // Check that enough memory has been allocted in the 'sources' array for n Sources
48 if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
50 ALfilter **list = &g_FilterList;
51 while(*list)
52 list = &(*list)->next;
54 i = 0;
55 while(i < n)
57 *list = calloc(1, sizeof(ALfilter));
58 if(!(*list))
60 // We must have run out or memory
61 alDeleteFilters(i, filters);
62 alSetError(AL_OUT_OF_MEMORY);
63 break;
66 filters[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
67 (*list)->filter = filters[i];
69 InitFilterParams(*list, AL_FILTER_NULL);
70 g_FilterCount++;
71 i++;
76 ProcessContext(Context);
79 AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
81 ALCcontext *Context;
82 ALfilter *ALFilter;
83 ALsizei i;
85 Context = alcGetCurrentContext();
86 SuspendContext(Context);
88 if (n >= 0)
90 // Check that all filters are valid
91 for (i = 0; i < n; i++)
93 if (!alIsFilter(filters[i]))
95 alSetError(AL_INVALID_NAME);
96 break;
100 if (i == n)
102 // All filters are valid
103 for (i = 0; i < n; i++)
105 // Recheck that the filter is valid, because there could be duplicated names
106 if (filters[i] && alIsFilter(filters[i]))
108 ALfilter **list;
110 ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
112 // Remove Source from list of Sources
113 list = &g_FilterList;
114 while(*list && *list != ALFilter)
115 list = &(*list)->next;
117 if(*list)
118 *list = (*list)->next;
119 ALTHUNK_REMOVEENTRY(ALFilter->filter);
121 memset(ALFilter, 0, sizeof(ALfilter));
122 free(ALFilter);
124 g_FilterCount--;
129 else
130 alSetError(AL_INVALID_VALUE);
132 ProcessContext(Context);
135 AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
137 ALCcontext *Context;
138 ALfilter **list;
140 Context = alcGetCurrentContext();
141 SuspendContext(Context);
143 list = &g_FilterList;
144 while(*list && (*list)->filter != filter)
145 list = &(*list)->next;
147 ProcessContext(Context);
149 return ((*list || !filter) ? AL_TRUE : AL_FALSE);
152 AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
154 ALCcontext *Context;
156 Context = alcGetCurrentContext();
157 SuspendContext(Context);
159 if (filter && alIsFilter(filter))
161 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
163 switch(param)
165 case AL_FILTER_TYPE:
166 if(iValue == AL_FILTER_NULL ||
167 iValue == AL_FILTER_LOWPASS)
168 InitFilterParams(ALFilter, iValue);
169 else
170 alSetError(AL_INVALID_VALUE);
171 break;
173 default:
174 alSetError(AL_INVALID_ENUM);
175 break;
178 else
179 alSetError(AL_INVALID_NAME);
181 ProcessContext(Context);
184 AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
186 ALCcontext *Context;
188 Context = alcGetCurrentContext();
189 SuspendContext(Context);
191 if (filter && alIsFilter(filter))
193 switch(param)
195 case AL_FILTER_TYPE:
196 alFilteri(filter, param, piValues[0]);
197 break;
199 default:
200 alSetError(AL_INVALID_ENUM);
201 break;
204 else
205 alSetError(AL_INVALID_NAME);
207 ProcessContext(Context);
210 AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
212 ALCcontext *Context;
214 Context = alcGetCurrentContext();
215 SuspendContext(Context);
217 if (filter && alIsFilter(filter))
219 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
221 switch(param)
223 case AL_LOWPASS_GAIN:
224 if(ALFilter->type == AL_FILTER_LOWPASS)
226 if(flValue >= 0.0f && flValue <= 1.0f)
227 ALFilter->Gain = flValue;
229 else
230 alSetError(AL_INVALID_ENUM);
231 break;
233 case AL_LOWPASS_GAINHF:
234 if(ALFilter->type == AL_FILTER_LOWPASS)
236 if(flValue >= 0.0f && flValue <= 1.0f)
237 ALFilter->GainHF = flValue;
239 else
240 alSetError(AL_INVALID_ENUM);
241 break;
243 default:
244 alSetError(AL_INVALID_ENUM);
245 break;
248 else
249 alSetError(AL_INVALID_NAME);
251 ProcessContext(Context);
254 AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
256 ALCcontext *Context;
258 Context = alcGetCurrentContext();
259 SuspendContext(Context);
261 if (filter && alIsFilter(filter))
263 switch(param)
265 case AL_LOWPASS_GAIN:
266 case AL_LOWPASS_GAINHF:
267 alFilterf(filter, param, pflValues[0]);
268 break;
270 default:
271 alSetError(AL_INVALID_ENUM);
272 break;
275 else
276 alSetError(AL_INVALID_NAME);
278 ProcessContext(Context);
281 AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
283 ALCcontext *Context;
285 (void)piValue;
287 Context = alcGetCurrentContext();
288 SuspendContext(Context);
290 if (filter && alIsFilter(filter))
292 switch(param)
294 default:
295 alSetError(AL_INVALID_ENUM);
296 break;
299 else
300 alSetError(AL_INVALID_NAME);
302 ProcessContext(Context);
305 AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
307 ALCcontext *Context;
309 (void)piValues;
311 Context = alcGetCurrentContext();
312 SuspendContext(Context);
314 if (filter && alIsFilter(filter))
316 switch(param)
318 default:
319 alSetError(AL_INVALID_ENUM);
320 break;
323 else
324 alSetError(AL_INVALID_NAME);
326 ProcessContext(Context);
329 AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
331 ALCcontext *Context;
333 Context = alcGetCurrentContext();
334 SuspendContext(Context);
336 if (filter && alIsFilter(filter))
338 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
340 switch(param)
342 case AL_LOWPASS_GAIN:
343 if(ALFilter->type == AL_FILTER_LOWPASS)
344 *pflValue = ALFilter->Gain;
345 else
346 alSetError(AL_INVALID_ENUM);
347 break;
349 case AL_LOWPASS_GAINHF:
350 if(ALFilter->type == AL_FILTER_LOWPASS)
351 *pflValue = ALFilter->GainHF;
352 else
353 alSetError(AL_INVALID_ENUM);
354 break;
356 default:
357 alSetError(AL_INVALID_ENUM);
358 break;
361 else
362 alSetError(AL_INVALID_NAME);
364 ProcessContext(Context);
367 AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
369 ALCcontext *Context;
371 Context = alcGetCurrentContext();
372 SuspendContext(Context);
374 if (filter && alIsFilter(filter))
376 switch(param)
378 case AL_LOWPASS_GAIN:
379 case AL_LOWPASS_GAINHF:
380 alGetFilterf(filter, param, pflValues);
381 break;
383 default:
384 alSetError(AL_INVALID_ENUM);
385 break;
388 else
389 alSetError(AL_INVALID_NAME);
391 ProcessContext(Context);
395 ALvoid ReleaseALFilters(ALvoid)
397 #ifdef _DEBUG
398 if(g_FilterCount > 0)
399 AL_PRINT("exit() %d Filter(s) NOT deleted\n", g_FilterCount);
400 #endif
402 while(g_FilterList)
404 ALfilter *temp = g_FilterList;
405 g_FilterList = g_FilterList->next;
407 // Release filter structure
408 memset(temp, 0, sizeof(ALfilter));
409 free(temp);
411 g_FilterCount = 0;
415 static void InitFilterParams(ALfilter *filter, ALenum type)
417 filter->type = type;
419 filter->Gain = 1.0;
420 filter->GainHF = 1.0;