diff options
author | Chris Robinson <[email protected]> | 2007-11-13 18:02:18 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2007-11-13 18:02:18 -0800 |
commit | ae5f4e9a742b07e004b330c04a72fac4457c9b58 (patch) | |
tree | d1d5c9fadd918d9346fb871033f60e8c91600a63 /Router |
Initial import
Diffstat (limited to 'Router')
-rw-r--r-- | Router/OpenAL32.cpp | 135 | ||||
-rw-r--r-- | Router/OpenAL32.h | 341 | ||||
-rw-r--r-- | Router/OpenAL32.rc | 101 | ||||
-rw-r--r-- | Router/al.cpp | 981 | ||||
-rw-r--r-- | Router/alList.cpp | 1029 | ||||
-rw-r--r-- | Router/alList.h | 433 | ||||
-rw-r--r-- | Router/alc.cpp | 2332 | ||||
-rw-r--r-- | Router/resource.h | 15 |
8 files changed, 5367 insertions, 0 deletions
diff --git a/Router/OpenAL32.cpp b/Router/OpenAL32.cpp new file mode 100644 index 00000000..8c84148b --- /dev/null +++ b/Router/OpenAL32.cpp @@ -0,0 +1,135 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + + + +#include <windows.h> +#include "OpenAL32.h" + + +void CleanDeviceEnumeration(); +void CleanDeviceList(ALDEVICE *pDeviceList); + +//***************************************************************************** +// DllMain +//***************************************************************************** +// +BOOL APIENTRY DllMain(HANDLE module, DWORD reason, LPVOID reserved) +{ + BOOL result = TRUE; + + // Perform actions based on the reason for calling. + switch(reason) + { + case DLL_PROCESS_ATTACH: + // Create the context list lock so I can safely add/remove contexts. + result = alListCreate(&alContextList); + break; + + case DLL_THREAD_ATTACH: + // Do thread-specific initialization. + break; + + case DLL_THREAD_DETACH: + // Do thread-specific cleanup. + break; + + case DLL_PROCESS_DETACH: + // Perform any necessary cleanup. + CleanDeviceEnumeration(); + alListFree(alContextList); + alContextList = 0; + break; + } + + return TRUE; +} + + +void CleanDeviceEnumeration() +{ + if (pszDefaultDeviceSpecifier) + { + free(pszDefaultDeviceSpecifier); + pszDefaultDeviceSpecifier = NULL; + } + + if (pszDeviceSpecifierList) + { + free(pszDeviceSpecifierList); + pszDeviceSpecifierList = NULL; + } + + if (pszDefaultCaptureDeviceSpecifier) + { + free(pszDefaultCaptureDeviceSpecifier); + pszDefaultCaptureDeviceSpecifier = NULL; + } + + if (pszCaptureDeviceSpecifierList) + { + free(pszCaptureDeviceSpecifierList); + pszCaptureDeviceSpecifierList = NULL; + } + + if (pszDefaultAllDevicesSpecifier) + { + free(pszDefaultAllDevicesSpecifier); + pszDefaultAllDevicesSpecifier = NULL; + } + + if (pszAllDevicesSpecifierList) + { + free(pszAllDevicesSpecifierList); + pszAllDevicesSpecifierList = NULL; + } + + CleanDeviceList(g_pDeviceList); + g_pDeviceList = NULL; + + CleanDeviceList(g_pCaptureDeviceList); + g_pCaptureDeviceList = NULL; + + CleanDeviceList(g_pAllDevicesList); + g_pAllDevicesList = NULL; +} + +void CleanDeviceList(ALDEVICE *pDeviceList) +{ + ALDEVICE *pDevice, *pNextDevice; + + pDevice = pDeviceList; + + while (pDevice) + { + pNextDevice = pDevice->pNextDevice; + + if (pDevice->pszHostDLLFilename) + free(pDevice->pszHostDLLFilename); + + if (pDevice->pszDeviceName) + free(pDevice->pszDeviceName); + + free(pDevice); + + pDevice = pNextDevice; + } +}
\ No newline at end of file diff --git a/Router/OpenAL32.h b/Router/OpenAL32.h new file mode 100644 index 00000000..a291a5a8 --- /dev/null +++ b/Router/OpenAL32.h @@ -0,0 +1,341 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + + + +#ifndef _OPENAL32_H_ +#define _OPENAL32_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AL_BUILD_LIBRARY + +#include "al\al.h" + +// ALAPI +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_ENABLE)(ALenum capability); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DISABLE)(ALenum capability); +typedef ALAPI ALboolean (ALAPIENTRY *ALAPI_IS_ENABLED)(ALenum capability); + +typedef ALAPI const ALchar* (ALAPIENTRY *ALAPI_GET_STRING)(ALenum param); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BOOLEANV)(ALenum param, ALboolean* data); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_INTEGERV)(ALenum param, ALint* data); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_FLOATV)(ALenum param, ALfloat* data); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_DOUBLEV)(ALenum param, ALdouble* data); +typedef ALAPI ALboolean (ALAPIENTRY *ALAPI_GET_BOOLEAN)(ALenum param); +typedef ALAPI ALint (ALAPIENTRY *ALAPI_GET_INTEGER)(ALenum param); +typedef ALAPI ALfloat (ALAPIENTRY *ALAPI_GET_FLOAT)(ALenum param); +typedef ALAPI ALdouble (ALAPIENTRY *ALAPI_GET_DOUBLE)(ALenum param); + +typedef ALAPI ALenum (ALAPIENTRY *ALAPI_GET_ERROR)(ALvoid); + +typedef ALAPI ALboolean (ALAPIENTRY *ALAPI_IS_EXTENSION_PRESENT)(const ALchar* ename); +typedef ALAPI ALvoid* (ALAPIENTRY *ALAPI_GET_PROC_ADDRESS)(const ALchar* fname); +typedef ALAPI ALenum (ALAPIENTRY *ALAPI_GET_ENUM_VALUE)(const ALchar* ename); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENERF)(ALenum param, ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENER3F)(ALenum param, ALfloat v1, ALfloat v2, ALfloat v3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENERFV)(ALenum param, const ALfloat* values); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENERI)(ALenum param, ALint value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_LISTENERIV)( ALenum param, const ALint* values ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENERF)(ALenum param, ALfloat* value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENER3F)(ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENERFV)(ALenum param, ALfloat* values); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENERI)(ALenum param, ALint* value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_LISTENERIV)( ALenum param, ALint* values ); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GEN_SOURCES)(ALsizei n, ALuint* sourceNames); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DELETE_SOURCES)(ALsizei n, const ALuint* sourceNames); +typedef ALAPI ALboolean (ALAPIENTRY *ALAPI_IS_SOURCE)(ALuint id); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCEF)(ALuint sourceName, ALenum param, ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE3F)(ALuint sourceName, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCEFV)(ALuint sourceName, ALenum param, const ALfloat* values); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCEI)(ALuint sourceName, ALenum param, ALint value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCEIV)( ALuint sid, ALenum param, const ALint* values ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCEF)(ALuint sourceName, ALenum param, ALfloat* value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCE3F)(ALuint sourceName, ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCEFV)(ALuint sourceName, ALenum param, const ALfloat* values); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCEI)(ALuint sourceName, ALenum param, ALint* value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_SOURCEIV)( ALuint sid, ALenum param, ALint* values ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_PLAYV)(ALsizei n, const ALuint* sources); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_STOPV)(ALsizei n, const ALuint* sources); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_REWINDV)(ALsizei n, const ALuint* sources); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_PAUSEV)(ALsizei n, const ALuint* sources); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_PLAY)(ALuint sourceName); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_STOP)(ALuint sourceName); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_REWIND)(ALuint sourceName); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_PAUSE)(ALuint sourceName); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_QUEUE_BUFFERS)(ALuint sourceName, ALsizei n, const ALuint* bufferNames); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SOURCE_UNQUEUE_BUFFERS)(ALuint sourceName, ALsizei n, ALuint* bufferNames); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GEN_BUFFERS)(ALsizei n, ALuint* bufferNames); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DELETE_BUFFERS)(ALsizei n, const ALuint* bufferNames); +typedef ALAPI ALboolean (ALAPIENTRY *ALAPI_IS_BUFFER)(ALuint bufferName); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFER_DATA)(ALuint bufferName, ALenum format, const ALvoid* data, ALsizei size, ALuint freq); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFERF)( ALuint bid, ALenum param, ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFERFV)( ALuint bid, ALenum param, const ALfloat* values ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFERI)( ALuint bid, ALenum param, ALint value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_BUFFERIV)( ALuint bid, ALenum param, const ALint* values ); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFERF)( ALuint bid, ALenum param, ALfloat* value ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFERFV)( ALuint bid, ALenum param, ALfloat* values ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFERI)( ALuint bid, ALenum param, ALint* value ); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_GET_BUFFERIV)( ALuint bid, ALenum param, ALint* values ); + +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DOPPLER_FACTOR)(ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DOPPLER_VELOCITY)(ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_SPEED_OF_SOUND)(ALfloat value); +typedef ALAPI ALvoid (ALAPIENTRY *ALAPI_DISTANCE_MODEL)(ALenum value); + +typedef struct ALAPI_FXN_TABLE_STRUCT +{ + ALAPI_ENABLE alEnable; + ALAPI_DISABLE alDisable; + ALAPI_IS_ENABLED alIsEnabled; + + ALAPI_GET_STRING alGetString; + ALAPI_GET_BOOLEANV alGetBooleanv; + ALAPI_GET_INTEGERV alGetIntegerv; + ALAPI_GET_FLOATV alGetFloatv; + ALAPI_GET_DOUBLEV alGetDoublev; + ALAPI_GET_BOOLEAN alGetBoolean; + ALAPI_GET_INTEGER alGetInteger; + ALAPI_GET_FLOAT alGetFloat; + ALAPI_GET_DOUBLE alGetDouble; + + ALAPI_GET_ERROR alGetError; + + ALAPI_IS_EXTENSION_PRESENT alIsExtensionPresent; + ALAPI_GET_PROC_ADDRESS alGetProcAddress; + ALAPI_GET_ENUM_VALUE alGetEnumValue; + + ALAPI_LISTENERF alListenerf; + ALAPI_LISTENER3F alListener3f; + ALAPI_LISTENERFV alListenerfv; + ALAPI_LISTENERI alListeneri; + ALAPI_LISTENER3I alListener3i; + ALAPI_LISTENERIV alListeneriv; + + ALAPI_GET_LISTENERF alGetListenerf; + ALAPI_GET_LISTENER3F alGetListener3f; + ALAPI_GET_LISTENERFV alGetListenerfv; + ALAPI_GET_LISTENERI alGetListeneri; + ALAPI_GET_LISTENER3I alGetListener3i; + ALAPI_GET_LISTENERIV alGetListeneriv; + + ALAPI_GEN_SOURCES alGenSources; + ALAPI_DELETE_SOURCES alDeleteSources; + ALAPI_IS_SOURCE alIsSource; + ALAPI_SOURCEF alSourcef; + ALAPI_SOURCE3F alSource3f; + ALAPI_SOURCEFV alSourcefv; + ALAPI_SOURCEI alSourcei; + ALAPI_SOURCE3I alSource3i; + ALAPI_SOURCEIV alSourceiv; + ALAPI_GET_SOURCEF alGetSourcef; + ALAPI_GET_SOURCE3F alGetSource3f; + ALAPI_GET_SOURCEFV alGetSourcefv; + ALAPI_GET_SOURCEI alGetSourcei; + ALAPI_GET_SOURCE3I alGetSource3i; + ALAPI_GET_SOURCEIV alGetSourceiv; + ALAPI_SOURCE_PLAYV alSourcePlayv; + ALAPI_SOURCE_STOPV alSourceStopv; + ALAPI_SOURCE_REWINDV alSourceRewindv; + ALAPI_SOURCE_PAUSEV alSourcePausev; + ALAPI_SOURCE_PLAY alSourcePlay; + ALAPI_SOURCE_STOP alSourceStop; + ALAPI_SOURCE_REWIND alSourceRewind; + ALAPI_SOURCE_PAUSE alSourcePause; + + ALAPI_SOURCE_QUEUE_BUFFERS alSourceQueueBuffers; + ALAPI_SOURCE_UNQUEUE_BUFFERS alSourceUnqueueBuffers; + + ALAPI_GEN_BUFFERS alGenBuffers; + ALAPI_DELETE_BUFFERS alDeleteBuffers; + ALAPI_IS_BUFFER alIsBuffer; + ALAPI_BUFFER_DATA alBufferData; + ALAPI_BUFFERF alBufferf; + ALAPI_BUFFER3F alBuffer3f; + ALAPI_BUFFERFV alBufferfv; + ALAPI_BUFFERI alBufferi; + ALAPI_BUFFER3I alBuffer3i; + ALAPI_BUFFERIV alBufferiv; + ALAPI_GET_BUFFERF alGetBufferf; + ALAPI_GET_BUFFER3F alGetBuffer3f; + ALAPI_GET_BUFFERFV alGetBufferfv; + ALAPI_GET_BUFFERI alGetBufferi; + ALAPI_GET_BUFFER3I alGetBuffer3i; + ALAPI_GET_BUFFERIV alGetBufferiv; + + ALAPI_DOPPLER_FACTOR alDopplerFactor; + ALAPI_DOPPLER_VELOCITY alDopplerVelocity; + ALAPI_SPEED_OF_SOUND alSpeedOfSound; + ALAPI_DISTANCE_MODEL alDistanceModel; + +} ALAPI_FXN_TABLE; + +#include "al\alc.h" + +// ALCAPI +typedef struct ALCdevice_struct ALCdevice; +typedef struct ALCcontext_struct ALCcontext; + +typedef ALCAPI ALCcontext* (ALCAPIENTRY *ALCAPI_CREATE_CONTEXT)(ALCdevice* device, const ALint* attrList); +typedef ALCAPI ALboolean (ALCAPIENTRY *ALCAPI_MAKE_CONTEXT_CURRENT)(ALCcontext* context); +typedef ALCAPI ALvoid (ALCAPIENTRY *ALCAPI_PROCESS_CONTEXT)(ALCcontext* context); +typedef ALCAPI ALCvoid (ALCAPIENTRY *ALCAPI_SUSPEND_CONTEXT)(ALCcontext* context); +typedef ALCAPI ALvoid (ALCAPIENTRY *ALCAPI_DESTROY_CONTEXT)(ALCcontext* context); +typedef ALCAPI ALCcontext* (ALCAPIENTRY *ALCAPI_GET_CURRENT_CONTEXT)(ALvoid); +typedef ALCAPI ALCdevice* (ALCAPIENTRY *ALCAPI_GET_CONTEXTS_DEVICE)(ALCcontext* context); + +typedef ALCAPI ALCdevice* (ALCAPIENTRY *ALCAPI_OPEN_DEVICE)(const ALCchar* deviceName); +typedef ALCAPI ALCboolean (ALCAPIENTRY *ALCAPI_CLOSE_DEVICE)(ALCdevice* device); + +typedef ALCAPI ALenum (ALCAPIENTRY *ALCAPI_GET_ERROR)(ALCdevice* device); + +typedef ALCAPI ALboolean (ALCAPIENTRY *ALCAPI_IS_EXTENSION_PRESENT)(ALCdevice* device, const ALCchar* eName); +typedef ALCAPI ALvoid* (ALCAPIENTRY *ALCAPI_GET_PROC_ADDRESS)(ALCdevice* device, const ALCchar* fName); +typedef ALCAPI ALenum (ALCAPIENTRY *ALCAPI_GET_ENUM_VALUE)(ALCdevice* device, const ALCchar* eName); + +typedef ALCAPI const ALCchar* (ALCAPIENTRY *ALCAPI_GET_STRING)(ALCdevice* device, ALenum param); +typedef ALCAPI ALvoid (ALCAPIENTRY *ALCAPI_GET_INTEGERV)(ALCdevice* device, ALenum param, ALsizei size, ALint* data); + +typedef ALCAPI ALCdevice * (ALCAPIENTRY *ALCAPI_CAPTURE_OPEN_DEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); +typedef ALCAPI ALCboolean (ALCAPIENTRY *ALCAPI_CAPTURE_CLOSE_DEVICE)( ALCdevice *device ); +typedef ALCAPI void (ALCAPIENTRY *ALCAPI_CAPTURE_START)( ALCdevice *device ); +typedef ALCAPI void (ALCAPIENTRY *ALCAPI_CAPTURE_STOP)( ALCdevice *device ); +typedef ALCAPI void (ALCAPIENTRY *ALCAPI_CAPTURE_SAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); + +typedef struct ALCAPI_FXN_TABLE_STRUCT +{ + ALCAPI_CREATE_CONTEXT alcCreateContext; + ALCAPI_MAKE_CONTEXT_CURRENT alcMakeContextCurrent; + ALCAPI_PROCESS_CONTEXT alcProcessContext; + ALCAPI_SUSPEND_CONTEXT alcSuspendContext; + ALCAPI_DESTROY_CONTEXT alcDestroyContext; + ALCAPI_GET_CURRENT_CONTEXT alcGetCurrentContext; + ALCAPI_GET_CONTEXTS_DEVICE alcGetContextsDevice; + + ALCAPI_OPEN_DEVICE alcOpenDevice; + ALCAPI_CLOSE_DEVICE alcCloseDevice; + + ALCAPI_GET_ERROR alcGetError; + + ALCAPI_IS_EXTENSION_PRESENT alcIsExtensionPresent; + ALCAPI_GET_PROC_ADDRESS alcGetProcAddress; + ALCAPI_GET_ENUM_VALUE alcGetEnumValue; + + ALCAPI_GET_STRING alcGetString; + ALCAPI_GET_INTEGERV alcGetIntegerv; + + ALCAPI_CAPTURE_OPEN_DEVICE alcCaptureOpenDevice; + ALCAPI_CAPTURE_CLOSE_DEVICE alcCaptureCloseDevice; + ALCAPI_CAPTURE_START alcCaptureStart; + ALCAPI_CAPTURE_STOP alcCaptureStop; + ALCAPI_CAPTURE_SAMPLES alcCaptureSamples; + +} ALCAPI_FXN_TABLE; + +#include "windows.h" +#include "alList.h" + + +//***************************************************************************** +// Additional Defines +//***************************************************************************** + +typedef struct ALCdevice_struct +{ + // + // These variables must always be initialized. + // + ALenum LastError; + ALint InUse; + + // + // Support for 3rd party OpenAL implementations. + // + HINSTANCE Dll; + ALCAPI_FXN_TABLE AlcApi; + + // Capture Device + ALCdevice* CaptureDevice; + + struct ALCdevice_struct* DllDevice; + +} ALCdevice; + +typedef struct ALCcontext_struct +{ + // + // These variables are always initialized. + // + ALlistEntry ListEntry; + ALboolean Suspended; + ALenum LastError; + ALCdevice* Device; + ALAPI_FXN_TABLE AlApi; + CRITICAL_SECTION Lock; + struct ALCcontext_struct* DllContext; + +} ALCcontext; + + +extern ALlist* alContextList; +extern ALCcontext* alCurrentContext; + +// Device Enumeration structures, strings and variables +typedef struct _ALDEVICE +{ + ALchar *pszDeviceName; + TCHAR *pszHostDLLFilename; + struct _ALDEVICE *pNextDevice; +} ALDEVICE; + +extern ALchar *pszDefaultDeviceSpecifier; +extern ALchar *pszDeviceSpecifierList; +extern ALchar *pszDefaultCaptureDeviceSpecifier; +extern ALchar *pszCaptureDeviceSpecifierList; +extern ALchar *pszDefaultAllDevicesSpecifier; +extern ALchar *pszAllDevicesSpecifierList; + +extern ALDEVICE *g_pDeviceList; +extern ALDEVICE *g_pCaptureDeviceList; +extern ALDEVICE *g_pAllDevicesList; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Router/OpenAL32.rc b/Router/OpenAL32.rc new file mode 100644 index 00000000..5ddbb5b9 --- /dev/null +++ b/Router/OpenAL32.rc @@ -0,0 +1,101 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 6,14,357,23 + PRODUCTVERSION 6,14,357,23 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Portions (C) Creative Labs Inc. and NVIDIA Corp." + VALUE "FileDescription", "Standard OpenAL(TM) Implementation" + VALUE "FileVersion", "6.14.0357.23" + VALUE "LegalCopyright", "Copyright (C) 2000-2006" + VALUE "OriginalFilename", "OpenAL32.dll" + VALUE "ProductName", "Standard OpenAL(TM) Library" + VALUE "ProductVersion", "6.14.0357.23" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Router/al.cpp b/Router/al.cpp new file mode 100644 index 00000000..81e11461 --- /dev/null +++ b/Router/al.cpp @@ -0,0 +1,981 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2003 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + + + +#include <al\alc.h> +#include "OpenAL32.h" + +typedef struct ALfunction_struct +{ + ALchar *funcName; + ALvoid *address; +} ALfunction; + +static ALfunction function[]= { + { "alEnable", (ALvoid *) alEnable }, + { "alDisable", (ALvoid *) alDisable }, + { "alIsEnabled", (ALvoid *) alIsEnabled }, + { "alGetString", (ALvoid *) alGetString }, + { "alGetBooleanv", (ALvoid *) alGetBooleanv }, + { "alGetIntegerv", (ALvoid *) alGetIntegerv }, + { "alGetFloatv", (ALvoid *) alGetFloatv }, + { "alGetDoublev", (ALvoid *) alGetDoublev }, + { "alGetBoolean", (ALvoid *) alGetBoolean }, + { "alGetInteger", (ALvoid *) alGetInteger }, + { "alGetFloat", (ALvoid *) alGetFloat }, + { "alGetDouble", (ALvoid *) alGetDouble }, + { "alGetError", (ALvoid *) alGetError }, + { "alIsExtensionPresent", (ALvoid *) alIsExtensionPresent }, + { "alGetProcAddress", (ALvoid *) alGetProcAddress }, + { "alGetEnumValue", (ALvoid *) alGetEnumValue }, + { "alListenerf", (ALvoid *) alListenerf }, + { "alListener3f", (ALvoid *) alListener3f }, + { "alListenerfv", (ALvoid *) alListenerfv }, + { "alListeneri", (ALvoid *) alListeneri }, + { "alListener3i", (ALvoid *) alListener3i }, + { "alListeneriv", (ALvoid *) alListeneriv }, + { "alGetListenerf", (ALvoid *) alGetListenerf }, + { "alGetListener3f", (ALvoid *) alGetListener3f }, + { "alGetListenerfv", (ALvoid *) alGetListenerfv }, + { "alGetListeneri", (ALvoid *) alGetListeneri }, + { "alGetListener3i", (ALvoid *) alGetListener3i }, + { "alGetListeneriv", (ALvoid *) alGetListeneriv }, + { "alGenSources", (ALvoid *) alGenSources }, + { "alDeleteSources", (ALvoid *) alDeleteSources }, + { "alIsSource", (ALvoid *) alIsSource }, + { "alSourcef", (ALvoid *) alSourcef }, + { "alSource3f", (ALvoid *) alSource3f }, + { "alSourcefv", (ALvoid *) alSourcefv }, + { "alSourcei", (ALvoid *) alSourcei }, + { "alSource3i", (ALvoid *) alSource3i }, + { "alSourceiv", (ALvoid *) alSourceiv }, + { "alGetSourcef", (ALvoid *) alGetSourcef }, + { "alGetSource3f", (ALvoid *) alGetSource3f }, + { "alGetSourcefv", (ALvoid *) alGetSourcefv }, + { "alGetSourcei", (ALvoid *) alGetSourcei }, + { "alGetSource3i", (ALvoid *) alGetSource3i }, + { "alGetSourceiv", (ALvoid *) alGetSourceiv }, + { "alSourcePlayv", (ALvoid *) alSourcePlayv }, + { "alSourceStopv", (ALvoid *) alSourceStopv }, + { "alSourceRewindv", (ALvoid *) alSourceRewindv }, + { "alSourcePausev", (ALvoid *) alSourcePausev }, + { "alSourcePlay", (ALvoid *) alSourcePlay }, + { "alSourceStop", (ALvoid *) alSourceStop }, + { "alSourceRewind", (ALvoid *) alSourceRewind }, + { "alSourcePause", (ALvoid *) alSourcePause }, + { "alSourceQueueBuffers", (ALvoid *) alSourceQueueBuffers }, + { "alSourceUnqueueBuffers", (ALvoid *) alSourceUnqueueBuffers }, + { "alGenBuffers", (ALvoid *) alGenBuffers }, + { "alDeleteBuffers", (ALvoid *) alDeleteBuffers }, + { "alIsBuffer", (ALvoid *) alIsBuffer }, + { "alBufferData", (ALvoid *) alBufferData }, + { "alBufferf", (ALvoid *) alBufferf }, + { "alBuffer3f", (ALvoid *) alBuffer3f }, + { "alBufferfv", (ALvoid *) alBufferfv }, + { "alBufferi", (ALvoid *) alBufferi }, + { "alBuffer3i", (ALvoid *) alBuffer3i }, + { "alBufferiv", (ALvoid *) alBufferiv }, + { "alGetBufferf", (ALvoid *) alGetBufferf }, + { "alGetBuffer3f", (ALvoid *) alGetBuffer3f }, + { "alGetBufferfv", (ALvoid *) alGetBufferfv }, + { "alGetBufferi", (ALvoid *) alGetBufferi }, + { "alGetBuffer3i", (ALvoid *) alGetBuffer3i }, + { "alGetBufferiv", (ALvoid *) alGetBufferiv }, + { "alDopplerFactor", (ALvoid *) alDopplerFactor }, + { "alDopplerVelocity", (ALvoid *) alDopplerVelocity }, + { "alSpeedOfSound", (ALvoid *) alSpeedOfSound }, + { "alDistanceModel", (ALvoid *) alDistanceModel }, + { NULL, (ALvoid *) NULL } }; + + +//***************************************************************************** +//***************************************************************************** +// +// Defines +// +//***************************************************************************** +//***************************************************************************** + + +#ifdef __MINGW32__ +// fix for Mingw32. +#define AL_VOID_FXN(fxn) \ + ALCcontext* context; \ + \ + alListAcquireLock(alContextList); \ + if(!alCurrentContext) \ + { \ + alListReleaseLock(alContextList); \ + return; \ + } \ + \ + context = alCurrentContext; \ + EnterCriticalSection(&context->Lock); \ + alListReleaseLock(alContextList); \ + \ + context->AlApi.fxn; \ + LeaveCriticalSection(&context->Lock); \ + return +#define AL_RESULT_FXN(fxn, resultType, resultDefVal) \ + resultType result = resultDefVal; \ + ALCcontext* context; \ + \ + alListAcquireLock(alContextList); \ + if(!alCurrentContext) \ + { \ + alListReleaseLock(alContextList); \ + return result; \ + } \ + \ + context = alCurrentContext; \ + EnterCriticalSection(&context->Lock); \ + alListReleaseLock(alContextList); \ + \ + result = context->AlApi.fxn; \ + LeaveCriticalSection(&context->Lock); \ + return result + +#else +#define AL_RESULT_FXN(fxn, resultType, resultDefVal) \ + resultType result = resultDefVal; \ + ALCcontext* context; \ + \ + alListAcquireLock(alContextList); \ + if(!alCurrentContext) \ + { \ + alListReleaseLock(alContextList); \ + return result; \ + } \ + \ + context = alCurrentContext; \ + EnterCriticalSection(&context->Lock); \ + alListReleaseLock(alContextList); \ + \ + result = context->AlApi.##fxn; \ + LeaveCriticalSection(&context->Lock); \ + return result + +#define AL_VOID_FXN(fxn) \ + ALCcontext* context; \ + \ + alListAcquireLock(alContextList); \ + if(!alCurrentContext) \ + { \ + alListReleaseLock(alContextList); \ + return; \ + } \ + \ + context = alCurrentContext; \ + EnterCriticalSection(&context->Lock); \ + alListReleaseLock(alContextList); \ + \ + context->AlApi.##fxn; \ + LeaveCriticalSection(&context->Lock); \ + return +#endif + + +//***************************************************************************** +//***************************************************************************** +// +// AL API Buffer Entry Points +// +//***************************************************************************** +//***************************************************************************** + +//***************************************************************************** +// alGenBuffers +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n, ALuint* bufferNames) +{ + AL_VOID_FXN(alGenBuffers(n, bufferNames)); +} + + +//***************************************************************************** +// alDeleteBuffers +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint* bufferNames) +{ + AL_VOID_FXN(alDeleteBuffers(n, bufferNames)); +} + + +//***************************************************************************** +// alIsBuffer +//***************************************************************************** +// +ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint bufferName) +{ + AL_RESULT_FXN(alIsBuffer(bufferName), ALboolean, AL_FALSE); +} + +//***************************************************************************** +// alBuffer3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBuffer3f(ALuint bufferName, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3) +{ + AL_VOID_FXN(alBuffer3f(bufferName, param, v1, v2, v3)); +} + +//***************************************************************************** +// alBuffer3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBuffer3i(ALuint bufferName, ALenum param, ALint v1, ALint v2, ALint v3) +{ + AL_VOID_FXN(alBuffer3i(bufferName, param, v1, v2, v3)); +} + + +//***************************************************************************** +// alBufferData +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBufferData(ALuint bufferName, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq) +{ + AL_VOID_FXN(alBufferData(bufferName, format, data, size, freq)); +} + + +//***************************************************************************** +// alBufferf +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBufferf(ALuint bufferName, ALenum param, ALfloat value) +{ + AL_VOID_FXN(alBufferf(bufferName, param, value)); +} + + +//***************************************************************************** +// alBufferfv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBufferfv(ALuint bufferName, ALenum param, const ALfloat* values) +{ + AL_VOID_FXN(alBufferfv(bufferName, param, values)); +} + + +//***************************************************************************** +// alBufferi +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBufferi(ALuint bufferName, ALenum param, ALint value) +{ + AL_VOID_FXN(alBufferi(bufferName, param, value)); +} + + +//***************************************************************************** +// alBufferiv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alBufferiv(ALuint bufferName, ALenum param, const ALint* values) +{ + AL_VOID_FXN(alBufferiv(bufferName, param, values)); +} + +//***************************************************************************** +// alGetBuffer3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBuffer3f(ALuint bufferName, ALenum param, ALfloat *v1, ALfloat *v2, ALfloat *v3) +{ + AL_VOID_FXN(alGetBuffer3f(bufferName, param, v1, v2, v3)); +} + +//***************************************************************************** +// alGetBuffer3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBuffer3i(ALuint bufferName, ALenum param, ALint *v1, ALint *v2, ALint *v3) +{ + AL_VOID_FXN(alGetBuffer3i(bufferName, param, v1, v2, v3)); +} + +//***************************************************************************** +// alGetBufferf +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint bufferName, ALenum param, ALfloat* value) +{ + AL_VOID_FXN(alGetBufferf(bufferName, param, value)); +} + +//***************************************************************************** +// alGetBufferfv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBufferfv(ALuint bufferName, ALenum param, ALfloat* values) +{ + AL_VOID_FXN(alGetBufferfv(bufferName, param, values)); +} + + +//***************************************************************************** +// alGetBufferi +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint bufferName, ALenum param, ALint* value) +{ + AL_VOID_FXN(alGetBufferi(bufferName, param, value)); +} + +//***************************************************************************** +// alGetBufferiv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBufferiv(ALuint bufferName, ALenum param, ALint* values) +{ + AL_VOID_FXN(alGetBufferiv(bufferName, param, values)); +} + + +//***************************************************************************** +//***************************************************************************** +// +// AL API Generic Entry Points +// +//***************************************************************************** +//***************************************************************************** + +//***************************************************************************** +// alEnable +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alEnable(ALenum capability) +{ + AL_VOID_FXN(alEnable(capability)); +} + + +//***************************************************************************** +// alDisable +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDisable(ALenum capability) +{ + AL_VOID_FXN(alDisable(capability)); +} + + +//***************************************************************************** +// alDopplerFactor +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDopplerFactor(ALfloat value) +{ + AL_VOID_FXN(alDopplerFactor(value)); +} + + +//***************************************************************************** +// alDopplerVelocity +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDopplerVelocity(ALfloat value) +{ + AL_VOID_FXN(alDopplerVelocity(value)); +} + + +//***************************************************************************** +// alSpeedOfSound +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSpeedOfSound(ALfloat value) +{ + ALCcontext* context; + + alListAcquireLock(alContextList); + if(!alCurrentContext) + { + alListReleaseLock(alContextList); + return; + } + + context = alCurrentContext; + EnterCriticalSection(&context->Lock); + alListReleaseLock(alContextList); + + if (context->AlApi.alSpeedOfSound) { // protect against talking to a 1.0 lib + context->AlApi.alSpeedOfSound(value); + } + LeaveCriticalSection(&context->Lock); + return; +} + + +//***************************************************************************** +// alDistanceModel +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDistanceModel(ALenum value) +{ + AL_VOID_FXN(alDistanceModel(value)); +} + + +//***************************************************************************** +// alGetBoolean +//***************************************************************************** +// +ALAPI ALboolean ALAPIENTRY alGetBoolean(ALenum param) +{ + AL_RESULT_FXN(alGetBoolean(param), ALboolean, AL_FALSE); +} + + +//***************************************************************************** +// alGetBooleanv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetBooleanv(ALenum param, ALboolean* data) +{ + AL_VOID_FXN(alGetBooleanv(param, data)); +} + + +//***************************************************************************** +// alGetDouble +//***************************************************************************** +// +ALAPI ALdouble ALAPIENTRY alGetDouble(ALenum param) +{ + AL_RESULT_FXN(alGetDouble(param), ALdouble, 0.0); +} + + +//***************************************************************************** +// alGetDoublev +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetDoublev(ALenum param, ALdouble* data) +{ + AL_VOID_FXN(alGetDoublev(param, data)); +} + +//***************************************************************************** +// alGetFloat +//***************************************************************************** +// +ALAPI ALfloat ALAPIENTRY alGetFloat(ALenum param) +{ + AL_RESULT_FXN(alGetFloat(param), ALfloat, 0.0f); +} + + +//***************************************************************************** +// alGetFloatv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetFloatv(ALenum param, ALfloat* data) +{ + AL_VOID_FXN(alGetFloatv(param, data)); +} + + +//***************************************************************************** +// alGetInteger +//***************************************************************************** +// +ALAPI ALint ALAPIENTRY alGetInteger(ALenum param) +{ + AL_RESULT_FXN(alGetInteger(param), ALint, 0); +} + + +//***************************************************************************** +// alGetIntegerv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetIntegerv(ALenum param, ALint* data) +{ + AL_VOID_FXN(alGetIntegerv(param, data)); +} + + +//***************************************************************************** +// alGetEnumValue +//***************************************************************************** +// +ALAPI ALenum ALAPIENTRY alGetEnumValue(const ALCchar* ename) +{ + AL_RESULT_FXN(alGetEnumValue(ename), ALenum, AL_INVALID_ENUM); +} + + +//***************************************************************************** +// alGetError +//***************************************************************************** +// +ALAPI ALenum ALAPIENTRY alGetError(ALvoid) +{ + AL_RESULT_FXN(alGetError(), ALenum, AL_NO_ERROR); +} + + +//***************************************************************************** +// alGetProcAddress +//***************************************************************************** +// +ALAPI ALvoid* ALAPIENTRY alGetProcAddress(const ALCchar* fname) +{ + // return router's address if available + ALsizei i=0; + ALvoid *pAddress; + + while ((function[i].funcName)&&(strcmp((char *)function[i].funcName,(char *)fname))) + i++; + pAddress = function[i].address; + + if (pAddress != NULL) { + return pAddress; + } + + // router doesn't have this entry point, so go to the device... + AL_RESULT_FXN(alGetProcAddress(fname), ALvoid*, 0); + + return pAddress; +} + + +//***************************************************************************** +// alGetString +//***************************************************************************** +// +ALAPI const ALCchar* ALAPIENTRY alGetString(ALenum param) +{ + AL_RESULT_FXN(alGetString(param), const ALCchar*, 0); +} + + +//***************************************************************************** +// alIsExtensionPresent +//***************************************************************************** +// +ALAPI ALboolean ALAPIENTRY alIsExtensionPresent(const ALCchar* ename) +{ + AL_RESULT_FXN(alIsExtensionPresent(ename), ALboolean, AL_FALSE); +} + + +//***************************************************************************** +// alIsEnabled +//***************************************************************************** +// +ALAPI ALboolean ALAPIENTRY alIsEnabled(ALenum capability) +{ + AL_RESULT_FXN(alIsEnabled(capability), ALboolean, AL_FALSE); +} + + + +//***************************************************************************** +//***************************************************************************** +// +// AL API Listener Entry Points +// +//***************************************************************************** +//***************************************************************************** + +//***************************************************************************** +// alListenerf +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListenerf(ALenum param, ALfloat value) +{ + AL_VOID_FXN(alListenerf(param, value)); +} + + +//***************************************************************************** +// alListener3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListener3f(ALenum param, ALfloat v1, ALfloat v2, ALfloat v3) +{ + AL_VOID_FXN(alListener3f(param, v1, v2, v3)); +} + + +//***************************************************************************** +// alListener3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListener3i(ALenum param, ALint v1, ALint v2, ALint v3) +{ + AL_VOID_FXN(alListener3i(param, v1, v2, v3)); +} + + +//***************************************************************************** +// alListenerfv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum param, const ALfloat* values) +{ + AL_VOID_FXN(alListenerfv(param, values)); +} + + +//***************************************************************************** +// alListeneri +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListeneri(ALenum param, ALint value) +{ + AL_VOID_FXN(alListeneri(param, value)); +} + + +//***************************************************************************** +// alListeneriv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alListeneriv(ALenum param, const ALint *values) +{ + AL_VOID_FXN(alListeneriv(param, values)); +} + + +//***************************************************************************** +// alGetListenerf +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum param, ALfloat* value) +{ + AL_VOID_FXN(alGetListenerf(param, value)); +} + + +//***************************************************************************** +// alGetListener3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3) +{ + AL_VOID_FXN(alGetListener3f(param, v1, v2, v3)); +} + + +//***************************************************************************** +// alGetListener3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListener3i(ALenum param, ALint* v1, ALint* v2, ALint* v3) +{ + AL_VOID_FXN(alGetListener3i(param, v1, v2, v3)); +} + + +//***************************************************************************** +// alGetListenerfv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum param, ALfloat* values) +{ + AL_VOID_FXN(alGetListenerfv(param, values)); +} + + +//***************************************************************************** +// alGetListeneri +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListeneri(ALenum param, ALint* value) +{ + AL_VOID_FXN(alGetListeneri(param, value)); +} + + +//***************************************************************************** +// alGetListeneriv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetListeneriv(ALenum param, ALint* values) +{ + AL_VOID_FXN(alGetListeneriv(param, values)); +} + + +//***************************************************************************** +//***************************************************************************** +// +// AL API Source Entry Points +// +//***************************************************************************** +//***************************************************************************** + + +//***************************************************************************** +// alGenSources +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGenSources(ALsizei n, ALuint* sourceNames) +{ + AL_VOID_FXN(alGenSources(n, sourceNames)); +} + + +//***************************************************************************** +// alDeleteSources +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alDeleteSources(ALsizei n, const ALuint* sourceNames) +{ + AL_VOID_FXN(alDeleteSources(n, sourceNames)); +} + + +//***************************************************************************** +// alIsSource +//***************************************************************************** +// +ALAPI ALboolean ALAPIENTRY alIsSource(ALuint sourceName) +{ + AL_RESULT_FXN(alIsSource(sourceName), ALboolean, AL_FALSE); +} + + +//***************************************************************************** +// alSourcef +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcef(ALuint sourceName, ALenum param, ALfloat value) +{ + AL_VOID_FXN(alSourcef(sourceName, param, value)); +} + + +//***************************************************************************** +// alSourcefv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcefv(ALuint sourceName, ALenum param, const ALfloat* values) +{ + AL_VOID_FXN(alSourcefv(sourceName, param, values)); +} + + +//***************************************************************************** +// alSource3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSource3f(ALuint sourceName, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3) +{ + AL_VOID_FXN(alSource3f(sourceName, param, v1, v2, v3)); +} + + +//***************************************************************************** +// alSource3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSource3i(ALuint sourceName, ALenum param, ALint v1, ALint v2, ALint v3) +{ + AL_VOID_FXN(alSource3i(sourceName, param, v1, v2, v3)); +} + + +//***************************************************************************** +// alSourcei +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcei(ALuint sourceName, ALenum param, ALint value) +{ + AL_VOID_FXN(alSourcei(sourceName, param, value)); +} + +//***************************************************************************** +// alSourceiv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceiv(ALuint sourceName, ALenum param, const ALint* values) +{ + AL_VOID_FXN(alSourceiv(sourceName, param, values)); +} + + +//***************************************************************************** +// alGetSourcef +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSourcef(ALuint sourceName, ALenum param, ALfloat* value) +{ + AL_VOID_FXN(alGetSourcef(sourceName, param, value)); +} + +//***************************************************************************** +// alGetSource3f +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSource3f(ALuint sourceName, ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3) +{ + AL_VOID_FXN(alGetSource3f(sourceName, param, v1, v2, v3)); +} + + +//***************************************************************************** +// alGetSource3i +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSource3i(ALuint sourceName, ALenum param, ALint* v1, ALint* v2, ALint* v3) +{ + AL_VOID_FXN(alGetSource3i(sourceName, param, v1, v2, v3)); +} + + +//***************************************************************************** +// alGetSourcefv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSourcefv(ALuint sourceName, ALenum param, ALfloat* values) +{ + AL_VOID_FXN(alGetSourcefv(sourceName, param, values)); +} + + +//***************************************************************************** +// alGetSourcei +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSourcei(ALuint sourceName, ALenum param, ALint* value) +{ + AL_VOID_FXN(alGetSourcei(sourceName, param, value)); +} + + +//***************************************************************************** +// alGetSourceiv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alGetSourceiv(ALuint sourceName, ALenum param, ALint* values) +{ + AL_VOID_FXN(alGetSourceiv(sourceName, param, values)); +} + + +//***************************************************************************** +// alSourcePlay +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcePlay(ALuint sourceName) +{ + AL_VOID_FXN(alSourcePlay(sourceName)); +} + + +//***************************************************************************** +// alSourcePlayv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcePlayv(ALsizei n, const ALuint* sourceNames) +{ + AL_VOID_FXN(alSourcePlayv(n, sourceNames)); +} + + +//***************************************************************************** +// alSourcePause +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcePause(ALuint sourceName) +{ + AL_VOID_FXN(alSourcePause(sourceName)); +} + + +//***************************************************************************** +// alSourcePausev +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourcePausev(ALsizei n, const ALuint* sourceNames) +{ + AL_VOID_FXN(alSourcePausev(n, sourceNames)); +} + + +//***************************************************************************** +// alSourceStop +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceStop(ALuint sourceName) +{ + AL_VOID_FXN(alSourceStop(sourceName)); +} + + +//***************************************************************************** +// alSourceStopv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceStopv(ALsizei n, const ALuint* sourceNames) +{ + AL_VOID_FXN(alSourceStopv(n, sourceNames)); +} + + +//***************************************************************************** +// alSourceRewind +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceRewind(ALuint sourceName) +{ + AL_VOID_FXN(alSourceRewind(sourceName)); +} + + +//***************************************************************************** +// alSourceRewindv +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceRewindv(ALsizei n, const ALuint* sourceNames) +{ + AL_VOID_FXN(alSourceRewindv(n, sourceNames)); +} + + +//***************************************************************************** +// alSourceQueueBuffers +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceQueueBuffers(ALuint sourceName, ALsizei n, const ALuint* buffers) +{ + AL_VOID_FXN(alSourceQueueBuffers(sourceName, n, buffers)); +} + + +//***************************************************************************** +// alSourceUnqueueBuffers +//***************************************************************************** +// +ALAPI ALvoid ALAPIENTRY alSourceUnqueueBuffers(ALuint sourceName, ALsizei n, ALuint* buffers) +{ + AL_VOID_FXN(alSourceUnqueueBuffers(sourceName, n, buffers)); +} + diff --git a/Router/alList.cpp b/Router/alList.cpp new file mode 100644 index 00000000..2c884c56 --- /dev/null +++ b/Router/alList.cpp @@ -0,0 +1,1029 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2003 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + + + +#include "alList.h" +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> + + +//**************************************************************************** +//**************************************************************************** +// +// Defines +// +//**************************************************************************** +//**************************************************************************** + +// +// Some occasionally useful debugging stuff. +// +#if(DBG) + #ifndef ASSERT + static ALint alListDebugAssertsEnabled = 1; + #define ASSERT(exp) \ + { \ + if(!(exp) && alListDebugAssertsEnabled) \ + { \ + char tempStr[256]; \ + OutputDebugString("\n"); \ + sprintf(tempStr, "Assert failed in file %s, line %d!\n", \ + __FILE__, __LINE__); \ + OutputDebugString(tempStr); \ + OutputDebugString("\n"); \ + if(alListDebugAssertsEnabled) \ + { \ + DebugBreak(); \ + } \ + } \ + } + + #endif +#else + #ifndef ASSERT + #define ASSERT(exp) + #endif +#endif + + + +//**************************************************************************** +//**************************************************************************** +// +// List Functions +// +//**************************************************************************** +//**************************************************************************** + +//***************************************************************************** +// alListAddEntry +//***************************************************************************** +// Adds an entry to the tail of the list. Each entry must be unique. +// +ALvoid alListAddEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +) +{ +#if(DBG) + ALlistEntry* pCurrent = 0; +#endif + + ASSERT(pList); + ASSERT(pEntry); + ASSERT(pList->Locked); + ASSERT(!pEntry->Next); + ASSERT(!pEntry->Previous); + + // + // Verify the entry doesn't already exist. + // +#if(DBG) + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent == pEntry) + { + break; + } + + pCurrent = pCurrent->Next; + } + + if(pCurrent) + { + // Duplicate entries are not supported. + ASSERT(0); + return; + } +#endif + + + // + // Add the item to the tail of the list. + // + if(pList->Tail) + { + pList->Tail->Next = pEntry; + } + + pEntry->Previous = pList->Tail; + pList->Tail = pEntry; + + // + // Check if this is the first entry. + // + if(!pList->Head) + { + pList->Head = pEntry; + pList->Current = pEntry; + } + + pList->NumberOfEntries++; +} + + +//***************************************************************************** +// alListAddEntryToHead +//***************************************************************************** +// Adds an entry to the head of the list. Each entry must be unique. +// +ALvoid alListAddEntryToHead +( + IN ALlist* pList, + IN ALlistEntry* pEntry +) +{ +#if(DBG) + ALlistEntry* pCurrent = 0; +#endif + ASSERT(pList); + ASSERT(pEntry); + ASSERT(pList->Locked); + ASSERT(!pEntry->Next); + ASSERT(!pEntry->Previous); + + // + // Verify the entry doesn't already exist. + // +#if(DBG) + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent == pEntry) + { + break; + } + + pCurrent = pCurrent->Next; + } + + if(pCurrent) + { + // Duplicate entries are not supported. + ASSERT(0); + return; + } +#endif + + + // + // Add the item to the head of the list. + // + if(pList->Head) + { + pList->Head->Previous = pEntry; + } + + pEntry->Next = pList->Head; + pList->Head = pEntry; + + // + // Check if this is the first entry. + // + if(!pList->Tail) + { + pList->Tail = pEntry; + pList->Current = pEntry; + } + + pList->NumberOfEntries++; +} + + +//***************************************************************************** +// alListAcquireLock +//***************************************************************************** +// This is called to aquire the list lock for operations that span multiple +// list calls like iterating over the list. +// +ALvoid alListAcquireLock +( + IN ALlist* pList +) +{ + ASSERT(pList); + + EnterCriticalSection(&pList->Lock); +#if(DBG) + pList->Locked++; +#endif + + // + // Check that only one person has the lock. + // + ASSERT(pList->Locked == 1); +} + + +//***************************************************************************** +// alListCreate +//***************************************************************************** +// Creates and initializes a list. +// +ALboolean alListCreate +( + OUT ALlist** ppList +) +{ + ALlist* pList = 0; + + ASSERT(ppList); + + // + // Allocate and initialize the list context. + // + *ppList = 0; + pList = (ALlist*)malloc(sizeof(ALlist)); + if(!pList) + { + // Failed to allocate the list! + ASSERT(0); + return FALSE; + } + + memset(pList, 0, sizeof(ALlist)); + InitializeCriticalSection(&pList->Lock); + pList->NumberOfEntries = 0; + *ppList = pList; + return TRUE; +} + + +//***************************************************************************** +// alListFree +//***************************************************************************** +// Destroys the list. +// +ALvoid alListFree +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(!pList->Head); + + // + // Free the resources allocated during the creation. + // + if(pList) + { + DeleteCriticalSection(&pList->Lock); + free(pList); + } + + return; +} + + +//***************************************************************************** +// alListGetData +//***************************************************************************** +// Returns the data from the list entry. +// +ALvoid* alListGetData +( + IN ALlistEntry* pEntry +) +{ + ASSERT(pEntry); + + return pEntry->Data; +} + + +//***************************************************************************** +// alListGetEntryAt +//***************************************************************************** +// Returns the entry in the list at the specified index of the list. +// +ALlistEntry* alListGetEntryAt +( + IN ALlist* pList, + IN ALint Index +) +{ + ALlistEntry* pEntry = 0; + ALint i; + + ASSERT(pList); + ASSERT(pList->Locked); + ASSERT(Index < pList->NumberOfEntries); + + pEntry = pList->Head; + for(i = 0; i < Index && pEntry; i++) + { + pEntry = pEntry->Next; + } + + return pEntry; +} + + +//***************************************************************************** +// alListGetEntryCount +//***************************************************************************** +// Returns the number of items stored in the list. +// +ALint alListGetEntryCount +( + IN ALlist* pList +) +{ + ASSERT(pList->Locked); + return pList->NumberOfEntries; +} + + +//***************************************************************************** +// alListGetHead +//***************************************************************************** +// Returns the first entry in the list. +// +ALlistEntry* alListGetHead +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + return pList->Head; +} + + +//***************************************************************************** +// alListGetNext +//***************************************************************************** +// Returns the entry after to the entry pointed to by the iterator. If +// the iterator is at the last entry (or has finished iterating over the +// list), the returned entry will be 0. +// +ALlistEntry* alListGetNext +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + if(!pList->Current) + { + return 0; + } + + return pList->Current->Next; +} + + +//***************************************************************************** +// alListGetPrevious +//***************************************************************************** +// Returns the entry previous to the entry pointed to by the iterator. If +// the iterator is at the first entry, the returned entry will be 0. +// +ALlistEntry* alListGetPrevious +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + if(!pList->Current) + { + return 0; + } + + return pList->Current->Previous; +} + + +//***************************************************************************** +// alListGetTail +//***************************************************************************** +// Returns the last entry in the list. +// +ALlistEntry* alListGetTail +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + return pList->Tail; +} + + +//***************************************************************************** +// alListInitializeEntry +//***************************************************************************** +// Initializes a preallocated list entry. +// +ALvoid alListInitializeEntry +( + ALlistEntry* pEntry, + ALvoid* pData +) +{ + ASSERT(pEntry); + + pEntry->Data = pData; + pEntry->Next = 0; + pEntry->Previous = 0; +} + + +//***************************************************************************** +// alListIsEmpty +//***************************************************************************** +// Returns the TRUE if the list is empty. +// +ALboolean alListIsEmpty +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + return (pList->Head == 0); +} + + +//***************************************************************************** +// alListIteratorGet +//***************************************************************************** +// Returns the entry pointed to by the iterator. +// +ALlistEntry* alListIteratorGet +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + return pList->Current; +} + + +//***************************************************************************** +// alListIteratorFindData +//***************************************************************************** +// Searches the list for the matching item and return the pointer to the +// entry. If the match is not found, the return will be 0. +// +ALlistEntry* alListIteratorFindData +( + IN ALlist* pList, + IN ALvoid* pData +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Find the item. + // + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent->Data == pData) + { + break; + } + + pCurrent = pCurrent->Next; + } + + pList->Current = pCurrent; + return pCurrent; +} + + +//***************************************************************************** +// alListIteratorNext +//***************************************************************************** +// This is called to advance the list iterator to the next entry in the list +// and return that entry. +// +ALlistEntry* alListIteratorNext +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + if(!pList->Current) + { + return 0; + } + + pList->Current = pList->Current->Next; + return pList->Current; +} + + +//***************************************************************************** +// alListIteratorPrevious +//***************************************************************************** +// This is called to advance the list iterator to the previous entry in the +// list and return that entry. +// +ALlistEntry* alListIteratorPrevious +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + if(!pList->Current) + { + return 0; + } + + pList->Current = pList->Current->Previous; + return pList->Current; +} + + +//***************************************************************************** +// alListIteratorRemove +//***************************************************************************** +// Removes the current item from the list and returns it. The iterator will +// equal the next item in the list. +// +ALlistEntry* alListIteratorRemove +( + IN ALlist* pList +) +{ + ALlistEntry* pEntry = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Make sure we aren't at the end of the list. + // + if(!pList->Current) + { + return 0; + } + + // + // Remove the item from the list. + // + pEntry = pList->Current; + + // + // Fix up the next item in the list. + // + if(pEntry->Next) + { + pEntry->Next->Previous = pEntry->Previous; + } + + // + // Fix up the previous item in the list. + // + if(pEntry->Previous) + { + pEntry->Previous->Next = pEntry->Next; + } + + // + // Fix up the current pointer. + // + pList->Current = pEntry->Next; + + // + // Check the head pointer. + // + if(pList->Head == pEntry) + { + pList->Head = pEntry->Next; + } + + // + // Check the tail pointer. + // + if(pList->Tail == pEntry) + { + pList->Tail = pEntry->Previous; + } + + // + // Set the entry pointers. + // + pEntry->Next = 0; + pEntry->Previous = 0; + pList->NumberOfEntries--; + ASSERT(0 <= pList->NumberOfEntries); + return pEntry; +} + + +//***************************************************************************** +// alListIteratorReset +//***************************************************************************** +// Returns the list iterator to the head of the list. +// +ALlistEntry* alListIteratorReset +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + + pList->Current = pList->Head; + return pList->Current; +} + + +//***************************************************************************** +// alListIteratorSet +//***************************************************************************** +// Sets the current entry pointer to the entry passed in. If the entry is not +// found, the current entry will be 0. +// +ALlistEntry* alListIteratorSet +( + IN ALlist* pList, + IN ALlistEntry* pEntry +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent == pEntry) + { + break; + } + + pCurrent = pCurrent->Next; + } + + pList->Current = pCurrent; + return pList->Current; +} + + +//***************************************************************************** +// alListMatchEntry +//***************************************************************************** +// Matches the entry to an item in the list and returns the data in that +// entry. If the match is not found, the return will be 0. +// +ALvoid* alListMatchEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Find the item. + // + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent == pEntry) + { + break; + } + + pCurrent = pCurrent->Next; + } + + if(!pCurrent) + { + return 0; + } + + return pCurrent->Data; +} + + +//***************************************************************************** +// alListMatchData +//***************************************************************************** +// Searches the list for the first matching item and returns the pointer to +// the entry. If the match is not found, the return will be 0. +// +ALlistEntry* alListMatchData +( + IN ALlist* pList, + IN ALvoid* pData +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Find the item. + // + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent->Data == pData) + { + break; + } + + pCurrent = pCurrent->Next; + } + + return pCurrent; +} + + +//***************************************************************************** +// alListReleaseLock +//***************************************************************************** +// This is called to release the list lock. +// +ALvoid alListReleaseLock +( + IN ALlist* pList +) +{ + ASSERT(pList); + ASSERT(pList->Locked); + +#if(DBG) + pList->Locked--; + ASSERT(pList->Locked == 0); +#endif + + LeaveCriticalSection(&pList->Lock); +} + + +//***************************************************************************** +// alListRemoveEntry +//***************************************************************************** +// Removes the item from the list and returns the data from the item. If +// this is the current item, the current item will equal the next item in the +// list. +// +ALvoid* alListRemoveEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + ASSERT(pEntry); + + // + // Release the item from the list. + // + pCurrent = pList->Head; + while(pCurrent) + { + if(pCurrent == pEntry) + { + break; + } + + pCurrent = pCurrent->Next; + } + + if(!pCurrent) + { + return 0; + } + + // + // Fix up the next item in the list. + // + if(pEntry->Next) + { + pEntry->Next->Previous = pEntry->Previous; + } + + // + // Fix up the previous item in the list. + // + if(pEntry->Previous) + { + pEntry->Previous->Next = pEntry->Next; + } + + // + // Fix up the current pointer. + // + if(pCurrent == pList->Current) + { + pList->Current = pEntry->Next; + } + + // + // Check the head pointer. + // + if(pList->Head == pEntry) + { + pList->Head = pEntry->Next; + } + + // + // Check the tail pointer. + // + if(pList->Tail == pEntry) + { + pList->Tail = pEntry->Previous; + } + + // + // Set the entry pointers. + // + pEntry->Next = 0; + pEntry->Previous = 0; + pList->NumberOfEntries--; + ASSERT(0 <= pList->NumberOfEntries); + return pEntry->Data; +} + + +//***************************************************************************** +// alListRemoveHead +//***************************************************************************** +// Removes the list entry at the head of the list. If this is the current +// item, the current item will equal the next item in the list. +// +ALlistEntry* alListRemoveHead +( + IN ALlist* pList +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Release the item from the list. + // + pCurrent = pList->Head; + if(!pCurrent) + { + return 0; + } + + // + // Fix up the next item in the list. + // + if(pCurrent->Next) + { + pCurrent->Next->Previous = 0; + } + + // + // Fix up the previous item in the list. + // + ASSERT(!pCurrent->Previous) + + // + // Fix up the current pointer. + // + if(pCurrent == pList->Current) + { + pList->Current = pCurrent->Next; + } + + // + // Check the head pointer. + // + pList->Head = pCurrent->Next; + + // + // Check the tail pointer. + // + if(pList->Tail == pCurrent) + { + pList->Tail = 0; + } + + // + // Set the entry pointers. + // + pCurrent->Next = 0; + pCurrent->Previous = 0; + pList->NumberOfEntries--; + ASSERT(0 <= pList->NumberOfEntries); + return pCurrent; +} + + +//***************************************************************************** +// alListRemoveTail +//***************************************************************************** +// Removes the list entry at the tail of the list. If this is the current +// item, the current item will be null. +// +ALlistEntry* alListRemoveTail +( + IN ALlist* pList +) +{ + ALlistEntry* pCurrent = 0; + + ASSERT(pList); + ASSERT(pList->Locked); + + // + // Release the item from the list. + // + pCurrent = pList->Tail; + if(!pCurrent) + { + return 0; + } + + // + // Fix up the next item in the list. + // + ASSERT(!pCurrent->Next) + + // + // Fix up the previous item in the list. + // + if(pCurrent->Previous) + { + pCurrent->Previous->Next = 0; + } + + // + // Fix up the current pointer. + // + if(pCurrent == pList->Current) + { + pList->Current = 0; + } + + // + // Check the head pointer. + // + if(pList->Head == pCurrent) + { + pList->Head = 0; + } + + // + // Check the tail pointer. + // + pList->Tail = pCurrent->Previous; + + // + // Set the entry pointers. + // + pCurrent->Next = 0; + pCurrent->Previous = 0; + pList->NumberOfEntries--; + ASSERT(0 <= pList->NumberOfEntries); + return pCurrent; +} + diff --git a/Router/alList.h b/Router/alList.h new file mode 100644 index 00000000..71dc43c5 --- /dev/null +++ b/Router/alList.h @@ -0,0 +1,433 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2003 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + + + +#ifndef _AL_LIST_H_ +#define _AL_LIST_H_ + +#include <al/al.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <windows.h> + + + +//***************************************************************************** +//***************************************************************************** +// +// Defines +// +//***************************************************************************** +//***************************************************************************** + +// +// Some useful things to track parameters. +// +#ifndef IN +#define IN +#endif + +#ifndef OPTIONAL +#define OPTIONAL +#endif + +#ifndef OUT +#define OUT +#endif + +// +// The list entry. This should not be modified outside the list routines. +// +typedef struct ALlistEntry_Struct +{ + // + // The previous list entry. + // + struct ALlistEntry_Struct* Previous; + + // + // The next list entry. + // + struct ALlistEntry_Struct* Next; + + // + // The data for the current entry. + // + ALvoid* Data; + +} ALlistEntry; + + +// +// This is the context to pass to all the list calls. It must be initialized +// before any list calls are made. +// +typedef struct //ALlist_Struct +{ + // + // This is the pointer to the first item in the list. + // + ALlistEntry* Head; + + // + // This is the pointer to the last item in the list. + // + ALlistEntry* Tail; + + // + // This is the list iterator. + // + ALlistEntry* Current; + + // + // This is the list lock to prevent simultaneous addition and removal + // of entries. + // + CRITICAL_SECTION Lock; + + // + // This maintains a count of the number of entries in the list. + // + ALint NumberOfEntries; + + // + // This is set if the list is locked. For debug use only. + // +#if(DBG) + ALint Locked; +#endif + +} ALlist; + + + +//***************************************************************************** +//***************************************************************************** +// +// List Functions +// +//***************************************************************************** +//***************************************************************************** + +//***************************************************************************** +// alListAddEntry +//***************************************************************************** +// Adds an entry to the tail of the list. Each entry must be unique. +// +ALvoid alListAddEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListAddEntryToHead +//***************************************************************************** +// Adds an entry to the head of the list. Each entry must be unique. +// +ALvoid alListAddEntryToHead +( + IN ALlist* pList, + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListAcquireLock +//***************************************************************************** +// This is called to acquire the list lock for operations that span multiple +// list calls like iterating over the list. +// +ALvoid alListAcquireLock +( + IN ALlist* pList +); + +//***************************************************************************** +// alListCreate +//***************************************************************************** +// Creates and initializes a list. +// +ALboolean alListCreate +( + OUT ALlist** ppList +); + +//***************************************************************************** +// alListFree +//***************************************************************************** +// Destroys the list. Dynamically allocated entries are not freed. +// +ALvoid alListFree +( + IN ALlist* pList +); + +//***************************************************************************** +// alListGetData +//***************************************************************************** +// Returns the data from the list entry. +// +ALvoid* alListGetData +( + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListGetEntryAt +//***************************************************************************** +// Returns the entry in the list at the specified index of the list. +// +ALlistEntry* alListGetEntryAt +( + IN ALlist* pList, + IN ALint Index +); + +//***************************************************************************** +// alListGetEntryCount +//***************************************************************************** +// Returns the number of items stored in the list. +// +ALint alListGetEntryCount +( + IN ALlist* pList +); + +//***************************************************************************** +// alListGetHead +//***************************************************************************** +// Returns the first entry in the list. +// +ALlistEntry* alListGetHead +( + IN ALlist* pList +); + +//***************************************************************************** +// alListGetNext +//***************************************************************************** +// Returns the entry after to the entry pointed to by the iterator. If +// the iterator is at the last entry (or has finished iterating over the +// list), the returned entry will be 0. +// +ALlistEntry* alListGetNext +( + IN ALlist* pList +); + +//***************************************************************************** +// alListGetPrevious +//***************************************************************************** +// Returns the entry previous to the entry pointed to by the iterator. If +// the iterator is at the first entry, the returned entry will be 0. +// +ALlistEntry* alListGetPrevious +( + IN ALlist* pList +); + +//***************************************************************************** +// alListGetTail +//***************************************************************************** +// Returns the last entry in the list. +// +ALlistEntry* alListGetTail +( + IN ALlist* pList +); + +//***************************************************************************** +// alListInitializeEntry +//***************************************************************************** +// Initializes a preallocated list entry. +// +ALvoid alListInitializeEntry +( + IN ALlistEntry* pListEntry, + IN ALvoid* pData +); + +//***************************************************************************** +// alListIsEmpty +//***************************************************************************** +// Returns the TRUE if the list is empty. +// +ALboolean alListIsEmpty +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorGet +//***************************************************************************** +// Returns the entry pointed to by the iterator. +// +ALlistEntry* alListIteratorGet +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorFindData +//***************************************************************************** +// Searches the list for the matching item and return the pointer to the +// entry. If the match is not found, the return will be 0. +// +ALlistEntry* alListIteratorFindData +( + IN ALlist* pList, + IN ALvoid* pData +); + +//***************************************************************************** +// alListIteratorNext +//***************************************************************************** +// This is called to advance the list iterator to the next entry in the list +// and return that entry. +// +ALlistEntry* alListIteratorNext +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorPrevious +//***************************************************************************** +// This is called to advance the list iterator to the previous entry in the +// list and return that entry. +// +ALlistEntry* alListIteratorPrevious +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorReset +//***************************************************************************** +// Returns the list iterator to the head of the list and returns the head +// entry. +// +ALlistEntry* alListIteratorReset +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorRemove +//***************************************************************************** +// Removes the current item from the list and returns it. The iterator will +// equal the next item in the list. +// +ALlistEntry* alListIteratorRemove +( + IN ALlist* pList +); + +//***************************************************************************** +// alListIteratorSet +//***************************************************************************** +// Sets the current entry pointer to the entry passed in. If the entry is not +// found, the current entry will be 0. +// +ALlistEntry* alListIteratorSet +( + IN ALlist* pList, + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListMatchEntry +//***************************************************************************** +// Matches the entry to an item in the list and returns the data in that +// entry. If the match is not found, the return will be 0. +// +ALvoid* alListMatchEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListMatchData +//***************************************************************************** +// Searches the list for the matching item and return the pointer to the +// entry. If the match is not found, the return will be 0. +// +ALlistEntry* alListMatchData +( + IN ALlist* pList, + IN ALvoid* pData +); + +//***************************************************************************** +// alListReleaseLock +//***************************************************************************** +// This is called to release the list lock. +// +ALvoid alListReleaseLock +( + IN ALlist* pList +); + +//***************************************************************************** +// alListRemoveEntry +//***************************************************************************** +// Removes the item from the list and returns the data from the item. If +// this is the current item, the current item will equal the next item in the +// list. +// +ALvoid* alListRemoveEntry +( + IN ALlist* pList, + IN ALlistEntry* pEntry +); + +//***************************************************************************** +// alListRemoveHead +//***************************************************************************** +// Removes the list entry at the head of the list. If this is the current +// item, the current item will equal the next item in the list. +// +ALlistEntry* alListRemoveHead +( + IN ALlist* pList +); + +//***************************************************************************** +// alListRemoveTail +//***************************************************************************** +// Removes the list entry at the tail of the list. If this is the current +// item, the current item will be null. +// +ALlistEntry* alListRemoveTail +( + IN ALlist* pList +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Router/alc.cpp b/Router/alc.cpp new file mode 100644 index 00000000..c4abff8c --- /dev/null +++ b/Router/alc.cpp @@ -0,0 +1,2332 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef __MINGW32__ +#define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005 +#endif + +#include <stdlib.h> +#include <memory.h> +#define AL_BUILD_LIBRARY +#include <al/alc.h> +#include <stdio.h> +#include <tchar.h> +#include <assert.h> + +#include <stddef.h> +#include <windows.h> +#if defined(_MSC_VER) +#include <crtdbg.h> +#else +#define _malloc_dbg(s,x,f,l) malloc(s) +#define _realloc_dbg(p,s,x,f,l) realloc(p,s) +#endif +#include <objbase.h> +#ifndef __MINGW32__ +#include <atlconv.h> +#else +#define T2A(x) x +#endif +#include <mmsystem.h> + +#include "OpenAL32.h" + + +//***************************************************************************** +//***************************************************************************** +// +// Defines +// +//***************************************************************************** +//***************************************************************************** + +typedef struct ALCextension_struct +{ + + const char* ename; + +} ALCextension; + +typedef struct +{ + const char* ename; + ALenum value; + +} ALCRouterEnum; + +typedef struct ALCfunction_struct +{ + + const char* fname; + ALvoid* address; + +} ALCfunction; + + + +//***************************************************************************** +//***************************************************************************** +// +// Global Vars +// +//***************************************************************************** +//***************************************************************************** + +ALlist* alContextList = 0; +ALCcontext* alCurrentContext = 0; + +ALCdevice* g_CaptureDevice = NULL; + +//***************************************************************************** +//***************************************************************************** +// +// Local Vars +// +//***************************************************************************** +//***************************************************************************** + +// +// The values of the enums supported by OpenAL. +// +static ALCRouterEnum alcEnums[] = +{ + // Types + {"ALC_INVALID", ALC_INVALID}, + {"ALC_FALSE", ALC_FALSE}, + {"ALC_TRUE", ALC_TRUE}, + + // ALC Properties + {"ALC_MAJOR_VERSION", ALC_MAJOR_VERSION}, + {"ALC_MINOR_VERSION", ALC_MINOR_VERSION}, + {"ALC_ATTRIBUTES_SIZE", ALC_ATTRIBUTES_SIZE}, + {"ALC_ALL_ATTRIBUTES", ALC_ALL_ATTRIBUTES}, + {"ALC_DEFAULT_DEVICE_SPECIFIER", ALC_DEFAULT_DEVICE_SPECIFIER}, + {"ALC_DEVICE_SPECIFIER", ALC_DEVICE_SPECIFIER}, + {"ALC_EXTENSIONS", ALC_EXTENSIONS}, + {"ALC_FREQUENCY", ALC_FREQUENCY}, + {"ALC_REFRESH", ALC_REFRESH}, + {"ALC_SYNC", ALC_SYNC}, + {"ALC_MONO_SOURCES", ALC_MONO_SOURCES}, + {"ALC_STEREO_SOURCES", ALC_STEREO_SOURCES}, + {"ALC_CAPTURE_DEVICE_SPECIFIER", ALC_CAPTURE_DEVICE_SPECIFIER}, + {"ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER", ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER}, + {"ALC_CAPTURE_SAMPLES", ALC_CAPTURE_SAMPLES}, + + // New Enumeration extension + {"ALC_DEFAULT_ALL_DEVICES_SPECIFIER", ALC_DEFAULT_ALL_DEVICES_SPECIFIER}, + {"ALC_ALL_DEVICES_SPECIFIER", ALC_ALL_DEVICES_SPECIFIER}, + + // ALC Error Message + {"ALC_NO_ERROR", ALC_NO_ERROR}, + {"ALC_INVALID_DEVICE", ALC_INVALID_DEVICE}, + {"ALC_INVALID_CONTEXT", ALC_INVALID_CONTEXT}, + {"ALC_INVALID_ENUM", ALC_INVALID_ENUM}, + {"ALC_INVALID_VALUE", ALC_INVALID_VALUE}, + {"ALC_OUT_OF_MEMORY", ALC_OUT_OF_MEMORY}, + + // Default + {0, (ALenum)0} +}; + +// +// Our function pointers. +// +static ALCfunction alcFunctions[] = +{ + {"alcCreateContext", (ALvoid*)alcCreateContext}, + {"alcMakeContextCurrent", (ALvoid*)alcMakeContextCurrent}, + {"alcProcessContext", (ALvoid*)alcProcessContext}, + {"alcSuspendContext", (ALvoid*)alcSuspendContext}, + {"alcDestroyContext", (ALvoid*)alcDestroyContext}, + {"alcGetCurrentContext", (ALvoid*)alcGetCurrentContext}, + {"alcGetContextsDevice", (ALvoid*)alcGetContextsDevice}, + {"alcOpenDevice", (ALvoid*)alcOpenDevice}, + {"alcCloseDevice", (ALvoid*)alcCloseDevice}, + {"alcGetError", (ALvoid*)alcGetError}, + {"alcIsExtensionPresent", (ALvoid*)alcIsExtensionPresent}, + {"alcGetProcAddress", (ALvoid*)alcGetProcAddress}, + {"alcGetEnumValue", (ALvoid*)alcGetEnumValue}, + {"alcGetString", (ALvoid*)alcGetString}, + {"alcGetIntegerv", (ALvoid*)alcGetIntegerv}, + {"alcCaptureOpenDevice", (ALvoid*)alcCaptureOpenDevice}, + {"alcCaptureCloseDevice", (ALvoid*)alcCaptureCloseDevice}, + {"alcCaptureStart", (ALvoid*)alcCaptureStart}, + {"alcCaptureStop", (ALvoid*)alcCaptureStop}, + {"alcCaptureSamples", (ALvoid*)alcCaptureSamples}, + {0, (ALvoid*)0} +}; + +// +// Our extensions. +// +static ALCextension alcExtensions[] = +{ + "ALC_ENUMERATION_EXT", + "ALC_ENUMERATE_ALL_EXT", + "ALC_EXT_CAPTURE", + 0 +}; + + +// Error strings +static ALenum LastError = ALC_NO_ERROR; +static const ALCchar alcNoError[] = "No Error"; +static const ALCchar alcErrInvalidDevice[] = "Invalid Device"; +static const ALCchar alcErrInvalidContext[] = "Invalid Context"; +static const ALCchar alcErrInvalidEnum[] = "Invalid Enum"; +static const ALCchar alcErrInvalidValue[] = "Invalid Value"; + +static ALint alcMajorVersion = 1; +static ALint alcMinorVersion = 1; + +// Enumeration stuff +ALDEVICE *g_pDeviceList = NULL; // ALC_ENUMERATION_EXT Device List +ALDEVICE *g_pCaptureDeviceList = NULL; // ALC_ENUMERATION_EXT Capture Device List +ALDEVICE *g_pAllDevicesList = NULL; // ALC_ENUMERATE_ALL_EXT Device List + +ALchar *pszDefaultDeviceSpecifier = NULL; +ALchar *pszDeviceSpecifierList = NULL; +ALchar *pszDefaultCaptureDeviceSpecifier = NULL; +ALchar *pszCaptureDeviceSpecifierList = NULL; +ALchar *pszDefaultAllDevicesSpecifier = NULL; +ALchar *pszAllDevicesSpecifierList = NULL; +ALchar szEmptyString[] = ""; + +typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID); +typedef HRESULT (WINAPI *LPDIRECTSOUNDENUMERATEA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext); +typedef HRESULT (WINAPI *LPDIRECTSOUNDCAPTUREENUMERATEA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext); + +BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext); +bool GetDefaultPlaybackDeviceName(char **pszName); +bool GetDefaultCaptureDeviceName(char **pszName); +bool FindDevice(ALDEVICE *pDeviceList, char *szDeviceName, bool bExactMatch, char **ppszDefaultName); +bool HasDLLAlreadyBeenUsed(ALDEVICE *pDeviceList, TCHAR *szDLLName); +//bool ValidCaptureDevice(const char *szCaptureDeviceName); + +//***************************************************************************** +//***************************************************************************** +// +// Logging Options +// +//***************************************************************************** +//***************************************************************************** + +// NOTE : LOG macro below requires a compiler newer than Visual Studio 6 + +//#define _LOGCALLS + +#ifdef _LOGCALLS + void OutputMessage(const char *szTest,...); + #define LOG(x, ...) OutputMessage(x, ##__VA_ARGS__) + #define LOGFILENAME "OpenALCalls.txt" +#endif + +//***************************************************************************** +//***************************************************************************** +// +// Local Functions +// +//***************************************************************************** +//***************************************************************************** + +//***************************************************************************** +// GetLoadedModuleDirectory +//***************************************************************************** +BOOL GetLoadedModuleDirectory(LPCTSTR moduleName, + LPTSTR directoryContainingModule, + DWORD directoryContainingModuleLength) { + // Attempts to find the given module in the address space of this + // process and return the directory containing the module. A NULL + // moduleName means to look up the directory containing the + // application rather than any given loaded module. There is no + // trailing backslash ('\') on the returned path. If the named + // module was found in the address space of this process, returns + // TRUE, otherwise returns FALSE. directoryContainingModule may be + // mutated regardless. + HMODULE module = NULL; + TCHAR fileDrive[MAX_PATH + 1]; + TCHAR fileDir[MAX_PATH + 1]; + TCHAR fileName[MAX_PATH + 1]; + TCHAR fileExt[MAX_PATH + 1]; + DWORD numChars; + + if (moduleName != NULL) { + module = GetModuleHandle(moduleName); + if (module == NULL) + return FALSE; + } + + numChars = GetModuleFileName(module, + directoryContainingModule, + directoryContainingModuleLength); + if (numChars == 0) + return FALSE; + + _splitpath(directoryContainingModule, fileDrive, fileDir, fileName, fileExt); + _tcscpy(directoryContainingModule, fileDrive); + _tcscat(directoryContainingModule, fileDir); + return TRUE; +} + + + + +//***************************************************************************** +// AddDevice +//***************************************************************************** +void AddDevice(const char *pszDeviceName, TCHAR *pszHostDLLFilename, ALDEVICE **ppDeviceList) +{ + // Adds pszDeviceName nad pszHostDLLFilename to the given Device List *IF* pszDeviceName has + // not already been added. + ALDEVICE *pNewDevice, *pTempDevice; + + // Check if unique + for (pTempDevice = *ppDeviceList; pTempDevice; pTempDevice = pTempDevice->pNextDevice) + { + if (strcmp(pTempDevice->pszDeviceName, pszDeviceName) == 0) + break; + } + + if (pTempDevice) + return; + + pNewDevice = (ALDEVICE*)malloc(sizeof(ALDEVICE)); + if (pNewDevice) + { + pNewDevice->pszDeviceName = (char*)malloc((strlen(pszDeviceName)+1)*sizeof(char)); + if (pNewDevice->pszDeviceName) + strcpy(pNewDevice->pszDeviceName, pszDeviceName); + + pNewDevice->pszHostDLLFilename = (TCHAR*)malloc((_tcslen(pszHostDLLFilename)+1)*sizeof(TCHAR)); + if (pNewDevice->pszHostDLLFilename) + _tcscpy(pNewDevice->pszHostDLLFilename, pszHostDLLFilename); + + pNewDevice->pNextDevice = NULL; + + if (*ppDeviceList) + { + pTempDevice = *ppDeviceList; + while (pTempDevice->pNextDevice) + pTempDevice = pTempDevice->pNextDevice; + pTempDevice->pNextDevice = pNewDevice; + } + else + { + *ppDeviceList = pNewDevice; + } + } +} + + + + +//***************************************************************************** +// BuildDeviceList +//***************************************************************************** +ALvoid BuildDeviceList() +{ + // This function will scan several directories (details below) looking for + // OpenAL DLLs. Each OpenAL DLL found will be opened and queried for it's + // list of playback and capture devices. All the information is stored + // in various lists: - + // + // g_pDevicesList : List of Playback Devices + // g_pCaptureDeviceList : List of Capture devices + // g_pAllDevicesList : List of *all* possible Playback devices (ALC_ENUMERATE_ALL_EXT support) + // + // In addition this function allocates memory for the strings that will + // be returned to the application in response to alcGetString queries. + // + // pszDefaultDeviceSpecifier : Default Playback Device + // pszDeviceSpecifierList : List of Playback Devices + // pszDefaultCaptureDeviceSpecifier : Default Capture Device + // pszCaptureDeviceSpecifierList : List of Capture Devices + // pszDefaultAllDevicesSpecifier : Default *all* Playback Device (ALC_ENUMERATE_ALL_EXT support) + // pszAllDevicesSpecifierList : List of *all* Playback Devices (ALC_ENUMERATE_ALL_EXT support) + WIN32_FIND_DATA findData; + HANDLE searchHandle = INVALID_HANDLE_VALUE; + TCHAR searchName[MAX_PATH + 1]; + BOOL found = FALSE; + const ALCchar* specifier = 0; + ALuint specifierSize = 0; + ALCdevice *device; + void *context; + bool bUsedWrapper = false; + ALDEVICE *pDevice = NULL; + + // Only build the list once ... + if (((g_pDeviceList == NULL) && (waveOutGetNumDevs())) || + ((g_pCaptureDeviceList == NULL) && (waveInGetNumDevs()))) + { + // + // Directory[0] is the directory containing OpenAL32.dll + // Directory[1] is the current directory. + // Directory[2] is the current app directory + // Directory[3] is the system directory + // + TCHAR dir[4][MAX_PATH + 1] = { 0 }; + int numDirs = 0; + int i; + HINSTANCE dll = 0; + ALCAPI_GET_STRING alcGetStringFxn = 0; + ALCAPI_IS_EXTENSION_PRESENT alcIsExtensionPresentFxn = 0; + ALCAPI_OPEN_DEVICE alcOpenDeviceFxn = 0; + ALCAPI_CREATE_CONTEXT alcCreateContextFxn = 0; + ALCAPI_MAKE_CONTEXT_CURRENT alcMakeContextCurrentFxn = 0; + ALCAPI_DESTROY_CONTEXT alcDestroyContextFxn = 0; + ALCAPI_CLOSE_DEVICE alcCloseDeviceFxn = 0; + + // + // Construct our search paths + // + if (GetLoadedModuleDirectory("OpenAL32.dll", dir[0], MAX_PATH)) { + ++numDirs; + } + + GetCurrentDirectory(MAX_PATH, dir[1]); + _tcscat(dir[1], _T("\\")); + ++numDirs; + + GetLoadedModuleDirectory(NULL, dir[2], MAX_PATH); + ++numDirs; + + GetSystemDirectory(dir[3], MAX_PATH); + _tcscat(dir[3], _T("\\")); + ++numDirs; + + // + // Begin searching for additional OpenAL implementations. + // + for(i = 0; i < numDirs; i++) + { + if ((i == 0) && (strcmp(dir[0], dir[3]) == 0)) // if searching router dir and router dir is sys dir, skip search + continue; + + if ((i == 2) && (strcmp(dir[2], dir[1]) == 0)) // if searching app dir and app dir is current dir, skip search + continue; + + 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 + continue; + + _tcscpy(searchName, dir[i]); + _tcscat(searchName, _T("*oal.dll")); + searchHandle = FindFirstFile(searchName, &findData); + if(searchHandle != INVALID_HANDLE_VALUE) + { + while(TRUE) + { + // + // if this is an OpenAL32.dll, skip it -- it's probably a router and shouldn't be enumerated regardless + // + _tcscpy(searchName, dir[i]); + _tcscat(searchName, findData.cFileName); + TCHAR cmpName[MAX_PATH]; + _tcscpy(cmpName, searchName); + _tcsupr(cmpName); + if (_tcsstr(cmpName, _T("OPENAL32.DLL")) == 0) + { + boolean skipSearch = false; + + // don't search the same DLL twice + TCHAR *szDLLName = _tcsrchr(searchName, _T('\\')); + if (szDLLName) + szDLLName++; // Skip over the '\' + else + szDLLName = searchName; + + skipSearch = HasDLLAlreadyBeenUsed(g_pDeviceList, szDLLName); + if (!skipSearch) + skipSearch = HasDLLAlreadyBeenUsed(g_pCaptureDeviceList, szDLLName); + if (!skipSearch) + skipSearch = HasDLLAlreadyBeenUsed(g_pAllDevicesList, szDLLName); + + if (skipSearch == false) { + dll = LoadLibrary(searchName); + if(dll) + { + alcOpenDeviceFxn = (ALCAPI_OPEN_DEVICE)GetProcAddress(dll, "alcOpenDevice"); + alcCreateContextFxn = (ALCAPI_CREATE_CONTEXT)GetProcAddress(dll, "alcCreateContext"); + alcMakeContextCurrentFxn = (ALCAPI_MAKE_CONTEXT_CURRENT)GetProcAddress(dll, "alcMakeContextCurrent"); + alcGetStringFxn = (ALCAPI_GET_STRING)GetProcAddress(dll, "alcGetString"); + alcDestroyContextFxn = (ALCAPI_DESTROY_CONTEXT)GetProcAddress(dll, "alcDestroyContext"); + alcCloseDeviceFxn = (ALCAPI_CLOSE_DEVICE)GetProcAddress(dll, "alcCloseDevice"); + alcIsExtensionPresentFxn = (ALCAPI_IS_EXTENSION_PRESENT)GetProcAddress(dll, "alcIsExtensionPresent"); + + if ((alcOpenDeviceFxn != 0) && + (alcCreateContextFxn != 0) && + (alcMakeContextCurrentFxn != 0) && + (alcGetStringFxn != 0) && + (alcDestroyContextFxn != 0) && + (alcCloseDeviceFxn != 0) && + (alcIsExtensionPresentFxn != 0)) { + + bool bAddToAllDevicesList = false; + + if (alcIsExtensionPresentFxn(NULL, "ALC_ENUMERATE_ALL_EXT")) { + // this DLL can enumerate *all* devices -- so add complete list of devices + specifier = alcGetStringFxn(0, ALC_ALL_DEVICES_SPECIFIER); + if ((specifier) && strlen(specifier)) + { + do { + AddDevice(specifier, searchName, &g_pAllDevicesList); + specifier += strlen((char *)specifier) + 1; + } while (strlen((char *)specifier) > 0); + } + } else { + bAddToAllDevicesList = true; + } + + if (alcIsExtensionPresentFxn(NULL, "ALC_ENUMERATION_EXT")) { + // this DLL can enumerate devices -- so add complete list of devices + specifier = alcGetStringFxn(0, ALC_DEVICE_SPECIFIER); + if ((specifier) && strlen(specifier)) + { + do { + AddDevice(specifier, searchName, &g_pDeviceList); + if (bAddToAllDevicesList) + AddDevice(specifier, searchName, &g_pAllDevicesList); + specifier += strlen((char *)specifier) + 1; + } while (strlen((char *)specifier) > 0); + } + } else { + // no enumeration ability, -- so just add default device to the list + device = alcOpenDeviceFxn(NULL); + if (device != NULL) { + context = alcCreateContextFxn(device, NULL); + alcMakeContextCurrentFxn((ALCcontext *)context); + if (context != NULL) { + specifier = alcGetStringFxn(device, ALC_DEVICE_SPECIFIER); + if ((specifier) && strlen(specifier)) + { + AddDevice(specifier, searchName, &g_pDeviceList); + if (bAddToAllDevicesList) + AddDevice(specifier, searchName, &g_pAllDevicesList); + } + alcMakeContextCurrentFxn((ALCcontext *)NULL); + alcDestroyContextFxn((ALCcontext *)context); + alcCloseDeviceFxn(device); + } + } + } + + // add to capture device list + if (_tcsstr(cmpName, _T("CT_OAL.DLL")) == 0) { + // Skip native AL component (will contain same Capture List as the wrap_oal component) + if (alcIsExtensionPresentFxn(NULL, "ALC_EXT_CAPTURE")) { + // this DLL supports capture -- so add complete list of capture devices + specifier = alcGetStringFxn(0, ALC_CAPTURE_DEVICE_SPECIFIER); + if ((specifier) && strlen(specifier)) + { + do { + AddDevice(specifier, searchName, &g_pCaptureDeviceList); + specifier += strlen((char *)specifier) + 1; + } while (strlen((char *)specifier) > 0); + } + } + } + } + + FreeLibrary(dll); + dll = 0; + } + } + } + + if(!FindNextFile(searchHandle, &findData)) + { + if(GetLastError() == ERROR_NO_MORE_FILES) + { + break; + } + } + } + + FindClose(searchHandle); + searchHandle = INVALID_HANDLE_VALUE; + } + } + + // We now have a list of all the Device Names and their associated DLLs. + // Put the names in the appropriate strings + ALuint uiLength; + ALchar *pszTemp; + char *pszDefaultName = NULL; + bool bFound = false; + + if (g_pDeviceList) + { + uiLength = 0; + for (pDevice = g_pDeviceList; pDevice; pDevice = pDevice->pNextDevice) + uiLength += (strlen(pDevice->pszDeviceName) + 1); + + pszDeviceSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar)); + if (pszTemp = pszDeviceSpecifierList) + { + memset(pszDeviceSpecifierList, 0, (uiLength + 1) * sizeof(ALchar)); + for (pDevice = g_pDeviceList; pDevice; pDevice = pDevice->pNextDevice) + { + strcpy(pszTemp, pDevice->pszDeviceName); + pszTemp += (strlen(pDevice->pszDeviceName) + 1); + } + } + + // Determine what the Default Device should be + if (GetDefaultPlaybackDeviceName(&pszDefaultName)) + { + bFound = false; + + // Search for an exact match first + bFound = FindDevice(g_pDeviceList, pszDefaultName, true, &pszDefaultDeviceSpecifier); + + // If we haven't found a match ... search for a partial match if name contains 'X-Fi' + if ((!bFound) && (strstr(pszDefaultName, "X-Fi"))) + bFound = FindDevice(g_pDeviceList, "X-Fi", false, &pszDefaultDeviceSpecifier); + + // If we haven't found a match ... search for a partial match if name contains 'Audigy' + if ((!bFound) && (strstr(pszDefaultName, "Audigy"))) + bFound = FindDevice(g_pDeviceList, "Audigy", false, &pszDefaultDeviceSpecifier); + + // If we haven't found a match ... search for a partial match with 'Generic Hardware' + if (!bFound) + bFound = FindDevice(g_pDeviceList, "Generic Hardware", false, &pszDefaultDeviceSpecifier); + + // If we haven't found a match ... search for a partial match with 'Generic Software' + if (!bFound) + bFound = FindDevice(g_pDeviceList, "Generic Software", false, &pszDefaultDeviceSpecifier); + + // If we STILL haven't found a match ... pick the 1st device! + if (!bFound) + { + pszDefaultDeviceSpecifier = (char*)malloc((strlen(g_pDeviceList->pszDeviceName) + 1) * sizeof(char)); + if (pszDefaultDeviceSpecifier) + strcpy(pszDefaultDeviceSpecifier, g_pDeviceList->pszDeviceName); + } + + free(pszDefaultName); + pszDefaultName = NULL; + } + } + + if (g_pCaptureDeviceList) + { + uiLength = 0; + for (pDevice = g_pCaptureDeviceList; pDevice; pDevice = pDevice->pNextDevice) + uiLength += (strlen(pDevice->pszDeviceName) + 1); + + pszCaptureDeviceSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar)); + if (pszTemp = pszCaptureDeviceSpecifierList) + { + memset(pszCaptureDeviceSpecifierList, 0, (uiLength + 1) * sizeof(ALchar)); + for (pDevice = g_pCaptureDeviceList; pDevice; pDevice = pDevice->pNextDevice) + { + strcpy(pszTemp, pDevice->pszDeviceName); + pszTemp += (strlen(pDevice->pszDeviceName) + 1); + } + } + + if (GetDefaultCaptureDeviceName(&pszDefaultName)) + { + bFound = false; + + // Search for an exact match first + bFound = FindDevice(g_pCaptureDeviceList, pszDefaultName, true, &pszDefaultCaptureDeviceSpecifier); + + // If we haven't found a match, truncate the default name to 32 characters (MMSYSTEM limitation) + if ((!bFound) && (strlen(pszDefaultName) > 31)) + { + pszDefaultName[31] = '\0'; + bFound = FindDevice(g_pCaptureDeviceList, pszDefaultName, true, &pszDefaultCaptureDeviceSpecifier); + } + + // If we haven't found a match ... pick the 1st device! + if (!bFound) + { + pszDefaultCaptureDeviceSpecifier = (char*)malloc((strlen(g_pCaptureDeviceList->pszDeviceName) + 1) * sizeof(char)); + if (pszDefaultCaptureDeviceSpecifier) + strcpy(pszDefaultCaptureDeviceSpecifier, g_pCaptureDeviceList->pszDeviceName); + } + + free(pszDefaultName); + pszDefaultName = NULL; + } + } + + if (g_pAllDevicesList) + { + uiLength = 0; + for (pDevice = g_pAllDevicesList; pDevice; pDevice = pDevice->pNextDevice) + uiLength += (strlen(pDevice->pszDeviceName) + 1); + + pszAllDevicesSpecifierList = (ALchar*)malloc((uiLength + 1) * sizeof(ALchar)); + if (pszTemp = pszAllDevicesSpecifierList) + { + memset(pszAllDevicesSpecifierList, 0, (uiLength + 1) * sizeof(ALchar)); + for (pDevice = g_pAllDevicesList; pDevice; pDevice = pDevice->pNextDevice) + { + strcpy(pszTemp, pDevice->pszDeviceName); + pszTemp += (strlen(pDevice->pszDeviceName) + 1); + } + } + + // Determine what the Default Device should be + if (GetDefaultPlaybackDeviceName(&pszDefaultName)) + { + bFound = false; + + // If the (regular) default Playback device exists in this list ... use that + bFound = FindDevice(g_pAllDevicesList, pszDefaultDeviceSpecifier, true, &pszDefaultAllDevicesSpecifier); + + // If we haven't found a match ... pick a partial match with the Default Device Name + if (!bFound) + bFound = FindDevice(g_pAllDevicesList, pszDefaultName, false, &pszDefaultAllDevicesSpecifier); + + // If we STILL haven't found a match ... pick the 1st device! + if (!bFound) + { + pszDefaultAllDevicesSpecifier = (char*)malloc((strlen(g_pAllDevicesList->pszDeviceName) + 1) * sizeof(char)); + if (pszDefaultAllDevicesSpecifier) + strcpy(pszDefaultAllDevicesSpecifier, g_pAllDevicesList->pszDeviceName); + } + + free(pszDefaultName); + pszDefaultName = NULL; + } + } + } + + return; +} + + + + +//***************************************************************************** +// HasDLLAlreadyBeenUsed +//***************************************************************************** +bool HasDLLAlreadyBeenUsed(ALDEVICE *pDeviceList, TCHAR *szDLLName) +{ + // Checks if an OpenAL DLL has already been enumerated + ALDEVICE *pDevice = NULL; + TCHAR *szHostDLLName; + bool bReturn = false; + + for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice) + { + szHostDLLName = _tcsrchr(pDevice->pszHostDLLFilename, _T('\\')); + if (szHostDLLName) + szHostDLLName++; // Skip over the '\' + else + szHostDLLName = pDevice->pszHostDLLFilename; + + if (_tcscmp(szHostDLLName, szDLLName) == 0) + { + bReturn = true; + break; + } + } + + return bReturn; +} + + + + +//***************************************************************************** +// ValidCaptureDevice +//***************************************************************************** +/* +bool ValidCaptureDevice(const char *szCaptureDeviceName) +{ + // Microsoft changed the behaviour of Input devices on Windows Vista such that *each* input + // on each soundcard is reported as a separate device. Unfortunately, even though you can + // enumerate each input there are restrictions on what devices can be opened (e.g. you can only + // open the soundcard's default input). There is no API call to change the default input, so + // there is little point enumerating input devices that cannot be used, so we filter them out here. + WAVEFORMATEX wfex = { WAVE_FORMAT_PCM, 1, 22050, 44100, 2, 16, 0 }; // 16bit Mono 22050Hz + WAVEINCAPS WaveInCaps; + HWAVEIN hWaveIn; + bool bValid = false; + + // Find the device ID from the device name + long lNumCaptureDevs = waveInGetNumDevs(); + long lDeviceID = -1; + for (long lLoop = 0; lLoop < lNumCaptureDevs; lLoop++) + { + if (waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) + { + if (!strcmp(szCaptureDeviceName, WaveInCaps.szPname)) + { + lDeviceID = lLoop; + break; + } + } + } + + if (lDeviceID != -1) + { + if (waveInOpen(&hWaveIn, lDeviceID, &wfex, NULL, NULL, WAVE_MAPPED) == MMSYSERR_NOERROR) + { + waveInClose(hWaveIn); + bValid = true; + } + } + + return bValid; +} +*/ + + + +//***************************************************************************** +// GetDefaultPlaybackDeviceName +//***************************************************************************** +bool GetDefaultPlaybackDeviceName(char **pszName) +{ + // Try to use DirectSound to get the name of the 'Preferred Audio Device / Endpoint" + // If that fails use MMSYSTEM (name will be limited to 32 characters in length) + TCHAR szPath[_MAX_PATH]; + HINSTANCE hDSoundDLL; + + if (!pszName) + return false; + + *pszName = NULL; + + // Load dsound.dll from the System Directory and use the DirectSoundEnumerateA function to + // get the list of playback devices + if (GetSystemDirectory(szPath, _MAX_PATH)) + { + _tcscat(szPath, "\\dsound.dll"); + hDSoundDLL = LoadLibrary(szPath); + if (hDSoundDLL) + { + LPDIRECTSOUNDENUMERATEA pfnDirectSoundEnumerateA = (LPDIRECTSOUNDENUMERATEA)GetProcAddress(hDSoundDLL, "DirectSoundEnumerateA"); + if (pfnDirectSoundEnumerateA) + pfnDirectSoundEnumerateA(&DSEnumCallback, pszName); + FreeLibrary(hDSoundDLL); + } + } + + // Falling back to MMSYSTEM + if (*pszName == NULL) + { + UINT uDeviceID=0; + DWORD dwFlags=1; + WAVEOUTCAPS outputInfo; + + #if !defined(_WIN64) + #ifdef __GNUC__ + __asm__ ("pusha;"); + #else + __asm pusha; // workaround for register destruction caused by these wavOutMessage calls (weird but true) + #endif + #endif // !defined(_WIN64) + waveOutMessage((HWAVEOUT)(UINT_PTR)WAVE_MAPPER,0x2000+0x0015,(LPARAM)&uDeviceID,(WPARAM)&dwFlags); + waveOutGetDevCaps(uDeviceID,&outputInfo,sizeof(outputInfo)); + #if !defined(_WIN64) + #ifdef __GNUC__ + __asm__ ("popa;"); + #else + __asm popa; + #endif + #endif // !defined(_WIN64) + + *pszName = (char*)malloc((strlen(outputInfo.szPname) + 1) * sizeof(char)); + if (*pszName) + strcpy(*pszName, outputInfo.szPname); + } + + return (*pszName) ? true : false; +} + + + + +//***************************************************************************** +// GetDefaultCaptureDeviceName +//***************************************************************************** +bool GetDefaultCaptureDeviceName(char **pszName) +{ + // Try to use DirectSound to get the name of the 'Preferred Audio Device / Endpoint" for recording. + // If that fails use MMSYSTEM (name will be limited to 32 characters in length) + TCHAR szPath[_MAX_PATH]; + HINSTANCE hDSoundDLL; + + if (!pszName) + return false; + + *pszName = NULL; + + // Load dsound.dll from the System Directory and use the DirectSoundCaptureEnumerateA function to + // get the list of capture devices + if (GetSystemDirectory(szPath, _MAX_PATH)) + { + _tcscat(szPath, "\\dsound.dll"); + hDSoundDLL = LoadLibrary(szPath); + if (hDSoundDLL) + { + LPDIRECTSOUNDCAPTUREENUMERATEA pfnDirectSoundCaptureEnumerateA = (LPDIRECTSOUNDCAPTUREENUMERATEA)GetProcAddress(hDSoundDLL, "DirectSoundCaptureEnumerateA"); + if (pfnDirectSoundCaptureEnumerateA) + pfnDirectSoundCaptureEnumerateA(&DSEnumCallback, pszName); + FreeLibrary(hDSoundDLL); + } + } + + // Falling back to MMSYSTEM + if (*pszName == NULL) + { + UINT uDeviceID=0; + DWORD dwFlags=1; + WAVEINCAPS inputInfo; + + #if !defined(_WIN64) + #ifdef __GNUC__ + __asm__ ("pusha;"); + #else + __asm pusha; // workaround for register destruction caused by these wavOutMessage calls (weird but true) + #endif + #endif // !defined(_WIN64) + waveInMessage((HWAVEIN)(UINT_PTR)WAVE_MAPPER,0x2000+0x0015,(LPARAM)&uDeviceID,(WPARAM)&dwFlags); + waveInGetDevCaps(uDeviceID, &inputInfo, sizeof(inputInfo)); + #if !defined(_WIN64) + #ifdef __GNUC__ + __asm__ ("popa;"); + #else + __asm popa; + #endif + #endif // !defined(_WIN64) + + *pszName = (char*)malloc((strlen(inputInfo.szPname) + 1) * sizeof(char)); + if (*pszName) + strcpy(*pszName, inputInfo.szPname); + } + + return (*pszName) ? true : false; +} + + + + +//***************************************************************************** +// DSEnumCallback +//***************************************************************************** +BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) +{ + // DirectSound Enumeration callback will be called for each device found. + // The first device returned with a non-NULL GUID is the 'preferred device' + + // Skip over the device without a GUID + if (lpGuid) + { + char **pszName = (char**)lpContext; + *pszName = (char*)malloc((strlen(lpcstrDescription)+1) * sizeof(char)); + if (*pszName) + { + strcpy(*pszName, lpcstrDescription); + return FALSE; + } + } + + return TRUE; +} + + + +//***************************************************************************** +// FindDevice +//***************************************************************************** +bool FindDevice(ALDEVICE *pDeviceList, char *szDeviceName, bool bExactMatch, char **ppszDefaultName) +{ + // Search through pDeviceList for szDeviceName using an exact match if bExactMatch is true, or using + // a sub-string search otherwise. + // If found, allocate memory for *ppszDefaultName and copy the device name over + ALDEVICE *pDevice = NULL; + bool bFound = false; + + if (!pDeviceList || !szDeviceName || !ppszDefaultName) + return false; + + for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice) + { + if (bExactMatch) + bFound = (strcmp(pDevice->pszDeviceName, szDeviceName) == 0) ? true : false; + else + bFound = (strstr(pDevice->pszDeviceName, szDeviceName)) ? true : false; + + if (bFound) + { + *ppszDefaultName = (char*)malloc((strlen(pDevice->pszDeviceName) + 1) * sizeof(char)); + if (*ppszDefaultName) + { + strcpy(*ppszDefaultName, pDevice->pszDeviceName); + break; + } + } + } + + return *ppszDefaultName ? true : false; +} + + + + +//***************************************************************************** +// LoadDevicesDLL +//***************************************************************************** +HINSTANCE LoadDevicesDLL(ALDEVICE *pDeviceList, const ALchar *szDeviceName) +{ + // Search pDeviceList for szDeviceName, and when found load the OpenAL DLL + // that contains that Device name. + HINSTANCE hDLL = NULL; + ALDEVICE *pDevice; + + for (pDevice = pDeviceList; pDevice; pDevice = pDevice->pNextDevice) + { + if (strcmp(pDevice->pszDeviceName, szDeviceName) == 0) + { + hDLL = LoadLibrary(pDevice->pszHostDLLFilename); + break; + } + } + + return hDLL; +} + + + + +//***************************************************************************** +// FillOutAlcFunctions +//***************************************************************************** +ALboolean FillOutAlcFunctions(ALCdevice* device) +{ + ALboolean alcFxns = FALSE; + ALCAPI_FXN_TABLE* alcApi = &device->AlcApi; + + memset(alcApi, 0, sizeof(ALCAPI_FXN_TABLE)); + + // + // Get the OpenAL 1.0 Entry points. + // + alcApi->alcCreateContext = (ALCAPI_CREATE_CONTEXT)GetProcAddress(device->Dll, "alcCreateContext"); + alcApi->alcMakeContextCurrent = (ALCAPI_MAKE_CONTEXT_CURRENT)GetProcAddress(device->Dll, "alcMakeContextCurrent"); + alcApi->alcProcessContext = (ALCAPI_PROCESS_CONTEXT)GetProcAddress(device->Dll, "alcProcessContext"); + alcApi->alcSuspendContext = (ALCAPI_SUSPEND_CONTEXT)GetProcAddress(device->Dll, "alcSuspendContext"); + alcApi->alcDestroyContext = (ALCAPI_DESTROY_CONTEXT)GetProcAddress(device->Dll, "alcDestroyContext"); + alcApi->alcGetCurrentContext = (ALCAPI_GET_CURRENT_CONTEXT)GetProcAddress(device->Dll, "alcGetCurrentContext"); + alcApi->alcGetContextsDevice = (ALCAPI_GET_CONTEXTS_DEVICE)GetProcAddress(device->Dll, "alcGetContextsDevice"); + + alcApi->alcOpenDevice = (ALCAPI_OPEN_DEVICE)GetProcAddress(device->Dll, "alcOpenDevice"); + alcApi->alcCloseDevice = (ALCAPI_CLOSE_DEVICE)GetProcAddress(device->Dll, "alcCloseDevice"); + + alcApi->alcGetError = (ALCAPI_GET_ERROR)GetProcAddress(device->Dll, "alcGetError"); + + alcApi->alcIsExtensionPresent = (ALCAPI_IS_EXTENSION_PRESENT)GetProcAddress(device->Dll, "alcIsExtensionPresent"); + alcApi->alcGetProcAddress = (ALCAPI_GET_PROC_ADDRESS)GetProcAddress(device->Dll, "alcGetProcAddress"); + alcApi->alcGetEnumValue = (ALCAPI_GET_ENUM_VALUE)GetProcAddress(device->Dll, "alcGetEnumValue"); + + alcApi->alcGetString = (ALCAPI_GET_STRING)GetProcAddress(device->Dll, "alcGetString"); + alcApi->alcGetIntegerv = (ALCAPI_GET_INTEGERV)GetProcAddress(device->Dll, "alcGetIntegerv"); + + // + // Get the OpenAL 1.1 Entry points. + // + alcApi->alcCaptureOpenDevice = (ALCAPI_CAPTURE_OPEN_DEVICE)GetProcAddress(device->Dll, "alcCaptureOpenDevice"); + alcApi->alcCaptureCloseDevice = (ALCAPI_CAPTURE_CLOSE_DEVICE)GetProcAddress(device->Dll, "alcCaptureCloseDevice"); + alcApi->alcCaptureStart = (ALCAPI_CAPTURE_START)GetProcAddress(device->Dll, "alcCaptureStart"); + alcApi->alcCaptureStop = (ALCAPI_CAPTURE_STOP)GetProcAddress(device->Dll, "alcCaptureStop"); + alcApi->alcCaptureSamples = (ALCAPI_CAPTURE_SAMPLES)GetProcAddress(device->Dll, "alcCaptureSamples"); + + // handle legacy issue with old Creative DLLs which may not have alcGetProcAddress, alcIsExtensionPresent, alcGetEnumValue + if (alcApi->alcGetProcAddress == NULL) { + alcApi->alcGetProcAddress = (ALCAPI_GET_PROC_ADDRESS)alcGetProcAddress; + } + if (alcApi->alcIsExtensionPresent == NULL) { + alcApi->alcIsExtensionPresent = (ALCAPI_IS_EXTENSION_PRESENT)alcIsExtensionPresent; + } + if (alcApi->alcGetEnumValue == NULL) { + alcApi->alcGetEnumValue = (ALCAPI_GET_ENUM_VALUE)alcGetEnumValue; + } + + + alcFxns = (alcApi->alcCreateContext && + alcApi->alcMakeContextCurrent && + alcApi->alcProcessContext && + alcApi->alcSuspendContext && + alcApi->alcDestroyContext && + alcApi->alcGetCurrentContext && + alcApi->alcGetContextsDevice && + alcApi->alcOpenDevice && + alcApi->alcCloseDevice && + alcApi->alcGetError && + alcApi->alcIsExtensionPresent && + alcApi->alcGetProcAddress && + alcApi->alcGetEnumValue && + alcApi->alcGetString && + alcApi->alcGetIntegerv); + + return alcFxns; +} + + + + +//***************************************************************************** +// FillOutAlFunctions +//***************************************************************************** +ALboolean FillOutAlFunctions(ALCcontext* context) +{ + ALboolean alFxns = FALSE; + ALAPI_FXN_TABLE* alApi = &context->AlApi; + + memset(alApi, 0, sizeof(ALAPI_FXN_TABLE)); + + // + // Get the OpenAL 1.0 & 1.1 Entry points. + // + alApi->alEnable = (ALAPI_ENABLE)GetProcAddress(context->Device->Dll, "alEnable"); + alApi->alDisable = (ALAPI_DISABLE)GetProcAddress(context->Device->Dll, "alDisable"); + alApi->alIsEnabled = (ALAPI_IS_ENABLED)GetProcAddress(context->Device->Dll, "alIsEnabled"); + + alApi->alGetString = (ALAPI_GET_STRING)GetProcAddress(context->Device->Dll, "alGetString"); + alApi->alGetBooleanv = (ALAPI_GET_BOOLEANV)GetProcAddress(context->Device->Dll, "alGetBooleanv"); + alApi->alGetIntegerv = (ALAPI_GET_INTEGERV)GetProcAddress(context->Device->Dll, "alGetIntegerv"); + alApi->alGetFloatv = (ALAPI_GET_FLOATV)GetProcAddress(context->Device->Dll, "alGetFloatv"); + alApi->alGetDoublev = (ALAPI_GET_DOUBLEV)GetProcAddress(context->Device->Dll, "alGetDoublev"); + alApi->alGetBoolean = (ALAPI_GET_BOOLEAN)GetProcAddress(context->Device->Dll, "alGetBoolean"); + alApi->alGetInteger = (ALAPI_GET_INTEGER)GetProcAddress(context->Device->Dll, "alGetInteger"); + alApi->alGetFloat = (ALAPI_GET_FLOAT)GetProcAddress(context->Device->Dll, "alGetFloat"); + alApi->alGetDouble = (ALAPI_GET_DOUBLE)GetProcAddress(context->Device->Dll, "alGetDouble"); + alApi->alGetError = (ALAPI_GET_ERROR)GetProcAddress(context->Device->Dll, "alGetError"); + alApi->alIsExtensionPresent = (ALAPI_IS_EXTENSION_PRESENT)GetProcAddress(context->Device->Dll, "alIsExtensionPresent"); + alApi->alGetProcAddress = (ALAPI_GET_PROC_ADDRESS)GetProcAddress(context->Device->Dll, "alGetProcAddress"); + alApi->alGetEnumValue = (ALAPI_GET_ENUM_VALUE)GetProcAddress(context->Device->Dll, "alGetEnumValue"); + + alApi->alListenerf = (ALAPI_LISTENERF)GetProcAddress(context->Device->Dll, "alListenerf"); + alApi->alListener3f = (ALAPI_LISTENER3F)GetProcAddress(context->Device->Dll, "alListener3f"); + alApi->alListenerfv = (ALAPI_LISTENERFV)GetProcAddress(context->Device->Dll, "alListenerfv"); + alApi->alListeneri = (ALAPI_LISTENERI)GetProcAddress(context->Device->Dll, "alListeneri"); + alApi->alListener3i = (ALAPI_LISTENER3I)GetProcAddress(context->Device->Dll, "alListener3i"); + alApi->alListeneriv = (ALAPI_LISTENERIV)GetProcAddress(context->Device->Dll, "alListeneriv"); + alApi->alGetListenerf = (ALAPI_GET_LISTENERF)GetProcAddress(context->Device->Dll, "alGetListenerf"); + alApi->alGetListener3f = (ALAPI_GET_LISTENER3F)GetProcAddress(context->Device->Dll, "alGetListener3f"); + alApi->alGetListenerfv = (ALAPI_GET_LISTENERFV)GetProcAddress(context->Device->Dll, "alGetListenerfv"); + alApi->alGetListeneri = (ALAPI_GET_LISTENERI)GetProcAddress(context->Device->Dll, "alGetListeneri"); + alApi->alGetListener3i = (ALAPI_GET_LISTENER3I)GetProcAddress(context->Device->Dll, "alGetListener3i"); + alApi->alGetListeneriv = (ALAPI_GET_LISTENERIV)GetProcAddress(context->Device->Dll, "alGetListeneriv"); + + alApi->alGenSources = (ALAPI_GEN_SOURCES)GetProcAddress(context->Device->Dll, "alGenSources"); + alApi->alDeleteSources = (ALAPI_DELETE_SOURCES)GetProcAddress(context->Device->Dll, "alDeleteSources"); + alApi->alIsSource = (ALAPI_IS_SOURCE)GetProcAddress(context->Device->Dll, "alIsSource"); + alApi->alSourcef = (ALAPI_SOURCEF)GetProcAddress(context->Device->Dll, "alSourcef"); + alApi->alSource3f = (ALAPI_SOURCE3F)GetProcAddress(context->Device->Dll, "alSource3f"); + alApi->alSourcefv = (ALAPI_SOURCEFV)GetProcAddress(context->Device->Dll, "alSourcefv"); + alApi->alSourcei = (ALAPI_SOURCEI)GetProcAddress(context->Device->Dll, "alSourcei"); + alApi->alSource3i = (ALAPI_SOURCE3I)GetProcAddress(context->Device->Dll, "alSource3i"); + alApi->alSourceiv = (ALAPI_SOURCEIV)GetProcAddress(context->Device->Dll, "alSourceiv"); + alApi->alGetSourcef = (ALAPI_GET_SOURCEF)GetProcAddress(context->Device->Dll, "alGetSourcef"); + alApi->alGetSource3f = (ALAPI_GET_SOURCE3F)GetProcAddress(context->Device->Dll, "alGetSource3f"); + alApi->alGetSourcefv = (ALAPI_GET_SOURCEFV)GetProcAddress(context->Device->Dll, "alGetSourcefv"); + alApi->alGetSourcei = (ALAPI_GET_SOURCEI)GetProcAddress(context->Device->Dll, "alGetSourcei"); + alApi->alGetSource3i = (ALAPI_GET_SOURCE3I)GetProcAddress(context->Device->Dll, "alGetSource3i"); + alApi->alGetSourceiv = (ALAPI_GET_SOURCEIV)GetProcAddress(context->Device->Dll, "alGetSourceiv"); + alApi->alSourcePlayv = (ALAPI_SOURCE_PLAYV)GetProcAddress(context->Device->Dll, "alSourcePlayv"); + alApi->alSourceStopv = (ALAPI_SOURCE_STOPV)GetProcAddress(context->Device->Dll, "alSourceStopv"); + alApi->alSourceRewindv = (ALAPI_SOURCE_REWINDV)GetProcAddress(context->Device->Dll, "alSourceRewindv"); + alApi->alSourcePausev = (ALAPI_SOURCE_PAUSEV)GetProcAddress(context->Device->Dll, "alSourcePausev"); + alApi->alSourcePlay = (ALAPI_SOURCE_PLAY)GetProcAddress(context->Device->Dll, "alSourcePlay"); + alApi->alSourceStop = (ALAPI_SOURCE_STOP)GetProcAddress(context->Device->Dll, "alSourceStop"); + alApi->alSourceRewind = (ALAPI_SOURCE_STOP)GetProcAddress(context->Device->Dll, "alSourceRewind"); + alApi->alSourcePause = (ALAPI_SOURCE_PAUSE)GetProcAddress(context->Device->Dll, "alSourcePause"); + + alApi->alSourceQueueBuffers = (ALAPI_SOURCE_QUEUE_BUFFERS)GetProcAddress(context->Device->Dll, "alSourceQueueBuffers"); + alApi->alSourceUnqueueBuffers = (ALAPI_SOURCE_UNQUEUE_BUFFERS)GetProcAddress(context->Device->Dll, "alSourceUnqueueBuffers"); + + alApi->alGenBuffers = (ALAPI_GEN_BUFFERS)GetProcAddress(context->Device->Dll, "alGenBuffers"); + alApi->alDeleteBuffers = (ALAPI_DELETE_BUFFERS)GetProcAddress(context->Device->Dll, "alDeleteBuffers"); + alApi->alIsBuffer = (ALAPI_IS_BUFFER)GetProcAddress(context->Device->Dll, "alIsBuffer"); + alApi->alBufferData = (ALAPI_BUFFER_DATA)GetProcAddress(context->Device->Dll, "alBufferData"); + alApi->alBufferf = (ALAPI_BUFFERF)GetProcAddress(context->Device->Dll, "alBufferf"); + alApi->alBuffer3f = (ALAPI_BUFFER3F)GetProcAddress(context->Device->Dll, "alBuffer3f"); + alApi->alBufferfv = (ALAPI_BUFFERFV)GetProcAddress(context->Device->Dll, "alBufferfv"); + alApi->alBufferi = (ALAPI_BUFFERI)GetProcAddress(context->Device->Dll, "alBufferi"); + alApi->alBuffer3i = (ALAPI_BUFFER3I)GetProcAddress(context->Device->Dll, "alBuffer3i"); + alApi->alBufferiv = (ALAPI_BUFFERIV)GetProcAddress(context->Device->Dll, "alBufferiv"); + alApi->alGetBufferf = (ALAPI_GET_BUFFERF)GetProcAddress(context->Device->Dll, "alGetBufferf"); + alApi->alGetBuffer3f = (ALAPI_GET_BUFFER3F)GetProcAddress(context->Device->Dll, "alGetBuffer3f"); + alApi->alGetBufferfv = (ALAPI_GET_BUFFERFV)GetProcAddress(context->Device->Dll, "alGetBufferfv"); + alApi->alGetBufferi = (ALAPI_GET_BUFFERI)GetProcAddress(context->Device->Dll, "alGetBufferi"); + alApi->alGetBuffer3i = (ALAPI_GET_BUFFER3I)GetProcAddress(context->Device->Dll, "alGetBuffer3i"); + alApi->alGetBufferiv = (ALAPI_GET_BUFFERIV)GetProcAddress(context->Device->Dll, "alGetBufferiv"); + + alApi->alDopplerFactor = (ALAPI_DOPPLER_FACTOR)GetProcAddress(context->Device->Dll, "alDopplerFactor"); + alApi->alDopplerVelocity = (ALAPI_DOPPLER_VELOCITY)GetProcAddress(context->Device->Dll, "alDopplerVelocity"); + alApi->alSpeedOfSound = (ALAPI_SPEED_OF_SOUND)GetProcAddress(context->Device->Dll, "alSpeedOfSound"); + alApi->alDistanceModel = (ALAPI_DISTANCE_MODEL)GetProcAddress(context->Device->Dll, "alDistanceModel"); + + alFxns = (alApi->alEnable && + alApi->alDisable && + alApi->alIsEnabled && + + alApi->alGetString && + alApi->alGetBooleanv && + alApi->alGetIntegerv && + alApi->alGetFloatv && + alApi->alGetDoublev && + alApi->alGetBoolean && + alApi->alGetInteger && + alApi->alGetFloat && + alApi->alGetDouble && + + alApi->alGetError && + + alApi->alIsExtensionPresent && + alApi->alGetProcAddress && + alApi->alGetEnumValue && + + alApi->alListenerf && + alApi->alListener3f && + alApi->alListenerfv && + alApi->alListeneri && + alApi->alGetListenerf && + alApi->alGetListener3f && + alApi->alGetListenerfv && + alApi->alGetListeneri && + + alApi->alGenSources && + alApi->alDeleteSources && + alApi->alIsSource && + alApi->alSourcef && + alApi->alSource3f && + alApi->alSourcefv && + alApi->alSourcei && + alApi->alGetSourcef && + alApi->alGetSource3f && + alApi->alGetSourcefv && + alApi->alGetSourcei && + alApi->alSourcePlayv && + alApi->alSourceStopv && + alApi->alSourceRewindv && + alApi->alSourcePausev && + alApi->alSourcePlay && + alApi->alSourceStop && + alApi->alSourceRewind && + alApi->alSourcePause && + + alApi->alSourceQueueBuffers && + alApi->alSourceUnqueueBuffers && + + alApi->alGenBuffers && + alApi->alDeleteBuffers && + alApi->alIsBuffer && + alApi->alBufferData && + alApi->alGetBufferf && + alApi->alGetBufferi && + + alApi->alDopplerFactor && + alApi->alDopplerVelocity && + alApi->alDistanceModel); + + return alFxns; +} + + + + +//***************************************************************************** +//***************************************************************************** +// +// ALC API Entry Points +// +//*****************************************************************************ALC_ +//***************************************************************************** + +//***************************************************************************** +// alcCloseDevice +//***************************************************************************** +// +ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice* device) +{ +#ifdef _LOGCALLS + LOG("alcCloseDevice device %p\n", device); +#endif + if(!device) + { + return ALC_FALSE; + } + + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcCloseDevice(g_CaptureDevice->CaptureDevice); + + // + // Check if its linked to a context. + // + if(device->InUse) + { + ALCcontext* context = 0; + ALlistEntry* entry = 0; + + // + // Not all of the contexts using the device have been destroyed. + // + assert(0); + + // + // Loop through the context list and free and contexts linked to the device. + // Go back to the beginning each time in case some one changed the context + // list iterator. + // + alListAcquireLock(alContextList); + entry = alListIteratorReset(alContextList); + while(entry) + { + context = (ALCcontext*)alListGetData(entry); + if(context->Device == device) + { + alListReleaseLock(alContextList); + alcDestroyContext((ALCcontext *)context); + alListAcquireLock(alContextList); + entry = alListIteratorReset(alContextList); + } + + else + { + entry = alListIteratorNext(alContextList); + } + } + + alListReleaseLock(alContextList); + assert(!device->InUse); + } + + device->AlcApi.alcCloseDevice(device->DllDevice); + FreeLibrary(device->Dll); + free(device); + + return ALC_TRUE; +} + + + + +//***************************************************************************** +// alcCreateContext +//***************************************************************************** +ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice* device, const ALint* attrList) +{ +#ifdef _LOGCALLS + LOG("alcCreateContext device %p ", device); + if (attrList) + { + unsigned long ulIndex = 0; + while ((ulIndex < 16) && (attrList[ulIndex])) + { + switch(attrList[ulIndex]) + { + case ALC_FREQUENCY: + LOG("ALC_FREQUENCY %d ", attrList[ulIndex + 1]); + break; + + case ALC_REFRESH: + LOG("ALC_REFRESH %d ", attrList[ulIndex + 1]); + break; + + case ALC_SYNC: + LOG("ALC_SYNC %d ", attrList[ulIndex + 1]); + break; + + case ALC_MONO_SOURCES: + LOG("ALC_MONO_SOURCES %d ", attrList[ulIndex + 1]); + break; + + case ALC_STEREO_SOURCES: + LOG("ALC_STEREO_SOURCES %d ", attrList[ulIndex + 1]); + break; + + case 0x20003/*ALC_MAX_AUXILIARY_SENDS*/: + LOG("ALC_MAX_AUXILIARY_SENDS %d", attrList[ulIndex + 1]); + break; + } + ulIndex += 2; + } + } + LOG("\n"); +#endif + + ALCcontext* context = 0; + + if(!device) + { + LastError = ALC_INVALID_DEVICE; + return 0; + } + + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcCreateContext(g_CaptureDevice->CaptureDevice, attrList); + + // + // Allocate the context. + // + context = (ALCcontext*)malloc(sizeof(ALCcontext)); + if(!context) + { + return 0; + } + + memset(context, 0, sizeof(ALCcontext)); + context->Device = device; + context->Suspended = FALSE; + context->LastError = ALC_NO_ERROR; + InitializeCriticalSection(&context->Lock); + + // + // We don't fill out the AL functions in case they are context specific. + // + + context->DllContext = device->AlcApi.alcCreateContext(device->DllDevice, attrList); + if(!context->DllContext) + { + DeleteCriticalSection(&context->Lock); + free(context); + context = 0; + return 0; + } + + device->InUse++; + + // + // Add it to the context list. + // + alListInitializeEntry(&context->ListEntry, context); + alListAcquireLock(alContextList); + alListAddEntry(alContextList, &context->ListEntry); + alListReleaseLock(alContextList); + return context; +} + + + + +//***************************************************************************** +// alcDestroyContext +//***************************************************************************** +ALCAPI ALvoid ALCAPIENTRY alcDestroyContext(ALCcontext* context) +{ +#ifdef _LOGCALLS + LOG("alcDestroyContext context %p\n", context); +#endif + ALCcontext* listData = 0; + + if(!context) + { + return; + } + + // + // Remove the entry from the context list. + // + alListAcquireLock(alContextList); + listData = (ALCcontext*)alListRemoveEntry(alContextList, &context->ListEntry); + if(!listData) + { + alListReleaseLock(alContextList); + return; + } + + if(context == alCurrentContext) + { + alCurrentContext = 0; + } + + EnterCriticalSection(&context->Lock); + alListReleaseLock(alContextList); + + context->Device->InUse--; + + // Clean up the context. + if(context->DllContext) + { + context->Device->AlcApi.alcDestroyContext(context->DllContext); + } + + LeaveCriticalSection(&context->Lock); + DeleteCriticalSection(&context->Lock); + free(context); +} + + + + +//***************************************************************************** +// alcGetContextsDevice +//***************************************************************************** +ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext* context) +{ +#ifdef _LOGCALLS + LOG("alcGetContextsDevice context %p\n", context); +#endif + ALCdevice* ALCdevice = 0; + + alListAcquireLock(alContextList); + if(alListMatchData(alContextList, context)) + { + ALCdevice = context->Device; + } + + alListReleaseLock(alContextList); + + return ALCdevice; +} + + + + +//***************************************************************************** +// alcGetCurrentContext +//***************************************************************************** +ALCAPI ALCcontext* ALCAPIENTRY alcGetCurrentContext(ALvoid) +{ +#ifdef _LOGCALLS + LOG("alcGetCurrentContext\n"); +#endif + return (ALCcontext *)alCurrentContext; +} + + + + +//***************************************************************************** +// alcGetEnumValue +//***************************************************************************** +ALCAPI ALenum ALCAPIENTRY alcGetEnumValue(ALCdevice* device, const ALCchar* ename) +{ +#ifdef _LOGCALLS + LOG("alcGetEnumValue device %p enum name '%s'\n", device, ename ? ename : "<NULL>"); +#endif + // + // Always return the router version of the ALC enum if it exists. + // + ALsizei i = 0; + while(alcEnums[i].ename && strcmp((char*)alcEnums[i].ename, (char*)ename)) + { + i++; + } + + if(alcEnums[i].ename) + { + return alcEnums[i].value; + } + + if(device) + { + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcGetEnumValue(g_CaptureDevice->CaptureDevice, ename); + + return device->AlcApi.alcGetEnumValue(device->DllDevice, ename); + } + + LastError = ALC_INVALID_ENUM; + return 0; +} + + + + +//***************************************************************************** +// alcGetError +//***************************************************************************** +ALCAPI ALenum ALCAPIENTRY alcGetError(ALCdevice* device) +{ +#ifdef _LOGCALLS + LOG("alcGetError device %p\n", device); +#endif + ALenum errorCode = ALC_NO_ERROR; + + // Try to get a valid device. + if(!device) + { + if (g_CaptureDevice == device) + return + errorCode = LastError; + LastError = ALC_NO_ERROR; + return errorCode; + } + + // + // Check if its a 3rd party device. + // + if (device == g_CaptureDevice) + errorCode = g_CaptureDevice->AlcApi.alcGetError(g_CaptureDevice->CaptureDevice); + else + errorCode = device->AlcApi.alcGetError(device->DllDevice); + + return errorCode; +} + + + + +//***************************************************************************** +// alcGetIntegerv +//***************************************************************************** +ALCAPI ALvoid ALCAPIENTRY alcGetIntegerv(ALCdevice* device, ALenum param, ALsizei size, ALint* data) +{ +#ifdef _LOGCALLS + LOG("alcGetIntegerv device %p enum ", device); + switch (param) + { + case ALC_ATTRIBUTES_SIZE: + LOG("ALC_ATTRIBUTES_SIZE\n"); + break; + case ALC_ALL_ATTRIBUTES: + LOG("ALC_ALL_ATTRIBUTES\n"); + break; + case ALC_MAJOR_VERSION: + LOG("ALC_MAJOR_VERSION\n"); + break; + case ALC_MINOR_VERSION: + LOG("ALC_MINOR_VERSION\n"); + break; + case ALC_CAPTURE_SAMPLES: + LOG("ALC_CAPTURE_SAMPLES\n"); + break; + case ALC_FREQUENCY: + LOG("ALC_FREQUENCY\n"); + break; + case ALC_REFRESH: + LOG("ALC_REFRESH\n"); + break; + case ALC_SYNC: + LOG("ALC_SYNC\n"); + break; + case ALC_MONO_SOURCES: + LOG("ALC_MONO_SOURCES\n"); + break; + case ALC_STEREO_SOURCES: + LOG("ALC_STEREO_SOURCES\n"); + break; + case 0x20003: // ALC_MAX_AUXILIARY_SENDS + LOG("ALC_MAX_AUXILIARY_SENDS\n"); + break; + case 0x20001: // ALC_EFX_MAJOR_VERSION + LOG("ALC_EFX_MAJOR_VERSION\n"); + break; + case 0x20002: // ALC_EFX_MINOR_VERSION + LOG("ALC_EFX_MINOR_VERSION\n"); + break; + default: + LOG("<Unknown>\n"); + break; + } +#endif + + if(device) + { + if (device == g_CaptureDevice) + { + g_CaptureDevice->AlcApi.alcGetIntegerv(g_CaptureDevice->CaptureDevice, param, size, data); + return; + } + + device->AlcApi.alcGetIntegerv(device->DllDevice, param, size, data); + return; + } + + switch(param) + { + case ALC_MAJOR_VERSION: + { + if((size < sizeof(ALint)) || (data == 0)) + { + LastError = ALC_INVALID; + return; + } + + *data = alcMajorVersion; + } + break; + + case ALC_MINOR_VERSION: + { + if((size < sizeof(ALint)) || (data == 0)) + { + LastError = ALC_INVALID; + return; + } + + *data = alcMinorVersion; + } + break; + + default: + { + device->LastError = ALC_INVALID_ENUM; + } + break; + } +} + + + + +//***************************************************************************** +// alcGetProcAddress +//***************************************************************************** +ALCAPI ALvoid* ALCAPIENTRY alcGetProcAddress(ALCdevice* device, const ALCchar* fname) +{ +#ifdef _LOGCALLS + LOG("alcGetProcAddress device %p function name '%s'\n", device, fname ? fname : "<NULL>"); +#endif + + // + // Always return the router version of the ALC function if it exists. + // + ALsizei i = 0; + while(alcFunctions[i].fname && strcmp((char*)alcFunctions[i].fname, (char*)fname)) + { + i++; + } + + if(alcFunctions[i].fname) + { + return alcFunctions[i].address; + } + + if(device) + { + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcGetProcAddress(g_CaptureDevice->CaptureDevice, fname); + + return device->AlcApi.alcGetProcAddress(device->DllDevice, fname); + } + + LastError = ALC_INVALID_ENUM; + return 0; +} + + + + +//***************************************************************************** +// alcIsExtensionPresent +//***************************************************************************** +ALCAPI ALboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice* device, const ALCchar* ename) +{ +#ifdef _LOGCALLS + LOG("alcIsExtensionPresent device %p extension name '%s'\n", device, ename ? ename : "<NULL>"); +#endif + // + // Check if its a router supported extension first as its a good idea to have + // ALC calls go through the router if possible. + // + ALsizei i = 0; + while(alcExtensions[i].ename && _stricmp((char*)alcExtensions[i].ename, (char*)ename)) + { + i++; + } + + if(alcExtensions[i].ename) + { + return ALC_TRUE; + } + + // + // Check the device passed in to see if the extension is supported. + // + if(device) + { + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcIsExtensionPresent(g_CaptureDevice->CaptureDevice, ename); + + return device->AlcApi.alcIsExtensionPresent(device->DllDevice, ename); + } + + LastError = ALC_INVALID_ENUM; + return ALC_FALSE; +} + + + + +//***************************************************************************** +// alcMakeContextCurrent +//***************************************************************************** +ALCAPI ALboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext* context) +{ +#ifdef _LOGCALLS + LOG("alcMakeContextCurrent context %p\n", context); +#endif + ALboolean contextSwitched = AL_TRUE; + + // + // Context must be a valid context or 0 + // + alListAcquireLock(alContextList); + if(!alListMatchData(alContextList, context) && context != 0) + { + alListReleaseLock(alContextList); + return ALC_FALSE; + } + + // + // Try the new context. + // + if(context) + { + contextSwitched = context->Device->AlcApi.alcMakeContextCurrent(context->DllContext); + + // + // If this is the first time the context has been made the current context, fill in the context + // function pointers. + // + if(contextSwitched && !context->AlApi.alGetProcAddress) + { + // + // Don't fill out the functions here in case they are context specific pointers in the device. + // + if(!FillOutAlFunctions(context)) + { + LastError = ALC_INVALID_CONTEXT; + contextSwitched = AL_FALSE; + + // + // Something went wrong, restore the old context. + // + if(alCurrentContext) + { + alCurrentContext->Device->AlcApi.alcMakeContextCurrent(alCurrentContext->DllContext); + } + + else + { + alCurrentContext->Device->AlcApi.alcMakeContextCurrent(0); + } + } + } + } else { + if ((alCurrentContext) && (alCurrentContext->Device) && (alCurrentContext->Device->AlcApi.alcMakeContextCurrent)) { + contextSwitched = alCurrentContext->Device->AlcApi.alcMakeContextCurrent(0); + } + } + + // + // Set the context states if the switch was successful. + // + if(contextSwitched) + { + alCurrentContext = context; + } + + alListReleaseLock(alContextList); + return contextSwitched; +} + + + + +//***************************************************************************** +// alcOpenDevice +//***************************************************************************** +ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar* deviceName) +{ +#ifdef _LOGCALLS + LOG("alcOpenDevice device name '%s'\n", deviceName ? deviceName : "<NULL>"); +#endif + HINSTANCE dll = 0; + ALCdevice* device = 0; + const ALchar *pszDeviceName = NULL; + + BuildDeviceList(); + + if (g_pDeviceList) + { + if ((!deviceName) || (strlen(deviceName)==0) || (strcmp(deviceName, "DirectSound3D")==0)) + pszDeviceName = pszDefaultDeviceSpecifier; + else + pszDeviceName = deviceName; + + // Search for device in Playback Device List + dll = LoadDevicesDLL(g_pDeviceList, pszDeviceName); + + if (!dll) + { + // If NOT found, and the requested name is one of these ... + // "Generic Hardware" (no longer available on Windows Vista) + // "DirectSound" (legacy name for OpenAL Software mixer device) + // "MMSYSTEM" (legacy name for OpenAL Software mixer using MMSYSTEM instead of DirectSound) + // try to open the "Generic Software" device instead + if ((strcmp(pszDeviceName, "Generic Hardware") == 0) || + (strcmp(pszDeviceName, "DirectSound") == 0) || + (strcmp(pszDeviceName, "MMSYSTEM") == 0)) + { + dll = LoadDevicesDLL(g_pDeviceList, "Generic Software"); + } + } + + if (!dll) + dll = LoadDevicesDLL(g_pAllDevicesList, pszDeviceName); + + if (dll) + { + device = (ALCdevice*)malloc(sizeof(ALCdevice)); + if (device) + { + memset(device, 0, sizeof(ALCdevice)); + device->LastError = ALC_NO_ERROR; + device->InUse = 0; + device->Dll = dll; + if (FillOutAlcFunctions(device)) + device->DllDevice = device->AlcApi.alcOpenDevice(pszDeviceName); + + if (!device->DllDevice) + { + FreeLibrary(dll); + free(device); + device = 0; + } + } + } + } + + if (!device) + LastError = ALC_INVALID_DEVICE; + + return device; +} + + + + +//***************************************************************************** +// alcProcessContext +//***************************************************************************** +ALCAPI ALvoid ALCAPIENTRY alcProcessContext(ALCcontext* context) +{ +#ifdef _LOGCALLS + LOG("alcProcessContext context %p\n", context); +#endif + alListAcquireLock(alContextList); + if(!context && !alCurrentContext) + { + alListReleaseLock(alContextList); + return; + } + + if(!context) + { + context = alCurrentContext; + } + + EnterCriticalSection(&context->Lock); + alListReleaseLock(alContextList); + + if(context->DllContext) + { + context->Device->AlcApi.alcProcessContext(context->DllContext); + } + + context->Suspended = FALSE; + + LeaveCriticalSection(&context->Lock); + return; +} + + + + +//***************************************************************************** +// alcSuspendContext +//***************************************************************************** +ALCAPI ALCvoid ALCAPIENTRY alcSuspendContext(ALCcontext* context) +{ +#ifdef _LOGCALLS + LOG("alcSuspendContext context %p\n", context); +#endif + alListAcquireLock(alContextList); + if(!context && !alCurrentContext) + { + alListReleaseLock(alContextList); + return; + } + + if(!context) + { + context = (ALCcontext *)alCurrentContext; + } + + EnterCriticalSection(&context->Lock); + alListReleaseLock(alContextList); + + context->Suspended = TRUE; + + if(context->DllContext) + { + context->Device->AlcApi.alcSuspendContext(context->DllContext); + } + + LeaveCriticalSection(&context->Lock); + return; +} + + + + +//***************************************************************************** +// alcGetString +//***************************************************************************** +ALCAPI const ALCchar* ALCAPIENTRY alcGetString(ALCdevice* device, ALenum param) +{ +#ifdef _LOGCALLS + LOG("alcGetString device %p enum ", device); + switch (param) + { + case ALC_NO_ERROR: + LOG("ALC_NO_ERROR\n"); + break; + case ALC_INVALID_ENUM: + LOG("ALC_INVALID_ENUM\n"); + break; + case ALC_INVALID_VALUE: + LOG("ALC_INVALID_VALUE\n"); + break; + case ALC_INVALID_DEVICE: + LOG("ALC_INVALID_DEVICE\n"); + break; + case ALC_INVALID_CONTEXT: + LOG("ALC_INVALID_CONTEXT\n"); + break; + case ALC_DEFAULT_DEVICE_SPECIFIER: + LOG("ALC_DEFAULT_DEVICE_SPECIFIER\n"); + break; + case ALC_DEVICE_SPECIFIER: + LOG("ALC_DEVICE_SPECIFIER\n"); + break; + case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: + LOG("ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER\n"); + break; + case ALC_CAPTURE_DEVICE_SPECIFIER: + LOG("ALC_CAPTURE_DEVICE_SPECIFIER\n"); + break; + case ALC_ALL_DEVICES_SPECIFIER: + LOG("ALC_ALL_DEVICES_SPECIFIER\n"); + break; + case ALC_DEFAULT_ALL_DEVICES_SPECIFIER: + LOG("ALC_DEFAULT_ALL_DEVICES_SPECIFIER\n"); + break; + case ALC_EXTENSIONS: + LOG("ALC_EXTENSIONS\n"); + break; + default: + LOG("<Unknown>\n"); + break; + } +#endif + + const ALCchar* value = 0; + + if ((param != ALC_DEFAULT_DEVICE_SPECIFIER) && (param != ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) { + if(device) + { + if (device == g_CaptureDevice) + return g_CaptureDevice->AlcApi.alcGetString(g_CaptureDevice->CaptureDevice, param); + + return device->AlcApi.alcGetString(device->DllDevice, param); + } + } + + switch(param) + { + case ALC_NO_ERROR: + { + value = alcNoError; + } + break; + + case ALC_INVALID_ENUM: + { + value = alcErrInvalidEnum; + } + break; + + case ALC_INVALID_VALUE: + { + value = alcErrInvalidValue; + } + break; + + case ALC_INVALID_DEVICE: + { + value = alcErrInvalidDevice; + } + break; + + case ALC_INVALID_CONTEXT: + { + value = alcErrInvalidContext; + } + break; + + case ALC_DEFAULT_DEVICE_SPECIFIER: + BuildDeviceList(); + if (pszDefaultDeviceSpecifier) + value = pszDefaultDeviceSpecifier; + else + value = szEmptyString; + break; + + case ALC_DEVICE_SPECIFIER: + BuildDeviceList(); + if (pszDeviceSpecifierList) + value = pszDeviceSpecifierList; + else + value = szEmptyString; + break; + + case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: + BuildDeviceList(); + if (pszDefaultCaptureDeviceSpecifier) + value = pszDefaultCaptureDeviceSpecifier; + else + value = szEmptyString; + break; + + case ALC_CAPTURE_DEVICE_SPECIFIER: + BuildDeviceList(); + if (pszCaptureDeviceSpecifierList) + value = pszCaptureDeviceSpecifierList; + else + value = szEmptyString; + break; + + case ALC_ALL_DEVICES_SPECIFIER: + BuildDeviceList(); + if (pszAllDevicesSpecifierList) + value = pszAllDevicesSpecifierList; + else + value = szEmptyString; + break; + + case ALC_DEFAULT_ALL_DEVICES_SPECIFIER: + BuildDeviceList(); + if (pszDefaultAllDevicesSpecifier) + value = pszDefaultAllDevicesSpecifier; + else + value = szEmptyString; + break; + + default: + LastError = ALC_INVALID_ENUM; + break; + } + + return value; +} + + + + +//***************************************************************************** +// alcCaptureOpenDevice +//***************************************************************************** +ALCAPI ALCdevice * ALCAPIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei buffersize) +{ +#ifdef _LOGCALLS + LOG("alcCaptureOpenDevice device name '%s' frequency %d format %d buffersize %d\n", deviceName ? deviceName : "<NULL>", frequency, format, buffersize); +#endif + const ALchar *pszDeviceName = NULL; + + BuildDeviceList(); + + if (!g_pCaptureDeviceList) + return NULL; + + if (!g_CaptureDevice) { + g_CaptureDevice = (ALCdevice*)malloc(sizeof(ALCdevice)); + + if (g_CaptureDevice) + { + // clear + memset(g_CaptureDevice, 0, sizeof(ALCdevice)); + + // make sure we have a device name + if ((!deviceName) || (strlen(deviceName) == 0)) + pszDeviceName = pszDefaultCaptureDeviceSpecifier; + else + pszDeviceName = deviceName; + + g_CaptureDevice->Dll = LoadDevicesDLL(g_pCaptureDeviceList, pszDeviceName); + + if (g_CaptureDevice->Dll) { + if(FillOutAlcFunctions(g_CaptureDevice)) { + if (g_CaptureDevice->AlcApi.alcCaptureOpenDevice) { + g_CaptureDevice->CaptureDevice = g_CaptureDevice->AlcApi.alcCaptureOpenDevice(pszDeviceName, frequency, format, buffersize); + g_CaptureDevice->LastError = ALC_NO_ERROR; + g_CaptureDevice->InUse = 0; + } else { + g_CaptureDevice->LastError = ALC_INVALID_DEVICE; + } + } + } + } + } else { + // already open + g_CaptureDevice->LastError = ALC_INVALID_VALUE; + } + + if (g_CaptureDevice != NULL) { + if (g_CaptureDevice->CaptureDevice) { + return g_CaptureDevice; + } else { + free(g_CaptureDevice); + g_CaptureDevice = NULL; + return NULL; + } + } else { + return NULL; + } +} + + + + +//***************************************************************************** +// alcCaptureCloseDevice +//***************************************************************************** +ALCAPI ALCboolean ALCAPIENTRY alcCaptureCloseDevice(ALCdevice *device) +{ +#ifdef _LOGCALLS + LOG("alcCaptureCloseDevice device %p\n", device); +#endif + ALCboolean bReturn = ALC_FALSE; + + if (device == g_CaptureDevice) + { + if (g_CaptureDevice != NULL) { + if (g_CaptureDevice->AlcApi.alcCaptureCloseDevice) { + bReturn = g_CaptureDevice->AlcApi.alcCaptureCloseDevice(g_CaptureDevice->CaptureDevice); + delete g_CaptureDevice; + g_CaptureDevice = NULL; + } else { + g_CaptureDevice->LastError = ALC_INVALID_DEVICE; + } + } + } + + return bReturn; +} + + + + +//***************************************************************************** +// alcCaptureStart +//***************************************************************************** +ALCAPI ALCvoid ALCAPIENTRY alcCaptureStart(ALCdevice *device) +{ +#ifdef _LOGCALLS + LOG("alcCaptureStart device %p\n", device); +#endif + if (device == g_CaptureDevice) + { + if (g_CaptureDevice != NULL) { + if (g_CaptureDevice->AlcApi.alcCaptureStart) { + g_CaptureDevice->AlcApi.alcCaptureStart(g_CaptureDevice->CaptureDevice); + } else { + g_CaptureDevice->LastError = ALC_INVALID_DEVICE; + } + } + } + + return; +} + + + + +//***************************************************************************** +// alcCaptureStop +//***************************************************************************** +ALCAPI ALCvoid ALCAPIENTRY alcCaptureStop(ALCdevice *device) +{ +#ifdef _LOGCALLS + LOG("alcCaptureStop device %p\n", device); +#endif + if (device == g_CaptureDevice) + { + if (g_CaptureDevice != NULL) { + if (g_CaptureDevice->AlcApi.alcCaptureStop) { + g_CaptureDevice->AlcApi.alcCaptureStop(g_CaptureDevice->CaptureDevice); + } else { + g_CaptureDevice->LastError = ALC_INVALID_DEVICE; + } + } + } + + return; +} + + + + +//***************************************************************************** +// alcCaptureSamples +//***************************************************************************** +ALCAPI ALCvoid ALCAPIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) +{ +#ifdef _LOGCALLS + LOG("alcCaptureSamples device %p buffer %p samples %d\n", device, buffer, samples); +#endif + if (device == g_CaptureDevice) + { + if (g_CaptureDevice != NULL) { + if (g_CaptureDevice->AlcApi.alcCaptureSamples) { + g_CaptureDevice->AlcApi.alcCaptureSamples(g_CaptureDevice->CaptureDevice, buffer, samples); + } else { + g_CaptureDevice->LastError = ALC_INVALID_DEVICE; + } + } + } + + return; +} + +#ifdef _LOGCALLS +void OutputMessage(const char *szDebug,...) +{ + static FILE *pFile = NULL; + SYSTEMTIME sysTime; + va_list args; + + va_start(args, szDebug); + + if (!pFile) + { + pFile = fopen(LOGFILENAME, "w"); + GetLocalTime(&sysTime); + fprintf(pFile, "OpenAL Router\n\nLog Time : %d/%d/%d at %d:%s%d:%s%d\n\n", sysTime.wDay, sysTime.wMonth, sysTime.wYear, + sysTime.wHour, (sysTime.wMinute < 10) ? "0" : "", sysTime.wMinute, (sysTime.wSecond < 10) ? "0" : "", sysTime.wSecond); + } + + vfprintf(pFile, szDebug, args); + fflush(pFile); + + va_end(args); +} +#endif
\ No newline at end of file diff --git a/Router/resource.h b/Router/resource.h new file mode 100644 index 00000000..bdff6160 --- /dev/null +++ b/Router/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by openal32.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif |