Move ALu.c to the Alc directory
[openal-soft.git] / Router / alc.cpp
blobc4abff8cc6535383618ab9998bc8d6e9b7de3a67
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 #ifndef __MINGW32__
22 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
23 #endif
25 #include <stdlib.h>
26 #include <memory.h>
27 #define AL_BUILD_LIBRARY
28 #include <al/alc.h>
29 #include <stdio.h>
30 #include <tchar.h>
31 #include <assert.h>
33 #include <stddef.h>
34 #include <windows.h>
35 #if defined(_MSC_VER)
36 #include <crtdbg.h>
37 #else
38 #define _malloc_dbg(s,x,f,l) malloc(s)
39 #define _realloc_dbg(p,s,x,f,l) realloc(p,s)
40 #endif
41 #include <objbase.h>
42 #ifndef __MINGW32__
43 #include <atlconv.h>
44 #else
45 #define T2A(x) x
46 #endif
47 #include <mmsystem.h>
49 #include "OpenAL32.h"
52 //*****************************************************************************
53 //*****************************************************************************
55 // Defines
57 //*****************************************************************************
58 //*****************************************************************************
60 typedef struct ALCextension_struct
63 const char* ename;
65 } ALCextension;
67 typedef struct
69 const char* ename;
70 ALenum value;
72 } ALCRouterEnum;
74 typedef struct ALCfunction_struct
77 const char* fname;
78 ALvoid* address;
80 } ALCfunction;
84 //*****************************************************************************
85 //*****************************************************************************
87 // Global Vars
89 //*****************************************************************************
90 //*****************************************************************************
92 ALlist* alContextList = 0;
93 ALCcontext* alCurrentContext = 0;
95 ALCdevice* g_CaptureDevice = NULL;
97 //*****************************************************************************
98 //*****************************************************************************
100 // Local Vars
102 //*****************************************************************************
103 //*****************************************************************************
106 // The values of the enums supported by OpenAL.
108 static ALCRouterEnum alcEnums[] =
110 // Types
111 {"ALC_INVALID", ALC_INVALID},
112 {"ALC_FALSE", ALC_FALSE},
113 {"ALC_TRUE", ALC_TRUE},
115 // ALC Properties
116 {"ALC_MAJOR_VERSION", ALC_MAJOR_VERSION},
117 {"ALC_MINOR_VERSION", ALC_MINOR_VERSION},
118 {"ALC_ATTRIBUTES_SIZE", ALC_ATTRIBUTES_SIZE},
119 {"ALC_ALL_ATTRIBUTES", ALC_ALL_ATTRIBUTES},
120 {"ALC_DEFAULT_DEVICE_SPECIFIER", ALC_DEFAULT_DEVICE_SPECIFIER},
121 {"ALC_DEVICE_SPECIFIER", ALC_DEVICE_SPECIFIER},
122 {"ALC_EXTENSIONS", ALC_EXTENSIONS},
123 {"ALC_FREQUENCY", ALC_FREQUENCY},
124 {"ALC_REFRESH", ALC_REFRESH},
125 {"ALC_SYNC", ALC_SYNC},
126 {"ALC_MONO_SOURCES", ALC_MONO_SOURCES},
127 {"ALC_STEREO_SOURCES", ALC_STEREO_SOURCES},
128 {"ALC_CAPTURE_DEVICE_SPECIFIER", ALC_CAPTURE_DEVICE_SPECIFIER},
129 {"ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER", ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER},
130 {"ALC_CAPTURE_SAMPLES", ALC_CAPTURE_SAMPLES},
132 // New Enumeration extension
133 {"ALC_DEFAULT_ALL_DEVICES_SPECIFIER", ALC_DEFAULT_ALL_DEVICES_SPECIFIER},
134 {"ALC_ALL_DEVICES_SPECIFIER", ALC_ALL_DEVICES_SPECIFIER},
136 // ALC Error Message
137 {"ALC_NO_ERROR", ALC_NO_ERROR},
138 {"ALC_INVALID_DEVICE", ALC_INVALID_DEVICE},
139 {"ALC_INVALID_CONTEXT", ALC_INVALID_CONTEXT},
140 {"ALC_INVALID_ENUM", ALC_INVALID_ENUM},
141 {"ALC_INVALID_VALUE", ALC_INVALID_VALUE},
142 {"ALC_OUT_OF_MEMORY", ALC_OUT_OF_MEMORY},
144 // Default
145 {0, (ALenum)0}
149 // Our function pointers.
151 static ALCfunction alcFunctions[] =
153 {"alcCreateContext", (ALvoid*)alcCreateContext},
154 {"alcMakeContextCurrent", (ALvoid*)alcMakeContextCurrent},
155 {"alcProcessContext", (ALvoid*)alcProcessContext},
156 {"alcSuspendContext", (ALvoid*)alcSuspendContext},
157 {"alcDestroyContext", (ALvoid*)alcDestroyContext},
158 {"alcGetCurrentContext", (ALvoid*)alcGetCurrentContext},
159 {"alcGetContextsDevice", (ALvoid*)alcGetContextsDevice},
160 {"alcOpenDevice", (ALvoid*)alcOpenDevice},
161 {"alcCloseDevice", (ALvoid*)alcCloseDevice},
162 {"alcGetError", (ALvoid*)alcGetError},
163 {"alcIsExtensionPresent", (ALvoid*)alcIsExtensionPresent},
164 {"alcGetProcAddress", (ALvoid*)alcGetProcAddress},
165 {"alcGetEnumValue", (ALvoid*)alcGetEnumValue},
166 {"alcGetString", (ALvoid*)alcGetString},
167 {"alcGetIntegerv", (ALvoid*)alcGetIntegerv},
168 {"alcCaptureOpenDevice", (ALvoid*)alcCaptureOpenDevice},
169 {"alcCaptureCloseDevice", (ALvoid*)alcCaptureCloseDevice},
170 {"alcCaptureStart", (ALvoid*)alcCaptureStart},
171 {"alcCaptureStop", (ALvoid*)alcCaptureStop},
172 {"alcCaptureSamples", (ALvoid*)alcCaptureSamples},
173 {0, (ALvoid*)0}
177 // Our extensions.
179 static ALCextension alcExtensions[] =
181 "ALC_ENUMERATION_EXT",
182 "ALC_ENUMERATE_ALL_EXT",
183 "ALC_EXT_CAPTURE",
188 // Error strings
189 static ALenum LastError = ALC_NO_ERROR;
190 static const ALCchar alcNoError[] = "No Error";
191 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
192 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
193 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
194 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
196 static ALint alcMajorVersion = 1;
197 static ALint alcMinorVersion = 1;
199 // Enumeration stuff
200 ALDEVICE *g_pDeviceList = NULL; // ALC_ENUMERATION_EXT Device List
201 ALDEVICE *g_pCaptureDeviceList = NULL; // ALC_ENUMERATION_EXT Capture Device List
202 ALDEVICE *g_pAllDevicesList = NULL; // ALC_ENUMERATE_ALL_EXT Device List
204 ALchar *pszDefaultDeviceSpecifier = NULL;
205 ALchar *pszDeviceSpecifierList = NULL;
206 ALchar *pszDefaultCaptureDeviceSpecifier = NULL;
207 ALchar *pszCaptureDeviceSpecifierList = NULL;
208 ALchar *pszDefaultAllDevicesSpecifier = NULL;
209 ALchar *pszAllDevicesSpecifierList = NULL;
210 ALchar szEmptyString[] = "";
212 typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID);
213 typedef HRESULT (WINAPI *LPDIRECTSOUNDENUMERATEA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
214 typedef HRESULT (WINAPI *LPDIRECTSOUNDCAPTUREENUMERATEA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
216 BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext);
217 bool GetDefaultPlaybackDeviceName(char **pszName);
218 bool GetDefaultCaptureDeviceName(char **pszName);
219 bool FindDevice(ALDEVICE *pDeviceList, char *szDeviceName, bool bExactMatch, char **ppszDefaultName);
220 bool HasDLLAlreadyBeenUsed(ALDEVICE *pDeviceList, TCHAR *szDLLName);
221 //bool ValidCaptureDevice(const char *szCaptureDeviceName);
223 //*****************************************************************************
224 //*****************************************************************************
226 // Logging Options
228 //*****************************************************************************
229 //*****************************************************************************
231 // NOTE : LOG macro below requires a compiler newer than Visual Studio 6
233 //#define _LOGCALLS
235 #ifdef _LOGCALLS
236 void OutputMessage(const char *szTest,...);
237 #define LOG(x, ...) OutputMessage(x, ##__VA_ARGS__)
238 #define LOGFILENAME "OpenALCalls.txt"
239 #endif
241 //*****************************************************************************
242 //*****************************************************************************
244 // Local Functions
246 //*****************************************************************************
247 //*****************************************************************************
249 //*****************************************************************************
250 // GetLoadedModuleDirectory
251 //*****************************************************************************
252 BOOL GetLoadedModuleDirectory(LPCTSTR moduleName,
253 LPTSTR directoryContainingModule,
254 DWORD directoryContainingModuleLength) {
255 // Attempts to find the given module in the address space of this
256 // process and return the directory containing the module. A NULL
257 // moduleName means to look up the directory containing the
258 // application rather than any given loaded module. There is no
259 // trailing backslash ('\') on the returned path. If the named
260 // module was found in the address space of this process, returns
261 // TRUE, otherwise returns FALSE. directoryContainingModule may be
262 // mutated regardless.
263 HMODULE module = NULL;
264 TCHAR fileDrive[MAX_PATH + 1];
265 TCHAR fileDir[MAX_PATH + 1];
266 TCHAR fileName[MAX_PATH + 1];
267 TCHAR fileExt[MAX_PATH + 1];
268 DWORD numChars;
270 if (moduleName != NULL) {
271 module = GetModuleHandle(moduleName);
272 if (module == NULL)
273 return FALSE;
276 numChars = GetModuleFileName(module,
277 directoryContainingModule,
278 directoryContainingModuleLength);
279 if (numChars == 0)
280 return FALSE;
282 _splitpath(directoryContainingModule, fileDrive, fileDir, fileName, fileExt);
283 _tcscpy(directoryContainingModule, fileDrive);
284 _tcscat(directoryContainingModule, fileDir);
285 return TRUE;
291 //*****************************************************************************
292 // AddDevice
293 //*****************************************************************************
294 void AddDevice(const char *pszDeviceName, TCHAR *pszHostDLLFilename, ALDEVICE **ppDeviceList)
296 // Adds pszDeviceName nad pszHostDLLFilename to the given Device List *IF* pszDeviceName has
297 // not already been added.
298 ALDEVICE *pNewDevice, *pTempDevice;
300 // Check if unique
301 for (pTempDevice = *ppDeviceList; pTempDevice; pTempDevice = pTempDevice->pNextDevice)
303 if (strcmp(pTempDevice->pszDeviceName, pszDeviceName) == 0)
304 break;
307 if (pTempDevice)
308 return;
310 pNewDevice = (ALDEVICE*)malloc(sizeof(ALDEVICE));
311 if (pNewDevice)
313 pNewDevice->pszDeviceName = (char*)malloc((strlen(pszDeviceName)+1)*sizeof(char));
314 if (pNewDevice->pszDeviceName)
315 strcpy(pNewDevice->pszDeviceName, pszDeviceName);
317 pNewDevice->pszHostDLLFilename = (TCHAR*)malloc((_tcslen(pszHostDLLFilename)+1)*sizeof(TCHAR));
318 if (pNewDevice->pszHostDLLFilename)
319 _tcscpy(pNewDevice->pszHostDLLFilename, pszHostDLLFilename);
321 pNewDevice->pNextDevice = NULL;
323 if (*ppDeviceList)
325 pTempDevice = *ppDeviceList;
326 while (pTempDevice->pNextDevice)
327 pTempDevice = pTempDevice->pNextDevice;
328 pTempDevice->pNextDevice = pNewDevice;
330 else
332 *ppDeviceList = pNewDevice;
340 //*****************************************************************************
341 // BuildDeviceList
342 //*****************************************************************************
343 ALvoid BuildDeviceList()
345 // This function will scan several directories (details below) looking for
346 // OpenAL DLLs. Each OpenAL DLL found will be opened and queried for it's
347 // list of playback and capture devices. All the information is stored
348 // in various lists: -
350 // g_pDevicesList : List of Playback Devices
351 // g_pCaptureDeviceList : List of Capture devices
352 // g_pAllDevicesList : List of *all* possible Playback devices (ALC_ENUMERATE_ALL_EXT support)
354 // In addition this function allocates memory for the strings that will
355 // be returned to the application in response to alcGetString queries.
357 // pszDefaultDeviceSpecifier : Default Playback Device
358 // pszDeviceSpecifierList : List of Playback Devices
359 // pszDefaultCaptureDeviceSpecifier : Default Capture Device
360 // pszCaptureDeviceSpecifierList : List of Capture Devices
361 // pszDefaultAllDevicesSpecifier : Default *all* Playback Device (ALC_ENUMERATE_ALL_EXT support)
362 // pszAllDevicesSpecifierList : List of *all* Playback Devices (ALC_ENUMERATE_ALL_EXT support)
363 WIN32_FIND_DATA findData;
364 HANDLE searchHandle = INVALID_HANDLE_VALUE;
365 TCHAR searchName[MAX_PATH + 1];
366 BOOL found = FALSE;
367 const ALCchar* specifier = 0;
368 ALuint specifierSize = 0;
369 ALCdevice *device;
370 void *context;
371 bool bUsedWrapper = false;
372 ALDEVICE *pDevice = NULL;
374 // Only build the list once ...
375 if (((g_pDeviceList == NULL) && (waveOutGetNumDevs())) ||
376 ((g_pCaptureDeviceList == NULL) && (waveInGetNumDevs())))
379 // Directory[0] is the directory containing OpenAL32.dll
380 // Directory[1] is the current directory.
381 // Directory[2] is the current app directory
382 // Directory[3] is the system directory
384 TCHAR dir[4][MAX_PATH + 1] = { 0 };
385 int numDirs = 0;
386 int i;
387 HINSTANCE dll = 0;
388 ALCAPI_GET_STRING alcGetStringFxn = 0;
389 ALCAPI_IS_EXTENSION_PRESENT alcIsExtensionPresentFxn = 0;
390 ALCAPI_OPEN_DEVICE alcOpenDeviceFxn = 0;
391 ALCAPI_CREATE_CONTEXT alcCreateContextFxn = 0;
392 ALCAPI_MAKE_CONTEXT_CURRENT alcMakeContextCurrentFxn = 0;
393 ALCAPI_DESTROY_CONTEXT alcDestroyContextFxn = 0;
394 ALCAPI_CLOSE_DEVICE alcCloseDeviceFxn = 0;
397 // Construct our search paths
399 if (GetLoadedModuleDirectory("OpenAL32.dll", dir[0], MAX_PATH)) {
400 ++numDirs;
403 GetCurrentDirectory(MAX_PATH, dir[1]);
404 _tcscat(dir[1], _T("\\"));
405 ++numDirs;
407 GetLoadedModuleDirectory(NULL, dir[2], MAX_PATH);
408 ++numDirs;
410 GetSystemDirectory(dir[3], MAX_PATH);
411 _tcscat(dir[3], _T("\\"));
412 ++numDirs;
415 // Begin searching for additional OpenAL implementations.
417 for(i = 0; i < numDirs; i++)
419 if ((i == 0) && (strcmp(dir[0], dir[3]) == 0)) // if searching router dir and router dir is sys dir, skip search
420 continue;
422 if ((i == 2) && (strcmp(dir[2], dir[1]) == 0)) // if searching app dir and app dir is current dir, skip search
423 continue;
425 if ((i == 3) && ((strcmp(dir[3], dir[2]) == 0) || (strcmp(dir[3], dir[1]) == 0))) // if searching sys dir and sys dir is either current or app directory, skip search
426 continue;
428 _tcscpy(searchName, dir[i]);
429 _tcscat(searchName, _T("*oal.dll"));
430 searchHandle = FindFirstFile(searchName, &findData);
431 if(searchHandle != INVALID_HANDLE_VALUE)
433 while(TRUE)
436 // if this is an OpenAL32.dll, skip it -- it's probably a router and shouldn't be enumerated regardless
438 _tcscpy(searchName, dir[i]);
439 _tcscat(searchName, findData.cFileName);
440 TCHAR cmpName[MAX_PATH];
441 _tcscpy(cmpName, searchName);
442 _tcsupr(cmpName);
443 if (_tcsstr(cmpName, _T("OPENAL32.DLL")) == 0)
445 boolean skipSearch = false;
447 // don't search the same DLL twice
448 TCHAR *szDLLName = _tcsrchr(searchName, _T('\\'));
449 if (szDLLName)
450 szDLLName++; // Skip over the '\'
451 else
452 szDLLName = searchName;
454 skipSearch = HasDLLAlreadyBeenUsed(g_pDeviceList, szDLLName);
455 if (!skipSearch)
456 skipSearch = HasDLLAlreadyBeenUsed(g_pCaptureDeviceList, szDLLName);
457 if (!skipSearch)
458 skipSearch = HasDLLAlreadyBeenUsed(g_pAllDevicesList, szDLLName);
460 if (skipSearch == false) {
461 dll = LoadLibrary(searchName);
462 if(dll)
464 alcOpenDeviceFxn = (ALCAPI_OPEN_DEVICE)GetProcAddress(dll, "alcOpenDevice");
465 alcCreateContextFxn = (ALCAPI_CREATE_CONTEXT)GetProcAddress(dll, "alcCreateContext");
466 alcMakeContextCurrentFxn = (ALCAPI_MAKE_CONTEXT_CURRENT)GetProcAddress(dll, "alcMakeContextCurrent");
467 alcGetStringFxn = (ALCAPI_GET_STRING)GetProcAddress(dll, "alcGetString");
468 alcDestroyContextFxn = (ALCAPI_DESTROY_CONTEXT)GetProcAddress(dll, "alcDestroyContext");
469 alcCloseDeviceFxn = (ALCAPI_CLOSE_DEVICE)GetProcAddress(dll, "alcCloseDevice");
470 alcIsExtensionPresentFxn = (ALCAPI_IS_EXTENSION_PRESENT)GetProcAddress(dll, "alcIsExtensionPresent");
472 if ((alcOpenDeviceFxn != 0) &&
473 (alcCreateContextFxn != 0) &&
474 (alcMakeContextCurrentFxn != 0) &&
475 (alcGetStringFxn != 0) &&
476 (alcDestroyContextFxn != 0) &&
477 (alcCloseDeviceFxn != 0) &&
478 (alcIsExtensionPresentFxn != 0)) {
480 bool bAddToAllDevicesList = false;
482 if (alcIsExtensionPresentFxn(NULL, "ALC_ENUMERATE_ALL_EXT")) {
483 // this DLL can enumerate *all* devices -- so add complete list of devices
484 specifier = alcGetStringFxn(0, ALC_ALL_DEVICES_SPECIFIER);
485 if ((specifier) && strlen(specifier))
487 do {
488 AddDevice(specifier, searchName, &g_pAllDevicesList);
489 specifier += strlen((char *)specifier) + 1;
490 } while (strlen((char *)specifier) > 0);
492 } else {
493 bAddToAllDevicesList = true;
496 if (alcIsExtensionPresentFxn(NULL, "ALC_ENUMERATION_EXT")) {
497 // this DLL can enumerate devices -- so add complete list of devices
498 specifier = alcGetStringFxn(0, ALC_DEVICE_SPECIFIER);
499 if ((specifier) && strlen(specifier))
501 do {
502 AddDevice(specifier, searchName, &g_pDeviceList);
503 if (bAddToAllDevicesList)
504 AddDevice(specifier, searchName, &g_pAllDevicesList);
505 specifier += strlen((char *)specifier) + 1;
506 } while (strlen((char *)specifier) > 0);
508 } else {
509 // no enumeration ability, -- so just add default device to the list
510 device = alcOpenDeviceFxn(NULL);
511 if (device != NULL) {
512 context = alcCreateContextFxn(device, NULL);
513 alcMakeContextCurrentFxn((ALCcontext *)context);
514 if (context != NULL) {
515 specifier = alcGetStringFxn(device, ALC_DEVICE_SPECIFIER);
516 if ((specifier) && strlen(specifier))
518 AddDevice(specifier, searchName, &g_pDeviceList);
519 if (bAddToAllDevicesList)
520 AddDevice(specifier, searchName, &g_pAllDevicesList);
522 alcMakeContextCurrentFxn((ALCcontext *)NULL);
523 alcDestroyContextFxn((ALCcontext *)context);
524 alcCloseDeviceFxn(device);
529 // add to capture device list
530 if (_tcsstr(cmpName, _T("CT_OAL.DLL")) == 0) {
531 // Skip native AL component (will contain same Capture List as the wrap_oal component)
532 if (alcIsExtensionPresentFxn(NULL, "ALC_EXT_CAPTURE")) {
533 // this DLL supports capture -- so add complete list of capture devices
534 specifier = alcGetStringFxn(0, ALC_CAPTURE_DEVICE_SPECIFIER);
535 if ((specifier) && strlen(specifier))
537 do {
538 AddDevice(specifier, searchName, &g_pCaptureDeviceList);
539 specifier += strlen((char *)specifier) + 1;
540 } while (strlen((char *)specifier) > 0);
546 FreeLibrary(dll);
547 dll = 0;
552 if(!FindNextFile(searchHandle, &findData))
554 if(GetLastError() == ERROR_NO_MORE_FILES)
556 break;
561 FindClose(searchHandle);
562 searchHandle = INVALID_HANDLE_VALUE;
566 // We now have a list of all the Device Names and their associated DLLs.
567 // Put the names in the appropriate strings
568 ALuint uiLength;
569 ALchar *pszTemp;
570 char *pszDefaultName = NULL;
571 bool bFound = false;
573 if (g_pDeviceList)
575 uiLength = 0;
576 for (pDevice = g_pDeviceList; pDevice; pDevice = pDevice->pNextDevice)
577 uiLength += (strlen(pDevice->pszDeviceName) + 1);
579 pszDeviceSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar));
580 if (pszTemp = pszDeviceSpecifierList)
582 memset(pszDeviceSpecifierList, 0, (uiLength + 1) * sizeof(ALchar));
583 for (pDevice = g_pDeviceList; pDevice; pDevice = pDevice->pNextDevice)
585 strcpy(pszTemp, pDevice->pszDeviceName);
586 pszTemp += (strlen(pDevice->pszDeviceName) + 1);
590 // Determine what the Default Device should be
591 if (GetDefaultPlaybackDeviceName(&pszDefaultName))
593 bFound = false;
595 // Search for an exact match first
596 bFound = FindDevice(g_pDeviceList, pszDefaultName, true, &pszDefaultDeviceSpecifier);
598 // If we haven't found a match ... search for a partial match if name contains 'X-Fi'
599 if ((!bFound) && (strstr(pszDefaultName, "X-Fi")))
600 bFound = FindDevice(g_pDeviceList, "X-Fi", false, &pszDefaultDeviceSpecifier);
602 // If we haven't found a match ... search for a partial match if name contains 'Audigy'
603 if ((!bFound) && (strstr(pszDefaultName, "Audigy")))
604 bFound = FindDevice(g_pDeviceList, "Audigy", false, &pszDefaultDeviceSpecifier);
606 // If we haven't found a match ... search for a partial match with 'Generic Hardware'
607 if (!bFound)
608 bFound = FindDevice(g_pDeviceList, "Generic Hardware", false, &pszDefaultDeviceSpecifier);
610 // If we haven't found a match ... search for a partial match with 'Generic Software'
611 if (!bFound)
612 bFound = FindDevice(g_pDeviceList, "Generic Software", false, &pszDefaultDeviceSpecifier);
614 // If we STILL haven't found a match ... pick the 1st device!
615 if (!bFound)
617 pszDefaultDeviceSpecifier = (char*)malloc((strlen(g_pDeviceList->pszDeviceName) + 1) * sizeof(char));
618 if (pszDefaultDeviceSpecifier)
619 strcpy(pszDefaultDeviceSpecifier, g_pDeviceList->pszDeviceName);
622 free(pszDefaultName);
623 pszDefaultName = NULL;
627 if (g_pCaptureDeviceList)
629 uiLength = 0;
630 for (pDevice = g_pCaptureDeviceList; pDevice; pDevice = pDevice->pNextDevice)
631 uiLength += (strlen(pDevice->pszDeviceName) + 1);
633 pszCaptureDeviceSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar));
634 if (pszTemp = pszCaptureDeviceSpecifierList)
636 memset(pszCaptureDeviceSpecifierList, 0, (uiLength + 1) * sizeof(ALchar));
637 for (pDevice = g_pCaptureDeviceList; pDevice; pDevice = pDevice->pNextDevice)
639 strcpy(pszTemp, pDevice->pszDeviceName);
640 pszTemp += (strlen(pDevice->pszDeviceName) + 1);
644 if (GetDefaultCaptureDeviceName(&pszDefaultName))
646 bFound = false;
648 // Search for an exact match first
649 bFound = FindDevice(g_pCaptureDeviceList, pszDefaultName, true, &pszDefaultCaptureDeviceSpecifier);
651 // If we haven't found a match, truncate the default name to 32 characters (MMSYSTEM limitation)
652 if ((!bFound) && (strlen(pszDefaultName) > 31))
654 pszDefaultName[31] = '\0';
655 bFound = FindDevice(g_pCaptureDeviceList, pszDefaultName, true, &pszDefaultCaptureDeviceSpecifier);
658 // If we haven't found a match ... pick the 1st device!
659 if (!bFound)
661 pszDefaultCaptureDeviceSpecifier = (char*)malloc((strlen(g_pCaptureDeviceList->pszDeviceName) + 1) * sizeof(char));
662 if (pszDefaultCaptureDeviceSpecifier)
663 strcpy(pszDefaultCaptureDeviceSpecifier, g_pCaptureDeviceList->pszDeviceName);
666 free(pszDefaultName);
667 pszDefaultName = NULL;
671 if (g_pAllDevicesList)
673 uiLength = 0;
674 for (pDevice = g_pAllDevicesList; pDevice; pDevice = pDevice->pNextDevice)
675 uiLength += (strlen(pDevice->pszDeviceName) + 1);
677 pszAllDevicesSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar));
678 if (pszTemp = pszAllDevicesSpecifierList)
680 memset(pszAllDevicesSpecifierList, 0, (uiLength + 1) * sizeof(ALchar));
681 for (pDevice = g_pAllDevicesList; pDevice; pDevice = pDevice->pNextDevice)
683 strcpy(pszTemp, pDevice->pszDeviceName);
684 pszTemp += (strlen(pDevice->pszDeviceName) + 1);
688 // Determine what the Default Device should be
689 if (GetDefaultPlaybackDeviceName(&pszDefaultName))
691 bFound = false;
693 // If the (regular) default Playback device exists in this list ... use that
694 bFound = FindDevice(g_pAllDevicesList, pszDefaultDeviceSpecifier, true, &pszDefaultAllDevicesSpecifier);
696 // If we haven't found a match ... pick a partial match with the Default Device Name
697 if (!bFound)
698 bFound = FindDevice(g_pAllDevicesList, pszDefaultName, false, &pszDefaultAllDevicesSpecifier);
700 // If we STILL haven't found a match ... pick the 1st device!
701 if (!bFound)
703 pszDefaultAllDevicesSpecifier = (char*)malloc((strlen(g_pAllDevicesList->pszDeviceName) + 1) * sizeof(char));
704 if (pszDefaultAllDevicesSpecifier)
705 strcpy(pszDefaultAllDevicesSpecifier, g_pAllDevicesList->pszDeviceName);
708 free(pszDefaultName);
709 pszDefaultName = NULL;
714 return;
720 //*****************************************************************************
721 // HasDLLAlreadyBeenUsed
722 //*****************************************************************************
723 bool HasDLLAlreadyBeenUsed(ALDEVICE *pDeviceList, TCHAR *szDLLName)
725 // Checks if an OpenAL DLL has already been enumerated
726 ALDEVICE *pDevice = NULL;
727 TCHAR *szHostDLLName;
728 bool bReturn = false;
730 for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice)
732 szHostDLLName = _tcsrchr(pDevice->pszHostDLLFilename, _T('\\'));
733 if (szHostDLLName)
734 szHostDLLName++; // Skip over the '\'
735 else
736 szHostDLLName = pDevice->pszHostDLLFilename;
738 if (_tcscmp(szHostDLLName, szDLLName) == 0)
740 bReturn = true;
741 break;
745 return bReturn;
751 //*****************************************************************************
752 // ValidCaptureDevice
753 //*****************************************************************************
755 bool ValidCaptureDevice(const char *szCaptureDeviceName)
757 // Microsoft changed the behaviour of Input devices on Windows Vista such that *each* input
758 // on each soundcard is reported as a separate device. Unfortunately, even though you can
759 // enumerate each input there are restrictions on what devices can be opened (e.g. you can only
760 // open the soundcard's default input). There is no API call to change the default input, so
761 // there is little point enumerating input devices that cannot be used, so we filter them out here.
762 WAVEFORMATEX wfex = { WAVE_FORMAT_PCM, 1, 22050, 44100, 2, 16, 0 }; // 16bit Mono 22050Hz
763 WAVEINCAPS WaveInCaps;
764 HWAVEIN hWaveIn;
765 bool bValid = false;
767 // Find the device ID from the device name
768 long lNumCaptureDevs = waveInGetNumDevs();
769 long lDeviceID = -1;
770 for (long lLoop = 0; lLoop < lNumCaptureDevs; lLoop++)
772 if (waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
774 if (!strcmp(szCaptureDeviceName, WaveInCaps.szPname))
776 lDeviceID = lLoop;
777 break;
782 if (lDeviceID != -1)
784 if (waveInOpen(&hWaveIn, lDeviceID, &wfex, NULL, NULL, WAVE_MAPPED) == MMSYSERR_NOERROR)
786 waveInClose(hWaveIn);
787 bValid = true;
791 return bValid;
797 //*****************************************************************************
798 // GetDefaultPlaybackDeviceName
799 //*****************************************************************************
800 bool GetDefaultPlaybackDeviceName(char **pszName)
802 // Try to use DirectSound to get the name of the 'Preferred Audio Device / Endpoint"
803 // If that fails use MMSYSTEM (name will be limited to 32 characters in length)
804 TCHAR szPath[_MAX_PATH];
805 HINSTANCE hDSoundDLL;
807 if (!pszName)
808 return false;
810 *pszName = NULL;
812 // Load dsound.dll from the System Directory and use the DirectSoundEnumerateA function to
813 // get the list of playback devices
814 if (GetSystemDirectory(szPath, _MAX_PATH))
816 _tcscat(szPath, "\\dsound.dll");
817 hDSoundDLL = LoadLibrary(szPath);
818 if (hDSoundDLL)
820 LPDIRECTSOUNDENUMERATEA pfnDirectSoundEnumerateA = (LPDIRECTSOUNDENUMERATEA)GetProcAddress(hDSoundDLL, "DirectSoundEnumerateA");
821 if (pfnDirectSoundEnumerateA)
822 pfnDirectSoundEnumerateA(&DSEnumCallback, pszName);
823 FreeLibrary(hDSoundDLL);
827 // Falling back to MMSYSTEM
828 if (*pszName == NULL)
830 UINT uDeviceID=0;
831 DWORD dwFlags=1;
832 WAVEOUTCAPS outputInfo;
834 #if !defined(_WIN64)
835 #ifdef __GNUC__
836 __asm__ ("pusha;");
837 #else
838 __asm pusha; // workaround for register destruction caused by these wavOutMessage calls (weird but true)
839 #endif
840 #endif // !defined(_WIN64)
841 waveOutMessage((HWAVEOUT)(UINT_PTR)WAVE_MAPPER,0x2000+0x0015,(LPARAM)&uDeviceID,(WPARAM)&dwFlags);
842 waveOutGetDevCaps(uDeviceID,&outputInfo,sizeof(outputInfo));
843 #if !defined(_WIN64)
844 #ifdef __GNUC__
845 __asm__ ("popa;");
846 #else
847 __asm popa;
848 #endif
849 #endif // !defined(_WIN64)
851 *pszName = (char*)malloc((strlen(outputInfo.szPname) + 1) * sizeof(char));
852 if (*pszName)
853 strcpy(*pszName, outputInfo.szPname);
856 return (*pszName) ? true : false;
862 //*****************************************************************************
863 // GetDefaultCaptureDeviceName
864 //*****************************************************************************
865 bool GetDefaultCaptureDeviceName(char **pszName)
867 // Try to use DirectSound to get the name of the 'Preferred Audio Device / Endpoint" for recording.
868 // If that fails use MMSYSTEM (name will be limited to 32 characters in length)
869 TCHAR szPath[_MAX_PATH];
870 HINSTANCE hDSoundDLL;
872 if (!pszName)
873 return false;
875 *pszName = NULL;
877 // Load dsound.dll from the System Directory and use the DirectSoundCaptureEnumerateA function to
878 // get the list of capture devices
879 if (GetSystemDirectory(szPath, _MAX_PATH))
881 _tcscat(szPath, "\\dsound.dll");
882 hDSoundDLL = LoadLibrary(szPath);
883 if (hDSoundDLL)
885 LPDIRECTSOUNDCAPTUREENUMERATEA pfnDirectSoundCaptureEnumerateA = (LPDIRECTSOUNDCAPTUREENUMERATEA)GetProcAddress(hDSoundDLL, "DirectSoundCaptureEnumerateA");
886 if (pfnDirectSoundCaptureEnumerateA)
887 pfnDirectSoundCaptureEnumerateA(&DSEnumCallback, pszName);
888 FreeLibrary(hDSoundDLL);
892 // Falling back to MMSYSTEM
893 if (*pszName == NULL)
895 UINT uDeviceID=0;
896 DWORD dwFlags=1;
897 WAVEINCAPS inputInfo;
899 #if !defined(_WIN64)
900 #ifdef __GNUC__
901 __asm__ ("pusha;");
902 #else
903 __asm pusha; // workaround for register destruction caused by these wavOutMessage calls (weird but true)
904 #endif
905 #endif // !defined(_WIN64)
906 waveInMessage((HWAVEIN)(UINT_PTR)WAVE_MAPPER,0x2000+0x0015,(LPARAM)&uDeviceID,(WPARAM)&dwFlags);
907 waveInGetDevCaps(uDeviceID, &inputInfo, sizeof(inputInfo));
908 #if !defined(_WIN64)
909 #ifdef __GNUC__
910 __asm__ ("popa;");
911 #else
912 __asm popa;
913 #endif
914 #endif // !defined(_WIN64)
916 *pszName = (char*)malloc((strlen(inputInfo.szPname) + 1) * sizeof(char));
917 if (*pszName)
918 strcpy(*pszName, inputInfo.szPname);
921 return (*pszName) ? true : false;
927 //*****************************************************************************
928 // DSEnumCallback
929 //*****************************************************************************
930 BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
932 // DirectSound Enumeration callback will be called for each device found.
933 // The first device returned with a non-NULL GUID is the 'preferred device'
935 // Skip over the device without a GUID
936 if (lpGuid)
938 char **pszName = (char**)lpContext;
939 *pszName = (char*)malloc((strlen(lpcstrDescription)+1) * sizeof(char));
940 if (*pszName)
942 strcpy(*pszName, lpcstrDescription);
943 return FALSE;
947 return TRUE;
952 //*****************************************************************************
953 // FindDevice
954 //*****************************************************************************
955 bool FindDevice(ALDEVICE *pDeviceList, char *szDeviceName, bool bExactMatch, char **ppszDefaultName)
957 // Search through pDeviceList for szDeviceName using an exact match if bExactMatch is true, or using
958 // a sub-string search otherwise.
959 // If found, allocate memory for *ppszDefaultName and copy the device name over
960 ALDEVICE *pDevice = NULL;
961 bool bFound = false;
963 if (!pDeviceList || !szDeviceName || !ppszDefaultName)
964 return false;
966 for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice)
968 if (bExactMatch)
969 bFound = (strcmp(pDevice->pszDeviceName, szDeviceName) == 0) ? true : false;
970 else
971 bFound = (strstr(pDevice->pszDeviceName, szDeviceName)) ? true : false;
973 if (bFound)
975 *ppszDefaultName = (char*)malloc((strlen(pDevice->pszDeviceName) + 1) * sizeof(char));
976 if (*ppszDefaultName)
978 strcpy(*ppszDefaultName, pDevice->pszDeviceName);
979 break;
984 return *ppszDefaultName ? true : false;
990 //*****************************************************************************
991 // LoadDevicesDLL
992 //*****************************************************************************
993 HINSTANCE LoadDevicesDLL(ALDEVICE *pDeviceList, const ALchar *szDeviceName)
995 // Search pDeviceList for szDeviceName, and when found load the OpenAL DLL
996 // that contains that Device name.
997 HINSTANCE hDLL = NULL;
998 ALDEVICE *pDevice;
1000 for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice)
1002 if (strcmp(pDevice->pszDeviceName, szDeviceName) == 0)
1004 hDLL = LoadLibrary(pDevice->pszHostDLLFilename);
1005 break;
1009 return hDLL;
1015 //*****************************************************************************
1016 // FillOutAlcFunctions
1017 //*****************************************************************************
1018 ALboolean FillOutAlcFunctions(ALCdevice* device)
1020 ALboolean alcFxns = FALSE;
1021 ALCAPI_FXN_TABLE* alcApi = &device->AlcApi;
1023 memset(alcApi, 0, sizeof(ALCAPI_FXN_TABLE));
1026 // Get the OpenAL 1.0 Entry points.
1028 alcApi->alcCreateContext = (ALCAPI_CREATE_CONTEXT)GetProcAddress(device->Dll, "alcCreateContext");
1029 alcApi->alcMakeContextCurrent = (ALCAPI_MAKE_CONTEXT_CURRENT)GetProcAddress(device->Dll, "alcMakeContextCurrent");
1030 alcApi->alcProcessContext = (ALCAPI_PROCESS_CONTEXT)GetProcAddress(device->Dll, "alcProcessContext");
1031 alcApi->alcSuspendContext = (ALCAPI_SUSPEND_CONTEXT)GetProcAddress(device->Dll, "alcSuspendContext");
1032 alcApi->alcDestroyContext = (ALCAPI_DESTROY_CONTEXT)GetProcAddress(device->Dll, "alcDestroyContext");
1033 alcApi->alcGetCurrentContext = (ALCAPI_GET_CURRENT_CONTEXT)GetProcAddress(device->Dll, "alcGetCurrentContext");
1034 alcApi->alcGetContextsDevice = (ALCAPI_GET_CONTEXTS_DEVICE)GetProcAddress(device->Dll, "alcGetContextsDevice");
1036 alcApi->alcOpenDevice = (ALCAPI_OPEN_DEVICE)GetProcAddress(device->Dll, "alcOpenDevice");
1037 alcApi->alcCloseDevice = (ALCAPI_CLOSE_DEVICE)GetProcAddress(device->Dll, "alcCloseDevice");
1039 alcApi->alcGetError = (ALCAPI_GET_ERROR)GetProcAddress(device->Dll, "alcGetError");
1041 alcApi->alcIsExtensionPresent = (ALCAPI_IS_EXTENSION_PRESENT)GetProcAddress(device->Dll, "alcIsExtensionPresent");
1042 alcApi->alcGetProcAddress = (ALCAPI_GET_PROC_ADDRESS)GetProcAddress(device->Dll, "alcGetProcAddress");
1043 alcApi->alcGetEnumValue = (ALCAPI_GET_ENUM_VALUE)GetProcAddress(device->Dll, "alcGetEnumValue");
1045 alcApi->alcGetString = (ALCAPI_GET_STRING)GetProcAddress(device->Dll, "alcGetString");
1046 alcApi->alcGetIntegerv = (ALCAPI_GET_INTEGERV)GetProcAddress(device->Dll, "alcGetIntegerv");
1049 // Get the OpenAL 1.1 Entry points.
1051 alcApi->alcCaptureOpenDevice = (ALCAPI_CAPTURE_OPEN_DEVICE)GetProcAddress(device->Dll, "alcCaptureOpenDevice");
1052 alcApi->alcCaptureCloseDevice = (ALCAPI_CAPTURE_CLOSE_DEVICE)GetProcAddress(device->Dll, "alcCaptureCloseDevice");
1053 alcApi->alcCaptureStart = (ALCAPI_CAPTURE_START)GetProcAddress(device->Dll, "alcCaptureStart");
1054 alcApi->alcCaptureStop = (ALCAPI_CAPTURE_STOP)GetProcAddress(device->Dll, "alcCaptureStop");
1055 alcApi->alcCaptureSamples = (ALCAPI_CAPTURE_SAMPLES)GetProcAddress(device->Dll, "alcCaptureSamples");
1057 // handle legacy issue with old Creative DLLs which may not have alcGetProcAddress, alcIsExtensionPresent, alcGetEnumValue
1058 if (alcApi->alcGetProcAddress == NULL) {
1059 alcApi->alcGetProcAddress = (ALCAPI_GET_PROC_ADDRESS)alcGetProcAddress;
1061 if (alcApi->alcIsExtensionPresent == NULL) {
1062 alcApi->alcIsExtensionPresent = (ALCAPI_IS_EXTENSION_PRESENT)alcIsExtensionPresent;
1064 if (alcApi->alcGetEnumValue == NULL) {
1065 alcApi->alcGetEnumValue = (ALCAPI_GET_ENUM_VALUE)alcGetEnumValue;
1069 alcFxns = (alcApi->alcCreateContext &&
1070 alcApi->alcMakeContextCurrent &&
1071 alcApi->alcProcessContext &&
1072 alcApi->alcSuspendContext &&
1073 alcApi->alcDestroyContext &&
1074 alcApi->alcGetCurrentContext &&
1075 alcApi->alcGetContextsDevice &&
1076 alcApi->alcOpenDevice &&
1077 alcApi->alcCloseDevice &&
1078 alcApi->alcGetError &&
1079 alcApi->alcIsExtensionPresent &&
1080 alcApi->alcGetProcAddress &&
1081 alcApi->alcGetEnumValue &&
1082 alcApi->alcGetString &&
1083 alcApi->alcGetIntegerv);
1085 return alcFxns;
1091 //*****************************************************************************
1092 // FillOutAlFunctions
1093 //*****************************************************************************
1094 ALboolean FillOutAlFunctions(ALCcontext* context)
1096 ALboolean alFxns = FALSE;
1097 ALAPI_FXN_TABLE* alApi = &context->AlApi;
1099 memset(alApi, 0, sizeof(ALAPI_FXN_TABLE));
1102 // Get the OpenAL 1.0 & 1.1 Entry points.
1104 alApi->alEnable = (ALAPI_ENABLE)GetProcAddress(context->Device->Dll, "alEnable");
1105 alApi->alDisable = (ALAPI_DISABLE)GetProcAddress(context->Device->Dll, "alDisable");
1106 alApi->alIsEnabled = (ALAPI_IS_ENABLED)GetProcAddress(context->Device->Dll, "alIsEnabled");
1108 alApi->alGetString = (ALAPI_GET_STRING)GetProcAddress(context->Device->Dll, "alGetString");
1109 alApi->alGetBooleanv = (ALAPI_GET_BOOLEANV)GetProcAddress(context->Device->Dll, "alGetBooleanv");
1110 alApi->alGetIntegerv = (ALAPI_GET_INTEGERV)GetProcAddress(context->Device->Dll, "alGetIntegerv");
1111 alApi->alGetFloatv = (ALAPI_GET_FLOATV)GetProcAddress(context->Device->Dll, "alGetFloatv");
1112 alApi->alGetDoublev = (ALAPI_GET_DOUBLEV)GetProcAddress(context->Device->Dll, "alGetDoublev");
1113 alApi->alGetBoolean = (ALAPI_GET_BOOLEAN)GetProcAddress(context->Device->Dll, "alGetBoolean");
1114 alApi->alGetInteger = (ALAPI_GET_INTEGER)GetProcAddress(context->Device->Dll, "alGetInteger");
1115 alApi->alGetFloat = (ALAPI_GET_FLOAT)GetProcAddress(context->Device->Dll, "alGetFloat");
1116 alApi->alGetDouble = (ALAPI_GET_DOUBLE)GetProcAddress(context->Device->Dll, "alGetDouble");
1117 alApi->alGetError = (ALAPI_GET_ERROR)GetProcAddress(context->Device->Dll, "alGetError");
1118 alApi->alIsExtensionPresent = (ALAPI_IS_EXTENSION_PRESENT)GetProcAddress(context->Device->Dll, "alIsExtensionPresent");
1119 alApi->alGetProcAddress = (ALAPI_GET_PROC_ADDRESS)GetProcAddress(context->Device->Dll, "alGetProcAddress");
1120 alApi->alGetEnumValue = (ALAPI_GET_ENUM_VALUE)GetProcAddress(context->Device->Dll, "alGetEnumValue");
1122 alApi->alListenerf = (ALAPI_LISTENERF)GetProcAddress(context->Device->Dll, "alListenerf");
1123 alApi->alListener3f = (ALAPI_LISTENER3F)GetProcAddress(context->Device->Dll, "alListener3f");
1124 alApi->alListenerfv = (ALAPI_LISTENERFV)GetProcAddress(context->Device->Dll, "alListenerfv");
1125 alApi->alListeneri = (ALAPI_LISTENERI)GetProcAddress(context->Device->Dll, "alListeneri");
1126 alApi->alListener3i = (ALAPI_LISTENER3I)GetProcAddress(context->Device->Dll, "alListener3i");
1127 alApi->alListeneriv = (ALAPI_LISTENERIV)GetProcAddress(context->Device->Dll, "alListeneriv");
1128 alApi->alGetListenerf = (ALAPI_GET_LISTENERF)GetProcAddress(context->Device->Dll, "alGetListenerf");
1129 alApi->alGetListener3f = (ALAPI_GET_LISTENER3F)GetProcAddress(context->Device->Dll, "alGetListener3f");
1130 alApi->alGetListenerfv = (ALAPI_GET_LISTENERFV)GetProcAddress(context->Device->Dll, "alGetListenerfv");
1131 alApi->alGetListeneri = (ALAPI_GET_LISTENERI)GetProcAddress(context->Device->Dll, "alGetListeneri");
1132 alApi->alGetListener3i = (ALAPI_GET_LISTENER3I)GetProcAddress(context->Device->Dll, "alGetListener3i");
1133 alApi->alGetListeneriv = (ALAPI_GET_LISTENERIV)GetProcAddress(context->Device->Dll, "alGetListeneriv");
1135 alApi->alGenSources = (ALAPI_GEN_SOURCES)GetProcAddress(context->Device->Dll, "alGenSources");
1136 alApi->alDeleteSources = (ALAPI_DELETE_SOURCES)GetProcAddress(context->Device->Dll, "alDeleteSources");
1137 alApi->alIsSource = (ALAPI_IS_SOURCE)GetProcAddress(context->Device->Dll, "alIsSource");
1138 alApi->alSourcef = (ALAPI_SOURCEF)GetProcAddress(context->Device->Dll, "alSourcef");
1139 alApi->alSource3f = (ALAPI_SOURCE3F)GetProcAddress(context->Device->Dll, "alSource3f");
1140 alApi->alSourcefv = (ALAPI_SOURCEFV)GetProcAddress(context->Device->Dll, "alSourcefv");
1141 alApi->alSourcei = (ALAPI_SOURCEI)GetProcAddress(context->Device->Dll, "alSourcei");
1142 alApi->alSource3i = (ALAPI_SOURCE3I)GetProcAddress(context->Device->Dll, "alSource3i");
1143 alApi->alSourceiv = (ALAPI_SOURCEIV)GetProcAddress(context->Device->Dll, "alSourceiv");
1144 alApi->alGetSourcef = (ALAPI_GET_SOURCEF)GetProcAddress(context->Device->Dll, "alGetSourcef");
1145 alApi->alGetSource3f = (ALAPI_GET_SOURCE3F)GetProcAddress(context->Device->Dll, "alGetSource3f");
1146 alApi->alGetSourcefv = (ALAPI_GET_SOURCEFV)GetProcAddress(context->Device->Dll, "alGetSourcefv");
1147 alApi->alGetSourcei = (ALAPI_GET_SOURCEI)GetProcAddress(context->Device->Dll, "alGetSourcei");
1148 alApi->alGetSource3i = (ALAPI_GET_SOURCE3I)GetProcAddress(context->Device->Dll, "alGetSource3i");
1149 alApi->alGetSourceiv = (ALAPI_GET_SOURCEIV)GetProcAddress(context->Device->Dll, "alGetSourceiv");
1150 alApi->alSourcePlayv = (ALAPI_SOURCE_PLAYV)GetProcAddress(context->Device->Dll, "alSourcePlayv");
1151 alApi->alSourceStopv = (ALAPI_SOURCE_STOPV)GetProcAddress(context->Device->Dll, "alSourceStopv");
1152 alApi->alSourceRewindv = (ALAPI_SOURCE_REWINDV)GetProcAddress(context->Device->Dll, "alSourceRewindv");
1153 alApi->alSourcePausev = (ALAPI_SOURCE_PAUSEV)GetProcAddress(context->Device->Dll, "alSourcePausev");
1154 alApi->alSourcePlay = (ALAPI_SOURCE_PLAY)GetProcAddress(context->Device->Dll, "alSourcePlay");
1155 alApi->alSourceStop = (ALAPI_SOURCE_STOP)GetProcAddress(context->Device->Dll, "alSourceStop");
1156 alApi->alSourceRewind = (ALAPI_SOURCE_STOP)GetProcAddress(context->Device->Dll, "alSourceRewind");
1157 alApi->alSourcePause = (ALAPI_SOURCE_PAUSE)GetProcAddress(context->Device->Dll, "alSourcePause");
1159 alApi->alSourceQueueBuffers = (ALAPI_SOURCE_QUEUE_BUFFERS)GetProcAddress(context->Device->Dll, "alSourceQueueBuffers");
1160 alApi->alSourceUnqueueBuffers = (ALAPI_SOURCE_UNQUEUE_BUFFERS)GetProcAddress(context->Device->Dll, "alSourceUnqueueBuffers");
1162 alApi->alGenBuffers = (ALAPI_GEN_BUFFERS)GetProcAddress(context->Device->Dll, "alGenBuffers");
1163 alApi->alDeleteBuffers = (ALAPI_DELETE_BUFFERS)GetProcAddress(context->Device->Dll, "alDeleteBuffers");
1164 alApi->alIsBuffer = (ALAPI_IS_BUFFER)GetProcAddress(context->Device->Dll, "alIsBuffer");
1165 alApi->alBufferData = (ALAPI_BUFFER_DATA)GetProcAddress(context->Device->Dll, "alBufferData");
1166 alApi->alBufferf = (ALAPI_BUFFERF)GetProcAddress(context->Device->Dll, "alBufferf");
1167 alApi->alBuffer3f = (ALAPI_BUFFER3F)GetProcAddress(context->Device->Dll, "alBuffer3f");
1168 alApi->alBufferfv = (ALAPI_BUFFERFV)GetProcAddress(context->Device->Dll, "alBufferfv");
1169 alApi->alBufferi = (ALAPI_BUFFERI)GetProcAddress(context->Device->Dll, "alBufferi");
1170 alApi->alBuffer3i = (ALAPI_BUFFER3I)GetProcAddress(context->Device->Dll, "alBuffer3i");
1171 alApi->alBufferiv = (ALAPI_BUFFERIV)GetProcAddress(context->Device->Dll, "alBufferiv");
1172 alApi->alGetBufferf = (ALAPI_GET_BUFFERF)GetProcAddress(context->Device->Dll, "alGetBufferf");
1173 alApi->alGetBuffer3f = (ALAPI_GET_BUFFER3F)GetProcAddress(context->Device->Dll, "alGetBuffer3f");
1174 alApi->alGetBufferfv = (ALAPI_GET_BUFFERFV)GetProcAddress(context->Device->Dll, "alGetBufferfv");
1175 alApi->alGetBufferi = (ALAPI_GET_BUFFERI)GetProcAddress(context->Device->Dll, "alGetBufferi");
1176 alApi->alGetBuffer3i = (ALAPI_GET_BUFFER3I)GetProcAddress(context->Device->Dll, "alGetBuffer3i");
1177 alApi->alGetBufferiv = (ALAPI_GET_BUFFERIV)GetProcAddress(context->Device->Dll, "alGetBufferiv");
1179 alApi->alDopplerFactor = (ALAPI_DOPPLER_FACTOR)GetProcAddress(context->Device->Dll, "alDopplerFactor");
1180 alApi->alDopplerVelocity = (ALAPI_DOPPLER_VELOCITY)GetProcAddress(context->Device->Dll, "alDopplerVelocity");
1181 alApi->alSpeedOfSound = (ALAPI_SPEED_OF_SOUND)GetProcAddress(context->Device->Dll, "alSpeedOfSound");
1182 alApi->alDistanceModel = (ALAPI_DISTANCE_MODEL)GetProcAddress(context->Device->Dll, "alDistanceModel");
1184 alFxns = (alApi->alEnable &&
1185 alApi->alDisable &&
1186 alApi->alIsEnabled &&
1188 alApi->alGetString &&
1189 alApi->alGetBooleanv &&
1190 alApi->alGetIntegerv &&
1191 alApi->alGetFloatv &&
1192 alApi->alGetDoublev &&
1193 alApi->alGetBoolean &&
1194 alApi->alGetInteger &&
1195 alApi->alGetFloat &&
1196 alApi->alGetDouble &&
1198 alApi->alGetError &&
1200 alApi->alIsExtensionPresent &&
1201 alApi->alGetProcAddress &&
1202 alApi->alGetEnumValue &&
1204 alApi->alListenerf &&
1205 alApi->alListener3f &&
1206 alApi->alListenerfv &&
1207 alApi->alListeneri &&
1208 alApi->alGetListenerf &&
1209 alApi->alGetListener3f &&
1210 alApi->alGetListenerfv &&
1211 alApi->alGetListeneri &&
1213 alApi->alGenSources &&
1214 alApi->alDeleteSources &&
1215 alApi->alIsSource &&
1216 alApi->alSourcef &&
1217 alApi->alSource3f &&
1218 alApi->alSourcefv &&
1219 alApi->alSourcei &&
1220 alApi->alGetSourcef &&
1221 alApi->alGetSource3f &&
1222 alApi->alGetSourcefv &&
1223 alApi->alGetSourcei &&
1224 alApi->alSourcePlayv &&
1225 alApi->alSourceStopv &&
1226 alApi->alSourceRewindv &&
1227 alApi->alSourcePausev &&
1228 alApi->alSourcePlay &&
1229 alApi->alSourceStop &&
1230 alApi->alSourceRewind &&
1231 alApi->alSourcePause &&
1233 alApi->alSourceQueueBuffers &&
1234 alApi->alSourceUnqueueBuffers &&
1236 alApi->alGenBuffers &&
1237 alApi->alDeleteBuffers &&
1238 alApi->alIsBuffer &&
1239 alApi->alBufferData &&
1240 alApi->alGetBufferf &&
1241 alApi->alGetBufferi &&
1243 alApi->alDopplerFactor &&
1244 alApi->alDopplerVelocity &&
1245 alApi->alDistanceModel);
1247 return alFxns;
1253 //*****************************************************************************
1254 //*****************************************************************************
1256 // ALC API Entry Points
1258 //*****************************************************************************ALC_
1259 //*****************************************************************************
1261 //*****************************************************************************
1262 // alcCloseDevice
1263 //*****************************************************************************
1265 ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice* device)
1267 #ifdef _LOGCALLS
1268 LOG("alcCloseDevice device %p\n", device);
1269 #endif
1270 if(!device)
1272 return ALC_FALSE;
1275 if (device == g_CaptureDevice)
1276 return g_CaptureDevice->AlcApi.alcCloseDevice(g_CaptureDevice->CaptureDevice);
1279 // Check if its linked to a context.
1281 if(device->InUse)
1283 ALCcontext* context = 0;
1284 ALlistEntry* entry = 0;
1287 // Not all of the contexts using the device have been destroyed.
1289 assert(0);
1292 // Loop through the context list and free and contexts linked to the device.
1293 // Go back to the beginning each time in case some one changed the context
1294 // list iterator.
1296 alListAcquireLock(alContextList);
1297 entry = alListIteratorReset(alContextList);
1298 while(entry)
1300 context = (ALCcontext*)alListGetData(entry);
1301 if(context->Device == device)
1303 alListReleaseLock(alContextList);
1304 alcDestroyContext((ALCcontext *)context);
1305 alListAcquireLock(alContextList);
1306 entry = alListIteratorReset(alContextList);
1309 else
1311 entry = alListIteratorNext(alContextList);
1315 alListReleaseLock(alContextList);
1316 assert(!device->InUse);
1319 device->AlcApi.alcCloseDevice(device->DllDevice);
1320 FreeLibrary(device->Dll);
1321 free(device);
1323 return ALC_TRUE;
1329 //*****************************************************************************
1330 // alcCreateContext
1331 //*****************************************************************************
1332 ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice* device, const ALint* attrList)
1334 #ifdef _LOGCALLS
1335 LOG("alcCreateContext device %p ", device);
1336 if (attrList)
1338 unsigned long ulIndex = 0;
1339 while ((ulIndex < 16) && (attrList[ulIndex]))
1341 switch(attrList[ulIndex])
1343 case ALC_FREQUENCY:
1344 LOG("ALC_FREQUENCY %d ", attrList[ulIndex + 1]);
1345 break;
1347 case ALC_REFRESH:
1348 LOG("ALC_REFRESH %d ", attrList[ulIndex + 1]);
1349 break;
1351 case ALC_SYNC:
1352 LOG("ALC_SYNC %d ", attrList[ulIndex + 1]);
1353 break;
1355 case ALC_MONO_SOURCES:
1356 LOG("ALC_MONO_SOURCES %d ", attrList[ulIndex + 1]);
1357 break;
1359 case ALC_STEREO_SOURCES:
1360 LOG("ALC_STEREO_SOURCES %d ", attrList[ulIndex + 1]);
1361 break;
1363 case 0x20003/*ALC_MAX_AUXILIARY_SENDS*/:
1364 LOG("ALC_MAX_AUXILIARY_SENDS %d", attrList[ulIndex + 1]);
1365 break;
1367 ulIndex += 2;
1370 LOG("\n");
1371 #endif
1373 ALCcontext* context = 0;
1375 if(!device)
1377 LastError = ALC_INVALID_DEVICE;
1378 return 0;
1381 if (device == g_CaptureDevice)
1382 return g_CaptureDevice->AlcApi.alcCreateContext(g_CaptureDevice->CaptureDevice, attrList);
1385 // Allocate the context.
1387 context = (ALCcontext*)malloc(sizeof(ALCcontext));
1388 if(!context)
1390 return 0;
1393 memset(context, 0, sizeof(ALCcontext));
1394 context->Device = device;
1395 context->Suspended = FALSE;
1396 context->LastError = ALC_NO_ERROR;
1397 InitializeCriticalSection(&context->Lock);
1400 // We don't fill out the AL functions in case they are context specific.
1403 context->DllContext = device->AlcApi.alcCreateContext(device->DllDevice, attrList);
1404 if(!context->DllContext)
1406 DeleteCriticalSection(&context->Lock);
1407 free(context);
1408 context = 0;
1409 return 0;
1412 device->InUse++;
1415 // Add it to the context list.
1417 alListInitializeEntry(&context->ListEntry, context);
1418 alListAcquireLock(alContextList);
1419 alListAddEntry(alContextList, &context->ListEntry);
1420 alListReleaseLock(alContextList);
1421 return context;
1427 //*****************************************************************************
1428 // alcDestroyContext
1429 //*****************************************************************************
1430 ALCAPI ALvoid ALCAPIENTRY alcDestroyContext(ALCcontext* context)
1432 #ifdef _LOGCALLS
1433 LOG("alcDestroyContext context %p\n", context);
1434 #endif
1435 ALCcontext* listData = 0;
1437 if(!context)
1439 return;
1443 // Remove the entry from the context list.
1445 alListAcquireLock(alContextList);
1446 listData = (ALCcontext*)alListRemoveEntry(alContextList, &context->ListEntry);
1447 if(!listData)
1449 alListReleaseLock(alContextList);
1450 return;
1453 if(context == alCurrentContext)
1455 alCurrentContext = 0;
1458 EnterCriticalSection(&context->Lock);
1459 alListReleaseLock(alContextList);
1461 context->Device->InUse--;
1463 // Clean up the context.
1464 if(context->DllContext)
1466 context->Device->AlcApi.alcDestroyContext(context->DllContext);
1469 LeaveCriticalSection(&context->Lock);
1470 DeleteCriticalSection(&context->Lock);
1471 free(context);
1477 //*****************************************************************************
1478 // alcGetContextsDevice
1479 //*****************************************************************************
1480 ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext* context)
1482 #ifdef _LOGCALLS
1483 LOG("alcGetContextsDevice context %p\n", context);
1484 #endif
1485 ALCdevice* ALCdevice = 0;
1487 alListAcquireLock(alContextList);
1488 if(alListMatchData(alContextList, context))
1490 ALCdevice = context->Device;
1493 alListReleaseLock(alContextList);
1495 return ALCdevice;
1501 //*****************************************************************************
1502 // alcGetCurrentContext
1503 //*****************************************************************************
1504 ALCAPI ALCcontext* ALCAPIENTRY alcGetCurrentContext(ALvoid)
1506 #ifdef _LOGCALLS
1507 LOG("alcGetCurrentContext\n");
1508 #endif
1509 return (ALCcontext *)alCurrentContext;
1515 //*****************************************************************************
1516 // alcGetEnumValue
1517 //*****************************************************************************
1518 ALCAPI ALenum ALCAPIENTRY alcGetEnumValue(ALCdevice* device, const ALCchar* ename)
1520 #ifdef _LOGCALLS
1521 LOG("alcGetEnumValue device %p enum name '%s'\n", device, ename ? ename : "<NULL>");
1522 #endif
1524 // Always return the router version of the ALC enum if it exists.
1526 ALsizei i = 0;
1527 while(alcEnums[i].ename && strcmp((char*)alcEnums[i].ename, (char*)ename))
1529 i++;
1532 if(alcEnums[i].ename)
1534 return alcEnums[i].value;
1537 if(device)
1539 if (device == g_CaptureDevice)
1540 return g_CaptureDevice->AlcApi.alcGetEnumValue(g_CaptureDevice->CaptureDevice, ename);
1542 return device->AlcApi.alcGetEnumValue(device->DllDevice, ename);
1545 LastError = ALC_INVALID_ENUM;
1546 return 0;
1552 //*****************************************************************************
1553 // alcGetError
1554 //*****************************************************************************
1555 ALCAPI ALenum ALCAPIENTRY alcGetError(ALCdevice* device)
1557 #ifdef _LOGCALLS
1558 LOG("alcGetError device %p\n", device);
1559 #endif
1560 ALenum errorCode = ALC_NO_ERROR;
1562 // Try to get a valid device.
1563 if(!device)
1565 if (g_CaptureDevice == device)
1566 return
1567 errorCode = LastError;
1568 LastError = ALC_NO_ERROR;
1569 return errorCode;
1573 // Check if its a 3rd party device.
1575 if (device == g_CaptureDevice)
1576 errorCode = g_CaptureDevice->AlcApi.alcGetError(g_CaptureDevice->CaptureDevice);
1577 else
1578 errorCode = device->AlcApi.alcGetError(device->DllDevice);
1580 return errorCode;
1586 //*****************************************************************************
1587 // alcGetIntegerv
1588 //*****************************************************************************
1589 ALCAPI ALvoid ALCAPIENTRY alcGetIntegerv(ALCdevice* device, ALenum param, ALsizei size, ALint* data)
1591 #ifdef _LOGCALLS
1592 LOG("alcGetIntegerv device %p enum ", device);
1593 switch (param)
1595 case ALC_ATTRIBUTES_SIZE:
1596 LOG("ALC_ATTRIBUTES_SIZE\n");
1597 break;
1598 case ALC_ALL_ATTRIBUTES:
1599 LOG("ALC_ALL_ATTRIBUTES\n");
1600 break;
1601 case ALC_MAJOR_VERSION:
1602 LOG("ALC_MAJOR_VERSION\n");
1603 break;
1604 case ALC_MINOR_VERSION:
1605 LOG("ALC_MINOR_VERSION\n");
1606 break;
1607 case ALC_CAPTURE_SAMPLES:
1608 LOG("ALC_CAPTURE_SAMPLES\n");
1609 break;
1610 case ALC_FREQUENCY:
1611 LOG("ALC_FREQUENCY\n");
1612 break;
1613 case ALC_REFRESH:
1614 LOG("ALC_REFRESH\n");
1615 break;
1616 case ALC_SYNC:
1617 LOG("ALC_SYNC\n");
1618 break;
1619 case ALC_MONO_SOURCES:
1620 LOG("ALC_MONO_SOURCES\n");
1621 break;
1622 case ALC_STEREO_SOURCES:
1623 LOG("ALC_STEREO_SOURCES\n");
1624 break;
1625 case 0x20003: // ALC_MAX_AUXILIARY_SENDS
1626 LOG("ALC_MAX_AUXILIARY_SENDS\n");
1627 break;
1628 case 0x20001: // ALC_EFX_MAJOR_VERSION
1629 LOG("ALC_EFX_MAJOR_VERSION\n");
1630 break;
1631 case 0x20002: // ALC_EFX_MINOR_VERSION
1632 LOG("ALC_EFX_MINOR_VERSION\n");
1633 break;
1634 default:
1635 LOG("<Unknown>\n");
1636 break;
1638 #endif
1640 if(device)
1642 if (device == g_CaptureDevice)
1644 g_CaptureDevice->AlcApi.alcGetIntegerv(g_CaptureDevice->CaptureDevice, param, size, data);
1645 return;
1648 device->AlcApi.alcGetIntegerv(device->DllDevice, param, size, data);
1649 return;
1652 switch(param)
1654 case ALC_MAJOR_VERSION:
1656 if((size < sizeof(ALint)) || (data == 0))
1658 LastError = ALC_INVALID;
1659 return;
1662 *data = alcMajorVersion;
1664 break;
1666 case ALC_MINOR_VERSION:
1668 if((size < sizeof(ALint)) || (data == 0))
1670 LastError = ALC_INVALID;
1671 return;
1674 *data = alcMinorVersion;
1676 break;
1678 default:
1680 device->LastError = ALC_INVALID_ENUM;
1682 break;
1689 //*****************************************************************************
1690 // alcGetProcAddress
1691 //*****************************************************************************
1692 ALCAPI ALvoid* ALCAPIENTRY alcGetProcAddress(ALCdevice* device, const ALCchar* fname)
1694 #ifdef _LOGCALLS
1695 LOG("alcGetProcAddress device %p function name '%s'\n", device, fname ? fname : "<NULL>");
1696 #endif
1699 // Always return the router version of the ALC function if it exists.
1701 ALsizei i = 0;
1702 while(alcFunctions[i].fname && strcmp((char*)alcFunctions[i].fname, (char*)fname))
1704 i++;
1707 if(alcFunctions[i].fname)
1709 return alcFunctions[i].address;
1712 if(device)
1714 if (device == g_CaptureDevice)
1715 return g_CaptureDevice->AlcApi.alcGetProcAddress(g_CaptureDevice->CaptureDevice, fname);
1717 return device->AlcApi.alcGetProcAddress(device->DllDevice, fname);
1720 LastError = ALC_INVALID_ENUM;
1721 return 0;
1727 //*****************************************************************************
1728 // alcIsExtensionPresent
1729 //*****************************************************************************
1730 ALCAPI ALboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice* device, const ALCchar* ename)
1732 #ifdef _LOGCALLS
1733 LOG("alcIsExtensionPresent device %p extension name '%s'\n", device, ename ? ename : "<NULL>");
1734 #endif
1736 // Check if its a router supported extension first as its a good idea to have
1737 // ALC calls go through the router if possible.
1739 ALsizei i = 0;
1740 while(alcExtensions[i].ename && _stricmp((char*)alcExtensions[i].ename, (char*)ename))
1742 i++;
1745 if(alcExtensions[i].ename)
1747 return ALC_TRUE;
1751 // Check the device passed in to see if the extension is supported.
1753 if(device)
1755 if (device == g_CaptureDevice)
1756 return g_CaptureDevice->AlcApi.alcIsExtensionPresent(g_CaptureDevice->CaptureDevice, ename);
1758 return device->AlcApi.alcIsExtensionPresent(device->DllDevice, ename);
1761 LastError = ALC_INVALID_ENUM;
1762 return ALC_FALSE;
1768 //*****************************************************************************
1769 // alcMakeContextCurrent
1770 //*****************************************************************************
1771 ALCAPI ALboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext* context)
1773 #ifdef _LOGCALLS
1774 LOG("alcMakeContextCurrent context %p\n", context);
1775 #endif
1776 ALboolean contextSwitched = AL_TRUE;
1779 // Context must be a valid context or 0
1781 alListAcquireLock(alContextList);
1782 if(!alListMatchData(alContextList, context) && context != 0)
1784 alListReleaseLock(alContextList);
1785 return ALC_FALSE;
1789 // Try the new context.
1791 if(context)
1793 contextSwitched = context->Device->AlcApi.alcMakeContextCurrent(context->DllContext);
1796 // If this is the first time the context has been made the current context, fill in the context
1797 // function pointers.
1799 if(contextSwitched && !context->AlApi.alGetProcAddress)
1802 // Don't fill out the functions here in case they are context specific pointers in the device.
1804 if(!FillOutAlFunctions(context))
1806 LastError = ALC_INVALID_CONTEXT;
1807 contextSwitched = AL_FALSE;
1810 // Something went wrong, restore the old context.
1812 if(alCurrentContext)
1814 alCurrentContext->Device->AlcApi.alcMakeContextCurrent(alCurrentContext->DllContext);
1817 else
1819 alCurrentContext->Device->AlcApi.alcMakeContextCurrent(0);
1823 } else {
1824 if ((alCurrentContext) && (alCurrentContext->Device) && (alCurrentContext->Device->AlcApi.alcMakeContextCurrent)) {
1825 contextSwitched = alCurrentContext->Device->AlcApi.alcMakeContextCurrent(0);
1830 // Set the context states if the switch was successful.
1832 if(contextSwitched)
1834 alCurrentContext = context;
1837 alListReleaseLock(alContextList);
1838 return contextSwitched;
1844 //*****************************************************************************
1845 // alcOpenDevice
1846 //*****************************************************************************
1847 ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar* deviceName)
1849 #ifdef _LOGCALLS
1850 LOG("alcOpenDevice device name '%s'\n", deviceName ? deviceName : "<NULL>");
1851 #endif
1852 HINSTANCE dll = 0;
1853 ALCdevice* device = 0;
1854 const ALchar *pszDeviceName = NULL;
1856 BuildDeviceList();
1858 if (g_pDeviceList)
1860 if ((!deviceName) || (strlen(deviceName)==0) || (strcmp(deviceName, "DirectSound3D")==0))
1861 pszDeviceName = pszDefaultDeviceSpecifier;
1862 else
1863 pszDeviceName = deviceName;
1865 // Search for device in Playback Device List
1866 dll = LoadDevicesDLL(g_pDeviceList, pszDeviceName);
1868 if (!dll)
1870 // If NOT found, and the requested name is one of these ...
1871 // "Generic Hardware" (no longer available on Windows Vista)
1872 // "DirectSound" (legacy name for OpenAL Software mixer device)
1873 // "MMSYSTEM" (legacy name for OpenAL Software mixer using MMSYSTEM instead of DirectSound)
1874 // try to open the "Generic Software" device instead
1875 if ((strcmp(pszDeviceName, "Generic Hardware") == 0) ||
1876 (strcmp(pszDeviceName, "DirectSound") == 0) ||
1877 (strcmp(pszDeviceName, "MMSYSTEM") == 0))
1879 dll = LoadDevicesDLL(g_pDeviceList, "Generic Software");
1883 if (!dll)
1884 dll = LoadDevicesDLL(g_pAllDevicesList, pszDeviceName);
1886 if (dll)
1888 device = (ALCdevice*)malloc(sizeof(ALCdevice));
1889 if (device)
1891 memset(device, 0, sizeof(ALCdevice));
1892 device->LastError = ALC_NO_ERROR;
1893 device->InUse = 0;
1894 device->Dll = dll;
1895 if (FillOutAlcFunctions(device))
1896 device->DllDevice = device->AlcApi.alcOpenDevice(pszDeviceName);
1898 if (!device->DllDevice)
1900 FreeLibrary(dll);
1901 free(device);
1902 device = 0;
1908 if (!device)
1909 LastError = ALC_INVALID_DEVICE;
1911 return device;
1917 //*****************************************************************************
1918 // alcProcessContext
1919 //*****************************************************************************
1920 ALCAPI ALvoid ALCAPIENTRY alcProcessContext(ALCcontext* context)
1922 #ifdef _LOGCALLS
1923 LOG("alcProcessContext context %p\n", context);
1924 #endif
1925 alListAcquireLock(alContextList);
1926 if(!context && !alCurrentContext)
1928 alListReleaseLock(alContextList);
1929 return;
1932 if(!context)
1934 context = alCurrentContext;
1937 EnterCriticalSection(&context->Lock);
1938 alListReleaseLock(alContextList);
1940 if(context->DllContext)
1942 context->Device->AlcApi.alcProcessContext(context->DllContext);
1945 context->Suspended = FALSE;
1947 LeaveCriticalSection(&context->Lock);
1948 return;
1954 //*****************************************************************************
1955 // alcSuspendContext
1956 //*****************************************************************************
1957 ALCAPI ALCvoid ALCAPIENTRY alcSuspendContext(ALCcontext* context)
1959 #ifdef _LOGCALLS
1960 LOG("alcSuspendContext context %p\n", context);
1961 #endif
1962 alListAcquireLock(alContextList);
1963 if(!context && !alCurrentContext)
1965 alListReleaseLock(alContextList);
1966 return;
1969 if(!context)
1971 context = (ALCcontext *)alCurrentContext;
1974 EnterCriticalSection(&context->Lock);
1975 alListReleaseLock(alContextList);
1977 context->Suspended = TRUE;
1979 if(context->DllContext)
1981 context->Device->AlcApi.alcSuspendContext(context->DllContext);
1984 LeaveCriticalSection(&context->Lock);
1985 return;
1991 //*****************************************************************************
1992 // alcGetString
1993 //*****************************************************************************
1994 ALCAPI const ALCchar* ALCAPIENTRY alcGetString(ALCdevice* device, ALenum param)
1996 #ifdef _LOGCALLS
1997 LOG("alcGetString device %p enum ", device);
1998 switch (param)
2000 case ALC_NO_ERROR:
2001 LOG("ALC_NO_ERROR\n");
2002 break;
2003 case ALC_INVALID_ENUM:
2004 LOG("ALC_INVALID_ENUM\n");
2005 break;
2006 case ALC_INVALID_VALUE:
2007 LOG("ALC_INVALID_VALUE\n");
2008 break;
2009 case ALC_INVALID_DEVICE:
2010 LOG("ALC_INVALID_DEVICE\n");
2011 break;
2012 case ALC_INVALID_CONTEXT:
2013 LOG("ALC_INVALID_CONTEXT\n");
2014 break;
2015 case ALC_DEFAULT_DEVICE_SPECIFIER:
2016 LOG("ALC_DEFAULT_DEVICE_SPECIFIER\n");
2017 break;
2018 case ALC_DEVICE_SPECIFIER:
2019 LOG("ALC_DEVICE_SPECIFIER\n");
2020 break;
2021 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2022 LOG("ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER\n");
2023 break;
2024 case ALC_CAPTURE_DEVICE_SPECIFIER:
2025 LOG("ALC_CAPTURE_DEVICE_SPECIFIER\n");
2026 break;
2027 case ALC_ALL_DEVICES_SPECIFIER:
2028 LOG("ALC_ALL_DEVICES_SPECIFIER\n");
2029 break;
2030 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2031 LOG("ALC_DEFAULT_ALL_DEVICES_SPECIFIER\n");
2032 break;
2033 case ALC_EXTENSIONS:
2034 LOG("ALC_EXTENSIONS\n");
2035 break;
2036 default:
2037 LOG("<Unknown>\n");
2038 break;
2040 #endif
2042 const ALCchar* value = 0;
2044 if ((param != ALC_DEFAULT_DEVICE_SPECIFIER) && (param != ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) {
2045 if(device)
2047 if (device == g_CaptureDevice)
2048 return g_CaptureDevice->AlcApi.alcGetString(g_CaptureDevice->CaptureDevice, param);
2050 return device->AlcApi.alcGetString(device->DllDevice, param);
2054 switch(param)
2056 case ALC_NO_ERROR:
2058 value = alcNoError;
2060 break;
2062 case ALC_INVALID_ENUM:
2064 value = alcErrInvalidEnum;
2066 break;
2068 case ALC_INVALID_VALUE:
2070 value = alcErrInvalidValue;
2072 break;
2074 case ALC_INVALID_DEVICE:
2076 value = alcErrInvalidDevice;
2078 break;
2080 case ALC_INVALID_CONTEXT:
2082 value = alcErrInvalidContext;
2084 break;
2086 case ALC_DEFAULT_DEVICE_SPECIFIER:
2087 BuildDeviceList();
2088 if (pszDefaultDeviceSpecifier)
2089 value = pszDefaultDeviceSpecifier;
2090 else
2091 value = szEmptyString;
2092 break;
2094 case ALC_DEVICE_SPECIFIER:
2095 BuildDeviceList();
2096 if (pszDeviceSpecifierList)
2097 value = pszDeviceSpecifierList;
2098 else
2099 value = szEmptyString;
2100 break;
2102 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2103 BuildDeviceList();
2104 if (pszDefaultCaptureDeviceSpecifier)
2105 value = pszDefaultCaptureDeviceSpecifier;
2106 else
2107 value = szEmptyString;
2108 break;
2110 case ALC_CAPTURE_DEVICE_SPECIFIER:
2111 BuildDeviceList();
2112 if (pszCaptureDeviceSpecifierList)
2113 value = pszCaptureDeviceSpecifierList;
2114 else
2115 value = szEmptyString;
2116 break;
2118 case ALC_ALL_DEVICES_SPECIFIER:
2119 BuildDeviceList();
2120 if (pszAllDevicesSpecifierList)
2121 value = pszAllDevicesSpecifierList;
2122 else
2123 value = szEmptyString;
2124 break;
2126 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2127 BuildDeviceList();
2128 if (pszDefaultAllDevicesSpecifier)
2129 value = pszDefaultAllDevicesSpecifier;
2130 else
2131 value = szEmptyString;
2132 break;
2134 default:
2135 LastError = ALC_INVALID_ENUM;
2136 break;
2139 return value;
2145 //*****************************************************************************
2146 // alcCaptureOpenDevice
2147 //*****************************************************************************
2148 ALCAPI ALCdevice * ALCAPIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei buffersize)
2150 #ifdef _LOGCALLS
2151 LOG("alcCaptureOpenDevice device name '%s' frequency %d format %d buffersize %d\n", deviceName ? deviceName : "<NULL>", frequency, format, buffersize);
2152 #endif
2153 const ALchar *pszDeviceName = NULL;
2155 BuildDeviceList();
2157 if (!g_pCaptureDeviceList)
2158 return NULL;
2160 if (!g_CaptureDevice) {
2161 g_CaptureDevice = (ALCdevice*)malloc(sizeof(ALCdevice));
2163 if (g_CaptureDevice)
2165 // clear
2166 memset(g_CaptureDevice, 0, sizeof(ALCdevice));
2168 // make sure we have a device name
2169 if ((!deviceName) || (strlen(deviceName) == 0))
2170 pszDeviceName = pszDefaultCaptureDeviceSpecifier;
2171 else
2172 pszDeviceName = deviceName;
2174 g_CaptureDevice->Dll = LoadDevicesDLL(g_pCaptureDeviceList, pszDeviceName);
2176 if (g_CaptureDevice->Dll) {
2177 if(FillOutAlcFunctions(g_CaptureDevice)) {
2178 if (g_CaptureDevice->AlcApi.alcCaptureOpenDevice) {
2179 g_CaptureDevice->CaptureDevice = g_CaptureDevice->AlcApi.alcCaptureOpenDevice(pszDeviceName, frequency, format, buffersize);
2180 g_CaptureDevice->LastError = ALC_NO_ERROR;
2181 g_CaptureDevice->InUse = 0;
2182 } else {
2183 g_CaptureDevice->LastError = ALC_INVALID_DEVICE;
2188 } else {
2189 // already open
2190 g_CaptureDevice->LastError = ALC_INVALID_VALUE;
2193 if (g_CaptureDevice != NULL) {
2194 if (g_CaptureDevice->CaptureDevice) {
2195 return g_CaptureDevice;
2196 } else {
2197 free(g_CaptureDevice);
2198 g_CaptureDevice = NULL;
2199 return NULL;
2201 } else {
2202 return NULL;
2209 //*****************************************************************************
2210 // alcCaptureCloseDevice
2211 //*****************************************************************************
2212 ALCAPI ALCboolean ALCAPIENTRY alcCaptureCloseDevice(ALCdevice *device)
2214 #ifdef _LOGCALLS
2215 LOG("alcCaptureCloseDevice device %p\n", device);
2216 #endif
2217 ALCboolean bReturn = ALC_FALSE;
2219 if (device == g_CaptureDevice)
2221 if (g_CaptureDevice != NULL) {
2222 if (g_CaptureDevice->AlcApi.alcCaptureCloseDevice) {
2223 bReturn = g_CaptureDevice->AlcApi.alcCaptureCloseDevice(g_CaptureDevice->CaptureDevice);
2224 delete g_CaptureDevice;
2225 g_CaptureDevice = NULL;
2226 } else {
2227 g_CaptureDevice->LastError = ALC_INVALID_DEVICE;
2232 return bReturn;
2238 //*****************************************************************************
2239 // alcCaptureStart
2240 //*****************************************************************************
2241 ALCAPI ALCvoid ALCAPIENTRY alcCaptureStart(ALCdevice *device)
2243 #ifdef _LOGCALLS
2244 LOG("alcCaptureStart device %p\n", device);
2245 #endif
2246 if (device == g_CaptureDevice)
2248 if (g_CaptureDevice != NULL) {
2249 if (g_CaptureDevice->AlcApi.alcCaptureStart) {
2250 g_CaptureDevice->AlcApi.alcCaptureStart(g_CaptureDevice->CaptureDevice);
2251 } else {
2252 g_CaptureDevice->LastError = ALC_INVALID_DEVICE;
2257 return;
2263 //*****************************************************************************
2264 // alcCaptureStop
2265 //*****************************************************************************
2266 ALCAPI ALCvoid ALCAPIENTRY alcCaptureStop(ALCdevice *device)
2268 #ifdef _LOGCALLS
2269 LOG("alcCaptureStop device %p\n", device);
2270 #endif
2271 if (device == g_CaptureDevice)
2273 if (g_CaptureDevice != NULL) {
2274 if (g_CaptureDevice->AlcApi.alcCaptureStop) {
2275 g_CaptureDevice->AlcApi.alcCaptureStop(g_CaptureDevice->CaptureDevice);
2276 } else {
2277 g_CaptureDevice->LastError = ALC_INVALID_DEVICE;
2282 return;
2288 //*****************************************************************************
2289 // alcCaptureSamples
2290 //*****************************************************************************
2291 ALCAPI ALCvoid ALCAPIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
2293 #ifdef _LOGCALLS
2294 LOG("alcCaptureSamples device %p buffer %p samples %d\n", device, buffer, samples);
2295 #endif
2296 if (device == g_CaptureDevice)
2298 if (g_CaptureDevice != NULL) {
2299 if (g_CaptureDevice->AlcApi.alcCaptureSamples) {
2300 g_CaptureDevice->AlcApi.alcCaptureSamples(g_CaptureDevice->CaptureDevice, buffer, samples);
2301 } else {
2302 g_CaptureDevice->LastError = ALC_INVALID_DEVICE;
2307 return;
2310 #ifdef _LOGCALLS
2311 void OutputMessage(const char *szDebug,...)
2313 static FILE *pFile = NULL;
2314 SYSTEMTIME sysTime;
2315 va_list args;
2317 va_start(args, szDebug);
2319 if (!pFile)
2321 pFile = fopen(LOGFILENAME, "w");
2322 GetLocalTime(&sysTime);
2323 fprintf(pFile, "OpenAL Router\n\nLog Time : %d/%d/%d at %d:%s%d:%s%d\n\n", sysTime.wDay, sysTime.wMonth, sysTime.wYear,
2324 sysTime.wHour, (sysTime.wMinute < 10) ? "0" : "", sysTime.wMinute, (sysTime.wSecond < 10) ? "0" : "", sysTime.wSecond);
2327 vfprintf(pFile, szDebug, args);
2328 fflush(pFile);
2330 va_end(args);
2332 #endif