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
22 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
27 #define AL_BUILD_LIBRARY
38 #define _malloc_dbg(s,x,f,l) malloc(s)
39 #define _realloc_dbg(p,s,x,f,l) realloc(p,s)
52 //*****************************************************************************
53 //*****************************************************************************
57 //*****************************************************************************
58 //*****************************************************************************
60 typedef struct ALCextension_struct
74 typedef struct ALCfunction_struct
84 //*****************************************************************************
85 //*****************************************************************************
89 //*****************************************************************************
90 //*****************************************************************************
92 ALlist
* alContextList
= 0;
93 ALCcontext
* alCurrentContext
= 0;
95 ALCdevice
* g_CaptureDevice
= NULL
;
97 //*****************************************************************************
98 //*****************************************************************************
102 //*****************************************************************************
103 //*****************************************************************************
106 // The values of the enums supported by OpenAL.
108 static ALCRouterEnum alcEnums
[] =
111 {"ALC_INVALID", ALC_INVALID
},
112 {"ALC_FALSE", ALC_FALSE
},
113 {"ALC_TRUE", ALC_TRUE
},
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
},
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
},
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
},
179 static ALCextension alcExtensions
[] =
181 "ALC_ENUMERATION_EXT",
182 "ALC_ENUMERATE_ALL_EXT",
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;
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 //*****************************************************************************
228 //*****************************************************************************
229 //*****************************************************************************
231 // NOTE : LOG macro below requires a compiler newer than Visual Studio 6
236 void OutputMessage(const char *szTest
,...);
237 #define LOG(x, ...) OutputMessage(x, ##__VA_ARGS__)
238 #define LOGFILENAME "OpenALCalls.txt"
241 //*****************************************************************************
242 //*****************************************************************************
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];
270 if (moduleName
!= NULL
) {
271 module
= GetModuleHandle(moduleName
);
276 numChars
= GetModuleFileName(module
,
277 directoryContainingModule
,
278 directoryContainingModuleLength
);
282 _splitpath(directoryContainingModule
, fileDrive
, fileDir
, fileName
, fileExt
);
283 _tcscpy(directoryContainingModule
, fileDrive
);
284 _tcscat(directoryContainingModule
, fileDir
);
291 //*****************************************************************************
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
;
301 for (pTempDevice
= *ppDeviceList
; pTempDevice
; pTempDevice
= pTempDevice
->pNextDevice
)
303 if (strcmp(pTempDevice
->pszDeviceName
, pszDeviceName
) == 0)
310 pNewDevice
= (ALDEVICE
*)malloc(sizeof(ALDEVICE
));
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
;
325 pTempDevice
= *ppDeviceList
;
326 while (pTempDevice
->pNextDevice
)
327 pTempDevice
= pTempDevice
->pNextDevice
;
328 pTempDevice
->pNextDevice
= pNewDevice
;
332 *ppDeviceList
= pNewDevice
;
340 //*****************************************************************************
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];
367 const ALCchar
* specifier
= 0;
368 ALuint specifierSize
= 0;
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 };
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
)) {
403 GetCurrentDirectory(MAX_PATH
, dir
[1]);
404 _tcscat(dir
[1], _T("\\"));
407 GetLoadedModuleDirectory(NULL
, dir
[2], MAX_PATH
);
410 GetSystemDirectory(dir
[3], MAX_PATH
);
411 _tcscat(dir
[3], _T("\\"));
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
422 if ((i
== 2) && (strcmp(dir
[2], dir
[1]) == 0)) // if searching app dir and app dir is current dir, skip search
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
428 _tcscpy(searchName
, dir
[i
]);
429 _tcscat(searchName
, _T("*oal.dll"));
430 searchHandle
= FindFirstFile(searchName
, &findData
);
431 if(searchHandle
!= INVALID_HANDLE_VALUE
)
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
);
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('\\'));
450 szDLLName
++; // Skip over the '\'
452 szDLLName
= searchName
;
454 skipSearch
= HasDLLAlreadyBeenUsed(g_pDeviceList
, szDLLName
);
456 skipSearch
= HasDLLAlreadyBeenUsed(g_pCaptureDeviceList
, szDLLName
);
458 skipSearch
= HasDLLAlreadyBeenUsed(g_pAllDevicesList
, szDLLName
);
460 if (skipSearch
== false) {
461 dll
= LoadLibrary(searchName
);
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
))
488 AddDevice(specifier
, searchName
, &g_pAllDevicesList
);
489 specifier
+= strlen((char *)specifier
) + 1;
490 } while (strlen((char *)specifier
) > 0);
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
))
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);
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
))
538 AddDevice(specifier
, searchName
, &g_pCaptureDeviceList
);
539 specifier
+= strlen((char *)specifier
) + 1;
540 } while (strlen((char *)specifier
) > 0);
552 if(!FindNextFile(searchHandle
, &findData
))
554 if(GetLastError() == ERROR_NO_MORE_FILES
)
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
570 char *pszDefaultName
= NULL
;
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
))
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'
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'
612 bFound
= FindDevice(g_pDeviceList
, "Generic Software", false, &pszDefaultDeviceSpecifier
);
614 // If we STILL haven't found a match ... pick the 1st device!
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
)
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
))
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!
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
)
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
))
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
698 bFound
= FindDevice(g_pAllDevicesList
, pszDefaultName
, false, &pszDefaultAllDevicesSpecifier
);
700 // If we STILL haven't found a match ... pick the 1st device!
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
;
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('\\'));
734 szHostDLLName
++; // Skip over the '\'
736 szHostDLLName
= pDevice
->pszHostDLLFilename
;
738 if (_tcscmp(szHostDLLName
, szDLLName
) == 0)
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;
767 // Find the device ID from the device name
768 long lNumCaptureDevs = waveInGetNumDevs();
770 for (long lLoop = 0; lLoop < lNumCaptureDevs; lLoop++)
772 if (waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
774 if (!strcmp(szCaptureDeviceName, WaveInCaps.szPname))
784 if (waveInOpen(&hWaveIn, lDeviceID, &wfex, NULL, NULL, WAVE_MAPPED) == MMSYSERR_NOERROR)
786 waveInClose(hWaveIn);
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
;
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
);
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
)
832 WAVEOUTCAPS outputInfo
;
838 __asm pusha
; // workaround for register destruction caused by these wavOutMessage calls (weird but true)
840 #endif // !defined(_WIN64)
841 waveOutMessage((HWAVEOUT
)(UINT_PTR
)WAVE_MAPPER
,0x2000+0x0015,(LPARAM
)&uDeviceID
,(WPARAM
)&dwFlags
);
842 waveOutGetDevCaps(uDeviceID
,&outputInfo
,sizeof(outputInfo
));
849 #endif // !defined(_WIN64)
851 *pszName
= (char*)malloc((strlen(outputInfo
.szPname
) + 1) * sizeof(char));
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
;
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
);
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
)
897 WAVEINCAPS inputInfo
;
903 __asm pusha
; // workaround for register destruction caused by these wavOutMessage calls (weird but true)
905 #endif // !defined(_WIN64)
906 waveInMessage((HWAVEIN
)(UINT_PTR
)WAVE_MAPPER
,0x2000+0x0015,(LPARAM
)&uDeviceID
,(WPARAM
)&dwFlags
);
907 waveInGetDevCaps(uDeviceID
, &inputInfo
, sizeof(inputInfo
));
914 #endif // !defined(_WIN64)
916 *pszName
= (char*)malloc((strlen(inputInfo
.szPname
) + 1) * sizeof(char));
918 strcpy(*pszName
, inputInfo
.szPname
);
921 return (*pszName
) ? true : false;
927 //*****************************************************************************
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
938 char **pszName
= (char**)lpContext
;
939 *pszName
= (char*)malloc((strlen(lpcstrDescription
)+1) * sizeof(char));
942 strcpy(*pszName
, lpcstrDescription
);
952 //*****************************************************************************
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
;
963 if (!pDeviceList
|| !szDeviceName
|| !ppszDefaultName
)
966 for (pDevice
= pDeviceList
; pDevice
; pDevice
= pDevice
->pNextDevice
)
969 bFound
= (strcmp(pDevice
->pszDeviceName
, szDeviceName
) == 0) ? true : false;
971 bFound
= (strstr(pDevice
->pszDeviceName
, szDeviceName
)) ? true : false;
975 *ppszDefaultName
= (char*)malloc((strlen(pDevice
->pszDeviceName
) + 1) * sizeof(char));
976 if (*ppszDefaultName
)
978 strcpy(*ppszDefaultName
, pDevice
->pszDeviceName
);
984 return *ppszDefaultName
? true : false;
990 //*****************************************************************************
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
;
1000 for (pDevice
= pDeviceList
; pDevice
; pDevice
= pDevice
->pNextDevice
)
1002 if (strcmp(pDevice
->pszDeviceName
, szDeviceName
) == 0)
1004 hDLL
= LoadLibrary(pDevice
->pszHostDLLFilename
);
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
);
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
&&
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
&&
1217 alApi
->alSource3f
&&
1218 alApi
->alSourcefv
&&
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
);
1253 //*****************************************************************************
1254 //*****************************************************************************
1256 // ALC API Entry Points
1258 //*****************************************************************************ALC_
1259 //*****************************************************************************
1261 //*****************************************************************************
1263 //*****************************************************************************
1265 ALCAPI ALCboolean ALCAPIENTRY
alcCloseDevice(ALCdevice
* device
)
1268 LOG("alcCloseDevice device %p\n", device
);
1275 if (device
== g_CaptureDevice
)
1276 return g_CaptureDevice
->AlcApi
.alcCloseDevice(g_CaptureDevice
->CaptureDevice
);
1279 // Check if its linked to a context.
1283 ALCcontext
* context
= 0;
1284 ALlistEntry
* entry
= 0;
1287 // Not all of the contexts using the device have been destroyed.
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
1296 alListAcquireLock(alContextList
);
1297 entry
= alListIteratorReset(alContextList
);
1300 context
= (ALCcontext
*)alListGetData(entry
);
1301 if(context
->Device
== device
)
1303 alListReleaseLock(alContextList
);
1304 alcDestroyContext((ALCcontext
*)context
);
1305 alListAcquireLock(alContextList
);
1306 entry
= alListIteratorReset(alContextList
);
1311 entry
= alListIteratorNext(alContextList
);
1315 alListReleaseLock(alContextList
);
1316 assert(!device
->InUse
);
1319 device
->AlcApi
.alcCloseDevice(device
->DllDevice
);
1320 FreeLibrary(device
->Dll
);
1329 //*****************************************************************************
1331 //*****************************************************************************
1332 ALCAPI ALCcontext
* ALCAPIENTRY
alcCreateContext(ALCdevice
* device
, const ALint
* attrList
)
1335 LOG("alcCreateContext device %p ", device
);
1338 unsigned long ulIndex
= 0;
1339 while ((ulIndex
< 16) && (attrList
[ulIndex
]))
1341 switch(attrList
[ulIndex
])
1344 LOG("ALC_FREQUENCY %d ", attrList
[ulIndex
+ 1]);
1348 LOG("ALC_REFRESH %d ", attrList
[ulIndex
+ 1]);
1352 LOG("ALC_SYNC %d ", attrList
[ulIndex
+ 1]);
1355 case ALC_MONO_SOURCES
:
1356 LOG("ALC_MONO_SOURCES %d ", attrList
[ulIndex
+ 1]);
1359 case ALC_STEREO_SOURCES
:
1360 LOG("ALC_STEREO_SOURCES %d ", attrList
[ulIndex
+ 1]);
1363 case 0x20003/*ALC_MAX_AUXILIARY_SENDS*/:
1364 LOG("ALC_MAX_AUXILIARY_SENDS %d", attrList
[ulIndex
+ 1]);
1373 ALCcontext
* context
= 0;
1377 LastError
= ALC_INVALID_DEVICE
;
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
));
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
);
1415 // Add it to the context list.
1417 alListInitializeEntry(&context
->ListEntry
, context
);
1418 alListAcquireLock(alContextList
);
1419 alListAddEntry(alContextList
, &context
->ListEntry
);
1420 alListReleaseLock(alContextList
);
1427 //*****************************************************************************
1428 // alcDestroyContext
1429 //*****************************************************************************
1430 ALCAPI ALvoid ALCAPIENTRY
alcDestroyContext(ALCcontext
* context
)
1433 LOG("alcDestroyContext context %p\n", context
);
1435 ALCcontext
* listData
= 0;
1443 // Remove the entry from the context list.
1445 alListAcquireLock(alContextList
);
1446 listData
= (ALCcontext
*)alListRemoveEntry(alContextList
, &context
->ListEntry
);
1449 alListReleaseLock(alContextList
);
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
);
1477 //*****************************************************************************
1478 // alcGetContextsDevice
1479 //*****************************************************************************
1480 ALCAPI ALCdevice
* ALCAPIENTRY
alcGetContextsDevice(ALCcontext
* context
)
1483 LOG("alcGetContextsDevice context %p\n", context
);
1485 ALCdevice
* ALCdevice
= 0;
1487 alListAcquireLock(alContextList
);
1488 if(alListMatchData(alContextList
, context
))
1490 ALCdevice
= context
->Device
;
1493 alListReleaseLock(alContextList
);
1501 //*****************************************************************************
1502 // alcGetCurrentContext
1503 //*****************************************************************************
1504 ALCAPI ALCcontext
* ALCAPIENTRY
alcGetCurrentContext(ALvoid
)
1507 LOG("alcGetCurrentContext\n");
1509 return (ALCcontext
*)alCurrentContext
;
1515 //*****************************************************************************
1517 //*****************************************************************************
1518 ALCAPI ALenum ALCAPIENTRY
alcGetEnumValue(ALCdevice
* device
, const ALCchar
* ename
)
1521 LOG("alcGetEnumValue device %p enum name '%s'\n", device
, ename
? ename
: "<NULL>");
1524 // Always return the router version of the ALC enum if it exists.
1527 while(alcEnums
[i
].ename
&& strcmp((char*)alcEnums
[i
].ename
, (char*)ename
))
1532 if(alcEnums
[i
].ename
)
1534 return alcEnums
[i
].value
;
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
;
1552 //*****************************************************************************
1554 //*****************************************************************************
1555 ALCAPI ALenum ALCAPIENTRY
alcGetError(ALCdevice
* device
)
1558 LOG("alcGetError device %p\n", device
);
1560 ALenum errorCode
= ALC_NO_ERROR
;
1562 // Try to get a valid device.
1565 if (g_CaptureDevice
== device
)
1567 errorCode
= LastError
;
1568 LastError
= ALC_NO_ERROR
;
1573 // Check if its a 3rd party device.
1575 if (device
== g_CaptureDevice
)
1576 errorCode
= g_CaptureDevice
->AlcApi
.alcGetError(g_CaptureDevice
->CaptureDevice
);
1578 errorCode
= device
->AlcApi
.alcGetError(device
->DllDevice
);
1586 //*****************************************************************************
1588 //*****************************************************************************
1589 ALCAPI ALvoid ALCAPIENTRY
alcGetIntegerv(ALCdevice
* device
, ALenum param
, ALsizei size
, ALint
* data
)
1592 LOG("alcGetIntegerv device %p enum ", device
);
1595 case ALC_ATTRIBUTES_SIZE
:
1596 LOG("ALC_ATTRIBUTES_SIZE\n");
1598 case ALC_ALL_ATTRIBUTES
:
1599 LOG("ALC_ALL_ATTRIBUTES\n");
1601 case ALC_MAJOR_VERSION
:
1602 LOG("ALC_MAJOR_VERSION\n");
1604 case ALC_MINOR_VERSION
:
1605 LOG("ALC_MINOR_VERSION\n");
1607 case ALC_CAPTURE_SAMPLES
:
1608 LOG("ALC_CAPTURE_SAMPLES\n");
1611 LOG("ALC_FREQUENCY\n");
1614 LOG("ALC_REFRESH\n");
1619 case ALC_MONO_SOURCES
:
1620 LOG("ALC_MONO_SOURCES\n");
1622 case ALC_STEREO_SOURCES
:
1623 LOG("ALC_STEREO_SOURCES\n");
1625 case 0x20003: // ALC_MAX_AUXILIARY_SENDS
1626 LOG("ALC_MAX_AUXILIARY_SENDS\n");
1628 case 0x20001: // ALC_EFX_MAJOR_VERSION
1629 LOG("ALC_EFX_MAJOR_VERSION\n");
1631 case 0x20002: // ALC_EFX_MINOR_VERSION
1632 LOG("ALC_EFX_MINOR_VERSION\n");
1642 if (device
== g_CaptureDevice
)
1644 g_CaptureDevice
->AlcApi
.alcGetIntegerv(g_CaptureDevice
->CaptureDevice
, param
, size
, data
);
1648 device
->AlcApi
.alcGetIntegerv(device
->DllDevice
, param
, size
, data
);
1654 case ALC_MAJOR_VERSION
:
1656 if((size
< sizeof(ALint
)) || (data
== 0))
1658 LastError
= ALC_INVALID
;
1662 *data
= alcMajorVersion
;
1666 case ALC_MINOR_VERSION
:
1668 if((size
< sizeof(ALint
)) || (data
== 0))
1670 LastError
= ALC_INVALID
;
1674 *data
= alcMinorVersion
;
1680 device
->LastError
= ALC_INVALID_ENUM
;
1689 //*****************************************************************************
1690 // alcGetProcAddress
1691 //*****************************************************************************
1692 ALCAPI ALvoid
* ALCAPIENTRY
alcGetProcAddress(ALCdevice
* device
, const ALCchar
* fname
)
1695 LOG("alcGetProcAddress device %p function name '%s'\n", device
, fname
? fname
: "<NULL>");
1699 // Always return the router version of the ALC function if it exists.
1702 while(alcFunctions
[i
].fname
&& strcmp((char*)alcFunctions
[i
].fname
, (char*)fname
))
1707 if(alcFunctions
[i
].fname
)
1709 return alcFunctions
[i
].address
;
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
;
1727 //*****************************************************************************
1728 // alcIsExtensionPresent
1729 //*****************************************************************************
1730 ALCAPI ALboolean ALCAPIENTRY
alcIsExtensionPresent(ALCdevice
* device
, const ALCchar
* ename
)
1733 LOG("alcIsExtensionPresent device %p extension name '%s'\n", device
, ename
? ename
: "<NULL>");
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.
1740 while(alcExtensions
[i
].ename
&& _stricmp((char*)alcExtensions
[i
].ename
, (char*)ename
))
1745 if(alcExtensions
[i
].ename
)
1751 // Check the device passed in to see if the extension is supported.
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
;
1768 //*****************************************************************************
1769 // alcMakeContextCurrent
1770 //*****************************************************************************
1771 ALCAPI ALboolean ALCAPIENTRY
alcMakeContextCurrent(ALCcontext
* context
)
1774 LOG("alcMakeContextCurrent context %p\n", context
);
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
);
1789 // Try the new 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
);
1819 alCurrentContext
->Device
->AlcApi
.alcMakeContextCurrent(0);
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.
1834 alCurrentContext
= context
;
1837 alListReleaseLock(alContextList
);
1838 return contextSwitched
;
1844 //*****************************************************************************
1846 //*****************************************************************************
1847 ALCAPI ALCdevice
* ALCAPIENTRY
alcOpenDevice(const ALCchar
* deviceName
)
1850 LOG("alcOpenDevice device name '%s'\n", deviceName
? deviceName
: "<NULL>");
1853 ALCdevice
* device
= 0;
1854 const ALchar
*pszDeviceName
= NULL
;
1860 if ((!deviceName
) || (strlen(deviceName
)==0) || (strcmp(deviceName
, "DirectSound3D")==0))
1861 pszDeviceName
= pszDefaultDeviceSpecifier
;
1863 pszDeviceName
= deviceName
;
1865 // Search for device in Playback Device List
1866 dll
= LoadDevicesDLL(g_pDeviceList
, pszDeviceName
);
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");
1884 dll
= LoadDevicesDLL(g_pAllDevicesList
, pszDeviceName
);
1888 device
= (ALCdevice
*)malloc(sizeof(ALCdevice
));
1891 memset(device
, 0, sizeof(ALCdevice
));
1892 device
->LastError
= ALC_NO_ERROR
;
1895 if (FillOutAlcFunctions(device
))
1896 device
->DllDevice
= device
->AlcApi
.alcOpenDevice(pszDeviceName
);
1898 if (!device
->DllDevice
)
1909 LastError
= ALC_INVALID_DEVICE
;
1917 //*****************************************************************************
1918 // alcProcessContext
1919 //*****************************************************************************
1920 ALCAPI ALvoid ALCAPIENTRY
alcProcessContext(ALCcontext
* context
)
1923 LOG("alcProcessContext context %p\n", context
);
1925 alListAcquireLock(alContextList
);
1926 if(!context
&& !alCurrentContext
)
1928 alListReleaseLock(alContextList
);
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
);
1954 //*****************************************************************************
1955 // alcSuspendContext
1956 //*****************************************************************************
1957 ALCAPI ALCvoid ALCAPIENTRY
alcSuspendContext(ALCcontext
* context
)
1960 LOG("alcSuspendContext context %p\n", context
);
1962 alListAcquireLock(alContextList
);
1963 if(!context
&& !alCurrentContext
)
1965 alListReleaseLock(alContextList
);
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
);
1991 //*****************************************************************************
1993 //*****************************************************************************
1994 ALCAPI
const ALCchar
* ALCAPIENTRY
alcGetString(ALCdevice
* device
, ALenum param
)
1997 LOG("alcGetString device %p enum ", device
);
2001 LOG("ALC_NO_ERROR\n");
2003 case ALC_INVALID_ENUM
:
2004 LOG("ALC_INVALID_ENUM\n");
2006 case ALC_INVALID_VALUE
:
2007 LOG("ALC_INVALID_VALUE\n");
2009 case ALC_INVALID_DEVICE
:
2010 LOG("ALC_INVALID_DEVICE\n");
2012 case ALC_INVALID_CONTEXT
:
2013 LOG("ALC_INVALID_CONTEXT\n");
2015 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2016 LOG("ALC_DEFAULT_DEVICE_SPECIFIER\n");
2018 case ALC_DEVICE_SPECIFIER
:
2019 LOG("ALC_DEVICE_SPECIFIER\n");
2021 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2022 LOG("ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER\n");
2024 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2025 LOG("ALC_CAPTURE_DEVICE_SPECIFIER\n");
2027 case ALC_ALL_DEVICES_SPECIFIER
:
2028 LOG("ALC_ALL_DEVICES_SPECIFIER\n");
2030 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2031 LOG("ALC_DEFAULT_ALL_DEVICES_SPECIFIER\n");
2033 case ALC_EXTENSIONS
:
2034 LOG("ALC_EXTENSIONS\n");
2042 const ALCchar
* value
= 0;
2044 if ((param
!= ALC_DEFAULT_DEVICE_SPECIFIER
) && (param
!= ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
)) {
2047 if (device
== g_CaptureDevice
)
2048 return g_CaptureDevice
->AlcApi
.alcGetString(g_CaptureDevice
->CaptureDevice
, param
);
2050 return device
->AlcApi
.alcGetString(device
->DllDevice
, param
);
2062 case ALC_INVALID_ENUM
:
2064 value
= alcErrInvalidEnum
;
2068 case ALC_INVALID_VALUE
:
2070 value
= alcErrInvalidValue
;
2074 case ALC_INVALID_DEVICE
:
2076 value
= alcErrInvalidDevice
;
2080 case ALC_INVALID_CONTEXT
:
2082 value
= alcErrInvalidContext
;
2086 case ALC_DEFAULT_DEVICE_SPECIFIER
:
2088 if (pszDefaultDeviceSpecifier
)
2089 value
= pszDefaultDeviceSpecifier
;
2091 value
= szEmptyString
;
2094 case ALC_DEVICE_SPECIFIER
:
2096 if (pszDeviceSpecifierList
)
2097 value
= pszDeviceSpecifierList
;
2099 value
= szEmptyString
;
2102 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
2104 if (pszDefaultCaptureDeviceSpecifier
)
2105 value
= pszDefaultCaptureDeviceSpecifier
;
2107 value
= szEmptyString
;
2110 case ALC_CAPTURE_DEVICE_SPECIFIER
:
2112 if (pszCaptureDeviceSpecifierList
)
2113 value
= pszCaptureDeviceSpecifierList
;
2115 value
= szEmptyString
;
2118 case ALC_ALL_DEVICES_SPECIFIER
:
2120 if (pszAllDevicesSpecifierList
)
2121 value
= pszAllDevicesSpecifierList
;
2123 value
= szEmptyString
;
2126 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
2128 if (pszDefaultAllDevicesSpecifier
)
2129 value
= pszDefaultAllDevicesSpecifier
;
2131 value
= szEmptyString
;
2135 LastError
= ALC_INVALID_ENUM
;
2145 //*****************************************************************************
2146 // alcCaptureOpenDevice
2147 //*****************************************************************************
2148 ALCAPI ALCdevice
* ALCAPIENTRY
alcCaptureOpenDevice(const ALCchar
*deviceName
, ALCuint frequency
, ALCenum format
, ALCsizei buffersize
)
2151 LOG("alcCaptureOpenDevice device name '%s' frequency %d format %d buffersize %d\n", deviceName
? deviceName
: "<NULL>", frequency
, format
, buffersize
);
2153 const ALchar
*pszDeviceName
= NULL
;
2157 if (!g_pCaptureDeviceList
)
2160 if (!g_CaptureDevice
) {
2161 g_CaptureDevice
= (ALCdevice
*)malloc(sizeof(ALCdevice
));
2163 if (g_CaptureDevice
)
2166 memset(g_CaptureDevice
, 0, sizeof(ALCdevice
));
2168 // make sure we have a device name
2169 if ((!deviceName
) || (strlen(deviceName
) == 0))
2170 pszDeviceName
= pszDefaultCaptureDeviceSpecifier
;
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;
2183 g_CaptureDevice
->LastError
= ALC_INVALID_DEVICE
;
2190 g_CaptureDevice
->LastError
= ALC_INVALID_VALUE
;
2193 if (g_CaptureDevice
!= NULL
) {
2194 if (g_CaptureDevice
->CaptureDevice
) {
2195 return g_CaptureDevice
;
2197 free(g_CaptureDevice
);
2198 g_CaptureDevice
= NULL
;
2209 //*****************************************************************************
2210 // alcCaptureCloseDevice
2211 //*****************************************************************************
2212 ALCAPI ALCboolean ALCAPIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
2215 LOG("alcCaptureCloseDevice device %p\n", device
);
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
;
2227 g_CaptureDevice
->LastError
= ALC_INVALID_DEVICE
;
2238 //*****************************************************************************
2240 //*****************************************************************************
2241 ALCAPI ALCvoid ALCAPIENTRY
alcCaptureStart(ALCdevice
*device
)
2244 LOG("alcCaptureStart device %p\n", device
);
2246 if (device
== g_CaptureDevice
)
2248 if (g_CaptureDevice
!= NULL
) {
2249 if (g_CaptureDevice
->AlcApi
.alcCaptureStart
) {
2250 g_CaptureDevice
->AlcApi
.alcCaptureStart(g_CaptureDevice
->CaptureDevice
);
2252 g_CaptureDevice
->LastError
= ALC_INVALID_DEVICE
;
2263 //*****************************************************************************
2265 //*****************************************************************************
2266 ALCAPI ALCvoid ALCAPIENTRY
alcCaptureStop(ALCdevice
*device
)
2269 LOG("alcCaptureStop device %p\n", device
);
2271 if (device
== g_CaptureDevice
)
2273 if (g_CaptureDevice
!= NULL
) {
2274 if (g_CaptureDevice
->AlcApi
.alcCaptureStop
) {
2275 g_CaptureDevice
->AlcApi
.alcCaptureStop(g_CaptureDevice
->CaptureDevice
);
2277 g_CaptureDevice
->LastError
= ALC_INVALID_DEVICE
;
2288 //*****************************************************************************
2289 // alcCaptureSamples
2290 //*****************************************************************************
2291 ALCAPI ALCvoid ALCAPIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
2294 LOG("alcCaptureSamples device %p buffer %p samples %d\n", device
, buffer
, samples
);
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
);
2302 g_CaptureDevice
->LastError
= ALC_INVALID_DEVICE
;
2311 void OutputMessage(const char *szDebug
,...)
2313 static FILE *pFile
= NULL
;
2317 va_start(args
, szDebug
);
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
);