Pass a device to the effect update functions
[openal-soft.git] / OpenAL32 / alState.c
blobec6ee827553cd42713b208677f64fcf971808262
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/alext.h"
27 #include "alError.h"
28 #include "alSource.h"
29 #include "alAuxEffectSlot.h"
30 #include "alState.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";
36 // Error Messages
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)
46 ALCcontext *Context;
48 Context = GetContextRef();
49 if(!Context) return;
51 switch(capability)
53 case AL_SOURCE_DISTANCE_MODEL:
54 Context->SourceDistanceModel = AL_TRUE;
55 Context->UpdateSources = AL_TRUE;
56 break;
58 default:
59 alSetError(Context, AL_INVALID_ENUM);
60 break;
63 ALCcontext_DecRef(Context);
66 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
68 ALCcontext *Context;
70 Context = GetContextRef();
71 if(!Context) return;
73 switch(capability)
75 case AL_SOURCE_DISTANCE_MODEL:
76 Context->SourceDistanceModel = AL_FALSE;
77 Context->UpdateSources = AL_TRUE;
78 break;
80 default:
81 alSetError(Context, AL_INVALID_ENUM);
82 break;
85 ALCcontext_DecRef(Context);
88 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
90 ALCcontext *Context;
91 ALboolean value=AL_FALSE;
93 Context = GetContextRef();
94 if(!Context) return AL_FALSE;
96 switch(capability)
98 case AL_SOURCE_DISTANCE_MODEL:
99 value = Context->SourceDistanceModel;
100 break;
102 default:
103 alSetError(Context, AL_INVALID_ENUM);
104 break;
107 ALCcontext_DecRef(Context);
109 return value;
112 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
114 ALCcontext *Context;
115 ALboolean value=AL_FALSE;
117 Context = GetContextRef();
118 if(!Context) return AL_FALSE;
120 switch(pname)
122 case AL_DOPPLER_FACTOR:
123 if(Context->DopplerFactor != 0.0f)
124 value = AL_TRUE;
125 break;
127 case AL_DOPPLER_VELOCITY:
128 if(Context->DopplerVelocity != 0.0f)
129 value = AL_TRUE;
130 break;
132 case AL_DISTANCE_MODEL:
133 if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
134 value = AL_TRUE;
135 break;
137 case AL_SPEED_OF_SOUND:
138 if(Context->flSpeedOfSound != 0.0f)
139 value = AL_TRUE;
140 break;
142 case AL_DEFERRED_UPDATES_SOFT:
143 value = Context->DeferUpdates;
144 break;
146 default:
147 alSetError(Context, AL_INVALID_ENUM);
148 break;
151 ALCcontext_DecRef(Context);
153 return value;
156 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
158 ALCcontext *Context;
159 ALdouble value = 0.0;
161 Context = GetContextRef();
162 if(!Context) return 0.0;
164 switch(pname)
166 case AL_DOPPLER_FACTOR:
167 value = (double)Context->DopplerFactor;
168 break;
170 case AL_DOPPLER_VELOCITY:
171 value = (double)Context->DopplerVelocity;
172 break;
174 case AL_DISTANCE_MODEL:
175 value = (double)Context->DistanceModel;
176 break;
178 case AL_SPEED_OF_SOUND:
179 value = (double)Context->flSpeedOfSound;
180 break;
182 case AL_DEFERRED_UPDATES_SOFT:
183 value = (ALdouble)Context->DeferUpdates;
184 break;
186 default:
187 alSetError(Context, AL_INVALID_ENUM);
188 break;
191 ALCcontext_DecRef(Context);
193 return value;
196 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
198 ALCcontext *Context;
199 ALfloat value = 0.0f;
201 Context = GetContextRef();
202 if(!Context) return 0.0f;
204 switch(pname)
206 case AL_DOPPLER_FACTOR:
207 value = Context->DopplerFactor;
208 break;
210 case AL_DOPPLER_VELOCITY:
211 value = Context->DopplerVelocity;
212 break;
214 case AL_DISTANCE_MODEL:
215 value = (float)Context->DistanceModel;
216 break;
218 case AL_SPEED_OF_SOUND:
219 value = Context->flSpeedOfSound;
220 break;
222 case AL_DEFERRED_UPDATES_SOFT:
223 value = (ALfloat)Context->DeferUpdates;
224 break;
226 default:
227 alSetError(Context, AL_INVALID_ENUM);
228 break;
231 ALCcontext_DecRef(Context);
233 return value;
236 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
238 ALCcontext *Context;
239 ALint value = 0;
241 Context = GetContextRef();
242 if(!Context) return 0;
244 switch(pname)
246 case AL_DOPPLER_FACTOR:
247 value = (ALint)Context->DopplerFactor;
248 break;
250 case AL_DOPPLER_VELOCITY:
251 value = (ALint)Context->DopplerVelocity;
252 break;
254 case AL_DISTANCE_MODEL:
255 value = (ALint)Context->DistanceModel;
256 break;
258 case AL_SPEED_OF_SOUND:
259 value = (ALint)Context->flSpeedOfSound;
260 break;
262 case AL_DEFERRED_UPDATES_SOFT:
263 value = (ALint)Context->DeferUpdates;
264 break;
266 default:
267 alSetError(Context, AL_INVALID_ENUM);
268 break;
271 ALCcontext_DecRef(Context);
273 return value;
276 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
278 ALCcontext *Context;
280 if(data)
282 switch(pname)
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);
290 return;
294 Context = GetContextRef();
295 if(!Context) return;
297 if(data)
299 switch(pname)
301 default:
302 alSetError(Context, AL_INVALID_ENUM);
303 break;
306 else
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)
317 ALCcontext *Context;
319 if(data)
321 switch(pname)
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);
329 return;
333 Context = GetContextRef();
334 if(!Context) return;
336 if(data)
338 switch(pname)
340 default:
341 alSetError(Context, AL_INVALID_ENUM);
342 break;
345 else
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)
356 ALCcontext *Context;
358 if(data)
360 switch(pname)
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);
368 return;
372 Context = GetContextRef();
373 if(!Context) return;
375 if(data)
377 switch(pname)
379 default:
380 alSetError(Context, AL_INVALID_ENUM);
381 break;
384 else
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)
395 ALCcontext *Context;
397 if(data)
399 switch(pname)
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);
407 return;
411 Context = GetContextRef();
412 if(!Context) return;
414 if(data)
416 switch(pname)
418 default:
419 alSetError(Context, AL_INVALID_ENUM);
420 break;
423 else
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)
434 const ALchar *value;
435 ALCcontext *Context;
437 Context = GetContextRef();
438 if(!Context) return NULL;
440 switch(pname)
442 case AL_VENDOR:
443 value=alVendor;
444 break;
446 case AL_VERSION:
447 value=alVersion;
448 break;
450 case AL_RENDERER:
451 value=alRenderer;
452 break;
454 case AL_EXTENSIONS:
455 value=Context->ExtensionList;
456 break;
458 case AL_NO_ERROR:
459 value=alNoError;
460 break;
462 case AL_INVALID_NAME:
463 value=alErrInvalidName;
464 break;
466 case AL_INVALID_ENUM:
467 value=alErrInvalidEnum;
468 break;
470 case AL_INVALID_VALUE:
471 value=alErrInvalidValue;
472 break;
474 case AL_INVALID_OPERATION:
475 value=alErrInvalidOp;
476 break;
478 case AL_OUT_OF_MEMORY:
479 value=alErrOutOfMemory;
480 break;
482 default:
483 value=NULL;
484 alSetError(Context, AL_INVALID_ENUM);
485 break;
488 ALCcontext_DecRef(Context);
490 return value;
493 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
495 ALCcontext *Context;
497 Context = GetContextRef();
498 if(!Context) return;
500 if(value >= 0.0f && isfinite(value))
502 Context->DopplerFactor = value;
503 Context->UpdateSources = AL_TRUE;
505 else
506 alSetError(Context, AL_INVALID_VALUE);
508 ALCcontext_DecRef(Context);
511 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
513 ALCcontext *Context;
515 Context = GetContextRef();
516 if(!Context) return;
518 if(value > 0.0f && isfinite(value))
520 Context->DopplerVelocity=value;
521 Context->UpdateSources = AL_TRUE;
523 else
524 alSetError(Context, AL_INVALID_VALUE);
526 ALCcontext_DecRef(Context);
529 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat flSpeedOfSound)
531 ALCcontext *Context;
533 Context = GetContextRef();
534 if(!Context) return;
536 if(flSpeedOfSound > 0.0f && isfinite(flSpeedOfSound))
538 Context->flSpeedOfSound = flSpeedOfSound;
539 Context->UpdateSources = AL_TRUE;
541 else
542 alSetError(Context, AL_INVALID_VALUE);
544 ALCcontext_DecRef(Context);
547 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
549 ALCcontext *Context;
551 Context = GetContextRef();
552 if(!Context) return;
554 switch(value)
556 case AL_NONE:
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;
565 break;
567 default:
568 alSetError(Context, AL_INVALID_VALUE);
569 break;
572 ALCcontext_DecRef(Context);
576 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
578 ALCcontext *Context;
580 Context = GetContextRef();
581 if(!Context) return;
583 if(!Context->DeferUpdates)
585 ALboolean UpdateSources;
586 ALsource **src, **src_end;
587 ALeffectslot **slot, **slot_end;
588 int fpuState;
590 fpuState = SetMixerFPUMode();
592 LockContext(Context);
593 Context->DeferUpdates = AL_TRUE;
595 /* Make sure all pending updates are performed */
596 UpdateSources = ExchangeInt(&Context->UpdateSources, AL_FALSE);
598 src = Context->ActiveSources;
599 src_end = src + Context->ActiveSourceCount;
600 while(src != src_end)
602 if((*src)->state != AL_PLAYING)
604 Context->ActiveSourceCount--;
605 *src = *(--src_end);
606 continue;
609 if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources)
610 ALsource_Update(*src, Context);
612 src++;
615 slot = Context->ActiveEffectSlots;
616 slot_end = slot + Context->ActiveEffectSlotCount;
617 while(slot != slot_end)
619 if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
620 ALeffectState_Update((*slot)->EffectState, Context->Device, *slot);
621 slot++;
624 UnlockContext(Context);
625 RestoreFPUMode(fpuState);
628 ALCcontext_DecRef(Context);
631 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
633 ALCcontext *Context;
635 Context = GetContextRef();
636 if(!Context) return;
638 if(ExchangeInt(&Context->DeferUpdates, AL_FALSE))
640 ALsizei pos;
642 LockContext(Context);
643 LockUIntMapRead(&Context->SourceMap);
644 for(pos = 0;pos < Context->SourceMap.size;pos++)
646 ALsource *Source = Context->SourceMap.array[pos].value;
647 ALenum new_state;
649 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
650 Source->lOffset != -1)
651 ApplyOffset(Source);
653 new_state = ExchangeInt(&Source->new_state, AL_NONE);
654 if(new_state)
655 SetSourceState(Source, Context, new_state);
657 UnlockUIntMapRead(&Context->SourceMap);
658 UnlockContext(Context);
661 ALCcontext_DecRef(Context);