Add a method to enumerate resamplers
[openal-soft.git] / OpenAL32 / alState.c
blob231e2192a8eab02ba51e05faa0f6e7f30c7ff732
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 /* Resampler strings */
51 static const ALchar alPointResampler[] = "Zero-Order Hold (Point)";
52 static const ALchar alLinearResampler[] = "Linear";
53 static const ALchar alSinc4Resampler[] = "4-Point Sinc";
54 static const ALchar alBSincResampler[] = "Band-limited Sinc (12/24)";
56 AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
58 ALCcontext *context;
60 context = GetContextRef();
61 if(!context) return;
63 WriteLock(&context->PropLock);
64 switch(capability)
66 case AL_SOURCE_DISTANCE_MODEL:
67 context->SourceDistanceModel = AL_TRUE;
68 break;
70 default:
71 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
73 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
74 UpdateListenerProps(context);
76 done:
77 WriteUnlock(&context->PropLock);
78 ALCcontext_DecRef(context);
81 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
83 ALCcontext *context;
85 context = GetContextRef();
86 if(!context) return;
88 WriteLock(&context->PropLock);
89 switch(capability)
91 case AL_SOURCE_DISTANCE_MODEL:
92 context->SourceDistanceModel = AL_FALSE;
93 break;
95 default:
96 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
98 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
99 UpdateListenerProps(context);
101 done:
102 WriteUnlock(&context->PropLock);
103 ALCcontext_DecRef(context);
106 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
108 ALCcontext *context;
109 ALboolean value=AL_FALSE;
111 context = GetContextRef();
112 if(!context) return AL_FALSE;
114 switch(capability)
116 case AL_SOURCE_DISTANCE_MODEL:
117 value = context->SourceDistanceModel;
118 break;
120 default:
121 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
124 done:
125 ALCcontext_DecRef(context);
127 return value;
130 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
132 ALCcontext *context;
133 ALboolean value=AL_FALSE;
135 context = GetContextRef();
136 if(!context) return AL_FALSE;
138 switch(pname)
140 case AL_DOPPLER_FACTOR:
141 if(context->DopplerFactor != 0.0f)
142 value = AL_TRUE;
143 break;
145 case AL_DOPPLER_VELOCITY:
146 if(context->DopplerVelocity != 0.0f)
147 value = AL_TRUE;
148 break;
150 case AL_DISTANCE_MODEL:
151 if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
152 value = AL_TRUE;
153 break;
155 case AL_SPEED_OF_SOUND:
156 if(context->SpeedOfSound != 0.0f)
157 value = AL_TRUE;
158 break;
160 case AL_DEFERRED_UPDATES_SOFT:
161 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
162 value = AL_TRUE;
163 break;
165 case AL_GAIN_LIMIT_SOFT:
166 if(GAIN_MIX_MAX/context->GainBoost != 0.0f)
167 value = AL_TRUE;
168 break;
170 case AL_NUM_RESAMPLERS_SOFT:
171 /* Always non-0. */
172 value = AL_TRUE;
173 break;
175 case AL_DEFAULT_RESAMPLER_SOFT:
176 value = ResamplerDefault ? AL_TRUE : AL_FALSE;
177 break;
179 default:
180 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
183 done:
184 ALCcontext_DecRef(context);
186 return value;
189 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
191 ALCcontext *context;
192 ALdouble value = 0.0;
194 context = GetContextRef();
195 if(!context) return 0.0;
197 switch(pname)
199 case AL_DOPPLER_FACTOR:
200 value = (ALdouble)context->DopplerFactor;
201 break;
203 case AL_DOPPLER_VELOCITY:
204 value = (ALdouble)context->DopplerVelocity;
205 break;
207 case AL_DISTANCE_MODEL:
208 value = (ALdouble)context->DistanceModel;
209 break;
211 case AL_SPEED_OF_SOUND:
212 value = (ALdouble)context->SpeedOfSound;
213 break;
215 case AL_DEFERRED_UPDATES_SOFT:
216 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
217 value = (ALdouble)AL_TRUE;
218 break;
220 case AL_GAIN_LIMIT_SOFT:
221 value = (ALdouble)GAIN_MIX_MAX/context->GainBoost;
222 break;
224 case AL_NUM_RESAMPLERS_SOFT:
225 value = (ALdouble)(ResamplerMax + 1);
226 break;
228 case AL_DEFAULT_RESAMPLER_SOFT:
229 value = (ALdouble)ResamplerDefault;
230 break;
232 default:
233 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
236 done:
237 ALCcontext_DecRef(context);
239 return value;
242 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
244 ALCcontext *context;
245 ALfloat value = 0.0f;
247 context = GetContextRef();
248 if(!context) return 0.0f;
250 switch(pname)
252 case AL_DOPPLER_FACTOR:
253 value = context->DopplerFactor;
254 break;
256 case AL_DOPPLER_VELOCITY:
257 value = context->DopplerVelocity;
258 break;
260 case AL_DISTANCE_MODEL:
261 value = (ALfloat)context->DistanceModel;
262 break;
264 case AL_SPEED_OF_SOUND:
265 value = context->SpeedOfSound;
266 break;
268 case AL_DEFERRED_UPDATES_SOFT:
269 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
270 value = (ALfloat)AL_TRUE;
271 break;
273 case AL_GAIN_LIMIT_SOFT:
274 value = GAIN_MIX_MAX/context->GainBoost;
275 break;
277 case AL_NUM_RESAMPLERS_SOFT:
278 value = (ALfloat)(ResamplerMax + 1);
279 break;
281 case AL_DEFAULT_RESAMPLER_SOFT:
282 value = (ALfloat)ResamplerDefault;
283 break;
285 default:
286 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
289 done:
290 ALCcontext_DecRef(context);
292 return value;
295 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
297 ALCcontext *context;
298 ALint value = 0;
300 context = GetContextRef();
301 if(!context) return 0;
303 switch(pname)
305 case AL_DOPPLER_FACTOR:
306 value = (ALint)context->DopplerFactor;
307 break;
309 case AL_DOPPLER_VELOCITY:
310 value = (ALint)context->DopplerVelocity;
311 break;
313 case AL_DISTANCE_MODEL:
314 value = (ALint)context->DistanceModel;
315 break;
317 case AL_SPEED_OF_SOUND:
318 value = (ALint)context->SpeedOfSound;
319 break;
321 case AL_DEFERRED_UPDATES_SOFT:
322 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
323 value = (ALint)AL_TRUE;
324 break;
326 case AL_GAIN_LIMIT_SOFT:
327 value = (ALint)(GAIN_MIX_MAX/context->GainBoost);
328 break;
330 case AL_NUM_RESAMPLERS_SOFT:
331 value = ResamplerMax + 1;
332 break;
334 case AL_DEFAULT_RESAMPLER_SOFT:
335 value = ResamplerDefault;
336 break;
338 default:
339 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
342 done:
343 ALCcontext_DecRef(context);
345 return value;
348 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
350 ALCcontext *context;
351 ALint64SOFT value = 0;
353 context = GetContextRef();
354 if(!context) return 0;
356 switch(pname)
358 case AL_DOPPLER_FACTOR:
359 value = (ALint64SOFT)context->DopplerFactor;
360 break;
362 case AL_DOPPLER_VELOCITY:
363 value = (ALint64SOFT)context->DopplerVelocity;
364 break;
366 case AL_DISTANCE_MODEL:
367 value = (ALint64SOFT)context->DistanceModel;
368 break;
370 case AL_SPEED_OF_SOUND:
371 value = (ALint64SOFT)context->SpeedOfSound;
372 break;
374 case AL_DEFERRED_UPDATES_SOFT:
375 if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
376 value = (ALint64SOFT)AL_TRUE;
377 break;
379 case AL_GAIN_LIMIT_SOFT:
380 value = (ALint64SOFT)(GAIN_MIX_MAX/context->GainBoost);
381 break;
383 case AL_NUM_RESAMPLERS_SOFT:
384 value = (ALint64SOFT)(ResamplerMax + 1);
385 break;
387 case AL_DEFAULT_RESAMPLER_SOFT:
388 value = (ALint64SOFT)ResamplerDefault;
389 break;
391 default:
392 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
395 done:
396 ALCcontext_DecRef(context);
398 return value;
401 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
403 ALCcontext *context;
405 if(values)
407 switch(pname)
409 case AL_DOPPLER_FACTOR:
410 case AL_DOPPLER_VELOCITY:
411 case AL_DISTANCE_MODEL:
412 case AL_SPEED_OF_SOUND:
413 case AL_DEFERRED_UPDATES_SOFT:
414 case AL_GAIN_LIMIT_SOFT:
415 case AL_NUM_RESAMPLERS_SOFT:
416 case AL_DEFAULT_RESAMPLER_SOFT:
417 values[0] = alGetBoolean(pname);
418 return;
422 context = GetContextRef();
423 if(!context) return;
425 if(!(values))
426 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
427 switch(pname)
429 default:
430 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
433 done:
434 ALCcontext_DecRef(context);
437 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
439 ALCcontext *context;
441 if(values)
443 switch(pname)
445 case AL_DOPPLER_FACTOR:
446 case AL_DOPPLER_VELOCITY:
447 case AL_DISTANCE_MODEL:
448 case AL_SPEED_OF_SOUND:
449 case AL_DEFERRED_UPDATES_SOFT:
450 case AL_GAIN_LIMIT_SOFT:
451 case AL_NUM_RESAMPLERS_SOFT:
452 case AL_DEFAULT_RESAMPLER_SOFT:
453 values[0] = alGetDouble(pname);
454 return;
458 context = GetContextRef();
459 if(!context) return;
461 if(!(values))
462 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
463 switch(pname)
465 default:
466 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
469 done:
470 ALCcontext_DecRef(context);
473 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
475 ALCcontext *context;
477 if(values)
479 switch(pname)
481 case AL_DOPPLER_FACTOR:
482 case AL_DOPPLER_VELOCITY:
483 case AL_DISTANCE_MODEL:
484 case AL_SPEED_OF_SOUND:
485 case AL_DEFERRED_UPDATES_SOFT:
486 case AL_GAIN_LIMIT_SOFT:
487 case AL_NUM_RESAMPLERS_SOFT:
488 case AL_DEFAULT_RESAMPLER_SOFT:
489 values[0] = alGetFloat(pname);
490 return;
494 context = GetContextRef();
495 if(!context) return;
497 if(!(values))
498 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
499 switch(pname)
501 default:
502 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
505 done:
506 ALCcontext_DecRef(context);
509 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
511 ALCcontext *context;
513 if(values)
515 switch(pname)
517 case AL_DOPPLER_FACTOR:
518 case AL_DOPPLER_VELOCITY:
519 case AL_DISTANCE_MODEL:
520 case AL_SPEED_OF_SOUND:
521 case AL_DEFERRED_UPDATES_SOFT:
522 case AL_GAIN_LIMIT_SOFT:
523 case AL_NUM_RESAMPLERS_SOFT:
524 case AL_DEFAULT_RESAMPLER_SOFT:
525 values[0] = alGetInteger(pname);
526 return;
530 context = GetContextRef();
531 if(!context) return;
533 switch(pname)
535 default:
536 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
539 done:
540 ALCcontext_DecRef(context);
543 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
545 ALCcontext *context;
547 if(values)
549 switch(pname)
551 case AL_DOPPLER_FACTOR:
552 case AL_DOPPLER_VELOCITY:
553 case AL_DISTANCE_MODEL:
554 case AL_SPEED_OF_SOUND:
555 case AL_DEFERRED_UPDATES_SOFT:
556 case AL_GAIN_LIMIT_SOFT:
557 case AL_NUM_RESAMPLERS_SOFT:
558 case AL_DEFAULT_RESAMPLER_SOFT:
559 values[0] = alGetInteger64SOFT(pname);
560 return;
564 context = GetContextRef();
565 if(!context) return;
567 switch(pname)
569 default:
570 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
573 done:
574 ALCcontext_DecRef(context);
577 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
579 const ALchar *value = NULL;
580 ALCcontext *context;
582 context = GetContextRef();
583 if(!context) return NULL;
585 switch(pname)
587 case AL_VENDOR:
588 value = alVendor;
589 break;
591 case AL_VERSION:
592 value = alVersion;
593 break;
595 case AL_RENDERER:
596 value = alRenderer;
597 break;
599 case AL_EXTENSIONS:
600 value = context->ExtensionList;
601 break;
603 case AL_NO_ERROR:
604 value = alNoError;
605 break;
607 case AL_INVALID_NAME:
608 value = alErrInvalidName;
609 break;
611 case AL_INVALID_ENUM:
612 value = alErrInvalidEnum;
613 break;
615 case AL_INVALID_VALUE:
616 value = alErrInvalidValue;
617 break;
619 case AL_INVALID_OPERATION:
620 value = alErrInvalidOp;
621 break;
623 case AL_OUT_OF_MEMORY:
624 value = alErrOutOfMemory;
625 break;
627 default:
628 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
631 done:
632 ALCcontext_DecRef(context);
634 return value;
637 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
639 ALCcontext *context;
641 context = GetContextRef();
642 if(!context) return;
644 if(!(value >= 0.0f && isfinite(value)))
645 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
647 WriteLock(&context->PropLock);
648 context->DopplerFactor = value;
649 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
650 UpdateListenerProps(context);
651 WriteUnlock(&context->PropLock);
653 done:
654 ALCcontext_DecRef(context);
657 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
659 ALCcontext *context;
661 context = GetContextRef();
662 if(!context) return;
664 if(!(value >= 0.0f && isfinite(value)))
665 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
667 WriteLock(&context->PropLock);
668 context->DopplerVelocity = value;
669 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
670 UpdateListenerProps(context);
671 WriteUnlock(&context->PropLock);
673 done:
674 ALCcontext_DecRef(context);
677 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
679 ALCcontext *context;
681 context = GetContextRef();
682 if(!context) return;
684 if(!(value > 0.0f && isfinite(value)))
685 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
687 WriteLock(&context->PropLock);
688 context->SpeedOfSound = value;
689 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
690 UpdateListenerProps(context);
691 WriteUnlock(&context->PropLock);
693 done:
694 ALCcontext_DecRef(context);
697 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
699 ALCcontext *context;
701 context = GetContextRef();
702 if(!context) return;
704 if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
705 value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
706 value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
707 value == AL_NONE))
708 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
710 WriteLock(&context->PropLock);
711 context->DistanceModel = value;
712 if(!context->SourceDistanceModel)
714 if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
715 UpdateListenerProps(context);
717 WriteUnlock(&context->PropLock);
719 done:
720 ALCcontext_DecRef(context);
724 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
726 ALCcontext *context;
728 context = GetContextRef();
729 if(!context) return;
731 ALCcontext_DeferUpdates(context);
733 ALCcontext_DecRef(context);
736 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
738 ALCcontext *context;
740 context = GetContextRef();
741 if(!context) return;
743 ALCcontext_ProcessUpdates(context);
745 ALCcontext_DecRef(context);
749 AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index)
751 const char *ResamplerNames[] = {
752 alPointResampler, alLinearResampler,
753 alSinc4Resampler, alBSincResampler,
755 const ALchar *value = NULL;
756 ALCcontext *context;
758 static_assert(COUNTOF(ResamplerNames) == ResamplerMax+1, "Incorrect ResamplerNames list");
760 context = GetContextRef();
761 if(!context) return NULL;
763 switch(pname)
765 case AL_RESAMPLER_NAME_SOFT:
766 if(index < 0 || (size_t)index >= COUNTOF(ResamplerNames))
767 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
768 value = ResamplerNames[index];
769 break;
771 default:
772 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
775 done:
776 ALCcontext_DecRef(context);
778 return value;