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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
29 #include "alAuxEffectSlot.h"
32 static const ALchar alVendor
[] = "OpenAL Community";
33 static const ALchar alVersion
[] = "1.1 ALSOFT "ALSOFT_VERSION
;
34 static const ALchar alRenderer
[] = "OpenAL Soft";
37 static const ALchar alNoError
[] = "No Error";
38 static const ALchar alErrInvalidName
[] = "Invalid Name";
39 static const ALchar alErrInvalidEnum
[] = "Invalid Enum";
40 static const ALchar alErrInvalidValue
[] = "Invalid Value";
41 static const ALchar alErrInvalidOp
[] = "Invalid Operation";
42 static const ALchar alErrOutOfMemory
[] = "Out of Memory";
44 AL_API ALvoid AL_APIENTRY
alEnable(ALenum capability
)
48 Context
= GetContextRef();
53 case AL_SOURCE_DISTANCE_MODEL
:
54 Context
->SourceDistanceModel
= AL_TRUE
;
55 Context
->UpdateSources
= AL_TRUE
;
59 alSetError(Context
, AL_INVALID_ENUM
);
63 ALCcontext_DecRef(Context
);
66 AL_API ALvoid AL_APIENTRY
alDisable(ALenum capability
)
70 Context
= GetContextRef();
75 case AL_SOURCE_DISTANCE_MODEL
:
76 Context
->SourceDistanceModel
= AL_FALSE
;
77 Context
->UpdateSources
= AL_TRUE
;
81 alSetError(Context
, AL_INVALID_ENUM
);
85 ALCcontext_DecRef(Context
);
88 AL_API ALboolean AL_APIENTRY
alIsEnabled(ALenum capability
)
91 ALboolean value
=AL_FALSE
;
93 Context
= GetContextRef();
94 if(!Context
) return AL_FALSE
;
98 case AL_SOURCE_DISTANCE_MODEL
:
99 value
= Context
->SourceDistanceModel
;
103 alSetError(Context
, AL_INVALID_ENUM
);
107 ALCcontext_DecRef(Context
);
112 AL_API ALboolean AL_APIENTRY
alGetBoolean(ALenum pname
)
115 ALboolean value
=AL_FALSE
;
117 Context
= GetContextRef();
118 if(!Context
) return AL_FALSE
;
122 case AL_DOPPLER_FACTOR
:
123 if(Context
->DopplerFactor
!= 0.0f
)
127 case AL_DOPPLER_VELOCITY
:
128 if(Context
->DopplerVelocity
!= 0.0f
)
132 case AL_DISTANCE_MODEL
:
133 if(Context
->DistanceModel
== AL_INVERSE_DISTANCE_CLAMPED
)
137 case AL_SPEED_OF_SOUND
:
138 if(Context
->flSpeedOfSound
!= 0.0f
)
142 case AL_DEFERRED_UPDATES_SOFT
:
143 value
= Context
->DeferUpdates
;
147 alSetError(Context
, AL_INVALID_ENUM
);
151 ALCcontext_DecRef(Context
);
156 AL_API ALdouble AL_APIENTRY
alGetDouble(ALenum pname
)
159 ALdouble value
= 0.0;
161 Context
= GetContextRef();
162 if(!Context
) return 0.0;
166 case AL_DOPPLER_FACTOR
:
167 value
= (double)Context
->DopplerFactor
;
170 case AL_DOPPLER_VELOCITY
:
171 value
= (double)Context
->DopplerVelocity
;
174 case AL_DISTANCE_MODEL
:
175 value
= (double)Context
->DistanceModel
;
178 case AL_SPEED_OF_SOUND
:
179 value
= (double)Context
->flSpeedOfSound
;
182 case AL_DEFERRED_UPDATES_SOFT
:
183 value
= (ALdouble
)Context
->DeferUpdates
;
187 alSetError(Context
, AL_INVALID_ENUM
);
191 ALCcontext_DecRef(Context
);
196 AL_API ALfloat AL_APIENTRY
alGetFloat(ALenum pname
)
199 ALfloat value
= 0.0f
;
201 Context
= GetContextRef();
202 if(!Context
) return 0.0f
;
206 case AL_DOPPLER_FACTOR
:
207 value
= Context
->DopplerFactor
;
210 case AL_DOPPLER_VELOCITY
:
211 value
= Context
->DopplerVelocity
;
214 case AL_DISTANCE_MODEL
:
215 value
= (float)Context
->DistanceModel
;
218 case AL_SPEED_OF_SOUND
:
219 value
= Context
->flSpeedOfSound
;
222 case AL_DEFERRED_UPDATES_SOFT
:
223 value
= (ALfloat
)Context
->DeferUpdates
;
227 alSetError(Context
, AL_INVALID_ENUM
);
231 ALCcontext_DecRef(Context
);
236 AL_API ALint AL_APIENTRY
alGetInteger(ALenum pname
)
241 Context
= GetContextRef();
242 if(!Context
) return 0;
246 case AL_DOPPLER_FACTOR
:
247 value
= (ALint
)Context
->DopplerFactor
;
250 case AL_DOPPLER_VELOCITY
:
251 value
= (ALint
)Context
->DopplerVelocity
;
254 case AL_DISTANCE_MODEL
:
255 value
= (ALint
)Context
->DistanceModel
;
258 case AL_SPEED_OF_SOUND
:
259 value
= (ALint
)Context
->flSpeedOfSound
;
262 case AL_DEFERRED_UPDATES_SOFT
:
263 value
= (ALint
)Context
->DeferUpdates
;
267 alSetError(Context
, AL_INVALID_ENUM
);
271 ALCcontext_DecRef(Context
);
276 AL_API ALvoid AL_APIENTRY
alGetBooleanv(ALenum pname
,ALboolean
*data
)
284 case AL_DOPPLER_FACTOR
:
285 case AL_DOPPLER_VELOCITY
:
286 case AL_DISTANCE_MODEL
:
287 case AL_SPEED_OF_SOUND
:
288 case AL_DEFERRED_UPDATES_SOFT
:
289 *data
= alGetBoolean(pname
);
294 Context
= GetContextRef();
302 alSetError(Context
, AL_INVALID_ENUM
);
308 // data is a NULL pointer
309 alSetError(Context
, AL_INVALID_VALUE
);
312 ALCcontext_DecRef(Context
);
315 AL_API ALvoid AL_APIENTRY
alGetDoublev(ALenum pname
,ALdouble
*data
)
323 case AL_DOPPLER_FACTOR
:
324 case AL_DOPPLER_VELOCITY
:
325 case AL_DISTANCE_MODEL
:
326 case AL_SPEED_OF_SOUND
:
327 case AL_DEFERRED_UPDATES_SOFT
:
328 *data
= alGetDouble(pname
);
333 Context
= GetContextRef();
341 alSetError(Context
, AL_INVALID_ENUM
);
347 // data is a NULL pointer
348 alSetError(Context
, AL_INVALID_VALUE
);
351 ALCcontext_DecRef(Context
);
354 AL_API ALvoid AL_APIENTRY
alGetFloatv(ALenum pname
,ALfloat
*data
)
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 *data
= alGetFloat(pname
);
372 Context
= GetContextRef();
380 alSetError(Context
, AL_INVALID_ENUM
);
386 // data is a NULL pointer
387 alSetError(Context
, AL_INVALID_VALUE
);
390 ALCcontext_DecRef(Context
);
393 AL_API ALvoid AL_APIENTRY
alGetIntegerv(ALenum pname
,ALint
*data
)
401 case AL_DOPPLER_FACTOR
:
402 case AL_DOPPLER_VELOCITY
:
403 case AL_DISTANCE_MODEL
:
404 case AL_SPEED_OF_SOUND
:
405 case AL_DEFERRED_UPDATES_SOFT
:
406 *data
= alGetInteger(pname
);
411 Context
= GetContextRef();
419 alSetError(Context
, AL_INVALID_ENUM
);
425 // data is a NULL pointer
426 alSetError(Context
, AL_INVALID_VALUE
);
429 ALCcontext_DecRef(Context
);
432 AL_API
const ALchar
* AL_APIENTRY
alGetString(ALenum pname
)
437 Context
= GetContextRef();
438 if(!Context
) return NULL
;
455 value
=Context
->ExtensionList
;
462 case AL_INVALID_NAME
:
463 value
=alErrInvalidName
;
466 case AL_INVALID_ENUM
:
467 value
=alErrInvalidEnum
;
470 case AL_INVALID_VALUE
:
471 value
=alErrInvalidValue
;
474 case AL_INVALID_OPERATION
:
475 value
=alErrInvalidOp
;
478 case AL_OUT_OF_MEMORY
:
479 value
=alErrOutOfMemory
;
484 alSetError(Context
, AL_INVALID_ENUM
);
488 ALCcontext_DecRef(Context
);
493 AL_API ALvoid AL_APIENTRY
alDopplerFactor(ALfloat value
)
497 Context
= GetContextRef();
500 if(value
>= 0.0f
&& isfinite(value
))
502 Context
->DopplerFactor
= value
;
503 Context
->UpdateSources
= AL_TRUE
;
506 alSetError(Context
, AL_INVALID_VALUE
);
508 ALCcontext_DecRef(Context
);
511 AL_API ALvoid AL_APIENTRY
alDopplerVelocity(ALfloat value
)
515 Context
= GetContextRef();
518 if(value
> 0.0f
&& isfinite(value
))
520 Context
->DopplerVelocity
=value
;
521 Context
->UpdateSources
= AL_TRUE
;
524 alSetError(Context
, AL_INVALID_VALUE
);
526 ALCcontext_DecRef(Context
);
529 AL_API ALvoid AL_APIENTRY
alSpeedOfSound(ALfloat flSpeedOfSound
)
533 Context
= GetContextRef();
536 if(flSpeedOfSound
> 0.0f
&& isfinite(flSpeedOfSound
))
538 Context
->flSpeedOfSound
= flSpeedOfSound
;
539 Context
->UpdateSources
= AL_TRUE
;
542 alSetError(Context
, AL_INVALID_VALUE
);
544 ALCcontext_DecRef(Context
);
547 AL_API ALvoid AL_APIENTRY
alDistanceModel(ALenum value
)
551 Context
= GetContextRef();
557 case AL_INVERSE_DISTANCE
:
558 case AL_INVERSE_DISTANCE_CLAMPED
:
559 case AL_LINEAR_DISTANCE
:
560 case AL_LINEAR_DISTANCE_CLAMPED
:
561 case AL_EXPONENT_DISTANCE
:
562 case AL_EXPONENT_DISTANCE_CLAMPED
:
563 Context
->DistanceModel
= value
;
564 Context
->UpdateSources
= AL_TRUE
;
568 alSetError(Context
, AL_INVALID_VALUE
);
572 ALCcontext_DecRef(Context
);
576 AL_API ALvoid AL_APIENTRY
alDeferUpdatesSOFT(void)
580 Context
= GetContextRef();
583 if(!Context
->DeferUpdates
)
585 ALboolean UpdateSources
;
586 ALsource
**src
, **src_end
;
587 ALeffectslot
**slot
, **slot_end
;
590 LockContext(Context
);
591 #if defined(HAVE_FESETROUND)
592 fpuState
= fegetround();
593 fesetround(FE_TOWARDZERO
);
594 #elif defined(HAVE__CONTROLFP)
595 fpuState
= _controlfp(0, 0);
596 (void)_controlfp(_RC_CHOP
, _MCW_RC
);
601 Context
->DeferUpdates
= AL_TRUE
;
603 /* Make sure all pending updates are performed */
604 UpdateSources
= ExchangeInt(&Context
->UpdateSources
, AL_FALSE
);
606 src
= Context
->ActiveSources
;
607 src_end
= src
+ Context
->ActiveSourceCount
;
608 while(src
!= src_end
)
610 if((*src
)->state
!= AL_PLAYING
)
612 Context
->ActiveSourceCount
--;
617 if(ExchangeInt(&(*src
)->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
618 ALsource_Update(*src
, Context
);
623 slot
= Context
->ActiveEffectSlots
;
624 slot_end
= slot
+ Context
->ActiveEffectSlotCount
;
625 while(slot
!= slot_end
)
627 if(ExchangeInt(&(*slot
)->NeedsUpdate
, AL_FALSE
))
628 ALeffectState_Update((*slot
)->EffectState
, Context
, *slot
);
632 UnlockContext(Context
);
633 #if defined(HAVE_FESETROUND)
634 fesetround(fpuState
);
635 #elif defined(HAVE__CONTROLFP)
636 _controlfp(fpuState
, _MCW_RC
);
640 ALCcontext_DecRef(Context
);
643 AL_API ALvoid AL_APIENTRY
alProcessUpdatesSOFT(void)
647 Context
= GetContextRef();
650 if(ExchangeInt(&Context
->DeferUpdates
, AL_FALSE
))
654 LockContext(Context
);
655 LockUIntMapRead(&Context
->SourceMap
);
656 for(pos
= 0;pos
< Context
->SourceMap
.size
;pos
++)
658 ALsource
*Source
= Context
->SourceMap
.array
[pos
].value
;
661 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
662 Source
->lOffset
!= -1)
665 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
667 SetSourceState(Source
, Context
, new_state
);
669 UnlockUIntMapRead(&Context
->SourceMap
);
670 UnlockContext(Context
);
673 ALCcontext_DecRef(Context
);