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
30 #include "alAuxEffectSlot.h"
33 #include "midi/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";
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
)
52 context
= GetContextRef();
57 case AL_SOURCE_DISTANCE_MODEL
:
58 context
->SourceDistanceModel
= AL_TRUE
;
59 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
63 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
67 ALCcontext_DecRef(context
);
70 AL_API ALvoid AL_APIENTRY
alDisable(ALenum capability
)
74 context
= GetContextRef();
79 case AL_SOURCE_DISTANCE_MODEL
:
80 context
->SourceDistanceModel
= AL_FALSE
;
81 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
85 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
89 ALCcontext_DecRef(context
);
92 AL_API ALboolean AL_APIENTRY
alIsEnabled(ALenum capability
)
95 ALboolean value
=AL_FALSE
;
97 context
= GetContextRef();
98 if(!context
) return AL_FALSE
;
102 case AL_SOURCE_DISTANCE_MODEL
:
103 value
= context
->SourceDistanceModel
;
107 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
111 ALCcontext_DecRef(context
);
116 AL_API ALboolean AL_APIENTRY
alGetBoolean(ALenum pname
)
119 ALboolean value
=AL_FALSE
;
121 context
= GetContextRef();
122 if(!context
) return AL_FALSE
;
126 case AL_DOPPLER_FACTOR
:
127 if(context
->DopplerFactor
!= 0.0f
)
131 case AL_DOPPLER_VELOCITY
:
132 if(context
->DopplerVelocity
!= 0.0f
)
136 case AL_DISTANCE_MODEL
:
137 if(context
->DistanceModel
== AL_INVERSE_DISTANCE_CLAMPED
)
141 case AL_SPEED_OF_SOUND
:
142 if(context
->SpeedOfSound
!= 0.0f
)
146 case AL_DEFERRED_UPDATES_SOFT
:
147 value
= context
->DeferUpdates
;
151 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
155 ALCcontext_DecRef(context
);
160 AL_API ALdouble AL_APIENTRY
alGetDouble(ALenum pname
)
164 ALdouble value
= 0.0;
166 context
= GetContextRef();
167 if(!context
) return 0.0;
171 case AL_DOPPLER_FACTOR
:
172 value
= (ALdouble
)context
->DopplerFactor
;
175 case AL_DOPPLER_VELOCITY
:
176 value
= (ALdouble
)context
->DopplerVelocity
;
179 case AL_DISTANCE_MODEL
:
180 value
= (ALdouble
)context
->DistanceModel
;
183 case AL_SPEED_OF_SOUND
:
184 value
= (ALdouble
)context
->SpeedOfSound
;
187 case AL_DEFERRED_UPDATES_SOFT
:
188 value
= (ALdouble
)context
->DeferUpdates
;
191 case AL_MIDI_GAIN_SOFT
:
192 device
= context
->Device
;
193 value
= (ALdouble
)MidiSynth_getGain(device
->Synth
);
196 case AL_MIDI_STATE_SOFT
:
197 device
= context
->Device
;
198 value
= (ALdouble
)MidiSynth_getState(device
->Synth
);
202 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
206 ALCcontext_DecRef(context
);
211 AL_API ALfloat AL_APIENTRY
alGetFloat(ALenum pname
)
215 ALfloat value
= 0.0f
;
217 context
= GetContextRef();
218 if(!context
) return 0.0f
;
222 case AL_DOPPLER_FACTOR
:
223 value
= context
->DopplerFactor
;
226 case AL_DOPPLER_VELOCITY
:
227 value
= context
->DopplerVelocity
;
230 case AL_DISTANCE_MODEL
:
231 value
= (ALfloat
)context
->DistanceModel
;
234 case AL_SPEED_OF_SOUND
:
235 value
= context
->SpeedOfSound
;
238 case AL_DEFERRED_UPDATES_SOFT
:
239 value
= (ALfloat
)context
->DeferUpdates
;
242 case AL_MIDI_GAIN_SOFT
:
243 device
= context
->Device
;
244 value
= MidiSynth_getGain(device
->Synth
);
247 case AL_MIDI_STATE_SOFT
:
248 device
= context
->Device
;
249 value
= (ALfloat
)MidiSynth_getState(device
->Synth
);
253 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
257 ALCcontext_DecRef(context
);
262 AL_API ALint AL_APIENTRY
alGetInteger(ALenum pname
)
269 context
= GetContextRef();
270 if(!context
) return 0;
274 case AL_DOPPLER_FACTOR
:
275 value
= (ALint
)context
->DopplerFactor
;
278 case AL_DOPPLER_VELOCITY
:
279 value
= (ALint
)context
->DopplerVelocity
;
282 case AL_DISTANCE_MODEL
:
283 value
= (ALint
)context
->DistanceModel
;
286 case AL_SPEED_OF_SOUND
:
287 value
= (ALint
)context
->SpeedOfSound
;
290 case AL_DEFERRED_UPDATES_SOFT
:
291 value
= (ALint
)context
->DeferUpdates
;
294 case AL_SOUNDFONTS_SIZE_SOFT
:
295 device
= context
->Device
;
296 synth
= device
->Synth
;
297 value
= synth
->NumSoundfonts
;
300 case AL_MIDI_STATE_SOFT
:
301 device
= context
->Device
;
302 value
= MidiSynth_getState(device
->Synth
);
306 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
310 ALCcontext_DecRef(context
);
315 AL_API ALint64SOFT AL_APIENTRY
alGetInteger64SOFT(ALenum pname
)
320 ALint64SOFT value
= 0;
322 context
= GetContextRef();
323 if(!context
) return 0;
327 case AL_DOPPLER_FACTOR
:
328 value
= (ALint64SOFT
)context
->DopplerFactor
;
331 case AL_DOPPLER_VELOCITY
:
332 value
= (ALint64SOFT
)context
->DopplerVelocity
;
335 case AL_DISTANCE_MODEL
:
336 value
= (ALint64SOFT
)context
->DistanceModel
;
339 case AL_SPEED_OF_SOUND
:
340 value
= (ALint64SOFT
)context
->SpeedOfSound
;
343 case AL_DEFERRED_UPDATES_SOFT
:
344 value
= (ALint64SOFT
)context
->DeferUpdates
;
347 case AL_MIDI_CLOCK_SOFT
:
348 device
= context
->Device
;
349 ALCdevice_Lock(device
);
350 value
= MidiSynth_getTime(device
->Synth
);
351 ALCdevice_Unlock(device
);
354 case AL_SOUNDFONTS_SIZE_SOFT
:
355 device
= context
->Device
;
356 synth
= device
->Synth
;
357 value
= (ALint64SOFT
)synth
->NumSoundfonts
;
360 case AL_MIDI_STATE_SOFT
:
361 device
= context
->Device
;
362 value
= (ALint64SOFT
)MidiSynth_getState(device
->Synth
);
366 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
370 ALCcontext_DecRef(context
);
375 AL_API ALvoid AL_APIENTRY
alGetBooleanv(ALenum pname
, ALboolean
*values
)
383 case AL_DOPPLER_FACTOR
:
384 case AL_DOPPLER_VELOCITY
:
385 case AL_DISTANCE_MODEL
:
386 case AL_SPEED_OF_SOUND
:
387 case AL_DEFERRED_UPDATES_SOFT
:
388 values
[0] = alGetBoolean(pname
);
393 context
= GetContextRef();
397 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
401 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
405 ALCcontext_DecRef(context
);
408 AL_API ALvoid AL_APIENTRY
alGetDoublev(ALenum pname
, ALdouble
*values
)
416 case AL_DOPPLER_FACTOR
:
417 case AL_DOPPLER_VELOCITY
:
418 case AL_DISTANCE_MODEL
:
419 case AL_SPEED_OF_SOUND
:
420 case AL_DEFERRED_UPDATES_SOFT
:
421 case AL_MIDI_GAIN_SOFT
:
422 case AL_MIDI_STATE_SOFT
:
423 values
[0] = alGetDouble(pname
);
428 context
= GetContextRef();
432 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
436 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
440 ALCcontext_DecRef(context
);
443 AL_API ALvoid AL_APIENTRY
alGetFloatv(ALenum pname
, ALfloat
*values
)
451 case AL_DOPPLER_FACTOR
:
452 case AL_DOPPLER_VELOCITY
:
453 case AL_DISTANCE_MODEL
:
454 case AL_SPEED_OF_SOUND
:
455 case AL_DEFERRED_UPDATES_SOFT
:
456 case AL_MIDI_GAIN_SOFT
:
457 case AL_MIDI_STATE_SOFT
:
458 values
[0] = alGetFloat(pname
);
463 context
= GetContextRef();
467 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
471 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
475 ALCcontext_DecRef(context
);
478 AL_API ALvoid AL_APIENTRY
alGetIntegerv(ALenum pname
, ALint
*values
)
489 case AL_DOPPLER_FACTOR
:
490 case AL_DOPPLER_VELOCITY
:
491 case AL_DISTANCE_MODEL
:
492 case AL_SPEED_OF_SOUND
:
493 case AL_DEFERRED_UPDATES_SOFT
:
494 case AL_SOUNDFONTS_SIZE_SOFT
:
495 case AL_MIDI_STATE_SOFT
:
496 values
[0] = alGetInteger(pname
);
501 context
= GetContextRef();
506 case AL_SOUNDFONTS_SOFT
:
507 device
= context
->Device
;
508 synth
= device
->Synth
;
509 if(synth
->NumSoundfonts
> 0)
512 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
513 for(i
= 0;i
< synth
->NumSoundfonts
;i
++)
514 values
[i
] = synth
->Soundfonts
[i
]->id
;
519 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
523 ALCcontext_DecRef(context
);
526 AL_API
void AL_APIENTRY
alGetInteger64vSOFT(ALenum pname
, ALint64SOFT
*values
)
537 case AL_DOPPLER_FACTOR
:
538 case AL_DOPPLER_VELOCITY
:
539 case AL_DISTANCE_MODEL
:
540 case AL_SPEED_OF_SOUND
:
541 case AL_DEFERRED_UPDATES_SOFT
:
542 case AL_MIDI_CLOCK_SOFT
:
543 case AL_SOUNDFONTS_SIZE_SOFT
:
544 case AL_MIDI_STATE_SOFT
:
545 values
[0] = alGetInteger64SOFT(pname
);
550 context
= GetContextRef();
555 case AL_SOUNDFONTS_SOFT
:
556 device
= context
->Device
;
557 synth
= device
->Synth
;
558 if(synth
->NumSoundfonts
> 0)
561 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
562 for(i
= 0;i
< synth
->NumSoundfonts
;i
++)
563 values
[i
] = (ALint64SOFT
)synth
->Soundfonts
[i
]->id
;
568 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
572 ALCcontext_DecRef(context
);
575 AL_API
const ALchar
* AL_APIENTRY
alGetString(ALenum pname
)
577 const ALchar
*value
= NULL
;
580 context
= GetContextRef();
581 if(!context
) return NULL
;
598 value
= context
->ExtensionList
;
605 case AL_INVALID_NAME
:
606 value
= alErrInvalidName
;
609 case AL_INVALID_ENUM
:
610 value
= alErrInvalidEnum
;
613 case AL_INVALID_VALUE
:
614 value
= alErrInvalidValue
;
617 case AL_INVALID_OPERATION
:
618 value
= alErrInvalidOp
;
621 case AL_OUT_OF_MEMORY
:
622 value
= alErrOutOfMemory
;
626 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
630 ALCcontext_DecRef(context
);
635 AL_API ALvoid AL_APIENTRY
alDopplerFactor(ALfloat value
)
639 context
= GetContextRef();
642 if(!(value
>= 0.0f
&& isfinite(value
)))
643 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
645 context
->DopplerFactor
= value
;
646 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
649 ALCcontext_DecRef(context
);
652 AL_API ALvoid AL_APIENTRY
alDopplerVelocity(ALfloat value
)
656 context
= GetContextRef();
659 if(!(value
>= 0.0f
&& isfinite(value
)))
660 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
662 context
->DopplerVelocity
= value
;
663 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
666 ALCcontext_DecRef(context
);
669 AL_API ALvoid AL_APIENTRY
alSpeedOfSound(ALfloat value
)
673 context
= GetContextRef();
676 if(!(value
> 0.0f
&& isfinite(value
)))
677 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
679 context
->SpeedOfSound
= value
;
680 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
683 ALCcontext_DecRef(context
);
686 AL_API ALvoid AL_APIENTRY
alDistanceModel(ALenum value
)
690 context
= GetContextRef();
693 if(!(value
== AL_INVERSE_DISTANCE
|| value
== AL_INVERSE_DISTANCE_CLAMPED
||
694 value
== AL_LINEAR_DISTANCE
|| value
== AL_LINEAR_DISTANCE_CLAMPED
||
695 value
== AL_EXPONENT_DISTANCE
|| value
== AL_EXPONENT_DISTANCE_CLAMPED
||
697 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
699 context
->DistanceModel
= value
;
700 if(!context
->SourceDistanceModel
)
701 ATOMIC_STORE(&context
->UpdateSources
, AL_TRUE
);
704 ALCcontext_DecRef(context
);
708 AL_API ALvoid AL_APIENTRY
alDeferUpdatesSOFT(void)
712 context
= GetContextRef();
715 if(!context
->DeferUpdates
)
717 ALboolean UpdateSources
;
718 ALactivesource
**src
, **src_end
;
719 ALeffectslot
**slot
, **slot_end
;
722 SetMixerFPUMode(&oldMode
);
724 LockContext(context
);
725 context
->DeferUpdates
= AL_TRUE
;
727 /* Make sure all pending updates are performed */
728 UpdateSources
= ATOMIC_EXCHANGE(ALenum
, &context
->UpdateSources
, AL_FALSE
);
730 src
= context
->ActiveSources
;
731 src_end
= src
+ context
->ActiveSourceCount
;
732 while(src
!= src_end
)
734 ALsource
*source
= (*src
)->Source
;
736 if(source
->state
!= AL_PLAYING
&& source
->state
!= AL_PAUSED
)
738 ALactivesource
*temp
= *(--src_end
);
741 --(context
->ActiveSourceCount
);
745 if(ATOMIC_EXCHANGE(ALenum
, &source
->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
746 (*src
)->Update(*src
, context
);
751 slot
= VECTOR_ITER_BEGIN(context
->ActiveAuxSlots
);
752 slot_end
= VECTOR_ITER_END(context
->ActiveAuxSlots
);
753 while(slot
!= slot_end
)
755 if(ATOMIC_EXCHANGE(ALenum
, &(*slot
)->NeedsUpdate
, AL_FALSE
))
756 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
760 UnlockContext(context
);
761 RestoreFPUMode(&oldMode
);
764 ALCcontext_DecRef(context
);
767 AL_API ALvoid AL_APIENTRY
alProcessUpdatesSOFT(void)
771 context
= GetContextRef();
774 if(ExchangeInt(&context
->DeferUpdates
, AL_FALSE
))
778 LockContext(context
);
779 LockUIntMapRead(&context
->SourceMap
);
780 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
782 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
785 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
786 Source
->Offset
>= 0.0)
788 ReadLock(&Source
->queue_lock
);
790 ReadUnlock(&Source
->queue_lock
);
793 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
795 SetSourceState(Source
, context
, new_state
);
797 UnlockUIntMapRead(&context
->SourceMap
);
798 UnlockContext(context
);
801 ALCcontext_DecRef(context
);