Seperate data converters into reusable functions
[openal-soft.git] / OpenAL32 / alFilter.c
blobb25a80934b76c8527e3ccc75e05a4710252ae041
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 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 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 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 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 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 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(ALFilter->type)
226 case AL_FILTER_LOWPASS:
227 switch(param)
229 case AL_LOWPASS_GAIN:
230 if(flValue >= 0.0f && flValue <= 1.0f)
231 ALFilter->Gain = flValue;
232 else
233 alSetError(AL_INVALID_VALUE);
234 break;
236 case AL_LOWPASS_GAINHF:
237 if(flValue >= 0.0f && flValue <= 1.0f)
238 ALFilter->GainHF = flValue;
239 else
240 alSetError(AL_INVALID_VALUE);
241 break;
243 default:
244 alSetError(AL_INVALID_ENUM);
245 break;
247 break;
249 default:
250 alSetError(AL_INVALID_ENUM);
251 break;
254 else
255 alSetError(AL_INVALID_NAME);
257 ProcessContext(Context);
260 ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
262 ALCcontext *Context;
264 Context = alcGetCurrentContext();
265 SuspendContext(Context);
267 if (filter && alIsFilter(filter))
269 switch(param)
271 default:
272 alFilterf(filter, param, pflValues[0]);
273 break;
276 else
277 alSetError(AL_INVALID_NAME);
279 ProcessContext(Context);
282 ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
284 ALCcontext *Context;
286 Context = alcGetCurrentContext();
287 SuspendContext(Context);
289 if (filter && alIsFilter(filter))
291 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
293 switch(param)
295 case AL_FILTER_TYPE:
296 *piValue = ALFilter->type;
297 break;
299 default:
300 alSetError(AL_INVALID_ENUM);
301 break;
304 else
305 alSetError(AL_INVALID_NAME);
307 ProcessContext(Context);
310 ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
312 ALCcontext *Context;
314 Context = alcGetCurrentContext();
315 SuspendContext(Context);
317 if (filter && alIsFilter(filter))
319 switch(param)
321 case AL_FILTER_TYPE:
322 alGetFilteri(filter, param, piValues);
323 break;
325 default:
326 alSetError(AL_INVALID_ENUM);
327 break;
330 else
331 alSetError(AL_INVALID_NAME);
333 ProcessContext(Context);
336 ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
338 ALCcontext *Context;
340 Context = alcGetCurrentContext();
341 SuspendContext(Context);
343 if (filter && alIsFilter(filter))
345 ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter);
347 switch(ALFilter->type)
349 case AL_FILTER_LOWPASS:
350 switch(param)
352 case AL_LOWPASS_GAIN:
353 *pflValue = ALFilter->Gain;
354 break;
356 case AL_LOWPASS_GAINHF:
357 *pflValue = ALFilter->GainHF;
358 break;
360 default:
361 alSetError(AL_INVALID_ENUM);
362 break;
364 break;
366 default:
367 alSetError(AL_INVALID_ENUM);
368 break;
371 else
372 alSetError(AL_INVALID_NAME);
374 ProcessContext(Context);
377 ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
379 ALCcontext *Context;
381 Context = alcGetCurrentContext();
382 SuspendContext(Context);
384 if (filter && alIsFilter(filter))
386 switch(param)
388 default:
389 alGetFilterf(filter, param, pflValues);
390 break;
393 else
394 alSetError(AL_INVALID_NAME);
396 ProcessContext(Context);
400 ALvoid ReleaseALFilters(ALvoid)
402 #ifdef _DEBUG
403 if(g_FilterCount > 0)
404 AL_PRINT("exit(): deleting %d Filter(s)\n", g_FilterCount);
405 #endif
407 while(g_FilterList)
409 ALfilter *temp = g_FilterList;
410 g_FilterList = g_FilterList->next;
412 // Release filter structure
413 memset(temp, 0, sizeof(ALfilter));
414 free(temp);
416 g_FilterCount = 0;
420 static void InitFilterParams(ALfilter *filter, ALenum type)
422 filter->type = type;
424 filter->Gain = 1.0;
425 filter->GainHF = 1.0;