aboutsummaryrefslogtreecommitdiffstats
path: root/Router
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2007-11-13 18:02:18 -0800
committerChris Robinson <[email protected]>2007-11-13 18:02:18 -0800
commitae5f4e9a742b07e004b330c04a72fac4457c9b58 (patch)
treed1d5c9fadd918d9346fb871033f60e8c91600a63 /Router
Initial import
Diffstat (limited to 'Router')
-rw-r--r--Router/OpenAL32.cpp135
-rw-r--r--Router/OpenAL32.h341
-rw-r--r--Router/OpenAL32.rc101
-rw-r--r--Router/al.cpp981
-rw-r--r--Router/alList.cpp1029
-rw-r--r--Router/alList.h433
-rw-r--r--Router/alc.cpp2332
-rw-r--r--Router/resource.h15
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