comparison ext/openal-soft/OpenAL32/alEffect.c @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
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.
8 *
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.
13 *
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
19 */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24
25 #include "AL/al.h"
26 #include "AL/alc.h"
27 #include "alMain.h"
28 #include "alEffect.h"
29 #include "alThunk.h"
30 #include "alError.h"
31
32 static ALeffect *g_EffectList;
33 static ALuint g_EffectCount;
34
35 static void InitEffectParams(ALeffect *effect, ALenum type);
36
37
38 AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
39 {
40 ALCcontext *Context;
41 ALsizei i;
42
43 Context = alcGetCurrentContext();
44 SuspendContext(Context);
45
46 if (n > 0)
47 {
48 // Check that enough memory has been allocted in the 'effects' array for n Effects
49 if (!IsBadWritePtr((void*)effects, n * sizeof(ALuint)))
50 {
51 ALeffect **list = &g_EffectList;
52 while(*list)
53 list = &(*list)->next;
54
55 i = 0;
56 while(i < n)
57 {
58 *list = calloc(1, sizeof(ALeffect));
59 if(!(*list))
60 {
61 // We must have run out or memory
62 alDeleteEffects(i, effects);
63 alSetError(AL_OUT_OF_MEMORY);
64 break;
65 }
66
67 effects[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
68 (*list)->effect = effects[i];
69
70 InitEffectParams(*list, AL_EFFECT_NULL);
71 g_EffectCount++;
72 i++;
73
74 list = &(*list)->next;
75 }
76 }
77 }
78
79 ProcessContext(Context);
80 }
81
82 AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects)
83 {
84 ALCcontext *Context;
85 ALeffect *ALEffect;
86 ALsizei i;
87
88 Context = alcGetCurrentContext();
89 SuspendContext(Context);
90
91 if (n >= 0)
92 {
93 // Check that all effects are valid
94 for (i = 0; i < n; i++)
95 {
96 if (!alIsEffect(effects[i]))
97 {
98 alSetError(AL_INVALID_NAME);
99 break;
100 }
101 }
102
103 if (i == n)
104 {
105 // All effects are valid
106 for (i = 0; i < n; i++)
107 {
108 // Recheck that the effect is valid, because there could be duplicated names
109 if (effects[i] && alIsEffect(effects[i]))
110 {
111 ALeffect **list;
112
113 ALEffect = ((ALeffect*)ALTHUNK_LOOKUPENTRY(effects[i]));
114
115 // Remove Source from list of Sources
116 list = &g_EffectList;
117 while(*list && *list != ALEffect)
118 list = &(*list)->next;
119
120 if(*list)
121 *list = (*list)->next;
122 ALTHUNK_REMOVEENTRY(ALEffect->effect);
123
124 memset(ALEffect, 0, sizeof(ALeffect));
125 free(ALEffect);
126
127 g_EffectCount--;
128 }
129 }
130 }
131 }
132 else
133 alSetError(AL_INVALID_VALUE);
134
135 ProcessContext(Context);
136 }
137
138 AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
139 {
140 ALCcontext *Context;
141 ALeffect **list;
142
143 Context = alcGetCurrentContext();
144 SuspendContext(Context);
145
146 list = &g_EffectList;
147 while(*list && (*list)->effect != effect)
148 list = &(*list)->next;
149
150 ProcessContext(Context);
151
152 return ((*list || !effect) ? AL_TRUE : AL_FALSE);
153 }
154
155 AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
156 {
157 ALCcontext *Context;
158
159 Context = alcGetCurrentContext();
160 SuspendContext(Context);
161
162 if (effect && alIsEffect(effect))
163 {
164 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
165
166 if(param == AL_EFFECT_TYPE)
167 {
168 if(iValue == AL_EFFECT_NULL ||
169 iValue == AL_EFFECT_REVERB)
170 InitEffectParams(ALEffect, iValue);
171 else
172 alSetError(AL_INVALID_VALUE);
173 }
174 else if(ALEffect->type == AL_EFFECT_REVERB)
175 {
176 switch(param)
177 {
178 case AL_REVERB_DECAY_HFLIMIT:
179 if(iValue == AL_TRUE || iValue == AL_FALSE)
180 ALEffect->Reverb.DecayHFLimit = iValue;
181 else
182 alSetError(AL_INVALID_VALUE);
183 break;
184
185 default:
186 alSetError(AL_INVALID_ENUM);
187 break;
188 }
189 }
190 else
191 alSetError(AL_INVALID_ENUM);
192 }
193 else
194 alSetError(AL_INVALID_NAME);
195
196 ProcessContext(Context);
197 }
198
199 AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues)
200 {
201 ALCcontext *Context;
202
203 Context = alcGetCurrentContext();
204 SuspendContext(Context);
205
206 if (effect && alIsEffect(effect))
207 {
208 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
209
210 if(param == AL_EFFECT_TYPE)
211 {
212 alEffecti(effect, param, piValues[0]);
213 }
214 else if(ALEffect->type == AL_EFFECT_REVERB)
215 {
216 switch(param)
217 {
218 case AL_REVERB_DECAY_HFLIMIT:
219 alEffecti(effect, param, piValues[0]);
220 break;
221
222 default:
223 alSetError(AL_INVALID_ENUM);
224 break;
225 }
226 }
227 else
228 alSetError(AL_INVALID_ENUM);
229 }
230 else
231 alSetError(AL_INVALID_NAME);
232
233 ProcessContext(Context);
234 }
235
236 AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue)
237 {
238 ALCcontext *Context;
239
240 Context = alcGetCurrentContext();
241 SuspendContext(Context);
242
243 if (effect && alIsEffect(effect))
244 {
245 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
246
247 if(ALEffect->type == AL_EFFECT_REVERB)
248 {
249 switch(param)
250 {
251 case AL_REVERB_DENSITY:
252 if(flValue >= 0.0f && flValue <= 1.0f)
253 ALEffect->Reverb.Density = flValue;
254 else
255 alSetError(AL_INVALID_VALUE);
256 break;
257
258 case AL_REVERB_DIFFUSION:
259 if(flValue >= 0.0f && flValue <= 1.0f)
260 ALEffect->Reverb.Diffusion = flValue;
261 else
262 alSetError(AL_INVALID_VALUE);
263 break;
264
265 case AL_REVERB_GAIN:
266 if(flValue >= 0.0f && flValue <= 1.0f)
267 ALEffect->Reverb.Gain = flValue;
268 else
269 alSetError(AL_INVALID_VALUE);
270 break;
271
272 case AL_REVERB_GAINHF:
273 if(flValue >= 0.0f && flValue <= 1.0f)
274 ALEffect->Reverb.GainHF = flValue;
275 else
276 alSetError(AL_INVALID_VALUE);
277 break;
278
279 case AL_REVERB_DECAY_TIME:
280 if(flValue >= 0.1f && flValue <= 20.0f)
281 ALEffect->Reverb.DecayTime = flValue;
282 else
283 alSetError(AL_INVALID_VALUE);
284 break;
285
286 case AL_REVERB_DECAY_HFRATIO:
287 if(flValue >= 0.1f && flValue <= 2.0f)
288 ALEffect->Reverb.DecayHFRatio = flValue;
289 else
290 alSetError(AL_INVALID_VALUE);
291 break;
292
293 case AL_REVERB_REFLECTIONS_GAIN:
294 if(flValue >= 0.0f && flValue <= 3.16f)
295 ALEffect->Reverb.ReflectionsGain = flValue;
296 else
297 alSetError(AL_INVALID_VALUE);
298 break;
299
300 case AL_REVERB_REFLECTIONS_DELAY:
301 if(flValue >= 0.0f && flValue <= 0.3f)
302 ALEffect->Reverb.ReflectionsDelay = flValue;
303 else
304 alSetError(AL_INVALID_VALUE);
305 break;
306
307 case AL_REVERB_LATE_REVERB_GAIN:
308 if(flValue >= 0.0f && flValue <= 10.0f)
309 ALEffect->Reverb.LateReverbGain = flValue;
310 else
311 alSetError(AL_INVALID_VALUE);
312 break;
313
314 case AL_REVERB_LATE_REVERB_DELAY:
315 if(flValue >= 0.0f && flValue <= 0.1f)
316 ALEffect->Reverb.LateReverbDelay = flValue;
317 else
318 alSetError(AL_INVALID_VALUE);
319 break;
320
321 case AL_REVERB_AIR_ABSORPTION_GAINHF:
322 if(flValue >= 0.892f && flValue <= 1.0f)
323 ALEffect->Reverb.AirAbsorptionGainHF = flValue;
324 else
325 alSetError(AL_INVALID_VALUE);
326 break;
327
328 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
329 if(flValue >= 0.0f && flValue <= 10.0f)
330 ALEffect->Reverb.RoomRolloffFactor = flValue;
331 else
332 alSetError(AL_INVALID_VALUE);
333 break;
334
335 default:
336 alSetError(AL_INVALID_ENUM);
337 break;
338 }
339 }
340 else
341 alSetError(AL_INVALID_ENUM);
342 }
343 else
344 alSetError(AL_INVALID_NAME);
345
346 ProcessContext(Context);
347 }
348
349 AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
350 {
351 ALCcontext *Context;
352
353 Context = alcGetCurrentContext();
354 SuspendContext(Context);
355
356 if (effect && alIsEffect(effect))
357 {
358 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
359
360 if(ALEffect->type == AL_EFFECT_REVERB)
361 {
362 switch(param)
363 {
364 case AL_REVERB_DENSITY:
365 case AL_REVERB_DIFFUSION:
366 case AL_REVERB_GAIN:
367 case AL_REVERB_GAINHF:
368 case AL_REVERB_DECAY_TIME:
369 case AL_REVERB_DECAY_HFRATIO:
370 case AL_REVERB_REFLECTIONS_GAIN:
371 case AL_REVERB_REFLECTIONS_DELAY:
372 case AL_REVERB_LATE_REVERB_GAIN:
373 case AL_REVERB_LATE_REVERB_DELAY:
374 case AL_REVERB_AIR_ABSORPTION_GAINHF:
375 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
376 alEffectf(effect, param, pflValues[0]);
377 break;
378
379 default:
380 alSetError(AL_INVALID_ENUM);
381 break;
382 }
383 }
384 else
385 alSetError(AL_INVALID_ENUM);
386 }
387 else
388 alSetError(AL_INVALID_NAME);
389
390 ProcessContext(Context);
391 }
392
393 AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue)
394 {
395 ALCcontext *Context;
396
397 Context = alcGetCurrentContext();
398 SuspendContext(Context);
399
400 if (effect && alIsEffect(effect))
401 {
402 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
403
404 if(param == AL_EFFECT_TYPE)
405 {
406 *piValue = ALEffect->type;
407 }
408 else if(ALEffect->type == AL_EFFECT_REVERB)
409 {
410 switch(param)
411 {
412 case AL_REVERB_DECAY_HFLIMIT:
413 *piValue = ALEffect->Reverb.DecayHFLimit;
414 break;
415
416 default:
417 alSetError(AL_INVALID_ENUM);
418 break;
419 }
420 }
421 else
422 alSetError(AL_INVALID_ENUM);
423 }
424 else
425 alSetError(AL_INVALID_NAME);
426
427 ProcessContext(Context);
428 }
429
430 AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues)
431 {
432 ALCcontext *Context;
433
434 Context = alcGetCurrentContext();
435 SuspendContext(Context);
436
437 if (effect && alIsEffect(effect))
438 {
439 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
440
441 if(param == AL_EFFECT_TYPE)
442 {
443 alGetEffecti(effect, param, piValues);
444 }
445 else if(ALEffect->type == AL_EFFECT_REVERB)
446 {
447 switch(param)
448 {
449 case AL_REVERB_DECAY_HFLIMIT:
450 alGetEffecti(effect, param, piValues);
451 break;
452
453 default:
454 alSetError(AL_INVALID_ENUM);
455 break;
456 }
457 }
458 else
459 alSetError(AL_INVALID_ENUM);
460 }
461 else
462 alSetError(AL_INVALID_NAME);
463
464 ProcessContext(Context);
465 }
466
467 AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue)
468 {
469 ALCcontext *Context;
470
471 Context = alcGetCurrentContext();
472 SuspendContext(Context);
473
474 if (effect && alIsEffect(effect))
475 {
476 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
477
478 if(ALEffect->type == AL_EFFECT_REVERB)
479 {
480 switch(param)
481 {
482 case AL_REVERB_DENSITY:
483 *pflValue = ALEffect->Reverb.Density;
484 break;
485
486 case AL_REVERB_DIFFUSION:
487 *pflValue = ALEffect->Reverb.Diffusion;
488 break;
489
490 case AL_REVERB_GAIN:
491 *pflValue = ALEffect->Reverb.Gain;
492 break;
493
494 case AL_REVERB_GAINHF:
495 *pflValue = ALEffect->Reverb.GainHF;
496 break;
497
498 case AL_REVERB_DECAY_TIME:
499 *pflValue = ALEffect->Reverb.DecayTime;
500 break;
501
502 case AL_REVERB_DECAY_HFRATIO:
503 *pflValue = ALEffect->Reverb.DecayHFRatio;
504 break;
505
506 case AL_REVERB_REFLECTIONS_GAIN:
507 *pflValue = ALEffect->Reverb.ReflectionsGain;
508 break;
509
510 case AL_REVERB_REFLECTIONS_DELAY:
511 *pflValue = ALEffect->Reverb.ReflectionsDelay;
512 break;
513
514 case AL_REVERB_LATE_REVERB_GAIN:
515 *pflValue = ALEffect->Reverb.LateReverbGain;
516 break;
517
518 case AL_REVERB_LATE_REVERB_DELAY:
519 *pflValue = ALEffect->Reverb.LateReverbDelay;
520 break;
521
522 case AL_REVERB_AIR_ABSORPTION_GAINHF:
523 *pflValue = ALEffect->Reverb.AirAbsorptionGainHF;
524 break;
525
526 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
527 *pflValue = ALEffect->Reverb.RoomRolloffFactor;
528 break;
529
530 default:
531 alSetError(AL_INVALID_ENUM);
532 break;
533 }
534 }
535 else
536 alSetError(AL_INVALID_ENUM);
537 }
538 else
539 alSetError(AL_INVALID_NAME);
540
541 ProcessContext(Context);
542 }
543
544 AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
545 {
546 ALCcontext *Context;
547
548 Context = alcGetCurrentContext();
549 SuspendContext(Context);
550
551 if (effect && alIsEffect(effect))
552 {
553 ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect);
554
555 if(ALEffect->type == AL_EFFECT_REVERB)
556 {
557 switch(param)
558 {
559 case AL_REVERB_DENSITY:
560 case AL_REVERB_DIFFUSION:
561 case AL_REVERB_GAIN:
562 case AL_REVERB_GAINHF:
563 case AL_REVERB_DECAY_TIME:
564 case AL_REVERB_DECAY_HFRATIO:
565 case AL_REVERB_REFLECTIONS_GAIN:
566 case AL_REVERB_REFLECTIONS_DELAY:
567 case AL_REVERB_LATE_REVERB_GAIN:
568 case AL_REVERB_LATE_REVERB_DELAY:
569 case AL_REVERB_AIR_ABSORPTION_GAINHF:
570 case AL_REVERB_ROOM_ROLLOFF_FACTOR:
571 alGetEffectf(effect, param, pflValues);
572 break;
573
574 default:
575 alSetError(AL_INVALID_ENUM);
576 break;
577 }
578 }
579 else
580 alSetError(AL_INVALID_ENUM);
581 }
582 else
583 alSetError(AL_INVALID_NAME);
584
585 ProcessContext(Context);
586 }
587
588
589 ALvoid ReleaseALEffects(ALvoid)
590 {
591 #ifdef _DEBUG
592 if(g_EffectCount > 0)
593 AL_PRINT("exit() %d Effect(s) NOT deleted\n", g_EffectCount);
594 #endif
595
596 while(g_EffectList)
597 {
598 ALeffect *temp = g_EffectList;
599 g_EffectList = g_EffectList->next;
600
601 // Release effect structure
602 memset(temp, 0, sizeof(ALeffect));
603 free(temp);
604 }
605 g_EffectCount = 0;
606 }
607
608
609 static void InitEffectParams(ALeffect *effect, ALenum type)
610 {
611 effect->type = type;
612 switch(type)
613 {
614 case AL_EFFECT_REVERB:
615 effect->Reverb.Density = 1.0f;
616 effect->Reverb.Diffusion = 1.0f;
617 effect->Reverb.Gain = 0.32f;
618 effect->Reverb.GainHF = 0.89f;
619 effect->Reverb.DecayTime = 1.49f;
620 effect->Reverb.DecayHFRatio = 0.83f;
621 effect->Reverb.ReflectionsGain = 0.05f;
622 effect->Reverb.ReflectionsDelay = 0.007f;
623 effect->Reverb.LateReverbGain = 1.26f;
624 effect->Reverb.LateReverbDelay = 0.011f;
625 effect->Reverb.AirAbsorptionGainHF = 0.994f;
626 effect->Reverb.RoomRolloffFactor = 0.0f;
627 effect->Reverb.DecayHFLimit = AL_TRUE;
628 break;
629 }
630 }