Multiply samples with the cubic coeffs before transposing
[openal-soft.git] / OpenAL32 / alState.c
blobf2f25f9795f8fb94e834db225f67b9e8c63b477c
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.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 "backends/base.h"
34 #include "midi/base.h"
37 static const ALchar alVendor[] = "OpenAL Community";
38 static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
39 static const ALchar alRenderer[] = "OpenAL Soft";
41 // Error Messages
42 static const ALchar alNoError[] = "No Error";
43 static const ALchar alErrInvalidName[] = "Invalid Name";
44 static const ALchar alErrInvalidEnum[] = "Invalid Enum";
45 static const ALchar alErrInvalidValue[] = "Invalid Value";
46 static const ALchar alErrInvalidOp[] = "Invalid Operation";
47 static const ALchar alErrOutOfMemory[] = "Out of Memory";
49 AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
51 ALCcontext *context;
53 context = GetContextRef();
54 if(!context) return;
56 switch(capability)
58 case AL_SOURCE_DISTANCE_MODEL:
59 context->SourceDistanceModel = AL_TRUE;
60 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
61 break;
63 default:
64 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
67 done:
68 ALCcontext_DecRef(context);
71 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
73 ALCcontext *context;
75 context = GetContextRef();
76 if(!context) return;
78 switch(capability)
80 case AL_SOURCE_DISTANCE_MODEL:
81 context->SourceDistanceModel = AL_FALSE;
82 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
83 break;
85 default:
86 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
89 done:
90 ALCcontext_DecRef(context);
93 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
95 ALCcontext *context;
96 ALboolean value=AL_FALSE;
98 context = GetContextRef();
99 if(!context) return AL_FALSE;
101 switch(capability)
103 case AL_SOURCE_DISTANCE_MODEL:
104 value = context->SourceDistanceModel;
105 break;
107 default:
108 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
111 done:
112 ALCcontext_DecRef(context);
114 return value;
117 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
119 ALCcontext *context;
120 ALboolean value=AL_FALSE;
122 context = GetContextRef();
123 if(!context) return AL_FALSE;
125 switch(pname)
127 case AL_DOPPLER_FACTOR:
128 if(context->DopplerFactor != 0.0f)
129 value = AL_TRUE;
130 break;
132 case AL_DOPPLER_VELOCITY:
133 if(context->DopplerVelocity != 0.0f)
134 value = AL_TRUE;
135 break;
137 case AL_DISTANCE_MODEL:
138 if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
139 value = AL_TRUE;
140 break;
142 case AL_SPEED_OF_SOUND:
143 if(context->SpeedOfSound != 0.0f)
144 value = AL_TRUE;
145 break;
147 case AL_DEFERRED_UPDATES_SOFT:
148 value = context->DeferUpdates;
149 break;
151 default:
152 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
155 done:
156 ALCcontext_DecRef(context);
158 return value;
161 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
163 ALCdevice *device;
164 ALCcontext *context;
165 ALdouble value = 0.0;
167 context = GetContextRef();
168 if(!context) return 0.0;
170 switch(pname)
172 case AL_DOPPLER_FACTOR:
173 value = (ALdouble)context->DopplerFactor;
174 break;
176 case AL_DOPPLER_VELOCITY:
177 value = (ALdouble)context->DopplerVelocity;
178 break;
180 case AL_DISTANCE_MODEL:
181 value = (ALdouble)context->DistanceModel;
182 break;
184 case AL_SPEED_OF_SOUND:
185 value = (ALdouble)context->SpeedOfSound;
186 break;
188 case AL_DEFERRED_UPDATES_SOFT:
189 value = (ALdouble)context->DeferUpdates;
190 break;
192 case AL_MIDI_GAIN_SOFT:
193 device = context->Device;
194 value = (ALdouble)MidiSynth_getGain(device->Synth);
195 break;
197 case AL_MIDI_STATE_SOFT:
198 device = context->Device;
199 value = (ALdouble)MidiSynth_getState(device->Synth);
200 break;
202 default:
203 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
206 done:
207 ALCcontext_DecRef(context);
209 return value;
212 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
214 ALCdevice *device;
215 ALCcontext *context;
216 ALfloat value = 0.0f;
218 context = GetContextRef();
219 if(!context) return 0.0f;
221 switch(pname)
223 case AL_DOPPLER_FACTOR:
224 value = context->DopplerFactor;
225 break;
227 case AL_DOPPLER_VELOCITY:
228 value = context->DopplerVelocity;
229 break;
231 case AL_DISTANCE_MODEL:
232 value = (ALfloat)context->DistanceModel;
233 break;
235 case AL_SPEED_OF_SOUND:
236 value = context->SpeedOfSound;
237 break;
239 case AL_DEFERRED_UPDATES_SOFT:
240 value = (ALfloat)context->DeferUpdates;
241 break;
243 case AL_MIDI_GAIN_SOFT:
244 device = context->Device;
245 value = MidiSynth_getGain(device->Synth);
246 break;
248 case AL_MIDI_STATE_SOFT:
249 device = context->Device;
250 value = (ALfloat)MidiSynth_getState(device->Synth);
251 break;
253 default:
254 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
257 done:
258 ALCcontext_DecRef(context);
260 return value;
263 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
265 ALCcontext *context;
266 ALCdevice *device;
267 MidiSynth *synth;
268 ALint value = 0;
270 context = GetContextRef();
271 if(!context) return 0;
273 switch(pname)
275 case AL_DOPPLER_FACTOR:
276 value = (ALint)context->DopplerFactor;
277 break;
279 case AL_DOPPLER_VELOCITY:
280 value = (ALint)context->DopplerVelocity;
281 break;
283 case AL_DISTANCE_MODEL:
284 value = (ALint)context->DistanceModel;
285 break;
287 case AL_SPEED_OF_SOUND:
288 value = (ALint)context->SpeedOfSound;
289 break;
291 case AL_DEFERRED_UPDATES_SOFT:
292 value = (ALint)context->DeferUpdates;
293 break;
295 case AL_SOUNDFONTS_SIZE_SOFT:
296 device = context->Device;
297 synth = device->Synth;
298 value = synth->NumSoundfonts;
299 break;
301 case AL_MIDI_STATE_SOFT:
302 device = context->Device;
303 value = MidiSynth_getState(device->Synth);
304 break;
306 default:
307 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
310 done:
311 ALCcontext_DecRef(context);
313 return value;
316 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
318 ALCcontext *context;
319 ALCdevice *device;
320 MidiSynth *synth;
321 ALint64SOFT value = 0;
323 context = GetContextRef();
324 if(!context) return 0;
326 switch(pname)
328 case AL_DOPPLER_FACTOR:
329 value = (ALint64SOFT)context->DopplerFactor;
330 break;
332 case AL_DOPPLER_VELOCITY:
333 value = (ALint64SOFT)context->DopplerVelocity;
334 break;
336 case AL_DISTANCE_MODEL:
337 value = (ALint64SOFT)context->DistanceModel;
338 break;
340 case AL_SPEED_OF_SOUND:
341 value = (ALint64SOFT)context->SpeedOfSound;
342 break;
344 case AL_DEFERRED_UPDATES_SOFT:
345 value = (ALint64SOFT)context->DeferUpdates;
346 break;
348 case AL_MIDI_CLOCK_SOFT:
349 device = context->Device;
350 V0(device->Backend,lock)();
351 value = MidiSynth_getTime(device->Synth);
352 V0(device->Backend,unlock)();
353 break;
355 case AL_SOUNDFONTS_SIZE_SOFT:
356 device = context->Device;
357 synth = device->Synth;
358 value = (ALint64SOFT)synth->NumSoundfonts;
359 break;
361 case AL_MIDI_STATE_SOFT:
362 device = context->Device;
363 value = (ALint64SOFT)MidiSynth_getState(device->Synth);
364 break;
366 default:
367 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
370 done:
371 ALCcontext_DecRef(context);
373 return value;
376 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
378 ALCcontext *context;
380 if(values)
382 switch(pname)
384 case AL_DOPPLER_FACTOR:
385 case AL_DOPPLER_VELOCITY:
386 case AL_DISTANCE_MODEL:
387 case AL_SPEED_OF_SOUND:
388 case AL_DEFERRED_UPDATES_SOFT:
389 values[0] = alGetBoolean(pname);
390 return;
394 context = GetContextRef();
395 if(!context) return;
397 if(!(values))
398 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
399 switch(pname)
401 default:
402 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
405 done:
406 ALCcontext_DecRef(context);
409 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
411 ALCcontext *context;
413 if(values)
415 switch(pname)
417 case AL_DOPPLER_FACTOR:
418 case AL_DOPPLER_VELOCITY:
419 case AL_DISTANCE_MODEL:
420 case AL_SPEED_OF_SOUND:
421 case AL_DEFERRED_UPDATES_SOFT:
422 case AL_MIDI_GAIN_SOFT:
423 case AL_MIDI_STATE_SOFT:
424 values[0] = alGetDouble(pname);
425 return;
429 context = GetContextRef();
430 if(!context) return;
432 if(!(values))
433 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
434 switch(pname)
436 default:
437 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
440 done:
441 ALCcontext_DecRef(context);
444 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
446 ALCcontext *context;
448 if(values)
450 switch(pname)
452 case AL_DOPPLER_FACTOR:
453 case AL_DOPPLER_VELOCITY:
454 case AL_DISTANCE_MODEL:
455 case AL_SPEED_OF_SOUND:
456 case AL_DEFERRED_UPDATES_SOFT:
457 case AL_MIDI_GAIN_SOFT:
458 case AL_MIDI_STATE_SOFT:
459 values[0] = alGetFloat(pname);
460 return;
464 context = GetContextRef();
465 if(!context) return;
467 if(!(values))
468 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
469 switch(pname)
471 default:
472 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
475 done:
476 ALCcontext_DecRef(context);
479 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
481 ALCcontext *context;
482 ALCdevice *device;
483 MidiSynth *synth;
484 ALsizei i;
486 if(values)
488 switch(pname)
490 case AL_DOPPLER_FACTOR:
491 case AL_DOPPLER_VELOCITY:
492 case AL_DISTANCE_MODEL:
493 case AL_SPEED_OF_SOUND:
494 case AL_DEFERRED_UPDATES_SOFT:
495 case AL_SOUNDFONTS_SIZE_SOFT:
496 case AL_MIDI_STATE_SOFT:
497 values[0] = alGetInteger(pname);
498 return;
502 context = GetContextRef();
503 if(!context) return;
505 switch(pname)
507 case AL_SOUNDFONTS_SOFT:
508 device = context->Device;
509 synth = device->Synth;
510 if(synth->NumSoundfonts > 0)
512 if(!(values))
513 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
514 for(i = 0;i < synth->NumSoundfonts;i++)
515 values[i] = synth->Soundfonts[i]->id;
517 break;
519 default:
520 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
523 done:
524 ALCcontext_DecRef(context);
527 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
529 ALCcontext *context;
530 ALCdevice *device;
531 MidiSynth *synth;
532 ALsizei i;
534 if(values)
536 switch(pname)
538 case AL_DOPPLER_FACTOR:
539 case AL_DOPPLER_VELOCITY:
540 case AL_DISTANCE_MODEL:
541 case AL_SPEED_OF_SOUND:
542 case AL_DEFERRED_UPDATES_SOFT:
543 case AL_MIDI_CLOCK_SOFT:
544 case AL_SOUNDFONTS_SIZE_SOFT:
545 case AL_MIDI_STATE_SOFT:
546 values[0] = alGetInteger64SOFT(pname);
547 return;
551 context = GetContextRef();
552 if(!context) return;
554 switch(pname)
556 case AL_SOUNDFONTS_SOFT:
557 device = context->Device;
558 synth = device->Synth;
559 if(synth->NumSoundfonts > 0)
561 if(!(values))
562 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
563 for(i = 0;i < synth->NumSoundfonts;i++)
564 values[i] = (ALint64SOFT)synth->Soundfonts[i]->id;
566 break;
568 default:
569 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
572 done:
573 ALCcontext_DecRef(context);
576 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
578 const ALchar *value = NULL;
579 ALCcontext *context;
581 context = GetContextRef();
582 if(!context) return NULL;
584 switch(pname)
586 case AL_VENDOR:
587 value = alVendor;
588 break;
590 case AL_VERSION:
591 value = alVersion;
592 break;
594 case AL_RENDERER:
595 value = alRenderer;
596 break;
598 case AL_EXTENSIONS:
599 value = context->ExtensionList;
600 break;
602 case AL_NO_ERROR:
603 value = alNoError;
604 break;
606 case AL_INVALID_NAME:
607 value = alErrInvalidName;
608 break;
610 case AL_INVALID_ENUM:
611 value = alErrInvalidEnum;
612 break;
614 case AL_INVALID_VALUE:
615 value = alErrInvalidValue;
616 break;
618 case AL_INVALID_OPERATION:
619 value = alErrInvalidOp;
620 break;
622 case AL_OUT_OF_MEMORY:
623 value = alErrOutOfMemory;
624 break;
626 default:
627 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
630 done:
631 ALCcontext_DecRef(context);
633 return value;
636 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
638 ALCcontext *context;
640 context = GetContextRef();
641 if(!context) return;
643 if(!(value >= 0.0f && isfinite(value)))
644 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
646 context->DopplerFactor = value;
647 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
649 done:
650 ALCcontext_DecRef(context);
653 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
655 ALCcontext *context;
657 context = GetContextRef();
658 if(!context) return;
660 if(!(value >= 0.0f && isfinite(value)))
661 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
663 context->DopplerVelocity = value;
664 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
666 done:
667 ALCcontext_DecRef(context);
670 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
672 ALCcontext *context;
674 context = GetContextRef();
675 if(!context) return;
677 if(!(value > 0.0f && isfinite(value)))
678 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
680 context->SpeedOfSound = value;
681 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
683 done:
684 ALCcontext_DecRef(context);
687 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
689 ALCcontext *context;
691 context = GetContextRef();
692 if(!context) return;
694 if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
695 value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
696 value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
697 value == AL_NONE))
698 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
700 context->DistanceModel = value;
701 if(!context->SourceDistanceModel)
702 ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
704 done:
705 ALCcontext_DecRef(context);
709 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
711 ALCcontext *context;
713 context = GetContextRef();
714 if(!context) return;
716 ALCcontext_DeferUpdates(context);
718 ALCcontext_DecRef(context);
721 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
723 ALCcontext *context;
725 context = GetContextRef();
726 if(!context) return;
728 ALCcontext_ProcessUpdates(context);
730 ALCcontext_DecRef(context);