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 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 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 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
200 ALCcontext_DecRef(context
);
205 AL_API ALfloat AL_APIENTRY
alGetFloat(ALenum pname
)
209 ALfloat value
= 0.0f
;
211 context
= GetContextRef();
212 if(!context
) return 0.0f
;
216 case AL_DOPPLER_FACTOR
:
217 value
= context
->DopplerFactor
;
220 case AL_DOPPLER_VELOCITY
:
221 value
= context
->DopplerVelocity
;
224 case AL_DISTANCE_MODEL
:
225 value
= (ALfloat
)context
->DistanceModel
;
228 case AL_SPEED_OF_SOUND
:
229 value
= context
->SpeedOfSound
;
232 case AL_DEFERRED_UPDATES_SOFT
:
233 value
= (ALfloat
)context
->DeferUpdates
;
236 case AL_MIDI_GAIN_SOFT
:
237 device
= context
->Device
;
238 value
= MidiSynth_getGain(device
->Synth
);
241 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
245 ALCcontext_DecRef(context
);
250 AL_API ALint AL_APIENTRY
alGetInteger(ALenum pname
)
257 context
= GetContextRef();
258 if(!context
) return 0;
262 case AL_DOPPLER_FACTOR
:
263 value
= (ALint
)context
->DopplerFactor
;
266 case AL_DOPPLER_VELOCITY
:
267 value
= (ALint
)context
->DopplerVelocity
;
270 case AL_DISTANCE_MODEL
:
271 value
= (ALint
)context
->DistanceModel
;
274 case AL_SPEED_OF_SOUND
:
275 value
= (ALint
)context
->SpeedOfSound
;
278 case AL_DEFERRED_UPDATES_SOFT
:
279 value
= (ALint
)context
->DeferUpdates
;
282 case AL_SOUNDFONTS_SIZE_SOFT
:
283 device
= context
->Device
;
284 synth
= device
->Synth
;
285 value
= synth
->NumSoundfonts
;
289 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
293 ALCcontext_DecRef(context
);
298 AL_API ALint64SOFT AL_APIENTRY
alGetInteger64SOFT(ALenum pname
)
303 ALint64SOFT value
= 0;
305 context
= GetContextRef();
306 if(!context
) return 0;
310 case AL_DOPPLER_FACTOR
:
311 value
= (ALint64SOFT
)context
->DopplerFactor
;
314 case AL_DOPPLER_VELOCITY
:
315 value
= (ALint64SOFT
)context
->DopplerVelocity
;
318 case AL_DISTANCE_MODEL
:
319 value
= (ALint64SOFT
)context
->DistanceModel
;
322 case AL_SPEED_OF_SOUND
:
323 value
= (ALint64SOFT
)context
->SpeedOfSound
;
326 case AL_DEFERRED_UPDATES_SOFT
:
327 value
= (ALint64SOFT
)context
->DeferUpdates
;
330 case AL_MIDI_CLOCK_SOFT
:
331 device
= context
->Device
;
332 ALCdevice_Lock(device
);
333 value
= MidiSynth_getTime(device
->Synth
);
334 ALCdevice_Unlock(device
);
337 case AL_SOUNDFONTS_SIZE_SOFT
:
338 device
= context
->Device
;
339 synth
= device
->Synth
;
340 value
= (ALint64SOFT
)synth
->NumSoundfonts
;
344 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
348 ALCcontext_DecRef(context
);
353 AL_API ALvoid AL_APIENTRY
alGetBooleanv(ALenum pname
, ALboolean
*values
)
361 case AL_DOPPLER_FACTOR
:
362 case AL_DOPPLER_VELOCITY
:
363 case AL_DISTANCE_MODEL
:
364 case AL_SPEED_OF_SOUND
:
365 case AL_DEFERRED_UPDATES_SOFT
:
366 values
[0] = alGetBoolean(pname
);
371 context
= GetContextRef();
375 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
379 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
383 ALCcontext_DecRef(context
);
386 AL_API ALvoid AL_APIENTRY
alGetDoublev(ALenum pname
, ALdouble
*values
)
394 case AL_DOPPLER_FACTOR
:
395 case AL_DOPPLER_VELOCITY
:
396 case AL_DISTANCE_MODEL
:
397 case AL_SPEED_OF_SOUND
:
398 case AL_DEFERRED_UPDATES_SOFT
:
399 case AL_MIDI_GAIN_SOFT
:
400 values
[0] = alGetDouble(pname
);
405 context
= GetContextRef();
409 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
413 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
417 ALCcontext_DecRef(context
);
420 AL_API ALvoid AL_APIENTRY
alGetFloatv(ALenum pname
, ALfloat
*values
)
428 case AL_DOPPLER_FACTOR
:
429 case AL_DOPPLER_VELOCITY
:
430 case AL_DISTANCE_MODEL
:
431 case AL_SPEED_OF_SOUND
:
432 case AL_DEFERRED_UPDATES_SOFT
:
433 case AL_MIDI_GAIN_SOFT
:
434 values
[0] = alGetFloat(pname
);
439 context
= GetContextRef();
443 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
447 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
451 ALCcontext_DecRef(context
);
454 AL_API ALvoid AL_APIENTRY
alGetIntegerv(ALenum pname
, ALint
*values
)
465 case AL_DOPPLER_FACTOR
:
466 case AL_DOPPLER_VELOCITY
:
467 case AL_DISTANCE_MODEL
:
468 case AL_SPEED_OF_SOUND
:
469 case AL_DEFERRED_UPDATES_SOFT
:
470 case AL_SOUNDFONTS_SIZE_SOFT
:
471 values
[0] = alGetInteger(pname
);
476 context
= GetContextRef();
481 case AL_SOUNDFONTS_SOFT
:
482 device
= context
->Device
;
483 synth
= device
->Synth
;
484 if(synth
->NumSoundfonts
> 0)
487 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
488 for(i
= 0;i
< synth
->NumSoundfonts
;i
++)
489 values
[i
] = synth
->Soundfonts
[i
]->id
;
494 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
498 ALCcontext_DecRef(context
);
501 AL_API
void AL_APIENTRY
alGetInteger64vSOFT(ALenum pname
, ALint64SOFT
*values
)
512 case AL_DOPPLER_FACTOR
:
513 case AL_DOPPLER_VELOCITY
:
514 case AL_DISTANCE_MODEL
:
515 case AL_SPEED_OF_SOUND
:
516 case AL_DEFERRED_UPDATES_SOFT
:
517 case AL_MIDI_CLOCK_SOFT
:
518 case AL_SOUNDFONTS_SIZE_SOFT
:
519 values
[0] = alGetInteger64SOFT(pname
);
524 context
= GetContextRef();
529 case AL_SOUNDFONTS_SOFT
:
530 device
= context
->Device
;
531 synth
= device
->Synth
;
532 if(synth
->NumSoundfonts
> 0)
535 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
536 for(i
= 0;i
< synth
->NumSoundfonts
;i
++)
537 values
[i
] = (ALint64SOFT
)synth
->Soundfonts
[i
]->id
;
542 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
546 ALCcontext_DecRef(context
);
549 AL_API
const ALchar
* AL_APIENTRY
alGetString(ALenum pname
)
551 const ALchar
*value
= NULL
;
554 context
= GetContextRef();
555 if(!context
) return NULL
;
572 value
= context
->ExtensionList
;
579 case AL_INVALID_NAME
:
580 value
= alErrInvalidName
;
583 case AL_INVALID_ENUM
:
584 value
= alErrInvalidEnum
;
587 case AL_INVALID_VALUE
:
588 value
= alErrInvalidValue
;
591 case AL_INVALID_OPERATION
:
592 value
= alErrInvalidOp
;
595 case AL_OUT_OF_MEMORY
:
596 value
= alErrOutOfMemory
;
600 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
604 ALCcontext_DecRef(context
);
609 AL_API ALvoid AL_APIENTRY
alDopplerFactor(ALfloat value
)
613 context
= GetContextRef();
616 if(!(value
>= 0.0f
&& isfinite(value
)))
617 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
619 context
->DopplerFactor
= value
;
620 context
->UpdateSources
= AL_TRUE
;
623 ALCcontext_DecRef(context
);
626 AL_API ALvoid AL_APIENTRY
alDopplerVelocity(ALfloat value
)
630 context
= GetContextRef();
633 if(!(value
>= 0.0f
&& isfinite(value
)))
634 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
636 context
->DopplerVelocity
= value
;
637 context
->UpdateSources
= AL_TRUE
;
640 ALCcontext_DecRef(context
);
643 AL_API ALvoid AL_APIENTRY
alSpeedOfSound(ALfloat value
)
647 context
= GetContextRef();
650 if(!(value
> 0.0f
&& isfinite(value
)))
651 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
653 context
->SpeedOfSound
= value
;
654 context
->UpdateSources
= AL_TRUE
;
657 ALCcontext_DecRef(context
);
660 AL_API ALvoid AL_APIENTRY
alDistanceModel(ALenum value
)
664 context
= GetContextRef();
667 if(!(value
== AL_INVERSE_DISTANCE
|| value
== AL_INVERSE_DISTANCE_CLAMPED
||
668 value
== AL_LINEAR_DISTANCE
|| value
== AL_LINEAR_DISTANCE_CLAMPED
||
669 value
== AL_EXPONENT_DISTANCE
|| value
== AL_EXPONENT_DISTANCE_CLAMPED
||
671 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
673 context
->DistanceModel
= value
;
674 if(!context
->SourceDistanceModel
)
675 context
->UpdateSources
= AL_TRUE
;
678 ALCcontext_DecRef(context
);
682 AL_API ALvoid AL_APIENTRY
alDeferUpdatesSOFT(void)
686 context
= GetContextRef();
689 if(!context
->DeferUpdates
)
691 ALboolean UpdateSources
;
692 ALsource
**src
, **src_end
;
693 ALeffectslot
**slot
, **slot_end
;
696 SetMixerFPUMode(&oldMode
);
698 LockContext(context
);
699 context
->DeferUpdates
= AL_TRUE
;
701 /* Make sure all pending updates are performed */
702 UpdateSources
= ExchangeInt(&context
->UpdateSources
, AL_FALSE
);
704 src
= context
->ActiveSources
;
705 src_end
= src
+ context
->ActiveSourceCount
;
706 while(src
!= src_end
)
708 if((*src
)->state
!= AL_PLAYING
)
710 context
->ActiveSourceCount
--;
715 if(ExchangeInt(&(*src
)->NeedsUpdate
, AL_FALSE
) || UpdateSources
)
716 ALsource_Update(*src
, context
);
721 slot
= context
->ActiveEffectSlots
;
722 slot_end
= slot
+ context
->ActiveEffectSlotCount
;
723 while(slot
!= slot_end
)
725 if(ExchangeInt(&(*slot
)->NeedsUpdate
, AL_FALSE
))
726 V((*slot
)->EffectState
,update
)(context
->Device
, *slot
);
730 UnlockContext(context
);
731 RestoreFPUMode(&oldMode
);
734 ALCcontext_DecRef(context
);
737 AL_API ALvoid AL_APIENTRY
alProcessUpdatesSOFT(void)
741 context
= GetContextRef();
744 if(ExchangeInt(&context
->DeferUpdates
, AL_FALSE
))
748 LockContext(context
);
749 LockUIntMapRead(&context
->SourceMap
);
750 for(pos
= 0;pos
< context
->SourceMap
.size
;pos
++)
752 ALsource
*Source
= context
->SourceMap
.array
[pos
].value
;
755 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
756 Source
->Offset
>= 0.0)
759 new_state
= ExchangeInt(&Source
->new_state
, AL_NONE
);
761 SetSourceState(Source
, context
, new_state
);
763 UnlockUIntMapRead(&context
->SourceMap
);
764 UnlockContext(context
);
767 ALCcontext_DecRef(context
);