Trace preset, instrument, and sample names with invalid key and velocity ranges
[openal-soft.git] / OpenAL32 / alState.c
blob6a52851955a4395ea860033ca890f250da4b0f73
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include "alMain.h"
25 #include "AL/alc.h"
26 #include "AL/al.h"
27 #include "AL/alext.h"
28 #include "alError.h"
29 #include "alSource.h"
30 #include "alAuxEffectSlot.h"
31 #include "alMidi.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";
40 // Error Messages
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)
50 ALCcontext *context;
52 context = GetContextRef();
53 if(!context) return;
55 switch(capability)
57 case AL_SOURCE_DISTANCE_MODEL:
58 context->SourceDistanceModel = AL_TRUE;
59 context->UpdateSources = AL_TRUE;
60 break;
62 default:
63 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
66 done:
67 ALCcontext_DecRef(context);
70 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
72 ALCcontext *context;
74 context = GetContextRef();
75 if(!context) return;
77 switch(capability)
79 case AL_SOURCE_DISTANCE_MODEL:
80 context->SourceDistanceModel = AL_FALSE;
81 context->UpdateSources = AL_TRUE;
82 break;
84 default:
85 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
88 done:
89 ALCcontext_DecRef(context);
92 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
94 ALCcontext *context;
95 ALboolean value=AL_FALSE;
97 context = GetContextRef();
98 if(!context) return AL_FALSE;
100 switch(capability)
102 case AL_SOURCE_DISTANCE_MODEL:
103 value = context->SourceDistanceModel;
104 break;
106 default:
107 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
110 done:
111 ALCcontext_DecRef(context);
113 return value;
116 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
118 ALCcontext *context;
119 ALboolean value=AL_FALSE;
121 context = GetContextRef();
122 if(!context) return AL_FALSE;
124 switch(pname)
126 case AL_DOPPLER_FACTOR:
127 if(context->DopplerFactor != 0.0f)
128 value = AL_TRUE;
129 break;
131 case AL_DOPPLER_VELOCITY:
132 if(context->DopplerVelocity != 0.0f)
133 value = AL_TRUE;
134 break;
136 case AL_DISTANCE_MODEL:
137 if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
138 value = AL_TRUE;
139 break;
141 case AL_SPEED_OF_SOUND:
142 if(context->SpeedOfSound != 0.0f)
143 value = AL_TRUE;
144 break;
146 case AL_DEFERRED_UPDATES_SOFT:
147 value = context->DeferUpdates;
148 break;
150 default:
151 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
154 done:
155 ALCcontext_DecRef(context);
157 return value;
160 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
162 ALCdevice *device;
163 ALCcontext *context;
164 ALdouble value = 0.0;
166 context = GetContextRef();
167 if(!context) return 0.0;
169 switch(pname)
171 case AL_DOPPLER_FACTOR:
172 value = (ALdouble)context->DopplerFactor;
173 break;
175 case AL_DOPPLER_VELOCITY:
176 value = (ALdouble)context->DopplerVelocity;
177 break;
179 case AL_DISTANCE_MODEL:
180 value = (ALdouble)context->DistanceModel;
181 break;
183 case AL_SPEED_OF_SOUND:
184 value = (ALdouble)context->SpeedOfSound;
185 break;
187 case AL_DEFERRED_UPDATES_SOFT:
188 value = (ALdouble)context->DeferUpdates;
189 break;
191 case AL_MIDI_GAIN_SOFT:
192 device = context->Device;
193 value = (ALdouble)MidiSynth_getGain(device->Synth);
195 default:
196 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
199 done:
200 ALCcontext_DecRef(context);
202 return value;
205 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
207 ALCdevice *device;
208 ALCcontext *context;
209 ALfloat value = 0.0f;
211 context = GetContextRef();
212 if(!context) return 0.0f;
214 switch(pname)
216 case AL_DOPPLER_FACTOR:
217 value = context->DopplerFactor;
218 break;
220 case AL_DOPPLER_VELOCITY:
221 value = context->DopplerVelocity;
222 break;
224 case AL_DISTANCE_MODEL:
225 value = (ALfloat)context->DistanceModel;
226 break;
228 case AL_SPEED_OF_SOUND:
229 value = context->SpeedOfSound;
230 break;
232 case AL_DEFERRED_UPDATES_SOFT:
233 value = (ALfloat)context->DeferUpdates;
234 break;
236 case AL_MIDI_GAIN_SOFT:
237 device = context->Device;
238 value = MidiSynth_getGain(device->Synth);
240 default:
241 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
244 done:
245 ALCcontext_DecRef(context);
247 return value;
250 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
252 ALCcontext *context;
253 ALCdevice *device;
254 MidiSynth *synth;
255 ALint value = 0;
257 context = GetContextRef();
258 if(!context) return 0;
260 switch(pname)
262 case AL_DOPPLER_FACTOR:
263 value = (ALint)context->DopplerFactor;
264 break;
266 case AL_DOPPLER_VELOCITY:
267 value = (ALint)context->DopplerVelocity;
268 break;
270 case AL_DISTANCE_MODEL:
271 value = (ALint)context->DistanceModel;
272 break;
274 case AL_SPEED_OF_SOUND:
275 value = (ALint)context->SpeedOfSound;
276 break;
278 case AL_DEFERRED_UPDATES_SOFT:
279 value = (ALint)context->DeferUpdates;
280 break;
282 case AL_SOUNDFONTS_SIZE_SOFT:
283 device = context->Device;
284 synth = device->Synth;
285 value = synth->NumSoundfonts;
286 break;
288 default:
289 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
292 done:
293 ALCcontext_DecRef(context);
295 return value;
298 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
300 ALCcontext *context;
301 ALCdevice *device;
302 MidiSynth *synth;
303 ALint64SOFT value = 0;
305 context = GetContextRef();
306 if(!context) return 0;
308 switch(pname)
310 case AL_DOPPLER_FACTOR:
311 value = (ALint64SOFT)context->DopplerFactor;
312 break;
314 case AL_DOPPLER_VELOCITY:
315 value = (ALint64SOFT)context->DopplerVelocity;
316 break;
318 case AL_DISTANCE_MODEL:
319 value = (ALint64SOFT)context->DistanceModel;
320 break;
322 case AL_SPEED_OF_SOUND:
323 value = (ALint64SOFT)context->SpeedOfSound;
324 break;
326 case AL_DEFERRED_UPDATES_SOFT:
327 value = (ALint64SOFT)context->DeferUpdates;
328 break;
330 case AL_MIDI_CLOCK_SOFT:
331 device = context->Device;
332 ALCdevice_Lock(device);
333 value = MidiSynth_getTime(device->Synth);
334 ALCdevice_Unlock(device);
335 break;
337 case AL_SOUNDFONTS_SIZE_SOFT:
338 device = context->Device;
339 synth = device->Synth;
340 value = (ALint64SOFT)synth->NumSoundfonts;
341 break;
343 default:
344 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
347 done:
348 ALCcontext_DecRef(context);
350 return value;
353 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
355 ALCcontext *context;
357 if(values)
359 switch(pname)
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);
367 return;
371 context = GetContextRef();
372 if(!context) return;
374 if(!(values))
375 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
376 switch(pname)
378 default:
379 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
382 done:
383 ALCcontext_DecRef(context);
386 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
388 ALCcontext *context;
390 if(values)
392 switch(pname)
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);
401 return;
405 context = GetContextRef();
406 if(!context) return;
408 if(!(values))
409 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
410 switch(pname)
412 default:
413 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
416 done:
417 ALCcontext_DecRef(context);
420 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
422 ALCcontext *context;
424 if(values)
426 switch(pname)
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);
435 return;
439 context = GetContextRef();
440 if(!context) return;
442 if(!(values))
443 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
444 switch(pname)
446 default:
447 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
450 done:
451 ALCcontext_DecRef(context);
454 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
456 ALCcontext *context;
457 ALCdevice *device;
458 MidiSynth *synth;
459 ALsizei i;
461 if(values)
463 switch(pname)
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);
472 return;
476 context = GetContextRef();
477 if(!context) return;
479 switch(pname)
481 case AL_SOUNDFONTS_SOFT:
482 device = context->Device;
483 synth = device->Synth;
484 if(synth->NumSoundfonts > 0)
486 if(!(values))
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;
491 break;
493 default:
494 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
497 done:
498 ALCcontext_DecRef(context);
501 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
503 ALCcontext *context;
504 ALCdevice *device;
505 MidiSynth *synth;
506 ALsizei i;
508 if(values)
510 switch(pname)
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);
520 return;
524 context = GetContextRef();
525 if(!context) return;
527 switch(pname)
529 case AL_SOUNDFONTS_SOFT:
530 device = context->Device;
531 synth = device->Synth;
532 if(synth->NumSoundfonts > 0)
534 if(!(values))
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;
539 break;
541 default:
542 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
545 done:
546 ALCcontext_DecRef(context);
549 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
551 const ALchar *value = NULL;
552 ALCcontext *context;
554 context = GetContextRef();
555 if(!context) return NULL;
557 switch(pname)
559 case AL_VENDOR:
560 value = alVendor;
561 break;
563 case AL_VERSION:
564 value = alVersion;
565 break;
567 case AL_RENDERER:
568 value = alRenderer;
569 break;
571 case AL_EXTENSIONS:
572 value = context->ExtensionList;
573 break;
575 case AL_NO_ERROR:
576 value = alNoError;
577 break;
579 case AL_INVALID_NAME:
580 value = alErrInvalidName;
581 break;
583 case AL_INVALID_ENUM:
584 value = alErrInvalidEnum;
585 break;
587 case AL_INVALID_VALUE:
588 value = alErrInvalidValue;
589 break;
591 case AL_INVALID_OPERATION:
592 value = alErrInvalidOp;
593 break;
595 case AL_OUT_OF_MEMORY:
596 value = alErrOutOfMemory;
597 break;
599 default:
600 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
603 done:
604 ALCcontext_DecRef(context);
606 return value;
609 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
611 ALCcontext *context;
613 context = GetContextRef();
614 if(!context) return;
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;
622 done:
623 ALCcontext_DecRef(context);
626 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
628 ALCcontext *context;
630 context = GetContextRef();
631 if(!context) return;
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;
639 done:
640 ALCcontext_DecRef(context);
643 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
645 ALCcontext *context;
647 context = GetContextRef();
648 if(!context) return;
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;
656 done:
657 ALCcontext_DecRef(context);
660 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
662 ALCcontext *context;
664 context = GetContextRef();
665 if(!context) return;
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 ||
670 value == AL_NONE))
671 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
673 context->DistanceModel = value;
674 if(!context->SourceDistanceModel)
675 context->UpdateSources = AL_TRUE;
677 done:
678 ALCcontext_DecRef(context);
682 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
684 ALCcontext *context;
686 context = GetContextRef();
687 if(!context) return;
689 if(!context->DeferUpdates)
691 ALboolean UpdateSources;
692 ALsource **src, **src_end;
693 ALeffectslot **slot, **slot_end;
694 FPUCtl oldMode;
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--;
711 *src = *(--src_end);
712 continue;
715 if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources)
716 ALsource_Update(*src, context);
718 src++;
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);
727 slot++;
730 UnlockContext(context);
731 RestoreFPUMode(&oldMode);
734 ALCcontext_DecRef(context);
737 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
739 ALCcontext *context;
741 context = GetContextRef();
742 if(!context) return;
744 if(ExchangeInt(&context->DeferUpdates, AL_FALSE))
746 ALsizei pos;
748 LockContext(context);
749 LockUIntMapRead(&context->SourceMap);
750 for(pos = 0;pos < context->SourceMap.size;pos++)
752 ALsource *Source = context->SourceMap.array[pos].value;
753 ALenum new_state;
755 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
756 Source->Offset >= 0.0)
757 ApplyOffset(Source);
759 new_state = ExchangeInt(&Source->new_state, AL_NONE);
760 if(new_state)
761 SetSourceState(Source, context, new_state);
763 UnlockUIntMapRead(&context->SourceMap);
764 UnlockContext(context);
767 ALCcontext_DecRef(context);