Fix setting Ambi formats for loopback devices
[openal-soft.git] / OpenAL32 / alState.c
blobeddd2999c25776ae98d9213f3fc893b7b60cd606
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 "version.h"
25 #include <stdlib.h>
26 #include "alMain.h"
27 #include "AL/alc.h"
28 #include "AL/al.h"
29 #include "AL/alext.h"
30 #include "alError.h"
31 #include "alListener.h"
32 #include "alSource.h"
33 #include "alAuxEffectSlot.h"
35 #include "backends/base.h"
38 static const ALchar alVendor[] = "OpenAL Community";
39 static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
40 static const ALchar alRenderer[] = "OpenAL Soft";
42 // Error Messages
43 static const ALchar alNoError[] = "No Error";
44 static const ALchar alErrInvalidName[] = "Invalid Name";
45 static const ALchar alErrInvalidEnum[] = "Invalid Enum";
46 static const ALchar alErrInvalidValue[] = "Invalid Value";
47 static const ALchar alErrInvalidOp[] = "Invalid Operation";
48 static const ALchar alErrOutOfMemory[] = "Out of Memory";
50 AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
52 ALCcontext *context;
54 context = GetContextRef();
55 if(!context) return;
57 WriteLock(&context->PropLock);
58 switch(capability)
60 case AL_SOURCE_DISTANCE_MODEL:
61 context->SourceDistanceModel = AL_TRUE;
62 break;
64 default:
65 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
67 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
68 UpdateListenerProps(context);
70 done:
71 WriteUnlock(&context->PropLock);
72 ALCcontext_DecRef(context);
75 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
77 ALCcontext *context;
79 context = GetContextRef();
80 if(!context) return;
82 WriteLock(&context->PropLock);
83 switch(capability)
85 case AL_SOURCE_DISTANCE_MODEL:
86 context->SourceDistanceModel = AL_FALSE;
87 break;
89 default:
90 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
92 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
93 UpdateListenerProps(context);
95 done:
96 WriteUnlock(&context->PropLock);
97 ALCcontext_DecRef(context);
100 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
102 ALCcontext *context;
103 ALboolean value=AL_FALSE;
105 context = GetContextRef();
106 if(!context) return AL_FALSE;
108 switch(capability)
110 case AL_SOURCE_DISTANCE_MODEL:
111 value = context->SourceDistanceModel;
112 break;
114 default:
115 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
118 done:
119 ALCcontext_DecRef(context);
121 return value;
124 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
126 ALCcontext *context;
127 ALboolean value=AL_FALSE;
129 context = GetContextRef();
130 if(!context) return AL_FALSE;
132 switch(pname)
134 case AL_DOPPLER_FACTOR:
135 if(context->DopplerFactor != 0.0f)
136 value = AL_TRUE;
137 break;
139 case AL_DOPPLER_VELOCITY:
140 if(context->DopplerVelocity != 0.0f)
141 value = AL_TRUE;
142 break;
144 case AL_DISTANCE_MODEL:
145 if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
146 value = AL_TRUE;
147 break;
149 case AL_SPEED_OF_SOUND:
150 if(context->SpeedOfSound != 0.0f)
151 value = AL_TRUE;
152 break;
154 case AL_DEFERRED_UPDATES_SOFT:
155 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
156 value = AL_TRUE;
157 break;
159 case AL_GAIN_LIMIT_SOFT:
160 if(GAIN_MIX_MAX/context->GainBoost != 0.0f)
161 value = AL_TRUE;
162 break;
164 default:
165 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
168 done:
169 ALCcontext_DecRef(context);
171 return value;
174 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
176 ALCcontext *context;
177 ALdouble value = 0.0;
179 context = GetContextRef();
180 if(!context) return 0.0;
182 switch(pname)
184 case AL_DOPPLER_FACTOR:
185 value = (ALdouble)context->DopplerFactor;
186 break;
188 case AL_DOPPLER_VELOCITY:
189 value = (ALdouble)context->DopplerVelocity;
190 break;
192 case AL_DISTANCE_MODEL:
193 value = (ALdouble)context->DistanceModel;
194 break;
196 case AL_SPEED_OF_SOUND:
197 value = (ALdouble)context->SpeedOfSound;
198 break;
200 case AL_DEFERRED_UPDATES_SOFT:
201 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
202 value = (ALdouble)AL_TRUE;
203 break;
205 case AL_GAIN_LIMIT_SOFT:
206 value = (ALdouble)GAIN_MIX_MAX/context->GainBoost;
207 break;
209 default:
210 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
213 done:
214 ALCcontext_DecRef(context);
216 return value;
219 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
221 ALCcontext *context;
222 ALfloat value = 0.0f;
224 context = GetContextRef();
225 if(!context) return 0.0f;
227 switch(pname)
229 case AL_DOPPLER_FACTOR:
230 value = context->DopplerFactor;
231 break;
233 case AL_DOPPLER_VELOCITY:
234 value = context->DopplerVelocity;
235 break;
237 case AL_DISTANCE_MODEL:
238 value = (ALfloat)context->DistanceModel;
239 break;
241 case AL_SPEED_OF_SOUND:
242 value = context->SpeedOfSound;
243 break;
245 case AL_DEFERRED_UPDATES_SOFT:
246 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
247 value = (ALfloat)AL_TRUE;
248 break;
250 case AL_GAIN_LIMIT_SOFT:
251 value = GAIN_MIX_MAX/context->GainBoost;
252 break;
254 default:
255 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
258 done:
259 ALCcontext_DecRef(context);
261 return value;
264 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
266 ALCcontext *context;
267 ALint value = 0;
269 context = GetContextRef();
270 if(!context) return 0;
272 switch(pname)
274 case AL_DOPPLER_FACTOR:
275 value = (ALint)context->DopplerFactor;
276 break;
278 case AL_DOPPLER_VELOCITY:
279 value = (ALint)context->DopplerVelocity;
280 break;
282 case AL_DISTANCE_MODEL:
283 value = (ALint)context->DistanceModel;
284 break;
286 case AL_SPEED_OF_SOUND:
287 value = (ALint)context->SpeedOfSound;
288 break;
290 case AL_DEFERRED_UPDATES_SOFT:
291 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
292 value = (ALint)AL_TRUE;
293 break;
295 case AL_GAIN_LIMIT_SOFT:
296 value = (ALint)(GAIN_MIX_MAX/context->GainBoost);
297 break;
299 default:
300 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
303 done:
304 ALCcontext_DecRef(context);
306 return value;
309 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
311 ALCcontext *context;
312 ALint64SOFT value = 0;
314 context = GetContextRef();
315 if(!context) return 0;
317 switch(pname)
319 case AL_DOPPLER_FACTOR:
320 value = (ALint64SOFT)context->DopplerFactor;
321 break;
323 case AL_DOPPLER_VELOCITY:
324 value = (ALint64SOFT)context->DopplerVelocity;
325 break;
327 case AL_DISTANCE_MODEL:
328 value = (ALint64SOFT)context->DistanceModel;
329 break;
331 case AL_SPEED_OF_SOUND:
332 value = (ALint64SOFT)context->SpeedOfSound;
333 break;
335 case AL_DEFERRED_UPDATES_SOFT:
336 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
337 value = (ALint64SOFT)AL_TRUE;
338 break;
340 case AL_GAIN_LIMIT_SOFT:
341 value = (ALint64SOFT)(GAIN_MIX_MAX/context->GainBoost);
342 break;
344 default:
345 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
348 done:
349 ALCcontext_DecRef(context);
351 return value;
354 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
356 ALCcontext *context;
358 if(values)
360 switch(pname)
362 case AL_DOPPLER_FACTOR:
363 case AL_DOPPLER_VELOCITY:
364 case AL_DISTANCE_MODEL:
365 case AL_SPEED_OF_SOUND:
366 case AL_DEFERRED_UPDATES_SOFT:
367 case AL_GAIN_LIMIT_SOFT:
368 values[0] = alGetBoolean(pname);
369 return;
373 context = GetContextRef();
374 if(!context) return;
376 if(!(values))
377 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
378 switch(pname)
380 default:
381 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
384 done:
385 ALCcontext_DecRef(context);
388 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
390 ALCcontext *context;
392 if(values)
394 switch(pname)
396 case AL_DOPPLER_FACTOR:
397 case AL_DOPPLER_VELOCITY:
398 case AL_DISTANCE_MODEL:
399 case AL_SPEED_OF_SOUND:
400 case AL_DEFERRED_UPDATES_SOFT:
401 case AL_GAIN_LIMIT_SOFT:
402 values[0] = alGetDouble(pname);
403 return;
407 context = GetContextRef();
408 if(!context) return;
410 if(!(values))
411 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
412 switch(pname)
414 default:
415 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
418 done:
419 ALCcontext_DecRef(context);
422 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
424 ALCcontext *context;
426 if(values)
428 switch(pname)
430 case AL_DOPPLER_FACTOR:
431 case AL_DOPPLER_VELOCITY:
432 case AL_DISTANCE_MODEL:
433 case AL_SPEED_OF_SOUND:
434 case AL_DEFERRED_UPDATES_SOFT:
435 case AL_GAIN_LIMIT_SOFT:
436 values[0] = alGetFloat(pname);
437 return;
441 context = GetContextRef();
442 if(!context) return;
444 if(!(values))
445 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
446 switch(pname)
448 default:
449 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
452 done:
453 ALCcontext_DecRef(context);
456 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
458 ALCcontext *context;
460 if(values)
462 switch(pname)
464 case AL_DOPPLER_FACTOR:
465 case AL_DOPPLER_VELOCITY:
466 case AL_DISTANCE_MODEL:
467 case AL_SPEED_OF_SOUND:
468 case AL_DEFERRED_UPDATES_SOFT:
469 case AL_GAIN_LIMIT_SOFT:
470 values[0] = alGetInteger(pname);
471 return;
475 context = GetContextRef();
476 if(!context) return;
478 switch(pname)
480 default:
481 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
484 done:
485 ALCcontext_DecRef(context);
488 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
490 ALCcontext *context;
492 if(values)
494 switch(pname)
496 case AL_DOPPLER_FACTOR:
497 case AL_DOPPLER_VELOCITY:
498 case AL_DISTANCE_MODEL:
499 case AL_SPEED_OF_SOUND:
500 case AL_DEFERRED_UPDATES_SOFT:
501 case AL_GAIN_LIMIT_SOFT:
502 values[0] = alGetInteger64SOFT(pname);
503 return;
507 context = GetContextRef();
508 if(!context) return;
510 switch(pname)
512 default:
513 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
516 done:
517 ALCcontext_DecRef(context);
520 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
522 const ALchar *value = NULL;
523 ALCcontext *context;
525 context = GetContextRef();
526 if(!context) return NULL;
528 switch(pname)
530 case AL_VENDOR:
531 value = alVendor;
532 break;
534 case AL_VERSION:
535 value = alVersion;
536 break;
538 case AL_RENDERER:
539 value = alRenderer;
540 break;
542 case AL_EXTENSIONS:
543 value = context->ExtensionList;
544 break;
546 case AL_NO_ERROR:
547 value = alNoError;
548 break;
550 case AL_INVALID_NAME:
551 value = alErrInvalidName;
552 break;
554 case AL_INVALID_ENUM:
555 value = alErrInvalidEnum;
556 break;
558 case AL_INVALID_VALUE:
559 value = alErrInvalidValue;
560 break;
562 case AL_INVALID_OPERATION:
563 value = alErrInvalidOp;
564 break;
566 case AL_OUT_OF_MEMORY:
567 value = alErrOutOfMemory;
568 break;
570 default:
571 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
574 done:
575 ALCcontext_DecRef(context);
577 return value;
580 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
582 ALCcontext *context;
584 context = GetContextRef();
585 if(!context) return;
587 if(!(value >= 0.0f && isfinite(value)))
588 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
590 WriteLock(&context->PropLock);
591 context->DopplerFactor = value;
592 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
593 UpdateListenerProps(context);
594 WriteUnlock(&context->PropLock);
596 done:
597 ALCcontext_DecRef(context);
600 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
602 ALCcontext *context;
604 context = GetContextRef();
605 if(!context) return;
607 if(!(value >= 0.0f && isfinite(value)))
608 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
610 WriteLock(&context->PropLock);
611 context->DopplerVelocity = value;
612 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
613 UpdateListenerProps(context);
614 WriteUnlock(&context->PropLock);
616 done:
617 ALCcontext_DecRef(context);
620 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
622 ALCcontext *context;
624 context = GetContextRef();
625 if(!context) return;
627 if(!(value > 0.0f && isfinite(value)))
628 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
630 WriteLock(&context->PropLock);
631 context->SpeedOfSound = value;
632 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
633 UpdateListenerProps(context);
634 WriteUnlock(&context->PropLock);
636 done:
637 ALCcontext_DecRef(context);
640 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
642 ALCcontext *context;
644 context = GetContextRef();
645 if(!context) return;
647 if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
648 value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
649 value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
650 value == AL_NONE))
651 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
653 WriteLock(&context->PropLock);
654 context->DistanceModel = value;
655 if(!context->SourceDistanceModel)
657 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
658 UpdateListenerProps(context);
660 WriteUnlock(&context->PropLock);
662 done:
663 ALCcontext_DecRef(context);
667 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
669 ALCcontext *context;
671 context = GetContextRef();
672 if(!context) return;
674 ALCcontext_DeferUpdates(context);
676 ALCcontext_DecRef(context);
679 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
681 ALCcontext *context;
683 context = GetContextRef();
684 if(!context) return;
686 ALCcontext_ProcessUpdates(context);
688 ALCcontext_DecRef(context);