Decorrelate the early reflection inputs
[openal-soft.git] / OpenAL32 / alState.c
blob3d8e6c404496605428fecc8b1cbb20411a4cc9fa
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2000 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.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include "alMain.h"
25 #include "AL/alc.h"
26 #include "AL/al.h"
27 #include "AL/alext.h"
28 #include "alError.h"
29 #include "alListener.h"
30 #include "alSource.h"
31 #include "alAuxEffectSlot.h"
33 #include "backends/base.h"
36 static const ALchar alVendor[] = "OpenAL Community";
37 static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
38 static const ALchar alRenderer[] = "OpenAL Soft";
40 // Error Messages
41 static const ALchar alNoError[] = "No Error";
42 static const ALchar alErrInvalidName[] = "Invalid Name";
43 static const ALchar alErrInvalidEnum[] = "Invalid Enum";
44 static const ALchar alErrInvalidValue[] = "Invalid Value";
45 static const ALchar alErrInvalidOp[] = "Invalid Operation";
46 static const ALchar alErrOutOfMemory[] = "Out of Memory";
48 AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
50 ALCcontext *context;
52 context = GetContextRef();
53 if(!context) return;
55 WriteLock(&context->PropLock);
56 switch(capability)
58 case AL_SOURCE_DISTANCE_MODEL:
59 context->SourceDistanceModel = AL_TRUE;
60 break;
62 default:
63 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
65 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
66 UpdateListenerProps(context);
68 done:
69 WriteUnlock(&context->PropLock);
70 ALCcontext_DecRef(context);
73 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
75 ALCcontext *context;
77 context = GetContextRef();
78 if(!context) return;
80 WriteLock(&context->PropLock);
81 switch(capability)
83 case AL_SOURCE_DISTANCE_MODEL:
84 context->SourceDistanceModel = AL_FALSE;
85 break;
87 default:
88 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
90 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
91 UpdateListenerProps(context);
93 done:
94 WriteUnlock(&context->PropLock);
95 ALCcontext_DecRef(context);
98 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
100 ALCcontext *context;
101 ALboolean value=AL_FALSE;
103 context = GetContextRef();
104 if(!context) return AL_FALSE;
106 switch(capability)
108 case AL_SOURCE_DISTANCE_MODEL:
109 value = context->SourceDistanceModel;
110 break;
112 default:
113 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
116 done:
117 ALCcontext_DecRef(context);
119 return value;
122 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
124 ALCcontext *context;
125 ALboolean value=AL_FALSE;
127 context = GetContextRef();
128 if(!context) return AL_FALSE;
130 switch(pname)
132 case AL_DOPPLER_FACTOR:
133 if(context->DopplerFactor != 0.0f)
134 value = AL_TRUE;
135 break;
137 case AL_DOPPLER_VELOCITY:
138 if(context->DopplerVelocity != 0.0f)
139 value = AL_TRUE;
140 break;
142 case AL_DISTANCE_MODEL:
143 if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
144 value = AL_TRUE;
145 break;
147 case AL_SPEED_OF_SOUND:
148 if(context->SpeedOfSound != 0.0f)
149 value = AL_TRUE;
150 break;
152 case AL_DEFERRED_UPDATES_SOFT:
153 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
154 value = AL_TRUE;
155 break;
157 case AL_GAIN_LIMIT_SOFT:
158 if(GAIN_MIX_MAX/context->GainBoost != 0.0f)
159 value = AL_TRUE;
160 break;
162 default:
163 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
166 done:
167 ALCcontext_DecRef(context);
169 return value;
172 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
174 ALCcontext *context;
175 ALdouble value = 0.0;
177 context = GetContextRef();
178 if(!context) return 0.0;
180 switch(pname)
182 case AL_DOPPLER_FACTOR:
183 value = (ALdouble)context->DopplerFactor;
184 break;
186 case AL_DOPPLER_VELOCITY:
187 value = (ALdouble)context->DopplerVelocity;
188 break;
190 case AL_DISTANCE_MODEL:
191 value = (ALdouble)context->DistanceModel;
192 break;
194 case AL_SPEED_OF_SOUND:
195 value = (ALdouble)context->SpeedOfSound;
196 break;
198 case AL_DEFERRED_UPDATES_SOFT:
199 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
200 value = (ALdouble)AL_TRUE;
201 break;
203 case AL_GAIN_LIMIT_SOFT:
204 value = (ALdouble)GAIN_MIX_MAX/context->GainBoost;
205 break;
207 default:
208 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
211 done:
212 ALCcontext_DecRef(context);
214 return value;
217 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
219 ALCcontext *context;
220 ALfloat value = 0.0f;
222 context = GetContextRef();
223 if(!context) return 0.0f;
225 switch(pname)
227 case AL_DOPPLER_FACTOR:
228 value = context->DopplerFactor;
229 break;
231 case AL_DOPPLER_VELOCITY:
232 value = context->DopplerVelocity;
233 break;
235 case AL_DISTANCE_MODEL:
236 value = (ALfloat)context->DistanceModel;
237 break;
239 case AL_SPEED_OF_SOUND:
240 value = context->SpeedOfSound;
241 break;
243 case AL_DEFERRED_UPDATES_SOFT:
244 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
245 value = (ALfloat)AL_TRUE;
246 break;
248 case AL_GAIN_LIMIT_SOFT:
249 value = GAIN_MIX_MAX/context->GainBoost;
250 break;
252 default:
253 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
256 done:
257 ALCcontext_DecRef(context);
259 return value;
262 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
264 ALCcontext *context;
265 ALint value = 0;
267 context = GetContextRef();
268 if(!context) return 0;
270 switch(pname)
272 case AL_DOPPLER_FACTOR:
273 value = (ALint)context->DopplerFactor;
274 break;
276 case AL_DOPPLER_VELOCITY:
277 value = (ALint)context->DopplerVelocity;
278 break;
280 case AL_DISTANCE_MODEL:
281 value = (ALint)context->DistanceModel;
282 break;
284 case AL_SPEED_OF_SOUND:
285 value = (ALint)context->SpeedOfSound;
286 break;
288 case AL_DEFERRED_UPDATES_SOFT:
289 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
290 value = (ALint)AL_TRUE;
291 break;
293 case AL_GAIN_LIMIT_SOFT:
294 value = (ALint)(GAIN_MIX_MAX/context->GainBoost);
295 break;
297 default:
298 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
301 done:
302 ALCcontext_DecRef(context);
304 return value;
307 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
309 ALCcontext *context;
310 ALint64SOFT value = 0;
312 context = GetContextRef();
313 if(!context) return 0;
315 switch(pname)
317 case AL_DOPPLER_FACTOR:
318 value = (ALint64SOFT)context->DopplerFactor;
319 break;
321 case AL_DOPPLER_VELOCITY:
322 value = (ALint64SOFT)context->DopplerVelocity;
323 break;
325 case AL_DISTANCE_MODEL:
326 value = (ALint64SOFT)context->DistanceModel;
327 break;
329 case AL_SPEED_OF_SOUND:
330 value = (ALint64SOFT)context->SpeedOfSound;
331 break;
333 case AL_DEFERRED_UPDATES_SOFT:
334 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
335 value = (ALint64SOFT)AL_TRUE;
336 break;
338 case AL_GAIN_LIMIT_SOFT:
339 value = (ALint64SOFT)(GAIN_MIX_MAX/context->GainBoost);
340 break;
342 default:
343 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
346 done:
347 ALCcontext_DecRef(context);
349 return value;
352 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
354 ALCcontext *context;
356 if(values)
358 switch(pname)
360 case AL_DOPPLER_FACTOR:
361 case AL_DOPPLER_VELOCITY:
362 case AL_DISTANCE_MODEL:
363 case AL_SPEED_OF_SOUND:
364 case AL_DEFERRED_UPDATES_SOFT:
365 case AL_GAIN_LIMIT_SOFT:
366 values[0] = alGetBoolean(pname);
367 return;
371 context = GetContextRef();
372 if(!context) return;
374 if(!(values))
375 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
376 switch(pname)
378 default:
379 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
382 done:
383 ALCcontext_DecRef(context);
386 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
388 ALCcontext *context;
390 if(values)
392 switch(pname)
394 case AL_DOPPLER_FACTOR:
395 case AL_DOPPLER_VELOCITY:
396 case AL_DISTANCE_MODEL:
397 case AL_SPEED_OF_SOUND:
398 case AL_DEFERRED_UPDATES_SOFT:
399 case AL_GAIN_LIMIT_SOFT:
400 values[0] = alGetDouble(pname);
401 return;
405 context = GetContextRef();
406 if(!context) return;
408 if(!(values))
409 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
410 switch(pname)
412 default:
413 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
416 done:
417 ALCcontext_DecRef(context);
420 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
422 ALCcontext *context;
424 if(values)
426 switch(pname)
428 case AL_DOPPLER_FACTOR:
429 case AL_DOPPLER_VELOCITY:
430 case AL_DISTANCE_MODEL:
431 case AL_SPEED_OF_SOUND:
432 case AL_DEFERRED_UPDATES_SOFT:
433 case AL_GAIN_LIMIT_SOFT:
434 values[0] = alGetFloat(pname);
435 return;
439 context = GetContextRef();
440 if(!context) return;
442 if(!(values))
443 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
444 switch(pname)
446 default:
447 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
450 done:
451 ALCcontext_DecRef(context);
454 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
456 ALCcontext *context;
458 if(values)
460 switch(pname)
462 case AL_DOPPLER_FACTOR:
463 case AL_DOPPLER_VELOCITY:
464 case AL_DISTANCE_MODEL:
465 case AL_SPEED_OF_SOUND:
466 case AL_DEFERRED_UPDATES_SOFT:
467 case AL_GAIN_LIMIT_SOFT:
468 values[0] = alGetInteger(pname);
469 return;
473 context = GetContextRef();
474 if(!context) return;
476 switch(pname)
478 default:
479 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
482 done:
483 ALCcontext_DecRef(context);
486 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
488 ALCcontext *context;
490 if(values)
492 switch(pname)
494 case AL_DOPPLER_FACTOR:
495 case AL_DOPPLER_VELOCITY:
496 case AL_DISTANCE_MODEL:
497 case AL_SPEED_OF_SOUND:
498 case AL_DEFERRED_UPDATES_SOFT:
499 case AL_GAIN_LIMIT_SOFT:
500 values[0] = alGetInteger64SOFT(pname);
501 return;
505 context = GetContextRef();
506 if(!context) return;
508 switch(pname)
510 default:
511 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
514 done:
515 ALCcontext_DecRef(context);
518 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
520 const ALchar *value = NULL;
521 ALCcontext *context;
523 context = GetContextRef();
524 if(!context) return NULL;
526 switch(pname)
528 case AL_VENDOR:
529 value = alVendor;
530 break;
532 case AL_VERSION:
533 value = alVersion;
534 break;
536 case AL_RENDERER:
537 value = alRenderer;
538 break;
540 case AL_EXTENSIONS:
541 value = context->ExtensionList;
542 break;
544 case AL_NO_ERROR:
545 value = alNoError;
546 break;
548 case AL_INVALID_NAME:
549 value = alErrInvalidName;
550 break;
552 case AL_INVALID_ENUM:
553 value = alErrInvalidEnum;
554 break;
556 case AL_INVALID_VALUE:
557 value = alErrInvalidValue;
558 break;
560 case AL_INVALID_OPERATION:
561 value = alErrInvalidOp;
562 break;
564 case AL_OUT_OF_MEMORY:
565 value = alErrOutOfMemory;
566 break;
568 default:
569 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
572 done:
573 ALCcontext_DecRef(context);
575 return value;
578 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
580 ALCcontext *context;
582 context = GetContextRef();
583 if(!context) return;
585 if(!(value >= 0.0f && isfinite(value)))
586 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
588 WriteLock(&context->PropLock);
589 context->DopplerFactor = value;
590 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
591 UpdateListenerProps(context);
592 WriteUnlock(&context->PropLock);
594 done:
595 ALCcontext_DecRef(context);
598 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
600 ALCcontext *context;
602 context = GetContextRef();
603 if(!context) return;
605 if(!(value >= 0.0f && isfinite(value)))
606 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
608 WriteLock(&context->PropLock);
609 context->DopplerVelocity = value;
610 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
611 UpdateListenerProps(context);
612 WriteUnlock(&context->PropLock);
614 done:
615 ALCcontext_DecRef(context);
618 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
620 ALCcontext *context;
622 context = GetContextRef();
623 if(!context) return;
625 if(!(value > 0.0f && isfinite(value)))
626 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
628 WriteLock(&context->PropLock);
629 context->SpeedOfSound = value;
630 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
631 UpdateListenerProps(context);
632 WriteUnlock(&context->PropLock);
634 done:
635 ALCcontext_DecRef(context);
638 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
640 ALCcontext *context;
642 context = GetContextRef();
643 if(!context) return;
645 if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
646 value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
647 value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
648 value == AL_NONE))
649 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
651 WriteLock(&context->PropLock);
652 context->DistanceModel = value;
653 if(!context->SourceDistanceModel)
655 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
656 UpdateListenerProps(context);
658 WriteUnlock(&context->PropLock);
660 done:
661 ALCcontext_DecRef(context);
665 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
667 ALCcontext *context;
669 context = GetContextRef();
670 if(!context) return;
672 ALCcontext_DeferUpdates(context, DeferAll);
674 ALCcontext_DecRef(context);
677 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
679 ALCcontext *context;
681 context = GetContextRef();
682 if(!context) return;
684 ALCcontext_ProcessUpdates(context);
686 ALCcontext_DecRef(context);