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
31 #include "alListener.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";
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
[] = "Nearest";
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
)
60 context
= GetContextRef();
63 WriteLock(&context
->PropLock
);
66 case AL_SOURCE_DISTANCE_MODEL
:
67 context
->SourceDistanceModel
= AL_TRUE
;
71 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
73 if(!ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
74 UpdateListenerProps(context
);
77 WriteUnlock(&context
->PropLock
);
78 ALCcontext_DecRef(context
);
81 AL_API ALvoid AL_APIENTRY
alDisable(ALenum capability
)
85 context
= GetContextRef();
88 WriteLock(&context
->PropLock
);
91 case AL_SOURCE_DISTANCE_MODEL
:
92 context
->SourceDistanceModel
= AL_FALSE
;
96 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
98 if(!ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
99 UpdateListenerProps(context
);
102 WriteUnlock(&context
->PropLock
);
103 ALCcontext_DecRef(context
);
106 AL_API ALboolean AL_APIENTRY
alIsEnabled(ALenum capability
)
109 ALboolean value
=AL_FALSE
;
111 context
= GetContextRef();
112 if(!context
) return AL_FALSE
;
116 case AL_SOURCE_DISTANCE_MODEL
:
117 value
= context
->SourceDistanceModel
;
121 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
125 ALCcontext_DecRef(context
);
130 AL_API ALboolean AL_APIENTRY
alGetBoolean(ALenum pname
)
133 ALboolean value
=AL_FALSE
;
135 context
= GetContextRef();
136 if(!context
) return AL_FALSE
;
140 case AL_DOPPLER_FACTOR
:
141 if(context
->DopplerFactor
!= 0.0f
)
145 case AL_DOPPLER_VELOCITY
:
146 if(context
->DopplerVelocity
!= 0.0f
)
150 case AL_DISTANCE_MODEL
:
151 if(context
->DistanceModel
== AL_INVERSE_DISTANCE_CLAMPED
)
155 case AL_SPEED_OF_SOUND
:
156 if(context
->SpeedOfSound
!= 0.0f
)
160 case AL_DEFERRED_UPDATES_SOFT
:
161 if(ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
165 case AL_GAIN_LIMIT_SOFT
:
166 if(GAIN_MIX_MAX
/context
->GainBoost
!= 0.0f
)
170 case AL_NUM_RESAMPLERS_SOFT
:
175 case AL_DEFAULT_RESAMPLER_SOFT
:
176 value
= ResamplerDefault
? AL_TRUE
: AL_FALSE
;
180 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
184 ALCcontext_DecRef(context
);
189 AL_API ALdouble AL_APIENTRY
alGetDouble(ALenum pname
)
192 ALdouble value
= 0.0;
194 context
= GetContextRef();
195 if(!context
) return 0.0;
199 case AL_DOPPLER_FACTOR
:
200 value
= (ALdouble
)context
->DopplerFactor
;
203 case AL_DOPPLER_VELOCITY
:
204 value
= (ALdouble
)context
->DopplerVelocity
;
207 case AL_DISTANCE_MODEL
:
208 value
= (ALdouble
)context
->DistanceModel
;
211 case AL_SPEED_OF_SOUND
:
212 value
= (ALdouble
)context
->SpeedOfSound
;
215 case AL_DEFERRED_UPDATES_SOFT
:
216 if(ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
217 value
= (ALdouble
)AL_TRUE
;
220 case AL_GAIN_LIMIT_SOFT
:
221 value
= (ALdouble
)GAIN_MIX_MAX
/context
->GainBoost
;
224 case AL_NUM_RESAMPLERS_SOFT
:
225 value
= (ALdouble
)(ResamplerMax
+ 1);
228 case AL_DEFAULT_RESAMPLER_SOFT
:
229 value
= (ALdouble
)ResamplerDefault
;
233 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
237 ALCcontext_DecRef(context
);
242 AL_API ALfloat AL_APIENTRY
alGetFloat(ALenum pname
)
245 ALfloat value
= 0.0f
;
247 context
= GetContextRef();
248 if(!context
) return 0.0f
;
252 case AL_DOPPLER_FACTOR
:
253 value
= context
->DopplerFactor
;
256 case AL_DOPPLER_VELOCITY
:
257 value
= context
->DopplerVelocity
;
260 case AL_DISTANCE_MODEL
:
261 value
= (ALfloat
)context
->DistanceModel
;
264 case AL_SPEED_OF_SOUND
:
265 value
= context
->SpeedOfSound
;
268 case AL_DEFERRED_UPDATES_SOFT
:
269 if(ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
270 value
= (ALfloat
)AL_TRUE
;
273 case AL_GAIN_LIMIT_SOFT
:
274 value
= GAIN_MIX_MAX
/context
->GainBoost
;
277 case AL_NUM_RESAMPLERS_SOFT
:
278 value
= (ALfloat
)(ResamplerMax
+ 1);
281 case AL_DEFAULT_RESAMPLER_SOFT
:
282 value
= (ALfloat
)ResamplerDefault
;
286 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
290 ALCcontext_DecRef(context
);
295 AL_API ALint AL_APIENTRY
alGetInteger(ALenum pname
)
300 context
= GetContextRef();
301 if(!context
) return 0;
305 case AL_DOPPLER_FACTOR
:
306 value
= (ALint
)context
->DopplerFactor
;
309 case AL_DOPPLER_VELOCITY
:
310 value
= (ALint
)context
->DopplerVelocity
;
313 case AL_DISTANCE_MODEL
:
314 value
= (ALint
)context
->DistanceModel
;
317 case AL_SPEED_OF_SOUND
:
318 value
= (ALint
)context
->SpeedOfSound
;
321 case AL_DEFERRED_UPDATES_SOFT
:
322 if(ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
323 value
= (ALint
)AL_TRUE
;
326 case AL_GAIN_LIMIT_SOFT
:
327 value
= (ALint
)(GAIN_MIX_MAX
/context
->GainBoost
);
330 case AL_NUM_RESAMPLERS_SOFT
:
331 value
= ResamplerMax
+ 1;
334 case AL_DEFAULT_RESAMPLER_SOFT
:
335 value
= ResamplerDefault
;
339 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
343 ALCcontext_DecRef(context
);
348 AL_API ALint64SOFT AL_APIENTRY
alGetInteger64SOFT(ALenum pname
)
351 ALint64SOFT value
= 0;
353 context
= GetContextRef();
354 if(!context
) return 0;
358 case AL_DOPPLER_FACTOR
:
359 value
= (ALint64SOFT
)context
->DopplerFactor
;
362 case AL_DOPPLER_VELOCITY
:
363 value
= (ALint64SOFT
)context
->DopplerVelocity
;
366 case AL_DISTANCE_MODEL
:
367 value
= (ALint64SOFT
)context
->DistanceModel
;
370 case AL_SPEED_OF_SOUND
:
371 value
= (ALint64SOFT
)context
->SpeedOfSound
;
374 case AL_DEFERRED_UPDATES_SOFT
:
375 if(ATOMIC_LOAD(&context
->DeferUpdates
, almemory_order_acquire
))
376 value
= (ALint64SOFT
)AL_TRUE
;
379 case AL_GAIN_LIMIT_SOFT
:
380 value
= (ALint64SOFT
)(GAIN_MIX_MAX
/context
->GainBoost
);
383 case AL_NUM_RESAMPLERS_SOFT
:
384 value
= (ALint64SOFT
)(ResamplerMax
+ 1);
387 case AL_DEFAULT_RESAMPLER_SOFT
:
388 value
= (ALint64SOFT
)ResamplerDefault
;
392 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
396 ALCcontext_DecRef(context
);
401 AL_API ALvoid AL_APIENTRY
alGetBooleanv(ALenum pname
, ALboolean
*values
)
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
);
422 context
= GetContextRef();
426 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
430 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
434 ALCcontext_DecRef(context
);
437 AL_API ALvoid AL_APIENTRY
alGetDoublev(ALenum pname
, ALdouble
*values
)
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
);
458 context
= GetContextRef();
462 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
466 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
470 ALCcontext_DecRef(context
);
473 AL_API ALvoid AL_APIENTRY
alGetFloatv(ALenum pname
, ALfloat
*values
)
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
);
494 context
= GetContextRef();
498 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
502 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
506 ALCcontext_DecRef(context
);
509 AL_API ALvoid AL_APIENTRY
alGetIntegerv(ALenum pname
, ALint
*values
)
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
);
530 context
= GetContextRef();
536 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
540 ALCcontext_DecRef(context
);
543 AL_API
void AL_APIENTRY
alGetInteger64vSOFT(ALenum pname
, ALint64SOFT
*values
)
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
);
564 context
= GetContextRef();
570 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
574 ALCcontext_DecRef(context
);
577 AL_API
const ALchar
* AL_APIENTRY
alGetString(ALenum pname
)
579 const ALchar
*value
= NULL
;
582 context
= GetContextRef();
583 if(!context
) return NULL
;
600 value
= context
->ExtensionList
;
607 case AL_INVALID_NAME
:
608 value
= alErrInvalidName
;
611 case AL_INVALID_ENUM
:
612 value
= alErrInvalidEnum
;
615 case AL_INVALID_VALUE
:
616 value
= alErrInvalidValue
;
619 case AL_INVALID_OPERATION
:
620 value
= alErrInvalidOp
;
623 case AL_OUT_OF_MEMORY
:
624 value
= alErrOutOfMemory
;
628 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
632 ALCcontext_DecRef(context
);
637 AL_API ALvoid AL_APIENTRY
alDopplerFactor(ALfloat value
)
641 context
= GetContextRef();
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
);
654 ALCcontext_DecRef(context
);
657 AL_API ALvoid AL_APIENTRY
alDopplerVelocity(ALfloat value
)
661 context
= GetContextRef();
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
);
674 ALCcontext_DecRef(context
);
677 AL_API ALvoid AL_APIENTRY
alSpeedOfSound(ALfloat value
)
681 context
= GetContextRef();
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
);
694 ALCcontext_DecRef(context
);
697 AL_API ALvoid AL_APIENTRY
alDistanceModel(ALenum value
)
701 context
= GetContextRef();
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
||
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
);
720 ALCcontext_DecRef(context
);
724 AL_API ALvoid AL_APIENTRY
alDeferUpdatesSOFT(void)
728 context
= GetContextRef();
731 ALCcontext_DeferUpdates(context
);
733 ALCcontext_DecRef(context
);
736 AL_API ALvoid AL_APIENTRY
alProcessUpdatesSOFT(void)
740 context
= GetContextRef();
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
;
758 static_assert(COUNTOF(ResamplerNames
) == ResamplerMax
+1, "Incorrect ResamplerNames list");
760 context
= GetContextRef();
761 if(!context
) return NULL
;
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
];
772 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
776 ALCcontext_DecRef(context
);