mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
209
Engine/source/sfx/openal/LoadOAL.h
Normal file
209
Engine/source/sfx/openal/LoadOAL.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _LOADOAL_H_
|
||||
#define _LOADOAL_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
# include "platform/platform.h"
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
# include <OpenAL/al.h>
|
||||
# include <OpenAL/alc.h>
|
||||
#else
|
||||
# include <al/al.h>
|
||||
# include <al/alc.h>
|
||||
#endif
|
||||
|
||||
#ifndef ALAPIENTRY
|
||||
#define ALAPIENTRY
|
||||
#endif
|
||||
|
||||
#ifndef ALCAPIENTRY
|
||||
#define ALCAPIENTRY
|
||||
#endif
|
||||
|
||||
// Open AL Function table definition
|
||||
|
||||
#ifndef _OPENALFNTABLE
|
||||
#define _OPENALFNTABLE
|
||||
|
||||
// AL 1.0 did not define the ALchar and ALCchar types, so define them here
|
||||
// if they don't exist
|
||||
|
||||
#ifndef ALchar
|
||||
#define ALchar char
|
||||
#endif
|
||||
|
||||
#ifndef ALCchar
|
||||
#define ALCchar char
|
||||
#endif
|
||||
|
||||
// Complete list of functions available in AL 1.0 implementations
|
||||
|
||||
typedef void (ALAPIENTRY *LPALENABLE)( ALenum capability );
|
||||
typedef void (ALAPIENTRY *LPALDISABLE)( ALenum capability );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISENABLED)( ALenum capability );
|
||||
typedef const ALchar* (ALAPIENTRY *LPALGETSTRING)( ALenum param );
|
||||
typedef void (ALAPIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data );
|
||||
typedef void (ALAPIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
|
||||
typedef void (ALAPIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
|
||||
typedef void (ALAPIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
|
||||
typedef ALboolean (ALAPIENTRY *LPALGETBOOLEAN)( ALenum param );
|
||||
typedef ALint (ALAPIENTRY *LPALGETINTEGER)( ALenum param );
|
||||
typedef ALfloat (ALAPIENTRY *LPALGETFLOAT)( ALenum param );
|
||||
typedef ALdouble (ALAPIENTRY *LPALGETDOUBLE)( ALenum param );
|
||||
typedef ALenum (ALAPIENTRY *LPALGETERROR)( void );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname );
|
||||
typedef void* (ALAPIENTRY *LPALGETPROCADDRESS)( const ALchar* fname );
|
||||
typedef ALenum (ALAPIENTRY *LPALGETENUMVALUE)( const ALchar* ename );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERF)( ALenum param, ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALLISTENERI)( ALenum param, ALint value );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources );
|
||||
typedef void (ALAPIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISSOURCE)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
|
||||
typedef void (ALAPIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPLAY)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCESTOP)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEREWIND)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEPAUSE)( ALuint sid );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
|
||||
typedef void (ALAPIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
|
||||
typedef void (ALAPIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers );
|
||||
typedef void (ALAPIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers );
|
||||
typedef ALboolean (ALAPIENTRY *LPALISBUFFER)( ALuint bid );
|
||||
typedef void (ALAPIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
|
||||
typedef void (ALAPIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
|
||||
typedef void (ALAPIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
|
||||
typedef void (ALAPIENTRY *LPALDOPPLERFACTOR)( ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALDOPPLERVELOCITY)( ALfloat value );
|
||||
typedef void (ALAPIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel );
|
||||
|
||||
typedef ALCcontext * (ALCAPIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
|
||||
typedef void (ALCAPIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
|
||||
typedef ALCcontext * (ALCAPIENTRY *LPALCGETCURRENTCONTEXT)( void );
|
||||
typedef ALCdevice * (ALCAPIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
|
||||
typedef ALCdevice * (ALCAPIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
|
||||
typedef ALCenum (ALCAPIENTRY *LPALCGETERROR)( ALCdevice *device );
|
||||
typedef ALCboolean (ALCAPIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
|
||||
typedef void * (ALCAPIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
|
||||
typedef ALCenum (ALCAPIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
|
||||
typedef const ALCchar* (ALCAPIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
|
||||
typedef void (ALCAPIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPALENABLE alEnable;
|
||||
LPALDISABLE alDisable;
|
||||
LPALISENABLED alIsEnabled;
|
||||
LPALGETBOOLEAN alGetBoolean;
|
||||
LPALGETINTEGER alGetInteger;
|
||||
LPALGETFLOAT alGetFloat;
|
||||
LPALGETDOUBLE alGetDouble;
|
||||
LPALGETBOOLEANV alGetBooleanv;
|
||||
LPALGETINTEGERV alGetIntegerv;
|
||||
LPALGETFLOATV alGetFloatv;
|
||||
LPALGETDOUBLEV alGetDoublev;
|
||||
LPALGETSTRING alGetString;
|
||||
LPALGETERROR alGetError;
|
||||
LPALISEXTENSIONPRESENT alIsExtensionPresent;
|
||||
LPALGETPROCADDRESS alGetProcAddress;
|
||||
LPALGETENUMVALUE alGetEnumValue;
|
||||
LPALLISTENERI alListeneri;
|
||||
LPALLISTENERF alListenerf;
|
||||
LPALLISTENER3F alListener3f;
|
||||
LPALLISTENERFV alListenerfv;
|
||||
LPALGETLISTENERI alGetListeneri;
|
||||
LPALGETLISTENERF alGetListenerf;
|
||||
LPALGETLISTENER3F alGetListener3f;
|
||||
LPALGETLISTENERFV alGetListenerfv;
|
||||
LPALGENSOURCES alGenSources;
|
||||
LPALDELETESOURCES alDeleteSources;
|
||||
LPALISSOURCE alIsSource;
|
||||
LPALSOURCEI alSourcei;
|
||||
LPALSOURCEF alSourcef;
|
||||
LPALSOURCE3F alSource3f;
|
||||
LPALSOURCEFV alSourcefv;
|
||||
LPALGETSOURCEI alGetSourcei;
|
||||
LPALGETSOURCEF alGetSourcef;
|
||||
LPALGETSOURCEFV alGetSourcefv;
|
||||
LPALSOURCEPLAYV alSourcePlayv;
|
||||
LPALSOURCESTOPV alSourceStopv;
|
||||
LPALSOURCEPLAY alSourcePlay;
|
||||
LPALSOURCEPAUSE alSourcePause;
|
||||
LPALSOURCESTOP alSourceStop;
|
||||
LPALSOURCEREWIND alSourceRewind;
|
||||
LPALGENBUFFERS alGenBuffers;
|
||||
LPALDELETEBUFFERS alDeleteBuffers;
|
||||
LPALISBUFFER alIsBuffer;
|
||||
LPALBUFFERDATA alBufferData;
|
||||
LPALGETBUFFERI alGetBufferi;
|
||||
LPALGETBUFFERF alGetBufferf;
|
||||
LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers;
|
||||
LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers;
|
||||
LPALDISTANCEMODEL alDistanceModel;
|
||||
LPALDOPPLERFACTOR alDopplerFactor;
|
||||
LPALDOPPLERVELOCITY alDopplerVelocity;
|
||||
LPALCGETSTRING alcGetString;
|
||||
LPALCGETINTEGERV alcGetIntegerv;
|
||||
LPALCOPENDEVICE alcOpenDevice;
|
||||
LPALCCLOSEDEVICE alcCloseDevice;
|
||||
LPALCCREATECONTEXT alcCreateContext;
|
||||
LPALCMAKECONTEXTCURRENT alcMakeContextCurrent;
|
||||
LPALCPROCESSCONTEXT alcProcessContext;
|
||||
LPALCGETCURRENTCONTEXT alcGetCurrentContext;
|
||||
LPALCGETCONTEXTSDEVICE alcGetContextsDevice;
|
||||
LPALCSUSPENDCONTEXT alcSuspendContext;
|
||||
LPALCDESTROYCONTEXT alcDestroyContext;
|
||||
LPALCGETERROR alcGetError;
|
||||
LPALCISEXTENSIONPRESENT alcIsExtensionPresent;
|
||||
LPALCGETPROCADDRESS alcGetProcAddress;
|
||||
LPALCGETENUMVALUE alcGetEnumValue;
|
||||
} OPENALFNTABLE, *LPOPENALFNTABLE;
|
||||
#endif
|
||||
|
||||
ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable);
|
||||
ALvoid UnloadOAL10Library();
|
||||
|
||||
#endif // _LOADOAL_H_
|
||||
314
Engine/source/sfx/openal/aldlist.cpp
Normal file
314
Engine/source/sfx/openal/aldlist.cpp
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (c) 2006, Creative Labs Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||
* the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
|
||||
* promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
#include "aldlist.h"
|
||||
#if defined(TORQUE_OS_MAC)
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
#include <al/alc.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Init call
|
||||
*/
|
||||
ALDeviceList::ALDeviceList( const OPENALFNTABLE &oalft )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( vDeviceInfo );
|
||||
|
||||
ALDEVICEINFO ALDeviceInfo;
|
||||
char *devices;
|
||||
int index;
|
||||
const char *defaultDeviceName;
|
||||
const char *actualDeviceName;
|
||||
|
||||
dMemcpy( &ALFunction, &oalft, sizeof( OPENALFNTABLE ) );
|
||||
|
||||
// DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
|
||||
vDeviceInfo.clear();
|
||||
vDeviceInfo.reserve(10);
|
||||
|
||||
defaultDeviceIndex = 0;
|
||||
|
||||
// grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices
|
||||
if (ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
|
||||
devices = (char *)ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
defaultDeviceName = (char *)ALFunction.alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
index = 0;
|
||||
// go through device list (each device terminated with a single NULL, list terminated with double NULL)
|
||||
while (*devices != 0) {
|
||||
if (dStrcmp(defaultDeviceName, devices) == 0) {
|
||||
defaultDeviceIndex = index;
|
||||
}
|
||||
ALCdevice *device = ALFunction.alcOpenDevice(devices);
|
||||
if (device) {
|
||||
ALCcontext *context = ALFunction.alcCreateContext(device, NULL);
|
||||
if (context) {
|
||||
ALFunction.alcMakeContextCurrent(context);
|
||||
// if new actual device name isn't already in the list, then add it...
|
||||
actualDeviceName = ALFunction.alcGetString(device, ALC_DEVICE_SPECIFIER);
|
||||
bool bNewName = true;
|
||||
for (int i = 0; i < GetNumDevices(); i++) {
|
||||
if (dStrcmp(GetDeviceName(i), actualDeviceName) == 0) {
|
||||
bNewName = false;
|
||||
}
|
||||
}
|
||||
if ((bNewName) && (actualDeviceName != NULL) && (dStrlen(actualDeviceName) > 0)) {
|
||||
dMemset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
|
||||
ALDeviceInfo.bSelected = true;
|
||||
dStrncpy(ALDeviceInfo.strDeviceName, actualDeviceName, sizeof(ALDeviceInfo.strDeviceName));
|
||||
ALFunction.alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
|
||||
ALFunction.alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
|
||||
|
||||
ALDeviceInfo.iCapsFlags = 0;
|
||||
|
||||
// Check for ALC Extensions
|
||||
if (ALFunction.alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALCapture;
|
||||
if (ALFunction.alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEFX;
|
||||
|
||||
// Check for AL Extensions
|
||||
if (ALFunction.alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALOffset;
|
||||
|
||||
if (ALFunction.alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALLinearDistance;
|
||||
if (ALFunction.alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALExponentDistance;
|
||||
|
||||
if (ALFunction.alIsExtensionPresent("EAX2.0") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEAX2;
|
||||
if (ALFunction.alIsExtensionPresent("EAX3.0") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEAX3;
|
||||
if (ALFunction.alIsExtensionPresent("EAX4.0") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEAX4;
|
||||
if (ALFunction.alIsExtensionPresent("EAX5.0") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEAX5;
|
||||
|
||||
if (ALFunction.alIsExtensionPresent("EAX-RAM") == AL_TRUE)
|
||||
ALDeviceInfo.iCapsFlags |= SFXALEAXRAM;
|
||||
|
||||
// Get Source Count
|
||||
ALDeviceInfo.uiSourceCount = GetMaxNumSources();
|
||||
|
||||
vDeviceInfo.push_back(ALDeviceInfo);
|
||||
}
|
||||
ALFunction.alcMakeContextCurrent(NULL);
|
||||
ALFunction.alcDestroyContext(context);
|
||||
}
|
||||
ALFunction.alcCloseDevice(device);
|
||||
}
|
||||
devices += dStrlen(devices) + 1;
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
ResetFilters();
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit call
|
||||
*/
|
||||
ALDeviceList::~ALDeviceList()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of devices in the complete device list
|
||||
*/
|
||||
int ALDeviceList::GetNumDevices()
|
||||
{
|
||||
return (int)vDeviceInfo.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the device name at an index in the complete device list
|
||||
*/
|
||||
const char *ALDeviceList::GetDeviceName(int index)
|
||||
{
|
||||
if (index < GetNumDevices())
|
||||
return vDeviceInfo[index].strDeviceName;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the major and minor version numbers for a device at a specified index in the complete list
|
||||
*/
|
||||
void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor)
|
||||
{
|
||||
if (index < GetNumDevices()) {
|
||||
if (*major)
|
||||
*major = vDeviceInfo[index].iMajorVersion;
|
||||
if (*minor)
|
||||
*minor = vDeviceInfo[index].iMinorVersion;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the maximum number of Sources that can be generate on the given device
|
||||
*/
|
||||
unsigned int ALDeviceList::GetMaxNumSources(int index)
|
||||
{
|
||||
if (index < GetNumDevices())
|
||||
return vDeviceInfo[index].uiSourceCount;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the extension is supported on the given device
|
||||
*/
|
||||
bool ALDeviceList::IsExtensionSupported(int index, SFXALCaps cap)
|
||||
{
|
||||
bool bReturn = false;
|
||||
|
||||
if (index < GetNumDevices())
|
||||
bReturn = vDeviceInfo[index].iCapsFlags & cap;
|
||||
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the index of the default device in the complete device list
|
||||
*/
|
||||
int ALDeviceList::GetDefaultDevice()
|
||||
{
|
||||
return defaultDeviceIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deselects devices which don't have the specified minimum version
|
||||
*/
|
||||
void ALDeviceList::FilterDevicesMinVer(int major, int minor)
|
||||
{
|
||||
int dMajor, dMinor;
|
||||
for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
|
||||
GetDeviceVersion(i, &dMajor, &dMinor);
|
||||
if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
|
||||
vDeviceInfo[i].bSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deselects devices which don't have the specified maximum version
|
||||
*/
|
||||
void ALDeviceList::FilterDevicesMaxVer(int major, int minor)
|
||||
{
|
||||
int dMajor, dMinor;
|
||||
for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
|
||||
GetDeviceVersion(i, &dMajor, &dMinor);
|
||||
if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
|
||||
vDeviceInfo[i].bSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deselects device which don't support the given extension name
|
||||
*/
|
||||
void ALDeviceList::FilterDevicesExtension(SFXALCaps cap)
|
||||
{
|
||||
for (unsigned int i = 0; i < vDeviceInfo.size(); i++)
|
||||
vDeviceInfo[i].bSelected = vDeviceInfo[i].iCapsFlags & cap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resets all filtering, such that all devices are in the list
|
||||
*/
|
||||
void ALDeviceList::ResetFilters()
|
||||
{
|
||||
for (int i = 0; i < GetNumDevices(); i++) {
|
||||
vDeviceInfo[i].bSelected = true;
|
||||
}
|
||||
filterIndex = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets index of first filtered device
|
||||
*/
|
||||
int ALDeviceList::GetFirstFilteredDevice()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GetNumDevices(); i++) {
|
||||
if (vDeviceInfo[i].bSelected == true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
filterIndex = i + 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets index of next filtered device
|
||||
*/
|
||||
int ALDeviceList::GetNextFilteredDevice()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = filterIndex; i < GetNumDevices(); i++) {
|
||||
if (vDeviceInfo[i].bSelected == true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
filterIndex = i + 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal function to detemine max number of Sources that can be generated
|
||||
*/
|
||||
unsigned int ALDeviceList::GetMaxNumSources()
|
||||
{
|
||||
ALuint uiSources[256];
|
||||
unsigned int iSourceCount = 0;
|
||||
|
||||
// Clear AL Error Code
|
||||
ALFunction.alGetError();
|
||||
|
||||
// Generate up to 256 Sources, checking for any errors
|
||||
for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
|
||||
{
|
||||
ALFunction.alGenSources(1, &uiSources[iSourceCount]);
|
||||
if (ALFunction.alGetError() != AL_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
// Release the Sources
|
||||
ALFunction.alDeleteSources(iSourceCount, uiSources);
|
||||
if (ALFunction.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
for (unsigned int i = 0; i < 256; i++)
|
||||
{
|
||||
ALFunction.alDeleteSources(1, &uiSources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return iSourceCount;
|
||||
}
|
||||
70
Engine/source/sfx/openal/aldlist.h
Normal file
70
Engine/source/sfx/openal/aldlist.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ALDEVICELIST_H
|
||||
#define ALDEVICELIST_H
|
||||
|
||||
#pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information"
|
||||
#include "core/util/tVector.h"
|
||||
#include "core/stringTable.h"
|
||||
#include "sfx/openal/sfxALCaps.h"
|
||||
#include "LoadOAL.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char strDeviceName[256];
|
||||
int iMajorVersion;
|
||||
int iMinorVersion;
|
||||
unsigned int uiSourceCount;
|
||||
int iCapsFlags;
|
||||
bool bSelected;
|
||||
} ALDEVICEINFO, *LPALDEVICEINFO;
|
||||
|
||||
class ALDeviceList
|
||||
{
|
||||
private:
|
||||
OPENALFNTABLE ALFunction;
|
||||
Vector<ALDEVICEINFO> vDeviceInfo;
|
||||
int defaultDeviceIndex;
|
||||
int filterIndex;
|
||||
|
||||
public:
|
||||
ALDeviceList ( const OPENALFNTABLE &oalft );
|
||||
~ALDeviceList ();
|
||||
int GetNumDevices();
|
||||
const char *GetDeviceName(int index);
|
||||
void GetDeviceVersion(int index, int *major, int *minor);
|
||||
unsigned int GetMaxNumSources(int index);
|
||||
bool IsExtensionSupported(int index, SFXALCaps caps);
|
||||
int GetDefaultDevice();
|
||||
void FilterDevicesMinVer(int major, int minor);
|
||||
void FilterDevicesMaxVer(int major, int minor);
|
||||
void FilterDevicesExtension(SFXALCaps caps);
|
||||
void ResetFilters();
|
||||
int GetFirstFilteredDevice();
|
||||
int GetNextFilteredDevice();
|
||||
|
||||
private:
|
||||
unsigned int GetMaxNumSources();
|
||||
};
|
||||
|
||||
#endif // ALDEVICELIST_H
|
||||
445
Engine/source/sfx/openal/mac/LoadOAL.mac.cpp
Normal file
445
Engine/source/sfx/openal/mac/LoadOAL.mac.cpp
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// TODO: Implement OpenAL loading code which is currently stubbed out.
|
||||
|
||||
#if defined(__MACOSX__) && !defined(TORQUE_OS_MAC)
|
||||
#define TORQUE_OS_MAC
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include "sfx/openal/LoadOAL.h"
|
||||
|
||||
ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
if (!lpOALFnTable)
|
||||
return AL_FALSE;
|
||||
|
||||
memset(lpOALFnTable, 0, sizeof(OPENALFNTABLE));
|
||||
|
||||
lpOALFnTable->alEnable = (LPALENABLE)alEnable;
|
||||
if (lpOALFnTable->alEnable == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alEnable' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDisable = (LPALDISABLE)alDisable;
|
||||
if (lpOALFnTable->alDisable == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDisable' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsEnabled = (LPALISENABLED)alIsEnabled;
|
||||
if (lpOALFnTable->alIsEnabled == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alIsEnabled' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBoolean = (LPALGETBOOLEAN)alGetBoolean;
|
||||
if (lpOALFnTable->alGetBoolean == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetBoolean' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetInteger = (LPALGETINTEGER)alGetInteger;
|
||||
if (lpOALFnTable->alGetInteger == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetInteger' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetFloat = (LPALGETFLOAT)alGetFloat;
|
||||
if (lpOALFnTable->alGetFloat == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetFloat' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetDouble = (LPALGETDOUBLE)alGetDouble;
|
||||
if (lpOALFnTable->alGetDouble == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetDouble' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBooleanv = (LPALGETBOOLEANV)alGetBooleanv;
|
||||
if (lpOALFnTable->alGetBooleanv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetBooleanv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetIntegerv = (LPALGETINTEGERV)alGetIntegerv;
|
||||
if (lpOALFnTable->alGetIntegerv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetIntegerv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetFloatv = (LPALGETFLOATV)alGetFloatv;
|
||||
if (lpOALFnTable->alGetFloatv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetFloatv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetDoublev = (LPALGETDOUBLEV)alGetDoublev;
|
||||
if (lpOALFnTable->alGetDoublev == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetDoublev' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetString = (LPALGETSTRING)alGetString;
|
||||
if (lpOALFnTable->alGetString == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetString' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetError = (LPALGETERROR)alGetError;
|
||||
if (lpOALFnTable->alGetError == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetError' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsExtensionPresent = (LPALISEXTENSIONPRESENT)alIsExtensionPresent;
|
||||
if (lpOALFnTable->alIsExtensionPresent == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alIsExtensionPresent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetProcAddress = (LPALGETPROCADDRESS)alGetProcAddress;
|
||||
if (lpOALFnTable->alGetProcAddress == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetProcAddress' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetEnumValue = (LPALGETENUMVALUE)alGetEnumValue;
|
||||
if (lpOALFnTable->alGetEnumValue == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetEnumValue' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListeneri = (LPALLISTENERI)alListeneri;
|
||||
if (lpOALFnTable->alListeneri == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alListeneri' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListenerf = (LPALLISTENERF)alListenerf;
|
||||
if (lpOALFnTable->alListenerf == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alListenerf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListener3f = (LPALLISTENER3F)alListener3f;
|
||||
if (lpOALFnTable->alListener3f == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alListener3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListenerfv = (LPALLISTENERFV)alListenerfv;
|
||||
if (lpOALFnTable->alListenerfv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alListenerfv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListeneri = (LPALGETLISTENERI)alGetListeneri;
|
||||
if (lpOALFnTable->alGetListeneri == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetListeneri' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListenerf =(LPALGETLISTENERF)alGetListenerf;
|
||||
if (lpOALFnTable->alGetListenerf == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetListenerf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListener3f = (LPALGETLISTENER3F)alGetListener3f;
|
||||
if (lpOALFnTable->alGetListener3f == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetListener3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListenerfv = (LPALGETLISTENERFV)alGetListenerfv;
|
||||
if (lpOALFnTable->alGetListenerfv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetListenerfv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGenSources = (LPALGENSOURCES)alGenSources;
|
||||
if (lpOALFnTable->alGenSources == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGenSources' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDeleteSources = (LPALDELETESOURCES)alDeleteSources;
|
||||
if (lpOALFnTable->alDeleteSources == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDeleteSources' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsSource = (LPALISSOURCE)alIsSource;
|
||||
if (lpOALFnTable->alIsSource == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alIsSource' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcei = (LPALSOURCEI)alSourcei;
|
||||
if (lpOALFnTable->alSourcei == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcei' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcef = (LPALSOURCEF)alSourcef;
|
||||
if (lpOALFnTable->alSourcef == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcef' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSource3f = (LPALSOURCE3F)alSource3f;
|
||||
if (lpOALFnTable->alSource3f == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSource3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcefv = (LPALSOURCEFV)alSourcefv;
|
||||
if (lpOALFnTable->alSourcefv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcefv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcei = (LPALGETSOURCEI)alGetSourcei;
|
||||
if (lpOALFnTable->alGetSourcei == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetSourcei' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcef = (LPALGETSOURCEF)alGetSourcef;
|
||||
if (lpOALFnTable->alGetSourcef == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetSourcef' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcefv = (LPALGETSOURCEFV)alGetSourcefv;
|
||||
if (lpOALFnTable->alGetSourcefv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetSourcefv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePlayv = (LPALSOURCEPLAYV)alSourcePlayv;
|
||||
if (lpOALFnTable->alSourcePlayv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcePlayv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceStopv = (LPALSOURCESTOPV)alSourceStopv;
|
||||
if (lpOALFnTable->alSourceStopv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourceStopv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePlay = (LPALSOURCEPLAY)alSourcePlay;
|
||||
if (lpOALFnTable->alSourcePlay == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcePlay' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePause = (LPALSOURCEPAUSE)alSourcePause;
|
||||
if (lpOALFnTable->alSourcePause == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourcePause' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceStop = (LPALSOURCESTOP)alSourceStop;
|
||||
if (lpOALFnTable->alSourceStop == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourceStop' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceRewind = (LPALSOURCEREWIND)alSourceRewind;
|
||||
if (lpOALFnTable->alSourceRewind == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourceRewind' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGenBuffers = (LPALGENBUFFERS)alGenBuffers;
|
||||
if (lpOALFnTable->alGenBuffers == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGenBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDeleteBuffers = (LPALDELETEBUFFERS)alDeleteBuffers;
|
||||
if (lpOALFnTable->alDeleteBuffers == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDeleteBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsBuffer = (LPALISBUFFER)alIsBuffer;
|
||||
if (lpOALFnTable->alIsBuffer == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alIsBuffer' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alBufferData = (LPALBUFFERDATA)alBufferData;
|
||||
if (lpOALFnTable->alBufferData == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alBufferData' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBufferi = (LPALGETBUFFERI)alGetBufferi;
|
||||
if (lpOALFnTable->alGetBufferi == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetBufferi' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBufferf = (LPALGETBUFFERF)alGetBufferf;
|
||||
if (lpOALFnTable->alGetBufferf == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alGetBufferf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceQueueBuffers = (LPALSOURCEQUEUEBUFFERS)alSourceQueueBuffers;
|
||||
if (lpOALFnTable->alSourceQueueBuffers == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourceQueueBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceUnqueueBuffers = (LPALSOURCEUNQUEUEBUFFERS)alSourceUnqueueBuffers;
|
||||
if (lpOALFnTable->alSourceUnqueueBuffers == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alSourceUnqueueBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDistanceModel = (LPALDISTANCEMODEL)alDistanceModel;
|
||||
if (lpOALFnTable->alDistanceModel == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDistanceModel' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDopplerFactor = (LPALDOPPLERFACTOR)alDopplerFactor;
|
||||
if (lpOALFnTable->alDopplerFactor == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDopplerFactor' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDopplerVelocity = (LPALDOPPLERVELOCITY)alDopplerVelocity;
|
||||
if (lpOALFnTable->alDopplerVelocity == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alDopplerVelocity' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetString = (LPALCGETSTRING)alcGetString;
|
||||
if (lpOALFnTable->alcGetString == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetString' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetIntegerv = (LPALCGETINTEGERV)alcGetIntegerv;
|
||||
if (lpOALFnTable->alcGetIntegerv == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetIntegerv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcOpenDevice = (LPALCOPENDEVICE)alcOpenDevice;
|
||||
if (lpOALFnTable->alcOpenDevice == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcOpenDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcCloseDevice = (LPALCCLOSEDEVICE)alcCloseDevice;
|
||||
if (lpOALFnTable->alcCloseDevice == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcCloseDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcCreateContext = (LPALCCREATECONTEXT)alcCreateContext;
|
||||
if (lpOALFnTable->alcCreateContext == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcCreateContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcMakeContextCurrent = (LPALCMAKECONTEXTCURRENT)alcMakeContextCurrent;
|
||||
if (lpOALFnTable->alcMakeContextCurrent == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcMakeContextCurrent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcProcessContext = (LPALCPROCESSCONTEXT)alcProcessContext;
|
||||
if (lpOALFnTable->alcProcessContext == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcProcessContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetCurrentContext = (LPALCGETCURRENTCONTEXT)alcGetCurrentContext;
|
||||
if (lpOALFnTable->alcGetCurrentContext == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetCurrentContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetContextsDevice = (LPALCGETCONTEXTSDEVICE)alcGetContextsDevice;
|
||||
if (lpOALFnTable->alcGetContextsDevice == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetContextsDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcSuspendContext = (LPALCSUSPENDCONTEXT)alcSuspendContext;
|
||||
if (lpOALFnTable->alcSuspendContext == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcSuspendContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcDestroyContext = (LPALCDESTROYCONTEXT)alcDestroyContext;
|
||||
if (lpOALFnTable->alcDestroyContext == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcDestroyContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetError = (LPALCGETERROR)alcGetError;
|
||||
if (lpOALFnTable->alcGetError == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetError' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcIsExtensionPresent = (LPALCISEXTENSIONPRESENT)alcIsExtensionPresent;
|
||||
if (lpOALFnTable->alcIsExtensionPresent == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcIsExtensionPresent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetProcAddress = (LPALCGETPROCADDRESS)alcGetProcAddress;
|
||||
if (lpOALFnTable->alcGetProcAddress == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetProcAddress' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetEnumValue = (LPALCGETENUMVALUE)alcGetEnumValue;
|
||||
if (lpOALFnTable->alcGetEnumValue == NULL)
|
||||
{
|
||||
warn("Failed to retrieve 'alcGetEnumValue' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
ALvoid UnloadOAL10Library()
|
||||
{
|
||||
// TODO: Implement this.
|
||||
}
|
||||
238
Engine/source/sfx/openal/sfxALBuffer.cpp
Normal file
238
Engine/source/sfx/openal/sfxALBuffer.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "sfx/openal/sfxALBuffer.h"
|
||||
#include "sfx/openal/sfxALVoice.h"
|
||||
#include "sfx/openal/sfxALDevice.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
#include "console/console.h"
|
||||
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
||||
|
||||
SFXALBuffer* SFXALBuffer::create( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware )
|
||||
{
|
||||
if( !_sfxFormatToALFormat( stream->getFormat() ) )
|
||||
{
|
||||
Con::errorf( "SFXALBuffer::create() - SFXFormat not supported by OpenAL" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SFXALBuffer *buffer = new SFXALBuffer( oalft,
|
||||
stream,
|
||||
description,
|
||||
useHardware );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
SFXALBuffer::SFXALBuffer( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware )
|
||||
: Parent( stream, description ),
|
||||
mOpenAL( oalft ),
|
||||
mUseHardware( useHardware ),
|
||||
mIs3d( description->mIs3D )
|
||||
{
|
||||
// Set up device buffers.
|
||||
|
||||
if( !isStreaming() )
|
||||
mOpenAL.alGenBuffers( 1, &mALBuffer );
|
||||
}
|
||||
|
||||
SFXALBuffer::~SFXALBuffer()
|
||||
{
|
||||
if( _getUniqueVoice() )
|
||||
_getUniqueVoice()->stop();
|
||||
|
||||
// Release buffers.
|
||||
if ( mOpenAL.alIsBuffer( mALBuffer ))
|
||||
mOpenAL.alDeleteBuffers( 1, &mALBuffer );
|
||||
|
||||
while( mFreeBuffers.size() )
|
||||
{
|
||||
ALuint buffer = mFreeBuffers.last();
|
||||
mOpenAL.alDeleteBuffers( 1, &buffer );
|
||||
mFreeBuffers.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num )
|
||||
{
|
||||
using namespace SFXInternal;
|
||||
|
||||
if( !num )
|
||||
return;
|
||||
|
||||
// If this is not a streaming buffer, just load the data into our single
|
||||
// static buffer.
|
||||
|
||||
if( !isStreaming() )
|
||||
{
|
||||
SFXStreamPacket* packet = packets[ num - 1 ];
|
||||
|
||||
ALenum alFormat = _sfxFormatToALFormat( getFormat() );
|
||||
AssertFatal( alFormat != 0, "SFXALBuffer::write() - format unsupported" );
|
||||
|
||||
mOpenAL.alBufferData( mALBuffer, alFormat,
|
||||
packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() );
|
||||
|
||||
destructSingle( packet );
|
||||
return;
|
||||
}
|
||||
|
||||
MutexHandle mutex;
|
||||
mutex.lock( &_getUniqueVoice()->mMutex, true );
|
||||
|
||||
// Unqueue processed packets.
|
||||
|
||||
ALuint source = _getUniqueVoice()->mSourceName;
|
||||
ALint numProcessed;
|
||||
mOpenAL.alGetSourcei( source, AL_BUFFERS_PROCESSED, &numProcessed );
|
||||
|
||||
for( U32 i = 0; i < numProcessed; ++ i )
|
||||
{
|
||||
// Unqueue the buffer.
|
||||
|
||||
ALuint buffer;
|
||||
mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer );
|
||||
|
||||
// Update the sample offset on the voice.
|
||||
|
||||
ALint size;
|
||||
mOpenAL.alGetBufferi( buffer, AL_SIZE, &size );
|
||||
_getUniqueVoice()->mSampleOffset += size / getFormat().getBytesPerSample();
|
||||
|
||||
// Push the buffer onto the freelist.
|
||||
|
||||
mFreeBuffers.push_back( buffer );
|
||||
}
|
||||
|
||||
// Queue buffers.
|
||||
|
||||
for( U32 i = 0; i < num; ++ i )
|
||||
{
|
||||
SFXStreamPacket* packet = packets[ i ];
|
||||
|
||||
// Allocate a buffer.
|
||||
|
||||
ALuint buffer;
|
||||
if( mFreeBuffers.size() )
|
||||
{
|
||||
buffer = mFreeBuffers.last();
|
||||
mFreeBuffers.pop_back();
|
||||
}
|
||||
else
|
||||
mOpenAL.alGenBuffers( 1, &buffer );
|
||||
|
||||
// Upload the data.
|
||||
|
||||
ALenum alFormat = _sfxFormatToALFormat( getFormat() );
|
||||
AssertFatal( alFormat != 0, "SFXALBuffer::write() - format unsupported" );
|
||||
AssertFatal( mOpenAL.alIsBuffer( buffer ), "SFXALBuffer::write() - buffer invalid" );
|
||||
|
||||
mOpenAL.alBufferData( buffer, alFormat,
|
||||
packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() );
|
||||
|
||||
destructSingle( packet );
|
||||
|
||||
// Queue the buffer.
|
||||
|
||||
mOpenAL.alSourceQueueBuffers( source, 1, &buffer );
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALBuffer::_flush()
|
||||
{
|
||||
AssertFatal( isStreaming(), "SFXALBuffer::_flush() - not a streaming buffer" );
|
||||
AssertFatal( SFXInternal::isSFXThread(), "SFXALBuffer::_flush() - not on SFX thread" );
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALBuffer] Flushing buffer" );
|
||||
#endif
|
||||
|
||||
_getUniqueVoice()->_stop();
|
||||
|
||||
MutexHandle mutex;
|
||||
mutex.lock( &_getUniqueVoice()->mMutex, true );
|
||||
|
||||
ALuint source = _getUniqueVoice()->mSourceName;
|
||||
|
||||
ALint numQueued;
|
||||
mOpenAL.alGetSourcei( source, AL_BUFFERS_QUEUED, &numQueued );
|
||||
|
||||
for( U32 i = 0; i < numQueued; ++ i )
|
||||
{
|
||||
ALuint buffer;
|
||||
mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer );
|
||||
mFreeBuffers.push_back( buffer );
|
||||
}
|
||||
|
||||
_getUniqueVoice()->mSampleOffset = 0;
|
||||
|
||||
//RD: disabling hack for now; rewritten queueing should be able to cope
|
||||
#if 0 //def TORQUE_OS_MAC
|
||||
|
||||
//WORKAROUND: Ugly hack on Mac. Apparently there's a bug in the OpenAL implementation
|
||||
// that will cause AL_BUFFERS_PROCESSED to not be reset as it should be causing write()
|
||||
// to fail. Brute-force this and just re-create the source. Let's pray that nobody
|
||||
// issues any concurrent state changes on the voice resulting in us losing state here.
|
||||
|
||||
ALuint newSource;
|
||||
mOpenAL.alGenSources( 1, &newSource );
|
||||
|
||||
#define COPY_F( name ) \
|
||||
{ \
|
||||
F32 val; \
|
||||
mOpenAL.alGetSourcef( source, name, &val ); \
|
||||
mOpenAL.alSourcef( source, name, val ); \
|
||||
}
|
||||
|
||||
#define COPY_FV( name ) \
|
||||
{ \
|
||||
VectorF val; \
|
||||
mOpenAL.alGetSourcefv( source, name, val ); \
|
||||
mOpenAL.alSourcefv( source, name, val ); \
|
||||
}
|
||||
|
||||
COPY_F( AL_REFERENCE_DISTANCE );
|
||||
COPY_F( AL_MAX_DISTANCE );
|
||||
COPY_F( AL_GAIN );
|
||||
COPY_F( AL_PITCH );
|
||||
COPY_F( AL_CONE_INNER_ANGLE );
|
||||
COPY_F( AL_CONE_OUTER_ANGLE );
|
||||
COPY_F( AL_CONE_OUTER_GAIN );
|
||||
|
||||
COPY_FV( AL_VELOCITY );
|
||||
COPY_FV( AL_POSITION );
|
||||
COPY_FV( AL_DIRECTION );
|
||||
|
||||
_getUniqueVoice()->mSourceName = newSource;
|
||||
mOpenAL.alDeleteSources( 1, &source );
|
||||
|
||||
#endif
|
||||
}
|
||||
119
Engine/source/sfx/openal/sfxALBuffer.h
Normal file
119
Engine/source/sfx/openal/sfxALBuffer.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXALBUFFER_H_
|
||||
#define _SFXALBUFFER_H_
|
||||
|
||||
#ifndef _LOADOAL_H
|
||||
#include "sfx/openal/LoadOAL.h"
|
||||
#endif
|
||||
#ifndef _SFXINTERNAL_H_
|
||||
#include "sfx/sfxInternal.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFXALVoice;
|
||||
|
||||
|
||||
class SFXALBuffer : public SFXBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXBuffer Parent;
|
||||
|
||||
friend class SFXALDevice;
|
||||
friend class SFXALVoice;
|
||||
|
||||
protected:
|
||||
|
||||
/// AL buffer in case this is a static, non-streaming buffer.
|
||||
ALuint mALBuffer;
|
||||
|
||||
/// Free buffers for use in queuing in case this is a streaming buffer.
|
||||
Vector< ALuint > mFreeBuffers;
|
||||
|
||||
///
|
||||
SFXALBuffer( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware );
|
||||
|
||||
///
|
||||
bool mIs3d;
|
||||
|
||||
///
|
||||
bool mUseHardware;
|
||||
|
||||
const OPENALFNTABLE &mOpenAL;
|
||||
|
||||
///
|
||||
ALenum _getALFormat() const
|
||||
{
|
||||
return _sfxFormatToALFormat( getFormat() );
|
||||
}
|
||||
|
||||
///
|
||||
static ALenum _sfxFormatToALFormat( const SFXFormat& format )
|
||||
{
|
||||
if( format.getChannels() == 2 )
|
||||
{
|
||||
const U32 bps = format.getBitsPerSample();
|
||||
if( bps == 16 )
|
||||
return AL_FORMAT_STEREO8;
|
||||
else if( bps == 32 )
|
||||
return AL_FORMAT_STEREO16;
|
||||
}
|
||||
else if( format.getChannels() == 1 )
|
||||
{
|
||||
const U32 bps = format.getBitsPerSample();
|
||||
if( bps == 8 )
|
||||
return AL_FORMAT_MONO8;
|
||||
else if( bps == 16 )
|
||||
return AL_FORMAT_MONO16;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///
|
||||
SFXALVoice* _getUniqueVoice() const
|
||||
{
|
||||
return ( SFXALVoice* ) mUniqueVoice.getPointer();
|
||||
}
|
||||
|
||||
// SFXBuffer.
|
||||
virtual void write( SFXInternal::SFXStreamPacket* const* packets, U32 num );
|
||||
void _flush();
|
||||
|
||||
public:
|
||||
|
||||
static SFXALBuffer* create( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware );
|
||||
|
||||
virtual ~SFXALBuffer();
|
||||
};
|
||||
|
||||
#endif // _SFXALBUFFER_H_
|
||||
40
Engine/source/sfx/openal/sfxALCaps.h
Normal file
40
Engine/source/sfx/openal/sfxALCaps.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXALCAPS_H_
|
||||
#define _SFXALCAPS_H_
|
||||
|
||||
enum SFXALCaps
|
||||
{
|
||||
SFXALCapture = 0,
|
||||
SFXALEFX,
|
||||
SFXALOffset,
|
||||
SFXALLinearDistance,
|
||||
SFXALExponentDistance,
|
||||
SFXALEAX2,
|
||||
SFXALEAX3,
|
||||
SFXALEAX4,
|
||||
SFXALEAX5,
|
||||
SFXALEAXRAM
|
||||
};
|
||||
|
||||
#endif
|
||||
199
Engine/source/sfx/openal/sfxALDevice.cpp
Normal file
199
Engine/source/sfx/openal/sfxALDevice.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "sfx/openal/sfxALDevice.h"
|
||||
#include "sfx/openal/sfxALBuffer.h"
|
||||
#include "platform/async/asyncUpdate.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXALDevice::SFXALDevice( SFXProvider *provider,
|
||||
const OPENALFNTABLE &openal,
|
||||
String name,
|
||||
bool useHardware,
|
||||
S32 maxBuffers )
|
||||
: Parent( name, provider, useHardware, maxBuffers ),
|
||||
mOpenAL( openal ),
|
||||
mDevice( NULL ),
|
||||
mContext( NULL )
|
||||
{
|
||||
mMaxBuffers = getMax( maxBuffers, 8 );
|
||||
|
||||
// TODO: The OpenAL device doesn't set the primary buffer
|
||||
// $pref::SFX::frequency or $pref::SFX::bitrate!
|
||||
|
||||
mDevice = mOpenAL.alcOpenDevice( name );
|
||||
mOpenAL.alcGetError( mDevice );
|
||||
if( mDevice )
|
||||
{
|
||||
mContext = mOpenAL.alcCreateContext( mDevice, NULL );
|
||||
|
||||
if( mContext )
|
||||
mOpenAL.alcMakeContextCurrent( mContext );
|
||||
|
||||
U32 err = mOpenAL.alcGetError( mDevice );
|
||||
|
||||
if( err != ALC_NO_ERROR )
|
||||
Con::errorf( "SFXALDevice - Initialization Error: %s", mOpenAL.alcGetString( mDevice, err ) );
|
||||
}
|
||||
|
||||
AssertFatal( mDevice != NULL && mContext != NULL, "Failed to create OpenAL device and/or context!" );
|
||||
|
||||
// Start the update thread.
|
||||
|
||||
if( !Con::getBoolVariable( "$_forceAllMainThread" ) )
|
||||
{
|
||||
SFXInternal::gUpdateThread = new AsyncPeriodicUpdateThread
|
||||
( "OpenAL Update Thread", SFXInternal::gBufferUpdateList,
|
||||
Con::getIntVariable( "$pref::SFX::updateInterval", SFXInternal::DEFAULT_UPDATE_INTERVAL ) );
|
||||
SFXInternal::gUpdateThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXALDevice::~SFXALDevice()
|
||||
{
|
||||
_releaseAllResources();
|
||||
|
||||
mOpenAL.alcMakeContextCurrent( NULL );
|
||||
mOpenAL.alcDestroyContext( mContext );
|
||||
mOpenAL.alcCloseDevice( mDevice );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXBuffer* SFXALDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
|
||||
{
|
||||
AssertFatal( stream, "SFXALDevice::createBuffer() - Got null stream!" );
|
||||
AssertFatal( description, "SFXALDevice::createBuffer() - Got null description!" );
|
||||
|
||||
SFXALBuffer* buffer = SFXALBuffer::create( mOpenAL,
|
||||
stream,
|
||||
description,
|
||||
mUseHardware );
|
||||
if ( !buffer )
|
||||
return NULL;
|
||||
|
||||
_addBuffer( buffer );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXVoice* SFXALDevice::createVoice( bool is3D, SFXBuffer *buffer )
|
||||
{
|
||||
// Don't bother going any further if we've
|
||||
// exceeded the maximum voices.
|
||||
if ( mVoices.size() >= mMaxBuffers )
|
||||
return NULL;
|
||||
|
||||
AssertFatal( buffer, "SFXALDevice::createVoice() - Got null buffer!" );
|
||||
|
||||
SFXALBuffer* alBuffer = dynamic_cast<SFXALBuffer*>( buffer );
|
||||
AssertFatal( alBuffer, "SFXALDevice::createVoice() - Got bad buffer!" );
|
||||
|
||||
SFXALVoice* voice = SFXALVoice::create( this, alBuffer );
|
||||
if ( !voice )
|
||||
return NULL;
|
||||
|
||||
_addVoice( voice );
|
||||
return voice;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXALDevice::setListener( U32 index, const SFXListenerProperties& listener )
|
||||
{
|
||||
if( index != 0 )
|
||||
return;
|
||||
|
||||
// Torque and OpenAL are both right handed
|
||||
// systems, so no coordinate flipping is needed.
|
||||
|
||||
const MatrixF &transform = listener.getTransform();
|
||||
Point3F pos, tupple[2];
|
||||
transform.getColumn( 3, &pos );
|
||||
transform.getColumn( 1, &tupple[0] );
|
||||
transform.getColumn( 2, &tupple[1] );
|
||||
|
||||
const VectorF &velocity = listener.getVelocity();
|
||||
|
||||
mOpenAL.alListenerfv( AL_POSITION, pos );
|
||||
mOpenAL.alListenerfv( AL_VELOCITY, velocity );
|
||||
mOpenAL.alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXALDevice::setDistanceModel( SFXDistanceModel model )
|
||||
{
|
||||
switch( model )
|
||||
{
|
||||
case SFXDistanceModelLinear:
|
||||
mOpenAL.alDistanceModel( AL_LINEAR_DISTANCE_CLAMPED );
|
||||
if( mRolloffFactor != 1.0f )
|
||||
_setRolloffFactor( 1.0f ); // No rolloff on linear.
|
||||
break;
|
||||
|
||||
case SFXDistanceModelLogarithmic:
|
||||
mOpenAL.alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
|
||||
if( mUserRolloffFactor != mRolloffFactor )
|
||||
_setRolloffFactor( mUserRolloffFactor );
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertWarn( false, "SFXALDevice::setDistanceModel - distance model not implemented" );
|
||||
}
|
||||
|
||||
mDistanceModel = model;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXALDevice::setDopplerFactor( F32 factor )
|
||||
{
|
||||
mOpenAL.alDopplerFactor( factor );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXALDevice::_setRolloffFactor( F32 factor )
|
||||
{
|
||||
mRolloffFactor = factor;
|
||||
|
||||
for( U32 i = 0, num = mVoices.size(); i < num; ++ i )
|
||||
mOpenAL.alSourcef( ( ( SFXALVoice* ) mVoices[ i ] )->mSourceName, AL_ROLLOFF_FACTOR, factor );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXALDevice::setRolloffFactor( F32 factor )
|
||||
{
|
||||
if( mDistanceModel == SFXDistanceModelLinear && factor != 1.0f )
|
||||
Con::errorf( "SFXALDevice::setRolloffFactor - rolloff factor <> 1.0f ignored in linear distance model" );
|
||||
else
|
||||
_setRolloffFactor( factor );
|
||||
|
||||
mUserRolloffFactor = factor;
|
||||
}
|
||||
90
Engine/source/sfx/openal/sfxALDevice.h
Normal file
90
Engine/source/sfx/openal/sfxALDevice.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXALDEVICE_H_
|
||||
#define _SFXALDEVICE_H_
|
||||
|
||||
class SFXProvider;
|
||||
|
||||
#ifndef _SFXDEVICE_H_
|
||||
# include "sfx/sfxDevice.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SFXPROVIDER_H_
|
||||
# include "sfx/sfxProvider.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SFXALBUFFER_H_
|
||||
# include "sfx/openal/sfxALBuffer.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SFXALVOICE_H_
|
||||
# include "sfx/openal/sfxALVoice.h"
|
||||
#endif
|
||||
|
||||
#ifndef _OPENALFNTABLE
|
||||
# include "sfx/openal/LoadOAL.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFXALDevice : public SFXDevice
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXDevice Parent;
|
||||
friend class SFXALVoice; // mDistanceFactor, mRolloffFactor
|
||||
|
||||
SFXALDevice( SFXProvider *provider,
|
||||
const OPENALFNTABLE &openal,
|
||||
String name,
|
||||
bool useHardware,
|
||||
S32 maxBuffers );
|
||||
|
||||
virtual ~SFXALDevice();
|
||||
|
||||
protected:
|
||||
|
||||
OPENALFNTABLE mOpenAL;
|
||||
|
||||
ALCcontext *mContext;
|
||||
|
||||
ALCdevice *mDevice;
|
||||
|
||||
SFXDistanceModel mDistanceModel;
|
||||
F32 mDistanceFactor;
|
||||
F32 mRolloffFactor;
|
||||
F32 mUserRolloffFactor;
|
||||
|
||||
void _setRolloffFactor( F32 factor );
|
||||
|
||||
public:
|
||||
|
||||
// SFXDevice.
|
||||
virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
|
||||
virtual SFXVoice* createVoice( bool is3D, SFXBuffer *buffer );
|
||||
virtual void setListener( U32 index, const SFXListenerProperties& listener );
|
||||
virtual void setDistanceModel( SFXDistanceModel model );
|
||||
virtual void setDopplerFactor( F32 factor );
|
||||
virtual void setRolloffFactor( F32 factor );
|
||||
};
|
||||
|
||||
#endif // _SFXALDEVICE_H_
|
||||
146
Engine/source/sfx/openal/sfxALProvider.cpp
Normal file
146
Engine/source/sfx/openal/sfxALProvider.cpp
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "sfx/sfxProvider.h"
|
||||
#include "sfx/openal/sfxALDevice.h"
|
||||
#include "sfx/openal/aldlist.h"
|
||||
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "console/console.h"
|
||||
#include "core/module.h"
|
||||
|
||||
|
||||
class SFXALProvider : public SFXProvider
|
||||
{
|
||||
public:
|
||||
|
||||
SFXALProvider()
|
||||
: SFXProvider( "OpenAL" ) { mALDL = NULL; }
|
||||
virtual ~SFXALProvider();
|
||||
|
||||
protected:
|
||||
OPENALFNTABLE mOpenAL;
|
||||
ALDeviceList *mALDL;
|
||||
|
||||
struct ALDeviceInfo : SFXDeviceInfo
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
void init();
|
||||
|
||||
public:
|
||||
SFXDevice *createDevice( const String& deviceName, bool useHardware, S32 maxBuffers );
|
||||
|
||||
};
|
||||
|
||||
MODULE_BEGIN( OpenAL )
|
||||
|
||||
MODULE_INIT_BEFORE( SFX )
|
||||
MODULE_SHUTDOWN_AFTER( SFX )
|
||||
|
||||
SFXALProvider* mProvider;
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
mProvider = new SFXALProvider;
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
delete mProvider;
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
void SFXALProvider::init()
|
||||
{
|
||||
if( LoadOAL10Library( NULL, &mOpenAL ) != AL_TRUE )
|
||||
{
|
||||
Con::printf( "SFXALProvider - OpenAL not available." );
|
||||
return;
|
||||
}
|
||||
mALDL = new ALDeviceList( mOpenAL );
|
||||
|
||||
// Did we get any devices?
|
||||
if ( mALDL->GetNumDevices() < 1 )
|
||||
{
|
||||
Con::printf( "SFXALProvider - No valid devices found!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Cool, loop through them, and caps em
|
||||
const char *deviceFormat = "OpenAL v%d.%d %s";
|
||||
|
||||
char temp[256];
|
||||
for( int i = 0; i < mALDL->GetNumDevices(); i++ )
|
||||
{
|
||||
ALDeviceInfo* info = new ALDeviceInfo;
|
||||
|
||||
info->name = String( mALDL->GetDeviceName( i ) );
|
||||
|
||||
int major, minor, eax = 0;
|
||||
|
||||
mALDL->GetDeviceVersion( i, &major, &minor );
|
||||
|
||||
// Apologies for the blatent enum hack -patw
|
||||
for( int j = SFXALEAX2; j < SFXALEAXRAM; j++ )
|
||||
eax += (int)mALDL->IsExtensionSupported( i, (SFXALCaps)j );
|
||||
|
||||
if( eax > 0 )
|
||||
{
|
||||
eax += 2; // EAX support starts at 2.0
|
||||
dSprintf( temp, sizeof( temp ), "[EAX %d.0] %s", eax, ( mALDL->IsExtensionSupported( i, SFXALEAXRAM ) ? "EAX-RAM" : "" ) );
|
||||
}
|
||||
else
|
||||
dStrcpy( temp, "" );
|
||||
|
||||
info->driver = String::ToString( deviceFormat, major, minor, temp );
|
||||
info->hasHardware = eax > 0;
|
||||
info->maxBuffers = mALDL->GetMaxNumSources( i );
|
||||
|
||||
mDeviceInfo.push_back( info );
|
||||
}
|
||||
|
||||
regProvider( this );
|
||||
}
|
||||
|
||||
SFXALProvider::~SFXALProvider()
|
||||
{
|
||||
UnloadOAL10Library();
|
||||
|
||||
if (mALDL)
|
||||
delete mALDL;
|
||||
}
|
||||
|
||||
SFXDevice *SFXALProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers )
|
||||
{
|
||||
ALDeviceInfo *info = dynamic_cast< ALDeviceInfo* >
|
||||
( _findDeviceInfo( deviceName) );
|
||||
|
||||
// Do we find one to create?
|
||||
if ( info )
|
||||
return new SFXALDevice( this, mOpenAL, info->name, useHardware, maxBuffers );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
257
Engine/source/sfx/openal/sfxALVoice.cpp
Normal file
257
Engine/source/sfx/openal/sfxALVoice.cpp
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "sfx/openal/sfxALVoice.h"
|
||||
#include "sfx/openal/sfxALBuffer.h"
|
||||
#include "sfx/openal/sfxALDevice.h"
|
||||
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
# define AL_SANITY_CHECK() \
|
||||
AssertFatal( mOpenAL.alIsSource( mSourceName ), "AL Source Sanity Check Failed!" );
|
||||
#else
|
||||
# define AL_SANITY_CHECK()
|
||||
#endif
|
||||
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
||||
|
||||
SFXALVoice* SFXALVoice::create( SFXALDevice* device, SFXALBuffer *buffer )
|
||||
{
|
||||
AssertFatal( buffer, "SFXALVoice::create() - Got null buffer!" );
|
||||
|
||||
ALuint sourceName;
|
||||
device->mOpenAL.alGenSources( 1, &sourceName );
|
||||
AssertFatal( device->mOpenAL.alIsSource( sourceName ), "AL Source Sanity Check Failed!" );
|
||||
|
||||
// Is this 3d?
|
||||
// Okay, this looks odd, but bear with me for a moment. AL_SOURCE_RELATIVE does NOT indicate
|
||||
// whether or not the volume of the sound should change depending on the position of the listener.
|
||||
// OpenAL assumes that the volume will ALWAYS depend on the position of the listener. What AL_SOURCE_RELATIVE
|
||||
// does do is dictate if the position of THIS SOURCE is relative to the listener. If AL_SOURCE_RELATIVE is AL_TRUE
|
||||
// and the source's position is 0, 0, 0, then the source is directly on top of the listener at all times, which is what
|
||||
// we want for non-3d sounds.
|
||||
device->mOpenAL.alSourcei( sourceName, AL_SOURCE_RELATIVE, ( buffer->mIs3d ? AL_FALSE : AL_TRUE ) );
|
||||
|
||||
if( buffer->mIs3d )
|
||||
device->mOpenAL.alSourcef( sourceName, AL_ROLLOFF_FACTOR, device->mRolloffFactor );
|
||||
|
||||
SFXALVoice *voice = new SFXALVoice( device->mOpenAL,
|
||||
buffer,
|
||||
sourceName );
|
||||
|
||||
return voice;
|
||||
}
|
||||
|
||||
SFXALVoice::SFXALVoice( const OPENALFNTABLE &oalft,
|
||||
SFXALBuffer *buffer,
|
||||
ALuint sourceName )
|
||||
|
||||
: Parent( buffer ),
|
||||
mOpenAL( oalft ),
|
||||
mResumeAtSampleOffset( -1.0f ),
|
||||
mSourceName( sourceName ),
|
||||
mSampleOffset( 0 )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
}
|
||||
|
||||
SFXALVoice::~SFXALVoice()
|
||||
{
|
||||
mOpenAL.alDeleteSources( 1, &mSourceName );
|
||||
}
|
||||
|
||||
void SFXALVoice::_lateBindStaticBufferIfNecessary()
|
||||
{
|
||||
if( !mBuffer->isStreaming() )
|
||||
{
|
||||
ALint bufferId;
|
||||
mOpenAL.alGetSourcei( mSourceName, AL_BUFFER, &bufferId );
|
||||
if( !bufferId )
|
||||
mOpenAL.alSourcei( mSourceName, AL_BUFFER, _getBuffer()->mALBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SFXStatus SFXALVoice::_status() const
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
ALint state;
|
||||
mOpenAL.alGetSourcei( mSourceName, AL_SOURCE_STATE, &state );
|
||||
|
||||
switch( state )
|
||||
{
|
||||
case AL_PLAYING: return SFXStatusPlaying;
|
||||
case AL_PAUSED: return SFXStatusPaused;
|
||||
default: return SFXStatusStopped;
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALVoice::_play()
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
_lateBindStaticBufferIfNecessary();
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALVoice] Starting playback" );
|
||||
#endif
|
||||
|
||||
mOpenAL.alSourcePlay( mSourceName );
|
||||
|
||||
//WORKAROUND: Adjust play cursor for buggy OAL when resuming playback. Do this after alSourcePlay
|
||||
// as it is the play function that will cause the cursor to jump.
|
||||
|
||||
if( mResumeAtSampleOffset != -1.0f )
|
||||
{
|
||||
mOpenAL.alSourcef( mSourceName, AL_SAMPLE_OFFSET, mResumeAtSampleOffset );
|
||||
mResumeAtSampleOffset = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALVoice::_pause()
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALVoice] Pausing playback" );
|
||||
#endif
|
||||
|
||||
mOpenAL.alSourcePause( mSourceName );
|
||||
|
||||
//WORKAROUND: Another workaround for buggy OAL. Resuming playback of a paused source will cause the
|
||||
// play cursor to jump. Save the cursor so we can manually move it into position in _play(). Sigh.
|
||||
|
||||
mOpenAL.alGetSourcef( mSourceName, AL_SAMPLE_OFFSET, &mResumeAtSampleOffset );
|
||||
}
|
||||
|
||||
void SFXALVoice::_stop()
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALVoice] Stopping playback" );
|
||||
#endif
|
||||
|
||||
mOpenAL.alSourceStop( mSourceName );
|
||||
mSampleOffset = 0;
|
||||
|
||||
mResumeAtSampleOffset = -1.0f;
|
||||
}
|
||||
|
||||
void SFXALVoice::_seek( U32 sample )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
_lateBindStaticBufferIfNecessary();
|
||||
mOpenAL.alSourcei( mSourceName, AL_SAMPLE_OFFSET, sample );
|
||||
|
||||
mResumeAtSampleOffset = -1.0f;
|
||||
}
|
||||
|
||||
U32 SFXALVoice::_tell() const
|
||||
{
|
||||
// Flush processed buffers as AL_SAMPLE_OFFSET will snap back to zero as soon
|
||||
// as the queue is processed in whole.
|
||||
|
||||
if( mBuffer->isStreaming() )
|
||||
mBuffer->write( NULL, 0 );
|
||||
|
||||
ALint pos;
|
||||
mOpenAL.alGetSourcei( mSourceName, AL_SAMPLE_OFFSET, &pos );
|
||||
return ( pos + mSampleOffset );
|
||||
}
|
||||
|
||||
void SFXALVoice::setMinMaxDistance( F32 min, F32 max )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
mOpenAL.alSourcef( mSourceName, AL_REFERENCE_DISTANCE, min );
|
||||
mOpenAL.alSourcef( mSourceName, AL_MAX_DISTANCE, max );
|
||||
}
|
||||
|
||||
void SFXALVoice::play( bool looping )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
mOpenAL.alSourceStop( mSourceName );
|
||||
if( !mBuffer->isStreaming() )
|
||||
mOpenAL.alSourcei( mSourceName, AL_LOOPING, ( looping ? AL_TRUE : AL_FALSE ) );
|
||||
|
||||
Parent::play( looping );
|
||||
}
|
||||
|
||||
void SFXALVoice::setVelocity( const VectorF& velocity )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
// Torque and OpenAL are both right handed
|
||||
// systems, so no coordinate flipping is needed.
|
||||
|
||||
mOpenAL.alSourcefv( mSourceName, AL_VELOCITY, velocity );
|
||||
}
|
||||
|
||||
void SFXALVoice::setTransform( const MatrixF& transform )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
// Torque and OpenAL are both right handed
|
||||
// systems, so no coordinate flipping is needed.
|
||||
|
||||
Point3F pos, dir;
|
||||
transform.getColumn( 3, &pos );
|
||||
transform.getColumn( 1, &dir );
|
||||
|
||||
mOpenAL.alSourcefv( mSourceName, AL_POSITION, pos );
|
||||
mOpenAL.alSourcefv( mSourceName, AL_DIRECTION, dir );
|
||||
}
|
||||
|
||||
void SFXALVoice::setVolume( F32 volume )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
mOpenAL.alSourcef( mSourceName, AL_GAIN, volume );
|
||||
}
|
||||
|
||||
void SFXALVoice::setPitch( F32 pitch )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
mOpenAL.alSourcef( mSourceName, AL_PITCH, pitch );
|
||||
}
|
||||
|
||||
void SFXALVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
|
||||
{
|
||||
AL_SANITY_CHECK();
|
||||
|
||||
mOpenAL.alSourcef( mSourceName, AL_CONE_INNER_ANGLE, innerAngle );
|
||||
mOpenAL.alSourcef( mSourceName, AL_CONE_OUTER_ANGLE, outerAngle );
|
||||
mOpenAL.alSourcef( mSourceName, AL_CONE_OUTER_GAIN, outerVolume );
|
||||
}
|
||||
|
||||
void SFXALVoice::setRolloffFactor( F32 factor )
|
||||
{
|
||||
mOpenAL.alSourcef( mSourceName, AL_ROLLOFF_FACTOR, factor );
|
||||
}
|
||||
107
Engine/source/sfx/openal/sfxALVoice.h
Normal file
107
Engine/source/sfx/openal/sfxALVoice.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SFXALVOICE_H_
|
||||
#define _SFXALVOICE_H_
|
||||
|
||||
#ifndef _SFXVOICE_H_
|
||||
#include "sfx/sfxVoice.h"
|
||||
#endif
|
||||
#ifndef _OPENALFNTABLE
|
||||
#include "sfx/openal/LoadOAL.h"
|
||||
#endif
|
||||
#ifndef _PLATFORM_THREADS_MUTEX_H_
|
||||
#include "platform/threads/mutex.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFXALBuffer;
|
||||
class SFXALDevice;
|
||||
|
||||
class SFXALVoice : public SFXVoice
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXVoice Parent;
|
||||
friend class SFXALDevice;
|
||||
friend class SFXALBuffer;
|
||||
|
||||
protected:
|
||||
|
||||
SFXALVoice( const OPENALFNTABLE &oalft,
|
||||
SFXALBuffer *buffer,
|
||||
ALuint sourceName );
|
||||
|
||||
ALuint mSourceName;
|
||||
|
||||
/// Buggy OAL jumps around when pausing. Save playback cursor here.
|
||||
F32 mResumeAtSampleOffset;
|
||||
|
||||
/// Amount by which OAL's reported sample position is offset.
|
||||
///
|
||||
/// OAL's sample position is relative to the current queue state,
|
||||
/// so we manually need to keep track of how far into the total
|
||||
/// queue we are.
|
||||
U32 mSampleOffset;
|
||||
|
||||
Mutex mMutex;
|
||||
|
||||
const OPENALFNTABLE &mOpenAL;
|
||||
|
||||
///
|
||||
SFXALBuffer* _getBuffer() const
|
||||
{
|
||||
return ( SFXALBuffer* ) mBuffer.getPointer();
|
||||
}
|
||||
|
||||
/// For non-streaming buffers, late-bind the audio buffer
|
||||
/// to the source as OAL will not accept writes to buffers
|
||||
/// already bound.
|
||||
void _lateBindStaticBufferIfNecessary();
|
||||
|
||||
// SFXVoice.
|
||||
virtual SFXStatus _status() const;
|
||||
virtual void _play();
|
||||
virtual void _pause();
|
||||
virtual void _stop();
|
||||
virtual void _seek( U32 sample );
|
||||
virtual U32 _tell() const;
|
||||
|
||||
public:
|
||||
|
||||
static SFXALVoice* create( SFXALDevice* device,
|
||||
SFXALBuffer *buffer );
|
||||
|
||||
virtual ~SFXALVoice();
|
||||
|
||||
/// SFXVoice
|
||||
void setMinMaxDistance( F32 min, F32 max );
|
||||
void play( bool looping );
|
||||
void setVelocity( const VectorF& velocity );
|
||||
void setTransform( const MatrixF& transform );
|
||||
void setVolume( F32 volume );
|
||||
void setPitch( F32 pitch );
|
||||
void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
|
||||
void setRolloffFactor( F32 factor );
|
||||
};
|
||||
|
||||
#endif // _SFXALVOICE_H_
|
||||
454
Engine/source/sfx/openal/win32/LoadOAL.cpp
Normal file
454
Engine/source/sfx/openal/win32/LoadOAL.cpp
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Copyright (c) 2006, Creative Labs Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||
* the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
|
||||
* promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "sfx/openal/LoadOAL.h"
|
||||
|
||||
HINSTANCE g_hOpenALDLL = NULL;
|
||||
|
||||
ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable)
|
||||
{
|
||||
if (!lpOALFnTable)
|
||||
return AL_FALSE;
|
||||
|
||||
if (szOALFullPathName)
|
||||
g_hOpenALDLL = LoadLibraryA(szOALFullPathName);
|
||||
else
|
||||
g_hOpenALDLL = LoadLibraryA("openal32.dll");
|
||||
|
||||
if (!g_hOpenALDLL)
|
||||
return AL_FALSE;
|
||||
|
||||
memset(lpOALFnTable, 0, sizeof(OPENALFNTABLE));
|
||||
|
||||
// Get function pointers
|
||||
lpOALFnTable->alEnable = (LPALENABLE)GetProcAddress(g_hOpenALDLL, "alEnable");
|
||||
if (lpOALFnTable->alEnable == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alEnable' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDisable = (LPALDISABLE)GetProcAddress(g_hOpenALDLL, "alDisable");
|
||||
if (lpOALFnTable->alDisable == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDisable' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsEnabled = (LPALISENABLED)GetProcAddress(g_hOpenALDLL, "alIsEnabled");
|
||||
if (lpOALFnTable->alIsEnabled == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alIsEnabled' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBoolean = (LPALGETBOOLEAN)GetProcAddress(g_hOpenALDLL, "alGetBoolean");
|
||||
if (lpOALFnTable->alGetBoolean == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetBoolean' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetInteger = (LPALGETINTEGER)GetProcAddress(g_hOpenALDLL, "alGetInteger");
|
||||
if (lpOALFnTable->alGetInteger == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetInteger' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetFloat = (LPALGETFLOAT)GetProcAddress(g_hOpenALDLL, "alGetFloat");
|
||||
if (lpOALFnTable->alGetFloat == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetFloat' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetDouble = (LPALGETDOUBLE)GetProcAddress(g_hOpenALDLL, "alGetDouble");
|
||||
if (lpOALFnTable->alGetDouble == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetDouble' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBooleanv = (LPALGETBOOLEANV)GetProcAddress(g_hOpenALDLL, "alGetBooleanv");
|
||||
if (lpOALFnTable->alGetBooleanv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetBooleanv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetIntegerv = (LPALGETINTEGERV)GetProcAddress(g_hOpenALDLL, "alGetIntegerv");
|
||||
if (lpOALFnTable->alGetIntegerv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetIntegerv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetFloatv = (LPALGETFLOATV)GetProcAddress(g_hOpenALDLL, "alGetFloatv");
|
||||
if (lpOALFnTable->alGetFloatv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetFloatv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetDoublev = (LPALGETDOUBLEV)GetProcAddress(g_hOpenALDLL, "alGetDoublev");
|
||||
if (lpOALFnTable->alGetDoublev == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetDoublev' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetString = (LPALGETSTRING)GetProcAddress(g_hOpenALDLL, "alGetString");
|
||||
if (lpOALFnTable->alGetString == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetString' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetError = (LPALGETERROR)GetProcAddress(g_hOpenALDLL, "alGetError");
|
||||
if (lpOALFnTable->alGetError == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetError' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsExtensionPresent = (LPALISEXTENSIONPRESENT)GetProcAddress(g_hOpenALDLL, "alIsExtensionPresent");
|
||||
if (lpOALFnTable->alIsExtensionPresent == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alIsExtensionPresent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetProcAddress = (LPALGETPROCADDRESS)GetProcAddress(g_hOpenALDLL, "alGetProcAddress");
|
||||
if (lpOALFnTable->alGetProcAddress == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetProcAddress' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetEnumValue = (LPALGETENUMVALUE)GetProcAddress(g_hOpenALDLL, "alGetEnumValue");
|
||||
if (lpOALFnTable->alGetEnumValue == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetEnumValue' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListeneri = (LPALLISTENERI)GetProcAddress(g_hOpenALDLL, "alListeneri");
|
||||
if (lpOALFnTable->alListeneri == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alListeneri' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListenerf = (LPALLISTENERF)GetProcAddress(g_hOpenALDLL, "alListenerf");
|
||||
if (lpOALFnTable->alListenerf == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alListenerf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListener3f = (LPALLISTENER3F)GetProcAddress(g_hOpenALDLL, "alListener3f");
|
||||
if (lpOALFnTable->alListener3f == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alListener3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alListenerfv = (LPALLISTENERFV)GetProcAddress(g_hOpenALDLL, "alListenerfv");
|
||||
if (lpOALFnTable->alListenerfv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alListenerfv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListeneri = (LPALGETLISTENERI)GetProcAddress(g_hOpenALDLL, "alGetListeneri");
|
||||
if (lpOALFnTable->alGetListeneri == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetListeneri' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListenerf =(LPALGETLISTENERF)GetProcAddress(g_hOpenALDLL, "alGetListenerf");
|
||||
if (lpOALFnTable->alGetListenerf == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetListenerf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListener3f = (LPALGETLISTENER3F)GetProcAddress(g_hOpenALDLL, "alGetListener3f");
|
||||
if (lpOALFnTable->alGetListener3f == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetListener3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetListenerfv = (LPALGETLISTENERFV)GetProcAddress(g_hOpenALDLL, "alGetListenerfv");
|
||||
if (lpOALFnTable->alGetListenerfv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetListenerfv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGenSources = (LPALGENSOURCES)GetProcAddress(g_hOpenALDLL, "alGenSources");
|
||||
if (lpOALFnTable->alGenSources == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGenSources' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDeleteSources = (LPALDELETESOURCES)GetProcAddress(g_hOpenALDLL, "alDeleteSources");
|
||||
if (lpOALFnTable->alDeleteSources == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDeleteSources' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsSource = (LPALISSOURCE)GetProcAddress(g_hOpenALDLL, "alIsSource");
|
||||
if (lpOALFnTable->alIsSource == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alIsSource' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcei = (LPALSOURCEI)GetProcAddress(g_hOpenALDLL, "alSourcei");
|
||||
if (lpOALFnTable->alSourcei == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcei' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcef = (LPALSOURCEF)GetProcAddress(g_hOpenALDLL, "alSourcef");
|
||||
if (lpOALFnTable->alSourcef == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcef' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSource3f = (LPALSOURCE3F)GetProcAddress(g_hOpenALDLL, "alSource3f");
|
||||
if (lpOALFnTable->alSource3f == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSource3f' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcefv = (LPALSOURCEFV)GetProcAddress(g_hOpenALDLL, "alSourcefv");
|
||||
if (lpOALFnTable->alSourcefv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcefv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcei = (LPALGETSOURCEI)GetProcAddress(g_hOpenALDLL, "alGetSourcei");
|
||||
if (lpOALFnTable->alGetSourcei == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetSourcei' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcef = (LPALGETSOURCEF)GetProcAddress(g_hOpenALDLL, "alGetSourcef");
|
||||
if (lpOALFnTable->alGetSourcef == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetSourcef' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetSourcefv = (LPALGETSOURCEFV)GetProcAddress(g_hOpenALDLL, "alGetSourcefv");
|
||||
if (lpOALFnTable->alGetSourcefv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetSourcefv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePlayv = (LPALSOURCEPLAYV)GetProcAddress(g_hOpenALDLL, "alSourcePlayv");
|
||||
if (lpOALFnTable->alSourcePlayv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcePlayv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceStopv = (LPALSOURCESTOPV)GetProcAddress(g_hOpenALDLL, "alSourceStopv");
|
||||
if (lpOALFnTable->alSourceStopv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourceStopv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePlay = (LPALSOURCEPLAY)GetProcAddress(g_hOpenALDLL, "alSourcePlay");
|
||||
if (lpOALFnTable->alSourcePlay == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcePlay' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourcePause = (LPALSOURCEPAUSE)GetProcAddress(g_hOpenALDLL, "alSourcePause");
|
||||
if (lpOALFnTable->alSourcePause == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourcePause' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceStop = (LPALSOURCESTOP)GetProcAddress(g_hOpenALDLL, "alSourceStop");
|
||||
if (lpOALFnTable->alSourceStop == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourceStop' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceRewind = (LPALSOURCEREWIND)GetProcAddress(g_hOpenALDLL, "alSourceRewind");
|
||||
if (lpOALFnTable->alSourceRewind == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourceRewind' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGenBuffers = (LPALGENBUFFERS)GetProcAddress(g_hOpenALDLL, "alGenBuffers");
|
||||
if (lpOALFnTable->alGenBuffers == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGenBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDeleteBuffers = (LPALDELETEBUFFERS)GetProcAddress(g_hOpenALDLL, "alDeleteBuffers");
|
||||
if (lpOALFnTable->alDeleteBuffers == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDeleteBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alIsBuffer = (LPALISBUFFER)GetProcAddress(g_hOpenALDLL, "alIsBuffer");
|
||||
if (lpOALFnTable->alIsBuffer == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alIsBuffer' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alBufferData = (LPALBUFFERDATA)GetProcAddress(g_hOpenALDLL, "alBufferData");
|
||||
if (lpOALFnTable->alBufferData == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alBufferData' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBufferi = (LPALGETBUFFERI)GetProcAddress(g_hOpenALDLL, "alGetBufferi");
|
||||
if (lpOALFnTable->alGetBufferi == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetBufferi' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alGetBufferf = (LPALGETBUFFERF)GetProcAddress(g_hOpenALDLL, "alGetBufferf");
|
||||
if (lpOALFnTable->alGetBufferf == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alGetBufferf' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceQueueBuffers = (LPALSOURCEQUEUEBUFFERS)GetProcAddress(g_hOpenALDLL, "alSourceQueueBuffers");
|
||||
if (lpOALFnTable->alSourceQueueBuffers == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourceQueueBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alSourceUnqueueBuffers = (LPALSOURCEUNQUEUEBUFFERS)GetProcAddress(g_hOpenALDLL, "alSourceUnqueueBuffers");
|
||||
if (lpOALFnTable->alSourceUnqueueBuffers == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alSourceUnqueueBuffers' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDistanceModel = (LPALDISTANCEMODEL)GetProcAddress(g_hOpenALDLL, "alDistanceModel");
|
||||
if (lpOALFnTable->alDistanceModel == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDistanceModel' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDopplerFactor = (LPALDOPPLERFACTOR)GetProcAddress(g_hOpenALDLL, "alDopplerFactor");
|
||||
if (lpOALFnTable->alDopplerFactor == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDopplerFactor' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alDopplerVelocity = (LPALDOPPLERVELOCITY)GetProcAddress(g_hOpenALDLL, "alDopplerVelocity");
|
||||
if (lpOALFnTable->alDopplerVelocity == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alDopplerVelocity' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetString = (LPALCGETSTRING)GetProcAddress(g_hOpenALDLL, "alcGetString");
|
||||
if (lpOALFnTable->alcGetString == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetString' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetIntegerv = (LPALCGETINTEGERV)GetProcAddress(g_hOpenALDLL, "alcGetIntegerv");
|
||||
if (lpOALFnTable->alcGetIntegerv == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetIntegerv' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcOpenDevice = (LPALCOPENDEVICE)GetProcAddress(g_hOpenALDLL, "alcOpenDevice");
|
||||
if (lpOALFnTable->alcOpenDevice == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcOpenDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcCloseDevice = (LPALCCLOSEDEVICE)GetProcAddress(g_hOpenALDLL, "alcCloseDevice");
|
||||
if (lpOALFnTable->alcCloseDevice == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcCloseDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcCreateContext = (LPALCCREATECONTEXT)GetProcAddress(g_hOpenALDLL, "alcCreateContext");
|
||||
if (lpOALFnTable->alcCreateContext == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcCreateContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcMakeContextCurrent = (LPALCMAKECONTEXTCURRENT)GetProcAddress(g_hOpenALDLL, "alcMakeContextCurrent");
|
||||
if (lpOALFnTable->alcMakeContextCurrent == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcMakeContextCurrent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcProcessContext = (LPALCPROCESSCONTEXT)GetProcAddress(g_hOpenALDLL, "alcProcessContext");
|
||||
if (lpOALFnTable->alcProcessContext == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcProcessContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetCurrentContext = (LPALCGETCURRENTCONTEXT)GetProcAddress(g_hOpenALDLL, "alcGetCurrentContext");
|
||||
if (lpOALFnTable->alcGetCurrentContext == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetCurrentContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetContextsDevice = (LPALCGETCONTEXTSDEVICE)GetProcAddress(g_hOpenALDLL, "alcGetContextsDevice");
|
||||
if (lpOALFnTable->alcGetContextsDevice == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetContextsDevice' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcSuspendContext = (LPALCSUSPENDCONTEXT)GetProcAddress(g_hOpenALDLL, "alcSuspendContext");
|
||||
if (lpOALFnTable->alcSuspendContext == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcSuspendContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcDestroyContext = (LPALCDESTROYCONTEXT)GetProcAddress(g_hOpenALDLL, "alcDestroyContext");
|
||||
if (lpOALFnTable->alcDestroyContext == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcDestroyContext' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetError = (LPALCGETERROR)GetProcAddress(g_hOpenALDLL, "alcGetError");
|
||||
if (lpOALFnTable->alcGetError == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetError' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcIsExtensionPresent = (LPALCISEXTENSIONPRESENT)GetProcAddress(g_hOpenALDLL, "alcIsExtensionPresent");
|
||||
if (lpOALFnTable->alcIsExtensionPresent == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcIsExtensionPresent' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetProcAddress = (LPALCGETPROCADDRESS)GetProcAddress(g_hOpenALDLL, "alcGetProcAddress");
|
||||
if (lpOALFnTable->alcGetProcAddress == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetProcAddress' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
lpOALFnTable->alcGetEnumValue = (LPALCGETENUMVALUE)GetProcAddress(g_hOpenALDLL, "alcGetEnumValue");
|
||||
if (lpOALFnTable->alcGetEnumValue == NULL)
|
||||
{
|
||||
OutputDebugStringA("Failed to retrieve 'alcGetEnumValue' function address\n");
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
ALvoid UnloadOAL10Library()
|
||||
{
|
||||
// Unload the dll
|
||||
if (g_hOpenALDLL)
|
||||
{
|
||||
FreeLibrary(g_hOpenALDLL);
|
||||
g_hOpenALDLL = NULL;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue