Use a single layout for the virtual speakers
[openal-soft/android/lowlatency.git] / Alc / ALc.c
blobebe7d1996f051b1ae7b8229cdd837c6fd14d47a6
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 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 <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
29 #include "alMain.h"
30 #include "alSource.h"
31 #include "AL/al.h"
32 #include "AL/alc.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alDatabuffer.h"
38 #include "bs2b.h"
39 #include "alu.h"
42 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
43 typedef struct BackendInfo {
44 const char *name;
45 void (*Init)(BackendFuncs*);
46 void (*Deinit)(void);
47 void (*Probe)(int);
48 BackendFuncs Funcs;
49 } BackendInfo;
50 static BackendInfo BackendList[] = {
51 #ifdef HAVE_PULSEAUDIO
52 { "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs },
53 #endif
54 #ifdef HAVE_ALSA
55 { "alsa", alc_alsa_init, alc_alsa_deinit, alc_alsa_probe, EmptyFuncs },
56 #endif
57 #ifdef HAVE_OSS
58 { "oss", alc_oss_init, alc_oss_deinit, alc_oss_probe, EmptyFuncs },
59 #endif
60 #ifdef HAVE_SOLARIS
61 { "solaris", alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
62 #endif
63 #ifdef HAVE_DSOUND
64 { "dsound", alcDSoundInit, alcDSoundDeinit, alcDSoundProbe, EmptyFuncs },
65 #endif
66 #ifdef HAVE_WINMM
67 { "winmm", alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs },
68 #endif
69 #ifdef HAVE_PORTAUDIO
70 { "port", alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
71 #endif
73 { "wave", alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs },
75 { NULL, NULL, NULL, NULL, EmptyFuncs }
77 #undef EmptyFuncs
79 ///////////////////////////////////////////////////////
81 #define ALC_EFX_MAJOR_VERSION 0x20001
82 #define ALC_EFX_MINOR_VERSION 0x20002
83 #define ALC_MAX_AUXILIARY_SENDS 0x20003
85 ///////////////////////////////////////////////////////
86 // STRING and EXTENSIONS
88 typedef struct ALCfunction {
89 const ALCchar *funcName;
90 ALCvoid *address;
91 } ALCfunction;
93 typedef struct ALCenums {
94 const ALCchar *enumName;
95 ALCenum value;
96 } ALCenums;
99 static const ALCfunction alcFunctions[] = {
100 { "alcCreateContext", (ALCvoid *) alcCreateContext },
101 { "alcMakeContextCurrent", (ALCvoid *) alcMakeContextCurrent },
102 { "alcProcessContext", (ALCvoid *) alcProcessContext },
103 { "alcSuspendContext", (ALCvoid *) alcSuspendContext },
104 { "alcDestroyContext", (ALCvoid *) alcDestroyContext },
105 { "alcGetCurrentContext", (ALCvoid *) alcGetCurrentContext },
106 { "alcGetContextsDevice", (ALCvoid *) alcGetContextsDevice },
107 { "alcOpenDevice", (ALCvoid *) alcOpenDevice },
108 { "alcCloseDevice", (ALCvoid *) alcCloseDevice },
109 { "alcGetError", (ALCvoid *) alcGetError },
110 { "alcIsExtensionPresent", (ALCvoid *) alcIsExtensionPresent },
111 { "alcGetProcAddress", (ALCvoid *) alcGetProcAddress },
112 { "alcGetEnumValue", (ALCvoid *) alcGetEnumValue },
113 { "alcGetString", (ALCvoid *) alcGetString },
114 { "alcGetIntegerv", (ALCvoid *) alcGetIntegerv },
115 { "alcCaptureOpenDevice", (ALCvoid *) alcCaptureOpenDevice },
116 { "alcCaptureCloseDevice", (ALCvoid *) alcCaptureCloseDevice },
117 { "alcCaptureStart", (ALCvoid *) alcCaptureStart },
118 { "alcCaptureStop", (ALCvoid *) alcCaptureStop },
119 { "alcCaptureSamples", (ALCvoid *) alcCaptureSamples },
121 { "alcSetThreadContext", (ALCvoid *) alcSetThreadContext },
122 { "alcGetThreadContext", (ALCvoid *) alcGetThreadContext },
124 { NULL, (ALCvoid *) NULL }
127 static const ALCenums enumeration[] = {
128 // Types
129 { "ALC_INVALID", ALC_INVALID },
130 { "ALC_FALSE", ALC_FALSE },
131 { "ALC_TRUE", ALC_TRUE },
133 // ALC Properties
134 { "ALC_MAJOR_VERSION", ALC_MAJOR_VERSION },
135 { "ALC_MINOR_VERSION", ALC_MINOR_VERSION },
136 { "ALC_ATTRIBUTES_SIZE", ALC_ATTRIBUTES_SIZE },
137 { "ALC_ALL_ATTRIBUTES", ALC_ALL_ATTRIBUTES },
138 { "ALC_DEFAULT_DEVICE_SPECIFIER", ALC_DEFAULT_DEVICE_SPECIFIER },
139 { "ALC_DEVICE_SPECIFIER", ALC_DEVICE_SPECIFIER },
140 { "ALC_ALL_DEVICES_SPECIFIER", ALC_ALL_DEVICES_SPECIFIER },
141 { "ALC_DEFAULT_ALL_DEVICES_SPECIFIER", ALC_DEFAULT_ALL_DEVICES_SPECIFIER },
142 { "ALC_EXTENSIONS", ALC_EXTENSIONS },
143 { "ALC_FREQUENCY", ALC_FREQUENCY },
144 { "ALC_REFRESH", ALC_REFRESH },
145 { "ALC_SYNC", ALC_SYNC },
146 { "ALC_MONO_SOURCES", ALC_MONO_SOURCES },
147 { "ALC_STEREO_SOURCES", ALC_STEREO_SOURCES },
148 { "ALC_CAPTURE_DEVICE_SPECIFIER", ALC_CAPTURE_DEVICE_SPECIFIER },
149 { "ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER", ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER},
150 { "ALC_CAPTURE_SAMPLES", ALC_CAPTURE_SAMPLES },
152 // EFX Properties
153 { "ALC_EFX_MAJOR_VERSION", ALC_EFX_MAJOR_VERSION },
154 { "ALC_EFX_MINOR_VERSION", ALC_EFX_MINOR_VERSION },
155 { "ALC_MAX_AUXILIARY_SENDS", ALC_MAX_AUXILIARY_SENDS },
157 // ALC Error Message
158 { "ALC_NO_ERROR", ALC_NO_ERROR },
159 { "ALC_INVALID_DEVICE", ALC_INVALID_DEVICE },
160 { "ALC_INVALID_CONTEXT", ALC_INVALID_CONTEXT },
161 { "ALC_INVALID_ENUM", ALC_INVALID_ENUM },
162 { "ALC_INVALID_VALUE", ALC_INVALID_VALUE },
163 { "ALC_OUT_OF_MEMORY", ALC_OUT_OF_MEMORY },
164 { NULL, (ALCenum)0 }
166 // Error strings
167 static const ALCchar alcNoError[] = "No Error";
168 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
169 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
170 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
171 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
172 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
174 /* Device lists. Sizes only include the first ending null character, not the
175 * second */
176 static ALCchar *alcDeviceList;
177 static size_t alcDeviceListSize;
178 static ALCchar *alcAllDeviceList;
179 static size_t alcAllDeviceListSize;
180 static ALCchar *alcCaptureDeviceList;
181 static size_t alcCaptureDeviceListSize;
182 // Default is always the first in the list
183 static ALCchar *alcDefaultDeviceSpecifier;
184 static ALCchar *alcDefaultAllDeviceSpecifier;
185 static ALCchar *alcCaptureDefaultDeviceSpecifier;
188 static const ALCchar alcNoDeviceExtList[] =
189 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
190 "ALC_EXT_thread_local_context";
191 static const ALCchar alcExtensionList[] =
192 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
193 "ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context";
194 static const ALCint alcMajorVersion = 1;
195 static const ALCint alcMinorVersion = 1;
197 static const ALCint alcEFXMajorVersion = 1;
198 static const ALCint alcEFXMinorVersion = 0;
200 ///////////////////////////////////////////////////////
203 ///////////////////////////////////////////////////////
204 // Global Variables
206 static ALCdevice *g_pDeviceList = NULL;
207 static ALCuint g_ulDeviceCount = 0;
209 static CRITICAL_SECTION g_csMutex;
211 // Context List
212 static ALCcontext *g_pContextList = NULL;
213 static ALCuint g_ulContextCount = 0;
215 // Thread-local current context
216 static tls_type LocalContext;
217 // Process-wide current context
218 static ALCcontext *GlobalContext;
220 // Context Error
221 static ALCenum g_eLastContextError = ALC_NO_ERROR;
223 // Default context extensions
224 static const ALchar alExtList[] =
225 "AL_EXTX_buffer_sub_data AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE "
226 "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS "
227 "AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET "
228 "AL_EXTX_sample_buffer_object AL_EXT_source_distance_model "
229 "AL_LOKI_quadriphonic";
231 // Mixing Priority Level
232 ALint RTPrioLevel;
234 // Resampler Quality
235 resampler_t DefaultResampler;
237 ///////////////////////////////////////////////////////
240 ///////////////////////////////////////////////////////
241 // ALC Related helper functions
242 #ifdef _WIN32
243 static void alc_init(void);
244 static void alc_deinit(void);
246 BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
248 (void)lpReserved;
250 // Perform actions based on the reason for calling.
251 switch(ul_reason_for_call)
253 case DLL_PROCESS_ATTACH:
254 DisableThreadLibraryCalls(hModule);
255 alc_init();
256 break;
258 case DLL_PROCESS_DETACH:
259 alc_deinit();
260 break;
262 return TRUE;
264 #else
265 #ifdef HAVE_GCC_DESTRUCTOR
266 static void alc_init(void) __attribute__((constructor));
267 static void alc_deinit(void) __attribute__((destructor));
268 #endif
269 #endif
271 static void alc_init(void)
273 int i;
274 const char *devs, *str;
276 InitializeCriticalSection(&g_csMutex);
277 ALTHUNK_INIT();
278 ReadALConfig();
280 tls_create(&LocalContext);
282 RTPrioLevel = GetConfigValueInt(NULL, "rt-prio", 0);
284 DefaultResampler = GetConfigValueInt(NULL, "resampler", RESAMPLER_DEFAULT);
285 if(DefaultResampler >= RESAMPLER_MAX || DefaultResampler <= RESAMPLER_MIN)
286 DefaultResampler = RESAMPLER_DEFAULT;
288 devs = GetConfigValue(NULL, "drivers", "");
289 if(devs[0])
291 int n;
292 size_t len;
293 const char *next = devs;
294 int endlist;
296 i = 0;
297 do {
298 devs = next;
299 next = strchr(devs, ',');
301 if(!devs[0] || devs[0] == ',')
303 endlist = 0;
304 continue;
306 endlist = 1;
308 len = (next ? ((size_t)(next-devs)) : strlen(devs));
309 for(n = i;BackendList[n].Init;n++)
311 if(len == strlen(BackendList[n].name) &&
312 strncmp(BackendList[n].name, devs, len) == 0)
314 BackendInfo Bkp = BackendList[n];
315 while(n > i)
317 BackendList[n] = BackendList[n-1];
318 --n;
320 BackendList[n] = Bkp;
322 i++;
323 break;
326 } while(next++);
328 if(endlist)
330 BackendList[i].name = NULL;
331 BackendList[i].Init = NULL;
332 BackendList[i].Deinit = NULL;
333 BackendList[i].Probe = NULL;
337 for(i = 0;BackendList[i].Init;i++)
338 BackendList[i].Init(&BackendList[i].Funcs);
340 DuplicateStereo = GetConfigValueBool(NULL, "stereodup", 0);
342 str = GetConfigValue(NULL, "excludefx", "");
343 if(str[0])
345 const struct {
346 const char *name;
347 int type;
348 } EffectList[] = {
349 { "eaxreverb", EAXREVERB },
350 { "reverb", REVERB },
351 { "echo", ECHO },
352 { "modulator", MODULATOR },
353 { NULL, 0 }
355 int n;
356 size_t len;
357 const char *next = str;
359 do {
360 str = next;
361 next = strchr(str, ',');
363 if(!str[0] || next == str)
364 continue;
366 len = (next ? ((size_t)(next-str)) : strlen(str));
367 for(n = 0;EffectList[n].name;n++)
369 if(len == strlen(EffectList[n].name) &&
370 strncmp(EffectList[n].name, str, len) == 0)
371 DisabledEffects[EffectList[n].type] = AL_TRUE;
373 } while(next++);
377 static void alc_deinit(void)
379 int i;
381 ReleaseALC();
383 for(i = 0;BackendList[i].Deinit;i++)
384 BackendList[i].Deinit();
386 tls_delete(LocalContext);
388 FreeALConfig();
389 ALTHUNK_EXIT();
390 DeleteCriticalSection(&g_csMutex);
394 static void ProbeDeviceList()
396 ALint i;
398 free(alcDeviceList); alcDeviceList = NULL;
399 alcDeviceListSize = 0;
401 for(i = 0;BackendList[i].Probe;i++)
402 BackendList[i].Probe(DEVICE_PROBE);
405 static void ProbeAllDeviceList()
407 ALint i;
409 free(alcAllDeviceList); alcAllDeviceList = NULL;
410 alcAllDeviceListSize = 0;
412 for(i = 0;BackendList[i].Probe;i++)
413 BackendList[i].Probe(ALL_DEVICE_PROBE);
416 static void ProbeCaptureDeviceList()
418 ALint i;
420 free(alcCaptureDeviceList); alcCaptureDeviceList = NULL;
421 alcCaptureDeviceListSize = 0;
423 for(i = 0;BackendList[i].Probe;i++)
424 BackendList[i].Probe(CAPTURE_DEVICE_PROBE);
428 #define DECL_APPEND_LIST_FUNC(type) \
429 void Append##type##List(const ALCchar *name) \
431 size_t len = strlen(name); \
432 void *temp; \
434 if(len == 0) \
435 return; \
437 temp = realloc(alc##type##List, alc##type##ListSize + len + 2); \
438 if(!temp) \
440 AL_PRINT("Realloc failed to add %s!\n", name); \
441 return; \
443 alc##type##List = temp; \
444 sprintf(alc##type##List+alc##type##ListSize, "%s", name); \
445 alc##type##ListSize += len+1; \
446 alc##type##List[alc##type##ListSize] = 0; \
449 DECL_APPEND_LIST_FUNC(Device)
450 DECL_APPEND_LIST_FUNC(AllDevice)
451 DECL_APPEND_LIST_FUNC(CaptureDevice)
454 void al_print(const char *fname, unsigned int line, const char *fmt, ...)
456 const char *fn;
457 char str[256];
458 int i;
460 fn = strrchr(fname, '/');
461 if(!fn) fn = strrchr(fname, '\\');;
462 if(!fn) fn = fname;
463 else fn += 1;
465 i = snprintf(str, sizeof(str), "AL lib: %s:%d: ", fn, line);
466 if(i < (int)sizeof(str) && i > 0)
468 va_list ap;
469 va_start(ap, fmt);
470 vsnprintf(str+i, sizeof(str)-i, fmt, ap);
471 va_end(ap);
473 str[sizeof(str)-1] = 0;
475 fprintf(stderr, "%s", str);
478 void EnableRTPrio(ALint level)
480 ALboolean failed;
482 #ifdef _WIN32
483 if(level > 0)
484 failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
485 else
486 failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
487 #elif defined(HAVE_PTHREAD_SETSCHEDPARAM)
488 struct sched_param param;
490 if(level > 0)
492 /* Use the minimum real-time priority possible for now (on Linux this
493 * should be 1 for SCHED_RR) */
494 param.sched_priority = sched_get_priority_min(SCHED_RR);
495 failed = !!pthread_setschedparam(pthread_self(), SCHED_RR, &param);
497 else
499 param.sched_priority = 0;
500 failed = !!pthread_setschedparam(pthread_self(), SCHED_OTHER, &param);
502 #else
503 /* Real-time priority not available */
504 failed = !!level;
505 #endif
506 if(failed)
507 AL_PRINT("Failed to set priority level for thread\n");
510 static void SetupChannelMatrix(ALCdevice *Device)
512 ALfloat maxout;
513 ALuint s, s2;
515 for(s = 0;s < OUTPUTCHANNELS;s++)
517 for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
518 Device->ChannelMatrix[s][s2] = ((s==s2) ? 1.0f : 0.0f);
521 switch(Device->Format)
523 case AL_FORMAT_MONO8:
524 case AL_FORMAT_MONO16:
525 case AL_FORMAT_MONO_FLOAT32:
526 Device->ChannelMatrix[FRONT_LEFT][FRONT_CENTER] = aluSqrt(0.5);
527 Device->ChannelMatrix[FRONT_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
528 Device->ChannelMatrix[SIDE_LEFT][FRONT_CENTER] = aluSqrt(0.5);
529 Device->ChannelMatrix[SIDE_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
530 Device->ChannelMatrix[BACK_LEFT][FRONT_CENTER] = aluSqrt(0.5);
531 Device->ChannelMatrix[BACK_RIGHT][FRONT_CENTER] = aluSqrt(0.5);
532 Device->ChannelMatrix[BACK_CENTER][FRONT_CENTER] = 1.0f;
533 break;
535 case AL_FORMAT_STEREO8:
536 case AL_FORMAT_STEREO16:
537 case AL_FORMAT_STEREO_FLOAT32:
538 Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
539 Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
540 Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = 1.0f;
541 Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = 1.0f;
542 Device->ChannelMatrix[BACK_LEFT][FRONT_LEFT] = 1.0f;
543 Device->ChannelMatrix[BACK_RIGHT][FRONT_RIGHT] = 1.0f;
544 Device->ChannelMatrix[BACK_CENTER][FRONT_LEFT] = aluSqrt(0.5);
545 Device->ChannelMatrix[BACK_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
546 break;
548 case AL_FORMAT_QUAD8:
549 case AL_FORMAT_QUAD16:
550 case AL_FORMAT_QUAD32:
551 Device->ChannelMatrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(0.5);
552 Device->ChannelMatrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(0.5);
553 Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
554 Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
555 Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
556 Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
557 Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
558 Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
559 break;
561 case AL_FORMAT_51CHN8:
562 case AL_FORMAT_51CHN16:
563 case AL_FORMAT_51CHN32:
564 Device->ChannelMatrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(0.5);
565 Device->ChannelMatrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(0.5);
566 Device->ChannelMatrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(0.5);
567 Device->ChannelMatrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(0.5);
568 Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
569 Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
570 break;
572 case AL_FORMAT_61CHN8:
573 case AL_FORMAT_61CHN16:
574 case AL_FORMAT_61CHN32:
575 Device->ChannelMatrix[BACK_LEFT][BACK_CENTER] = aluSqrt(0.5);
576 Device->ChannelMatrix[BACK_LEFT][SIDE_LEFT] = aluSqrt(0.5);
577 Device->ChannelMatrix[BACK_RIGHT][BACK_CENTER] = aluSqrt(0.5);
578 Device->ChannelMatrix[BACK_RIGHT][SIDE_RIGHT] = aluSqrt(0.5);
579 break;
581 case AL_FORMAT_71CHN8:
582 case AL_FORMAT_71CHN16:
583 case AL_FORMAT_71CHN32:
584 Device->ChannelMatrix[BACK_CENTER][BACK_LEFT] = aluSqrt(0.5);
585 Device->ChannelMatrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(0.5);
586 break;
588 default:
589 assert(0);
592 for(s = 0;s < OUTPUTCHANNELS;s++)
594 ALfloat out = 0.0f;
595 for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
596 out += Device->ChannelMatrix[s2][s];
597 maxout = __max(maxout, out);
600 maxout = 1.0f/maxout;
601 for(s = 0;s < OUTPUTCHANNELS;s++)
603 for(s2 = 0;s2 < OUTPUTCHANNELS;s2++)
604 Device->ChannelMatrix[s2][s] *= maxout;
609 IsDevice
611 Check pDevice is a valid Device pointer
613 static ALCboolean IsDevice(ALCdevice *pDevice)
615 ALCdevice *pTempDevice;
617 SuspendContext(NULL);
619 pTempDevice = g_pDeviceList;
620 while(pTempDevice && pTempDevice != pDevice)
621 pTempDevice = pTempDevice->next;
623 ProcessContext(NULL);
625 return (pTempDevice ? ALC_TRUE : ALC_FALSE);
629 IsContext
631 Check pContext is a valid Context pointer
633 static ALCboolean IsContext(ALCcontext *pContext)
635 ALCcontext *pTempContext;
637 SuspendContext(NULL);
639 pTempContext = g_pContextList;
640 while (pTempContext && pTempContext != pContext)
641 pTempContext = pTempContext->next;
643 ProcessContext(NULL);
645 return (pTempContext ? ALC_TRUE : ALC_FALSE);
650 alcSetError
652 Store latest ALC Error
654 ALCvoid alcSetError(ALCdevice *device, ALenum errorCode)
656 if(IsDevice(device))
657 device->LastError = errorCode;
658 else
659 g_eLastContextError = errorCode;
664 SuspendContext
666 Thread-safe entry
668 ALCvoid SuspendContext(ALCcontext *pContext)
670 (void)pContext;
671 EnterCriticalSection(&g_csMutex);
676 ProcessContext
678 Thread-safe exit
680 ALCvoid ProcessContext(ALCcontext *pContext)
682 (void)pContext;
683 LeaveCriticalSection(&g_csMutex);
688 GetContextSuspended
690 Returns the currently active Context, in a locked state
692 ALCcontext *GetContextSuspended(void)
694 ALCcontext *pContext = NULL;
696 SuspendContext(NULL);
698 pContext = tls_get(LocalContext);
699 if(pContext && !IsContext(pContext))
701 tls_set(LocalContext, NULL);
702 pContext = NULL;
704 if(!pContext)
705 pContext = GlobalContext;
707 if(pContext)
708 SuspendContext(pContext);
710 ProcessContext(NULL);
712 return pContext;
717 InitContext
719 Initialize Context variables
721 static ALvoid InitContext(ALCcontext *pContext)
723 //Initialise listener
724 pContext->Listener.Gain = 1.0f;
725 pContext->Listener.MetersPerUnit = 1.0f;
726 pContext->Listener.Position[0] = 0.0f;
727 pContext->Listener.Position[1] = 0.0f;
728 pContext->Listener.Position[2] = 0.0f;
729 pContext->Listener.Velocity[0] = 0.0f;
730 pContext->Listener.Velocity[1] = 0.0f;
731 pContext->Listener.Velocity[2] = 0.0f;
732 pContext->Listener.Forward[0] = 0.0f;
733 pContext->Listener.Forward[1] = 0.0f;
734 pContext->Listener.Forward[2] = -1.0f;
735 pContext->Listener.Up[0] = 0.0f;
736 pContext->Listener.Up[1] = 1.0f;
737 pContext->Listener.Up[2] = 0.0f;
739 //Validate pContext
740 pContext->LastError = AL_NO_ERROR;
741 pContext->Suspended = AL_FALSE;
743 //Set globals
744 pContext->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED;
745 pContext->SourceDistanceModel = AL_FALSE;
746 pContext->DopplerFactor = 1.0f;
747 pContext->DopplerVelocity = 1.0f;
748 pContext->flSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
750 pContext->ExtensionList = alExtList;
755 ExitContext
757 Clean up Context, destroy any remaining Sources
759 static ALCvoid ExitContext(ALCcontext *pContext)
761 //Invalidate context
762 pContext->LastError = AL_NO_ERROR;
765 ///////////////////////////////////////////////////////
768 ///////////////////////////////////////////////////////
769 // ALC Functions calls
772 // This should probably move to another c file but for now ...
773 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
775 ALCboolean DeviceFound = ALC_FALSE;
776 ALCdevice *device = NULL;
777 ALCint i;
779 if(SampleSize <= 0)
781 alcSetError(NULL, ALC_INVALID_VALUE);
782 return NULL;
785 if(deviceName && !deviceName[0])
786 deviceName = NULL;
788 device = calloc(1, sizeof(ALCdevice));
789 if(!device)
791 alcSetError(NULL, ALC_OUT_OF_MEMORY);
792 return NULL;
795 //Validate device
796 device->Connected = ALC_TRUE;
797 device->IsCaptureDevice = AL_TRUE;
799 device->szDeviceName = NULL;
801 device->Frequency = frequency;
802 device->Format = format;
803 device->UpdateSize = SampleSize;
804 device->NumUpdates = 1;
806 SuspendContext(NULL);
807 for(i = 0;BackendList[i].Init;i++)
809 device->Funcs = &BackendList[i].Funcs;
810 if(ALCdevice_OpenCapture(device, deviceName))
812 device->next = g_pDeviceList;
813 g_pDeviceList = device;
814 g_ulDeviceCount++;
816 DeviceFound = ALC_TRUE;
817 break;
820 ProcessContext(NULL);
822 if(!DeviceFound)
824 alcSetError(NULL, ALC_INVALID_VALUE);
825 free(device);
826 device = NULL;
829 return device;
832 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *pDevice)
834 ALCdevice **list;
836 if(!IsDevice(pDevice) || !pDevice->IsCaptureDevice)
838 alcSetError(pDevice, ALC_INVALID_DEVICE);
839 return ALC_FALSE;
842 SuspendContext(NULL);
844 list = &g_pDeviceList;
845 while(*list != pDevice)
846 list = &(*list)->next;
848 *list = (*list)->next;
849 g_ulDeviceCount--;
851 ProcessContext(NULL);
853 ALCdevice_CloseCapture(pDevice);
855 free(pDevice->szDeviceName);
856 pDevice->szDeviceName = NULL;
858 free(pDevice);
860 return ALC_TRUE;
863 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
865 if(!IsDevice(device) || !device->IsCaptureDevice)
867 alcSetError(device, ALC_INVALID_DEVICE);
868 return;
870 SuspendContext(NULL);
871 ALCdevice_StartCapture(device);
872 ProcessContext(NULL);
875 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
877 if(!IsDevice(device) || !device->IsCaptureDevice)
879 alcSetError(device, ALC_INVALID_DEVICE);
880 return;
882 SuspendContext(NULL);
883 ALCdevice_StopCapture(device);
884 ProcessContext(NULL);
887 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
889 if(!IsDevice(device) || !device->IsCaptureDevice)
891 alcSetError(device, ALC_INVALID_DEVICE);
892 return;
894 SuspendContext(NULL);
895 ALCdevice_CaptureSamples(device, buffer, samples);
896 ProcessContext(NULL);
900 alcGetError
902 Return last ALC generated error code
904 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
906 ALCenum errorCode = ALC_NO_ERROR;
908 if(IsDevice(device))
910 errorCode = device->LastError;
911 device->LastError = ALC_NO_ERROR;
913 else
915 errorCode = g_eLastContextError;
916 g_eLastContextError = ALC_NO_ERROR;
918 return errorCode;
923 alcSuspendContext
925 Not functional
927 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *pContext)
929 SuspendContext(NULL);
930 if(IsContext(pContext))
931 pContext->Suspended = AL_TRUE;
932 ProcessContext(NULL);
937 alcProcessContext
939 Not functional
941 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *pContext)
943 SuspendContext(NULL);
944 if(IsContext(pContext))
945 pContext->Suspended = AL_FALSE;
946 ProcessContext(NULL);
951 alcGetString
953 Returns information about the Device, and error strings
955 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *pDevice,ALCenum param)
957 const ALCchar *value = NULL;
959 switch (param)
961 case ALC_NO_ERROR:
962 value = alcNoError;
963 break;
965 case ALC_INVALID_ENUM:
966 value = alcErrInvalidEnum;
967 break;
969 case ALC_INVALID_VALUE:
970 value = alcErrInvalidValue;
971 break;
973 case ALC_INVALID_DEVICE:
974 value = alcErrInvalidDevice;
975 break;
977 case ALC_INVALID_CONTEXT:
978 value = alcErrInvalidContext;
979 break;
981 case ALC_OUT_OF_MEMORY:
982 value = alcErrOutOfMemory;
983 break;
985 case ALC_DEVICE_SPECIFIER:
986 if(IsDevice(pDevice))
987 value = pDevice->szDeviceName;
988 else
990 ProbeDeviceList();
991 value = alcDeviceList;
993 break;
995 case ALC_ALL_DEVICES_SPECIFIER:
996 ProbeAllDeviceList();
997 value = alcAllDeviceList;
998 break;
1000 case ALC_CAPTURE_DEVICE_SPECIFIER:
1001 if(IsDevice(pDevice))
1002 value = pDevice->szDeviceName;
1003 else
1005 ProbeCaptureDeviceList();
1006 value = alcCaptureDeviceList;
1008 break;
1010 /* Default devices are always first in the list */
1011 case ALC_DEFAULT_DEVICE_SPECIFIER:
1012 if(!alcDeviceList)
1013 ProbeDeviceList();
1015 free(alcDefaultDeviceSpecifier);
1016 alcDefaultDeviceSpecifier = strdup(alcDeviceList ? alcDeviceList : "");
1017 if(!alcDefaultDeviceSpecifier)
1018 alcSetError(pDevice, ALC_OUT_OF_MEMORY);
1019 value = alcDefaultDeviceSpecifier;
1020 break;
1022 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
1023 if(!alcAllDeviceList)
1024 ProbeAllDeviceList();
1026 free(alcDefaultAllDeviceSpecifier);
1027 alcDefaultAllDeviceSpecifier = strdup(alcAllDeviceList ?
1028 alcAllDeviceList : "");
1029 if(!alcDefaultAllDeviceSpecifier)
1030 alcSetError(pDevice, ALC_OUT_OF_MEMORY);
1031 value = alcDefaultAllDeviceSpecifier;
1032 break;
1034 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
1035 if(!alcCaptureDeviceList)
1036 ProbeCaptureDeviceList();
1038 free(alcCaptureDefaultDeviceSpecifier);
1039 alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ?
1040 alcCaptureDeviceList : "");
1041 if(!alcCaptureDefaultDeviceSpecifier)
1042 alcSetError(pDevice, ALC_OUT_OF_MEMORY);
1043 value = alcCaptureDefaultDeviceSpecifier;
1044 break;
1046 case ALC_EXTENSIONS:
1047 if(IsDevice(pDevice))
1048 value = alcExtensionList;
1049 else
1050 value = alcNoDeviceExtList;
1051 break;
1053 default:
1054 alcSetError(pDevice, ALC_INVALID_ENUM);
1055 break;
1058 return value;
1063 alcGetIntegerv
1065 Returns information about the Device and the version of Open AL
1067 ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsizei size,ALCint *data)
1069 if(size == 0 || data == NULL)
1071 alcSetError(device, ALC_INVALID_VALUE);
1072 return;
1075 if(IsDevice(device) && device->IsCaptureDevice)
1077 SuspendContext(NULL);
1079 // Capture device
1080 switch (param)
1082 case ALC_CAPTURE_SAMPLES:
1083 *data = ALCdevice_AvailableSamples(device);
1084 break;
1086 case ALC_CONNECTED:
1087 *data = device->Connected;
1088 break;
1090 default:
1091 alcSetError(device, ALC_INVALID_ENUM);
1092 break;
1095 ProcessContext(NULL);
1096 return;
1099 // Playback Device
1100 switch (param)
1102 case ALC_MAJOR_VERSION:
1103 *data = alcMajorVersion;
1104 break;
1106 case ALC_MINOR_VERSION:
1107 *data = alcMinorVersion;
1108 break;
1110 case ALC_EFX_MAJOR_VERSION:
1111 *data = alcEFXMajorVersion;
1112 break;
1114 case ALC_EFX_MINOR_VERSION:
1115 *data = alcEFXMinorVersion;
1116 break;
1118 case ALC_MAX_AUXILIARY_SENDS:
1119 if(!IsDevice(device))
1120 alcSetError(device, ALC_INVALID_DEVICE);
1121 else
1122 *data = device->NumAuxSends;
1123 break;
1125 case ALC_ATTRIBUTES_SIZE:
1126 if(!IsDevice(device))
1127 alcSetError(device, ALC_INVALID_DEVICE);
1128 else
1129 *data = 13;
1130 break;
1132 case ALC_ALL_ATTRIBUTES:
1133 if(!IsDevice(device))
1134 alcSetError(device, ALC_INVALID_DEVICE);
1135 else if (size < 13)
1136 alcSetError(device, ALC_INVALID_VALUE);
1137 else
1139 int i = 0;
1141 SuspendContext(NULL);
1142 data[i++] = ALC_FREQUENCY;
1143 data[i++] = device->Frequency;
1145 data[i++] = ALC_REFRESH;
1146 data[i++] = device->Frequency / device->UpdateSize;
1148 data[i++] = ALC_SYNC;
1149 data[i++] = ALC_FALSE;
1151 data[i++] = ALC_MONO_SOURCES;
1152 data[i++] = device->NumMonoSources;
1154 data[i++] = ALC_STEREO_SOURCES;
1155 data[i++] = device->NumStereoSources;
1157 data[i++] = ALC_MAX_AUXILIARY_SENDS;
1158 data[i++] = device->NumAuxSends;
1160 data[i++] = 0;
1161 ProcessContext(NULL);
1163 break;
1165 case ALC_FREQUENCY:
1166 if(!IsDevice(device))
1167 alcSetError(device, ALC_INVALID_DEVICE);
1168 else
1169 *data = device->Frequency;
1170 break;
1172 case ALC_REFRESH:
1173 if(!IsDevice(device))
1174 alcSetError(device, ALC_INVALID_DEVICE);
1175 else
1176 *data = device->Frequency / device->UpdateSize;
1177 break;
1179 case ALC_SYNC:
1180 if(!IsDevice(device))
1181 alcSetError(device, ALC_INVALID_DEVICE);
1182 else
1183 *data = ALC_FALSE;
1184 break;
1186 case ALC_MONO_SOURCES:
1187 if(!IsDevice(device))
1188 alcSetError(device, ALC_INVALID_DEVICE);
1189 else
1190 *data = device->NumMonoSources;
1191 break;
1193 case ALC_STEREO_SOURCES:
1194 if(!IsDevice(device))
1195 alcSetError(device, ALC_INVALID_DEVICE);
1196 else
1197 *data = device->NumStereoSources;
1198 break;
1200 case ALC_CONNECTED:
1201 if(!IsDevice(device))
1202 alcSetError(device, ALC_INVALID_DEVICE);
1203 else
1204 *data = device->Connected;
1205 break;
1207 default:
1208 alcSetError(device, ALC_INVALID_ENUM);
1209 break;
1215 alcIsExtensionPresent
1217 Determines if there is support for a particular extension
1219 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
1221 ALCboolean bResult = ALC_FALSE;
1222 const char *ptr;
1223 size_t len;
1225 if(!extName)
1227 alcSetError(device, ALC_INVALID_VALUE);
1228 return ALC_FALSE;
1231 len = strlen(extName);
1232 ptr = (IsDevice(device) ? alcExtensionList : alcNoDeviceExtList);
1233 while(ptr && *ptr)
1235 if(strncasecmp(ptr, extName, len) == 0 &&
1236 (ptr[len] == '\0' || isspace(ptr[len])))
1238 bResult = ALC_TRUE;
1239 break;
1241 if((ptr=strchr(ptr, ' ')) != NULL)
1243 do {
1244 ++ptr;
1245 } while(isspace(*ptr));
1249 return bResult;
1254 alcGetProcAddress
1256 Retrieves the function address for a particular extension function
1258 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
1260 ALsizei i = 0;
1262 if(!funcName)
1264 alcSetError(device, ALC_INVALID_VALUE);
1265 return NULL;
1268 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName,funcName) != 0)
1269 i++;
1270 return alcFunctions[i].address;
1275 alcGetEnumValue
1277 Get the value for a particular ALC Enumerated Value
1279 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
1281 ALsizei i = 0;
1283 if(!enumName)
1285 alcSetError(device, ALC_INVALID_VALUE);
1286 return (ALCenum)0;
1289 while(enumeration[i].enumName && strcmp(enumeration[i].enumName,enumName) != 0)
1290 i++;
1291 return enumeration[i].value;
1296 alcCreateContext
1298 Create and attach a Context to a particular Device.
1300 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
1302 ALCcontext *ALContext;
1303 ALuint attrIdx;
1304 void *temp;
1305 ALuint i;
1307 SuspendContext(NULL);
1309 if(!IsDevice(device) || device->IsCaptureDevice || !device->Connected)
1311 alcSetError(device, ALC_INVALID_DEVICE);
1312 ProcessContext(NULL);
1313 return NULL;
1316 // Reset Context Last Error code
1317 device->LastError = ALC_NO_ERROR;
1319 // If a context is already running on the device, stop playback so the
1320 // device attributes can be updated
1321 if(device->NumContexts > 0)
1323 ProcessContext(NULL);
1324 ALCdevice_StopPlayback(device);
1325 SuspendContext(NULL);
1328 // Check for attributes
1329 if(attrList)
1331 ALCuint freq = device->Frequency;
1332 ALCuint numMono = device->NumMonoSources;
1333 ALCuint numStereo = device->NumStereoSources;
1334 ALCuint numSends = device->NumAuxSends;
1336 attrIdx = 0;
1337 while(attrList[attrIdx])
1339 if(attrList[attrIdx] == ALC_FREQUENCY &&
1340 !ConfigValueExists(NULL, "frequency"))
1342 freq = attrList[attrIdx + 1];
1343 if(freq < 8000)
1344 freq = 8000;
1347 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1349 numStereo = attrList[attrIdx + 1];
1350 if(numStereo > device->MaxNoOfSources)
1351 numStereo = device->MaxNoOfSources;
1353 numMono = device->MaxNoOfSources - numStereo;
1356 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS &&
1357 !ConfigValueExists(NULL, "sends"))
1359 numSends = attrList[attrIdx + 1];
1360 if(numSends > MAX_SENDS)
1361 numSends = MAX_SENDS;
1364 attrIdx += 2;
1367 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1368 device->Frequency;
1370 device->Frequency = freq;
1371 device->NumMonoSources = numMono;
1372 device->NumStereoSources = numStereo;
1373 device->NumAuxSends = numSends;
1376 if(ALCdevice_ResetPlayback(device) == ALC_FALSE)
1378 alcSetError(device, ALC_INVALID_DEVICE);
1379 aluHandleDisconnect(device);
1380 ProcessContext(NULL);
1381 return NULL;
1383 SetupChannelMatrix(device);
1385 for(i = 0;i < device->NumContexts;i++)
1387 ALCcontext *context = device->Contexts[i];
1388 ALeffectslot *slot;
1389 ALsource *source;
1391 SuspendContext(context);
1392 for(slot = context->EffectSlotList;slot != NULL;slot = slot->next)
1394 if(!slot->EffectState)
1395 continue;
1397 if(ALEffect_DeviceUpdate(slot->EffectState, device) == AL_FALSE)
1399 alcSetError(device, ALC_INVALID_DEVICE);
1400 aluHandleDisconnect(device);
1401 ProcessContext(context);
1402 ProcessContext(NULL);
1403 ALCdevice_StopPlayback(device);
1404 return NULL;
1406 ALEffect_Update(slot->EffectState, context, &slot->effect);
1409 for(source = context->SourceList;source != NULL;source = source->next)
1411 ALuint s = device->NumAuxSends;
1412 while(s < MAX_SENDS)
1414 if(source->Send[s].Slot)
1415 source->Send[s].Slot->refcount--;
1416 source->Send[s].Slot = NULL;
1417 source->Send[s].WetFilter.type = 0;
1418 source->Send[s].WetFilter.filter = 0;
1419 s++;
1421 source->NeedsUpdate = AL_TRUE;
1423 aluInitPanning(context);
1424 ProcessContext(context);
1427 if(device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1429 if(!device->Bs2b)
1431 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1432 bs2b_clear(device->Bs2b);
1434 bs2b_set_srate(device->Bs2b, device->Frequency);
1435 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1437 else
1439 free(device->Bs2b);
1440 device->Bs2b = NULL;
1443 temp = realloc(device->Contexts, (device->NumContexts+1) * sizeof(*device->Contexts));
1444 if(!temp)
1446 alcSetError(device, ALC_OUT_OF_MEMORY);
1447 ProcessContext(NULL);
1448 return NULL;
1450 device->Contexts = temp;
1452 ALContext = calloc(1, sizeof(ALCcontext));
1453 if(!ALContext)
1455 alcSetError(device, ALC_OUT_OF_MEMORY);
1456 ProcessContext(NULL);
1457 return NULL;
1460 device->Contexts[device->NumContexts++] = ALContext;
1461 ALContext->Device = device;
1463 InitContext(ALContext);
1464 aluInitPanning(ALContext);
1466 ALContext->next = g_pContextList;
1467 g_pContextList = ALContext;
1468 g_ulContextCount++;
1470 ProcessContext(NULL);
1472 return ALContext;
1477 alcDestroyContext
1479 Remove a Context
1481 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
1483 ALCdevice *Device;
1484 ALCcontext **list;
1485 ALuint i;
1487 if(!IsContext(context))
1489 alcSetError(NULL, ALC_INVALID_CONTEXT);
1490 return;
1493 Device = context->Device;
1495 if(Device->NumContexts == 1)
1496 ALCdevice_StopPlayback(Device);
1498 SuspendContext(NULL);
1500 if(context == GlobalContext)
1501 GlobalContext = NULL;
1503 for(i = 0;i < Device->NumContexts-1;i++)
1505 if(Device->Contexts[i] == context)
1507 Device->Contexts[i] = Device->Contexts[Device->NumContexts-1];
1508 break;
1511 Device->NumContexts--;
1513 // Lock context
1514 SuspendContext(context);
1516 if(context->SourceCount > 0)
1518 #ifdef _DEBUG
1519 AL_PRINT("alcDestroyContext(): deleting %d Source(s)\n", context->SourceCount);
1520 #endif
1521 ReleaseALSources(context);
1523 if(context->EffectSlotCount > 0)
1525 #ifdef _DEBUG
1526 AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", context->EffectSlotCount);
1527 #endif
1528 ReleaseALAuxiliaryEffectSlots(context);
1531 list = &g_pContextList;
1532 while(*list != context)
1533 list = &(*list)->next;
1535 *list = (*list)->next;
1536 g_ulContextCount--;
1538 // Unlock context
1539 ProcessContext(context);
1540 ProcessContext(NULL);
1542 ExitContext(context);
1544 // Free memory (MUST do this after ProcessContext)
1545 memset(context, 0, sizeof(ALCcontext));
1546 free(context);
1551 alcGetCurrentContext
1553 Returns the currently active Context
1555 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid)
1557 ALCcontext *pContext;
1559 if((pContext=GetContextSuspended()) != NULL)
1560 ProcessContext(pContext);
1562 return pContext;
1566 alcGetThreadContext
1568 Returns the currently active thread-local Context
1570 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
1572 ALCcontext *pContext = NULL;
1574 SuspendContext(NULL);
1576 pContext = tls_get(LocalContext);
1577 if(pContext && !IsContext(pContext))
1579 tls_set(LocalContext, NULL);
1580 pContext = NULL;
1583 ProcessContext(NULL);
1585 return pContext;
1590 alcGetContextsDevice
1592 Returns the Device that a particular Context is attached to
1594 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *pContext)
1596 ALCdevice *pDevice = NULL;
1598 SuspendContext(NULL);
1599 if(IsContext(pContext))
1600 pDevice = pContext->Device;
1601 else
1602 alcSetError(NULL, ALC_INVALID_CONTEXT);
1603 ProcessContext(NULL);
1605 return pDevice;
1610 alcMakeContextCurrent
1612 Makes the given Context the active Context
1614 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
1616 ALboolean bReturn = AL_TRUE;
1618 SuspendContext(NULL);
1620 // context must be a valid Context or NULL
1621 if(context == NULL || IsContext(context))
1623 GlobalContext = context;
1624 tls_set(LocalContext, NULL);
1626 else
1628 alcSetError(NULL, ALC_INVALID_CONTEXT);
1629 bReturn = AL_FALSE;
1632 ProcessContext(NULL);
1634 return bReturn;
1638 alcSetThreadContext
1640 Makes the given Context the active Context for the current thread
1642 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
1644 ALboolean bReturn = AL_TRUE;
1646 SuspendContext(NULL);
1648 // context must be a valid Context or NULL
1649 if(context == NULL || IsContext(context))
1650 tls_set(LocalContext, context);
1651 else
1653 alcSetError(NULL, ALC_INVALID_CONTEXT);
1654 bReturn = AL_FALSE;
1657 ProcessContext(NULL);
1659 return bReturn;
1663 // Sets the default channel order used by most non-WaveFormatEx-based APIs
1664 void SetDefaultChannelOrder(ALCdevice *device)
1666 switch(aluChannelsFromFormat(device->Format))
1668 case 1: device->DevChannels[FRONT_CENTER] = 0; break;
1670 case 2: device->DevChannels[FRONT_LEFT] = 0;
1671 device->DevChannels[FRONT_RIGHT] = 1; break;
1673 case 4: device->DevChannels[FRONT_LEFT] = 0;
1674 device->DevChannels[FRONT_RIGHT] = 1;
1675 device->DevChannels[BACK_LEFT] = 2;
1676 device->DevChannels[BACK_RIGHT] = 3; break;
1678 case 6: device->DevChannels[FRONT_LEFT] = 0;
1679 device->DevChannels[FRONT_RIGHT] = 1;
1680 device->DevChannels[BACK_LEFT] = 2;
1681 device->DevChannels[BACK_RIGHT] = 3;
1682 device->DevChannels[FRONT_CENTER] = 4;
1683 device->DevChannels[LFE] = 5; break;
1685 case 7: device->DevChannels[FRONT_LEFT] = 0;
1686 device->DevChannels[FRONT_RIGHT] = 1;
1687 device->DevChannels[FRONT_CENTER] = 2;
1688 device->DevChannels[LFE] = 3;
1689 device->DevChannels[BACK_CENTER] = 4;
1690 device->DevChannels[SIDE_LEFT] = 5;
1691 device->DevChannels[SIDE_RIGHT] = 6; break;
1693 case 8: device->DevChannels[FRONT_LEFT] = 0;
1694 device->DevChannels[FRONT_RIGHT] = 1;
1695 device->DevChannels[BACK_LEFT] = 2;
1696 device->DevChannels[BACK_RIGHT] = 3;
1697 device->DevChannels[FRONT_CENTER] = 4;
1698 device->DevChannels[LFE] = 5;
1699 device->DevChannels[SIDE_LEFT] = 6;
1700 device->DevChannels[SIDE_RIGHT] = 7; break;
1703 // Sets the default order used by WaveFormatEx
1704 void SetDefaultWFXChannelOrder(ALCdevice *device)
1706 switch(aluChannelsFromFormat(device->Format))
1708 case 1: device->DevChannels[FRONT_CENTER] = 0; break;
1710 case 2: device->DevChannels[FRONT_LEFT] = 0;
1711 device->DevChannels[FRONT_RIGHT] = 1; break;
1713 case 4: device->DevChannels[FRONT_LEFT] = 0;
1714 device->DevChannels[FRONT_RIGHT] = 1;
1715 device->DevChannels[BACK_LEFT] = 2;
1716 device->DevChannels[BACK_RIGHT] = 3; break;
1718 case 6: device->DevChannels[FRONT_LEFT] = 0;
1719 device->DevChannels[FRONT_RIGHT] = 1;
1720 device->DevChannels[FRONT_CENTER] = 2;
1721 device->DevChannels[LFE] = 3;
1722 device->DevChannels[BACK_LEFT] = 4;
1723 device->DevChannels[BACK_RIGHT] = 5; break;
1725 case 7: device->DevChannels[FRONT_LEFT] = 0;
1726 device->DevChannels[FRONT_RIGHT] = 1;
1727 device->DevChannels[FRONT_CENTER] = 2;
1728 device->DevChannels[LFE] = 3;
1729 device->DevChannels[BACK_CENTER] = 4;
1730 device->DevChannels[SIDE_LEFT] = 5;
1731 device->DevChannels[SIDE_RIGHT] = 6; break;
1733 case 8: device->DevChannels[FRONT_LEFT] = 0;
1734 device->DevChannels[FRONT_RIGHT] = 1;
1735 device->DevChannels[FRONT_CENTER] = 2;
1736 device->DevChannels[LFE] = 3;
1737 device->DevChannels[BACK_LEFT] = 4;
1738 device->DevChannels[BACK_RIGHT] = 5;
1739 device->DevChannels[SIDE_LEFT] = 6;
1740 device->DevChannels[SIDE_RIGHT] = 7; break;
1744 static ALenum GetFormatFromString(const char *str)
1746 if(strcasecmp(str, "AL_FORMAT_MONO32") == 0) return AL_FORMAT_MONO_FLOAT32;
1747 if(strcasecmp(str, "AL_FORMAT_STEREO32") == 0) return AL_FORMAT_STEREO_FLOAT32;
1748 if(strcasecmp(str, "AL_FORMAT_QUAD32") == 0) return AL_FORMAT_QUAD32;
1749 if(strcasecmp(str, "AL_FORMAT_51CHN32") == 0) return AL_FORMAT_51CHN32;
1750 if(strcasecmp(str, "AL_FORMAT_61CHN32") == 0) return AL_FORMAT_61CHN32;
1751 if(strcasecmp(str, "AL_FORMAT_71CHN32") == 0) return AL_FORMAT_71CHN32;
1753 if(strcasecmp(str, "AL_FORMAT_MONO16") == 0) return AL_FORMAT_MONO16;
1754 if(strcasecmp(str, "AL_FORMAT_STEREO16") == 0) return AL_FORMAT_STEREO16;
1755 if(strcasecmp(str, "AL_FORMAT_QUAD16") == 0) return AL_FORMAT_QUAD16;
1756 if(strcasecmp(str, "AL_FORMAT_51CHN16") == 0) return AL_FORMAT_51CHN16;
1757 if(strcasecmp(str, "AL_FORMAT_61CHN16") == 0) return AL_FORMAT_61CHN16;
1758 if(strcasecmp(str, "AL_FORMAT_71CHN16") == 0) return AL_FORMAT_71CHN16;
1760 if(strcasecmp(str, "AL_FORMAT_MONO8") == 0) return AL_FORMAT_MONO8;
1761 if(strcasecmp(str, "AL_FORMAT_STEREO8") == 0) return AL_FORMAT_STEREO8;
1762 if(strcasecmp(str, "AL_FORMAT_QUAD8") == 0) return AL_FORMAT_QUAD8;
1763 if(strcasecmp(str, "AL_FORMAT_51CHN8") == 0) return AL_FORMAT_51CHN8;
1764 if(strcasecmp(str, "AL_FORMAT_61CHN8") == 0) return AL_FORMAT_61CHN8;
1765 if(strcasecmp(str, "AL_FORMAT_71CHN8") == 0) return AL_FORMAT_71CHN8;
1767 AL_PRINT("Unknown format: \"%s\"\n", str);
1768 return AL_FORMAT_STEREO16;
1772 alcOpenDevice
1774 Open the Device specified.
1776 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
1778 ALboolean bDeviceFound = AL_FALSE;
1779 const ALCchar *fmt;
1780 ALCdevice *device;
1781 ALint i;
1783 if(deviceName && !deviceName[0])
1784 deviceName = NULL;
1786 device = calloc(1, sizeof(ALCdevice));
1787 if(!device)
1789 alcSetError(NULL, ALC_OUT_OF_MEMORY);
1790 return NULL;
1793 //Validate device
1794 device->Connected = ALC_TRUE;
1795 device->IsCaptureDevice = AL_FALSE;
1796 device->LastError = ALC_NO_ERROR;
1798 device->Bs2b = NULL;
1799 device->szDeviceName = NULL;
1801 device->Contexts = NULL;
1802 device->NumContexts = 0;
1804 //Set output format
1805 device->Frequency = GetConfigValueInt(NULL, "frequency", SWMIXER_OUTPUT_RATE);
1806 if(device->Frequency < 8000)
1807 device->Frequency = 8000;
1809 fmt = GetConfigValue(NULL, "format", "AL_FORMAT_STEREO16");
1810 device->Format = GetFormatFromString(fmt);
1812 device->NumUpdates = GetConfigValueInt(NULL, "periods", 4);
1813 if(device->NumUpdates < 2)
1814 device->NumUpdates = 4;
1816 i = GetConfigValueInt(NULL, "refresh", 4096);
1817 if(i <= 0) i = 4096;
1819 device->UpdateSize = GetConfigValueInt(NULL, "period_size", i/device->NumUpdates);
1820 if(device->UpdateSize <= 0)
1821 device->UpdateSize = i/device->NumUpdates;
1823 device->MaxNoOfSources = GetConfigValueInt(NULL, "sources", 256);
1824 if((ALint)device->MaxNoOfSources <= 0)
1825 device->MaxNoOfSources = 256;
1827 device->AuxiliaryEffectSlotMax = GetConfigValueInt(NULL, "slots", 4);
1828 if((ALint)device->AuxiliaryEffectSlotMax <= 0)
1829 device->AuxiliaryEffectSlotMax = 4;
1831 device->NumStereoSources = 1;
1832 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
1834 device->NumAuxSends = GetConfigValueInt(NULL, "sends", MAX_SENDS);
1835 if(device->NumAuxSends > MAX_SENDS)
1836 device->NumAuxSends = MAX_SENDS;
1838 device->Bs2bLevel = GetConfigValueInt(NULL, "cf_level", 0);
1840 if(aluChannelsFromFormat(device->Format) <= 2)
1842 device->HeadDampen = GetConfigValueFloat(NULL, "head_dampen", DEFAULT_HEAD_DAMPEN);
1843 device->HeadDampen = __min(device->HeadDampen, 1.0f);
1844 device->HeadDampen = __max(device->HeadDampen, 0.0f);
1846 else
1847 device->HeadDampen = 0.0f;
1849 // Find a playback device to open
1850 SuspendContext(NULL);
1851 for(i = 0;BackendList[i].Init;i++)
1853 device->Funcs = &BackendList[i].Funcs;
1854 if(ALCdevice_OpenPlayback(device, deviceName))
1856 device->next = g_pDeviceList;
1857 g_pDeviceList = device;
1858 g_ulDeviceCount++;
1860 bDeviceFound = AL_TRUE;
1861 break;
1864 ProcessContext(NULL);
1866 if(!bDeviceFound)
1868 // No suitable output device found
1869 alcSetError(NULL, ALC_INVALID_VALUE);
1870 free(device);
1871 device = NULL;
1874 return device;
1879 alcCloseDevice
1881 Close the specified Device
1883 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *pDevice)
1885 ALCdevice **list;
1887 if(!IsDevice(pDevice) || pDevice->IsCaptureDevice)
1889 alcSetError(pDevice, ALC_INVALID_DEVICE);
1890 return ALC_FALSE;
1893 SuspendContext(NULL);
1895 list = &g_pDeviceList;
1896 while(*list != pDevice)
1897 list = &(*list)->next;
1899 *list = (*list)->next;
1900 g_ulDeviceCount--;
1902 ProcessContext(NULL);
1904 if(pDevice->NumContexts > 0)
1906 #ifdef _DEBUG
1907 AL_PRINT("alcCloseDevice(): destroying %u Context(s)\n", pDevice->NumContexts);
1908 #endif
1909 while(pDevice->NumContexts > 0)
1910 alcDestroyContext(pDevice->Contexts[0]);
1912 ALCdevice_ClosePlayback(pDevice);
1914 if(pDevice->BufferCount > 0)
1916 #ifdef _DEBUG
1917 AL_PRINT("alcCloseDevice(): deleting %d Buffer(s)\n", pDevice->BufferCount);
1918 #endif
1919 ReleaseALBuffers(pDevice);
1921 if(pDevice->EffectCount > 0)
1923 #ifdef _DEBUG
1924 AL_PRINT("alcCloseDevice(): deleting %d Effect(s)\n", pDevice->EffectCount);
1925 #endif
1926 ReleaseALEffects(pDevice);
1928 if(pDevice->FilterCount > 0)
1930 #ifdef _DEBUG
1931 AL_PRINT("alcCloseDevice(): deleting %d Filter(s)\n", pDevice->FilterCount);
1932 #endif
1933 ReleaseALFilters(pDevice);
1935 if(pDevice->DatabufferCount > 0)
1937 #ifdef _DEBUG
1938 AL_PRINT("alcCloseDevice(): deleting %d Databuffer(s)\n", pDevice->DatabufferCount);
1939 #endif
1940 ReleaseALDatabuffers(pDevice);
1943 free(pDevice->Bs2b);
1944 pDevice->Bs2b = NULL;
1946 free(pDevice->szDeviceName);
1947 pDevice->szDeviceName = NULL;
1949 free(pDevice->Contexts);
1950 pDevice->Contexts = NULL;
1952 //Release device structure
1953 memset(pDevice, 0, sizeof(ALCdevice));
1954 free(pDevice);
1956 return ALC_TRUE;
1960 ALCvoid ReleaseALC(ALCvoid)
1962 free(alcDeviceList); alcDeviceList = NULL;
1963 alcDeviceListSize = 0;
1964 free(alcAllDeviceList); alcAllDeviceList = NULL;
1965 alcAllDeviceListSize = 0;
1966 free(alcCaptureDeviceList); alcCaptureDeviceList = NULL;
1967 alcCaptureDeviceListSize = 0;
1969 free(alcDefaultDeviceSpecifier);
1970 alcDefaultDeviceSpecifier = NULL;
1971 free(alcDefaultAllDeviceSpecifier);
1972 alcDefaultAllDeviceSpecifier = NULL;
1973 free(alcCaptureDefaultDeviceSpecifier);
1974 alcCaptureDefaultDeviceSpecifier = NULL;
1976 #ifdef _DEBUG
1977 if(g_ulDeviceCount > 0)
1978 AL_PRINT("exit(): closing %u Device%s\n", g_ulDeviceCount, (g_ulDeviceCount>1)?"s":"");
1979 #endif
1981 while(g_pDeviceList)
1983 if(g_pDeviceList->IsCaptureDevice)
1984 alcCaptureCloseDevice(g_pDeviceList);
1985 else
1986 alcCloseDevice(g_pDeviceList);
1990 ///////////////////////////////////////////////////////