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
33 static void InitFilterParams(ALfilter
*filter
, ALenum type
);
36 AL_API ALvoid AL_APIENTRY
alGenFilters(ALsizei n
, ALuint
*filters
)
41 Context
= GetContextRef();
44 if(n
< 0 || IsBadWritePtr((void*)filters
, n
* sizeof(ALuint
)))
45 alSetError(Context
, AL_INVALID_VALUE
);
48 ALCdevice
*device
= Context
->Device
;
53 ALfilter
*filter
= calloc(1, sizeof(ALfilter
));
56 alSetError(Context
, AL_OUT_OF_MEMORY
);
57 alDeleteFilters(i
, filters
);
60 InitFilterParams(filter
, AL_FILTER_NULL
);
62 err
= NewThunkEntry(&filter
->id
);
63 if(err
== AL_NO_ERROR
)
64 err
= InsertUIntMapEntry(&device
->FilterMap
, filter
->id
, filter
);
65 if(err
!= AL_NO_ERROR
)
67 FreeThunkEntry(filter
->id
);
68 memset(filter
, 0, sizeof(ALfilter
));
71 alSetError(Context
, err
);
72 alDeleteFilters(i
, filters
);
76 filters
[i
] = filter
->id
;
80 ALCcontext_DecRef(Context
);
83 AL_API ALvoid AL_APIENTRY
alDeleteFilters(ALsizei n
, const ALuint
*filters
)
90 Context
= GetContextRef();
93 device
= Context
->Device
;
95 alSetError(Context
, AL_INVALID_VALUE
);
98 // Check that all filters are valid
104 if(LookupFilter(device
, filters
[i
]) == NULL
)
106 alSetError(Context
, AL_INVALID_NAME
);
114 // Recheck that the filter is valid, because there could be duplicated names
115 if((ALFilter
=RemoveFilter(device
, filters
[i
])) == NULL
)
117 FreeThunkEntry(ALFilter
->id
);
119 memset(ALFilter
, 0, sizeof(ALfilter
));
124 ALCcontext_DecRef(Context
);
127 AL_API ALboolean AL_APIENTRY
alIsFilter(ALuint filter
)
132 Context
= GetContextRef();
133 if(!Context
) return AL_FALSE
;
135 result
= ((!filter
|| LookupFilter(Context
->Device
, filter
)) ?
138 ALCcontext_DecRef(Context
);
143 AL_API ALvoid AL_APIENTRY
alFilteri(ALuint filter
, ALenum param
, ALint value
)
149 Context
= GetContextRef();
152 Device
= Context
->Device
;
153 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
154 alSetError(Context
, AL_INVALID_NAME
);
157 if(param
== AL_FILTER_TYPE
)
159 if(value
== AL_FILTER_NULL
|| value
== AL_FILTER_LOWPASS
)
160 InitFilterParams(ALFilter
, value
);
162 alSetError(Context
, AL_INVALID_VALUE
);
166 /* Call the appropriate handler */
167 ALfilter_SetParami(ALFilter
, Context
, param
, value
);
171 ALCcontext_DecRef(Context
);
174 AL_API ALvoid AL_APIENTRY
alFilteriv(ALuint filter
, ALenum param
, const ALint
*values
)
183 alFilteri(filter
, param
, values
[0]);
187 Context
= GetContextRef();
190 Device
= Context
->Device
;
191 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
192 alSetError(Context
, AL_INVALID_NAME
);
195 /* Call the appropriate handler */
196 ALfilter_SetParamiv(ALFilter
, Context
, param
, values
);
199 ALCcontext_DecRef(Context
);
202 AL_API ALvoid AL_APIENTRY
alFilterf(ALuint filter
, ALenum param
, ALfloat value
)
208 Context
= GetContextRef();
211 Device
= Context
->Device
;
212 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
213 alSetError(Context
, AL_INVALID_NAME
);
216 /* Call the appropriate handler */
217 ALfilter_SetParamf(ALFilter
, Context
, param
, value
);
220 ALCcontext_DecRef(Context
);
223 AL_API ALvoid AL_APIENTRY
alFilterfv(ALuint filter
, ALenum param
, const ALfloat
*values
)
229 Context
= GetContextRef();
232 Device
= Context
->Device
;
233 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
234 alSetError(Context
, AL_INVALID_NAME
);
237 /* Call the appropriate handler */
238 ALfilter_SetParamfv(ALFilter
, Context
, param
, values
);
241 ALCcontext_DecRef(Context
);
244 AL_API ALvoid AL_APIENTRY
alGetFilteri(ALuint filter
, ALenum param
, ALint
*value
)
250 Context
= GetContextRef();
253 Device
= Context
->Device
;
254 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
255 alSetError(Context
, AL_INVALID_NAME
);
258 if(param
== AL_FILTER_TYPE
)
259 *value
= ALFilter
->type
;
262 /* Call the appropriate handler */
263 ALfilter_GetParami(ALFilter
, Context
, param
, value
);
267 ALCcontext_DecRef(Context
);
270 AL_API ALvoid AL_APIENTRY
alGetFilteriv(ALuint filter
, ALenum param
, ALint
*values
)
279 alGetFilteri(filter
, param
, values
);
283 Context
= GetContextRef();
286 Device
= Context
->Device
;
287 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
288 alSetError(Context
, AL_INVALID_NAME
);
291 /* Call the appropriate handler */
292 ALfilter_GetParamiv(ALFilter
, Context
, param
, values
);
295 ALCcontext_DecRef(Context
);
298 AL_API ALvoid AL_APIENTRY
alGetFilterf(ALuint filter
, ALenum param
, ALfloat
*value
)
304 Context
= GetContextRef();
307 Device
= Context
->Device
;
308 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
309 alSetError(Context
, AL_INVALID_NAME
);
312 /* Call the appropriate handler */
313 ALfilter_GetParamf(ALFilter
, Context
, param
, value
);
316 ALCcontext_DecRef(Context
);
319 AL_API ALvoid AL_APIENTRY
alGetFilterfv(ALuint filter
, ALenum param
, ALfloat
*values
)
325 Context
= GetContextRef();
328 Device
= Context
->Device
;
329 if((ALFilter
=LookupFilter(Device
, filter
)) == NULL
)
330 alSetError(Context
, AL_INVALID_NAME
);
333 /* Call the appropriate handler */
334 ALfilter_GetParamfv(ALFilter
, Context
, param
, values
);
337 ALCcontext_DecRef(Context
);
341 ALfloat
lpCoeffCalc(ALfloat g
, ALfloat cw
)
345 /* Be careful with gains < 0.001, as that causes the coefficient head
346 * towards 1, which will flatten the signal */
347 if(g
< 0.9999f
) /* 1-epsilon */
350 a
= (1 - g
*cw
- aluSqrt(2*g
*(1-cw
) - g
*g
*(1 - cw
*cw
))) /
358 static void lp_SetParami(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint val
)
359 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
360 static void lp_SetParamiv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, const ALint
*vals
)
361 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
362 static void lp_SetParamf(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat val
)
366 case AL_LOWPASS_GAIN
:
367 if(val
>= AL_LOWPASS_MIN_GAIN
&& val
<= AL_LOWPASS_MAX_GAIN
)
370 alSetError(context
, AL_INVALID_VALUE
);
373 case AL_LOWPASS_GAINHF
:
374 if(val
>= AL_LOWPASS_MIN_GAINHF
&& val
<= AL_LOWPASS_MAX_GAINHF
)
375 filter
->GainHF
= val
;
377 alSetError(context
, AL_INVALID_VALUE
);
381 alSetError(context
, AL_INVALID_ENUM
);
385 static void lp_SetParamfv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, const ALfloat
*vals
)
387 lp_SetParamf(filter
, context
, param
, vals
[0]);
390 static void lp_GetParami(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint
*val
)
391 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
392 static void lp_GetParamiv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint
*vals
)
393 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
394 static void lp_GetParamf(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat
*val
)
398 case AL_LOWPASS_GAIN
:
402 case AL_LOWPASS_GAINHF
:
403 *val
= filter
->GainHF
;
407 alSetError(context
, AL_INVALID_ENUM
);
411 static void lp_GetParamfv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat
*vals
)
413 lp_GetParamf(filter
, context
, param
, vals
);
417 static void null_SetParami(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint val
)
418 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
419 static void null_SetParamiv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, const ALint
*vals
)
420 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
421 static void null_SetParamf(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat val
)
422 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
423 static void null_SetParamfv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, const ALfloat
*vals
)
424 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
426 static void null_GetParami(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint
*val
)
427 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
428 static void null_GetParamiv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALint
*vals
)
429 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
430 static void null_GetParamf(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat
*val
)
431 { (void)filter
;(void)param
;(void)val
; alSetError(context
, AL_INVALID_ENUM
); }
432 static void null_GetParamfv(ALfilter
*filter
, ALCcontext
*context
, ALenum param
, ALfloat
*vals
)
433 { (void)filter
;(void)param
;(void)vals
; alSetError(context
, AL_INVALID_ENUM
); }
436 ALvoid
ReleaseALFilters(ALCdevice
*device
)
439 for(i
= 0;i
< device
->FilterMap
.size
;i
++)
441 ALfilter
*temp
= device
->FilterMap
.array
[i
].value
;
442 device
->FilterMap
.array
[i
].value
= NULL
;
444 // Release filter structure
445 FreeThunkEntry(temp
->id
);
446 memset(temp
, 0, sizeof(ALfilter
));
452 static void InitFilterParams(ALfilter
*filter
, ALenum type
)
454 if(type
== AL_FILTER_LOWPASS
)
456 filter
->Gain
= AL_LOWPASS_DEFAULT_GAIN
;
457 filter
->GainHF
= AL_LOWPASS_DEFAULT_GAINHF
;
459 filter
->SetParami
= lp_SetParami
;
460 filter
->SetParamiv
= lp_SetParamiv
;
461 filter
->SetParamf
= lp_SetParamf
;
462 filter
->SetParamfv
= lp_SetParamfv
;
463 filter
->GetParami
= lp_GetParami
;
464 filter
->GetParamiv
= lp_GetParamiv
;
465 filter
->GetParamf
= lp_GetParamf
;
466 filter
->GetParamfv
= lp_GetParamfv
;
470 filter
->SetParami
= null_SetParami
;
471 filter
->SetParamiv
= null_SetParamiv
;
472 filter
->SetParamf
= null_SetParamf
;
473 filter
->SetParamfv
= null_SetParamfv
;
474 filter
->GetParami
= null_GetParami
;
475 filter
->GetParamiv
= null_GetParamiv
;
476 filter
->GetParamf
= null_GetParamf
;
477 filter
->GetParamfv
= null_GetParamfv
;