diff options
Diffstat (limited to '')
-rw-r--r-- | src/audio/oal/aldlist.cpp | 329 | ||||
-rw-r--r-- | src/audio/oal/aldlist.h | 49 | ||||
-rw-r--r-- | src/audio/oal/channel.cpp | 209 | ||||
-rw-r--r-- | src/audio/oal/channel.h | 51 | ||||
-rw-r--r-- | src/audio/oal/oal_utils.cpp | 176 | ||||
-rw-r--r-- | src/audio/oal/oal_utils.h | 48 | ||||
-rw-r--r-- | src/audio/oal/stream.cpp | 118 | ||||
-rw-r--r-- | src/audio/oal/stream.h | 57 |
8 files changed, 1037 insertions, 0 deletions
diff --git a/src/audio/oal/aldlist.cpp b/src/audio/oal/aldlist.cpp new file mode 100644 index 00000000..2c2f13a8 --- /dev/null +++ b/src/audio/oal/aldlist.cpp @@ -0,0 +1,329 @@ +/* + * 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 "aldlist.h" +#ifdef AUDIO_OAL +/* + * Init call + */ +ALDeviceList::ALDeviceList() +{ + ALDEVICEINFO ALDeviceInfo; + char *devices; + int index; + const char *defaultDeviceName; + const char *actualDeviceName; + + // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support + vDeviceInfo.empty(); + vDeviceInfo.reserve(10); + + defaultDeviceIndex = 0; + + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { + devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER); + defaultDeviceName = (char *)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 != NULL) { + if (strcmp(defaultDeviceName, devices) == 0) { + defaultDeviceIndex = index; + } + ALCdevice *device = alcOpenDevice(devices); + if (device) { + ALCcontext *context = alcCreateContext(device, NULL); + if (context) { + alcMakeContextCurrent(context); + // if new actual device name isn't already in the list, then add it... + actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER); + bool bNewName = true; + for (int i = 0; i < GetNumDevices(); i++) { + if (strcmp(GetDeviceName(i), actualDeviceName) == 0) { + bNewName = false; + } + } + if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) { + memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO)); + ALDeviceInfo.bSelected = true; + ALDeviceInfo.strDeviceName = std::string(actualDeviceName, strlen(actualDeviceName)); + alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion); + alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion); + + ALDeviceInfo.pvstrExtensions = new std::vector<std::string>; + + // Check for ALC Extensions + if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE"); + if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX"); + + // Check for AL Extensions + if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET"); + + if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE"); + if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE"); + + if (alIsExtensionPresent("EAX2.0") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("EAX2.0"); + if (alIsExtensionPresent("EAX3.0") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("EAX3.0"); + if (alIsExtensionPresent("EAX4.0") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("EAX4.0"); + if (alIsExtensionPresent("EAX5.0") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("EAX5.0"); + + if (alIsExtensionPresent("EAX-RAM") == AL_TRUE) + ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM"); + + // Get Source Count + ALDeviceInfo.uiSourceCount = GetMaxNumSources(); + + vDeviceInfo.push_back(ALDeviceInfo); + } + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + } + alcCloseDevice(device); + } + devices += strlen(devices) + 1; + index += 1; + } + } + + ResetFilters(); +} + +/* + * Exit call + */ +ALDeviceList::~ALDeviceList() +{ + for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { + if (vDeviceInfo[i].pvstrExtensions) { + vDeviceInfo[i].pvstrExtensions->empty(); + delete vDeviceInfo[i].pvstrExtensions; + } + } + + vDeviceInfo.empty(); +} + +/* + * 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 + */ +char * ALDeviceList::GetDeviceName(int index) +{ + if (index < GetNumDevices()) + return (char *)vDeviceInfo[index].strDeviceName.c_str(); + 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, char *szExtName) +{ + bool bReturn = false; + + if (index < GetNumDevices()) { + for (unsigned int i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) { + if (!_stricmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) { + bReturn = true; + break; + } + } + } + + 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(char *szExtName) +{ + bool bFound; + + for (unsigned int i = 0; i < vDeviceInfo.size(); i++) { + bFound = false; + for (unsigned int j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) { + if (!_stricmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) { + bFound = true; + break; + } + } + if (!bFound) + vDeviceInfo[i].bSelected = false; + } +} + +/* + * 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 + alGetError(); + + // Generate up to 256 Sources, checking for any errors + for (iSourceCount = 0; iSourceCount < 256; iSourceCount++) + { + alGenSources(1, &uiSources[iSourceCount]); + if (alGetError() != AL_NO_ERROR) + break; + } + + // Release the Sources + alDeleteSources(iSourceCount, uiSources); + if (alGetError() != AL_NO_ERROR) + { + for (unsigned int i = 0; i < 256; i++) + { + alDeleteSources(1, &uiSources[i]); + } + } + + return iSourceCount; +} +#endif
\ No newline at end of file diff --git a/src/audio/oal/aldlist.h b/src/audio/oal/aldlist.h new file mode 100644 index 00000000..b8f1b31a --- /dev/null +++ b/src/audio/oal/aldlist.h @@ -0,0 +1,49 @@ +#ifndef ALDEVICELIST_H +#define ALDEVICELIST_H + +#include "oal_utils.h" + +#ifdef AUDIO_OAL +#pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information" +#include <vector> +#include <string> + +typedef struct +{ + std::string strDeviceName; + int iMajorVersion; + int iMinorVersion; + unsigned int uiSourceCount; + std::vector<std::string> *pvstrExtensions; + bool bSelected; +} ALDEVICEINFO, *LPALDEVICEINFO; + +class ALDeviceList +{ +private: + std::vector<ALDEVICEINFO> vDeviceInfo; + int defaultDeviceIndex; + int filterIndex; + +public: + ALDeviceList (); + ~ALDeviceList (); + int GetNumDevices(); + char *GetDeviceName(int index); + void GetDeviceVersion(int index, int *major, int *minor); + unsigned int GetMaxNumSources(int index); + bool IsExtensionSupported(int index, char *szExtName); + int GetDefaultDevice(); + void FilterDevicesMinVer(int major, int minor); + void FilterDevicesMaxVer(int major, int minor); + void FilterDevicesExtension(char *szExtName); + void ResetFilters(); + int GetFirstFilteredDevice(); + int GetNextFilteredDevice(); + +private: + unsigned int GetMaxNumSources(); +}; +#endif + +#endif // ALDEVICELIST_H
\ No newline at end of file diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp new file mode 100644 index 00000000..d8b50161 --- /dev/null +++ b/src/audio/oal/channel.cpp @@ -0,0 +1,209 @@ +#include "channel.h" + +#ifdef AUDIO_OAL +#include "sampman.h" + +extern bool IsFXSupported(); + +CChannel::CChannel() +{ + alChannel = AL_NONE; + alFilter = AL_FILTER_NULL; + SetDefault(); +} + +void CChannel::SetDefault() +{ + Buffer = AL_NONE; + + Pitch = 1.0f; + Gain = 1.0f; + Mix = 0.0f; + + Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f; + Distances[0] = 0.0f; Distances[1] = FLT_MAX; + LoopCount = 1; + LoopPoints[0] = 0; LoopPoints[1] = -1; + + Frequency = MAX_FREQ; +} + +void CChannel::Reset() +{ + ClearBuffer(); + SetDefault(); +} + +void CChannel::Init(bool Is2D) +{ + ASSERT(!HasSource()); + alGenSources(1, &alChannel); + if ( HasSource() ) + { + alSourcei(alChannel, AL_SOURCE_RELATIVE, AL_TRUE); + if ( IsFXSupported() ) + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if ( Is2D ) + { + alSource3f(alChannel, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef (alChannel, AL_GAIN, 1.0f); + } + else + { + if ( IsFXSupported() ) + alGenFilters(1,&alFilter); + } + } +} + +void CChannel::Term() +{ + Stop(); + if ( HasSource() ) + { + if ( IsFXSupported() ) + { + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if(alFilter != AL_FILTER_NULL) + alDeleteFilters(1,&alFilter); + } + + alDeleteSources(1, &alChannel); + } + alChannel = AL_NONE; + alFilter = AL_FILTER_NULL; +} + +void CChannel::Start() +{ + if ( !HasSource() ) return; + + if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) + alBufferiv(Buffer, AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei (alChannel, AL_BUFFER, Buffer); + alSourcePlay(alChannel); +} + +void CChannel::Stop() +{ + if ( HasSource() ) + alSourceStop(alChannel); + + Reset(); +} + +bool CChannel::HasSource() +{ + return alChannel != AL_NONE; +} + +bool CChannel::IsUsed() +{ + if ( HasSource() ) + { + ALint sourceState; + alGetSourcei(alChannel, AL_SOURCE_STATE, &sourceState); + return sourceState == AL_PLAYING; + } + return false; +} + +void CChannel::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(alChannel, AL_PITCH, pitch); +} + +void CChannel::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(alChannel, AL_GAIN, gain); +} + +void CChannel::SetVolume(int32 vol) +{ + SetGain(ALfloat(vol) / MAX_VOLUME); +} + +void CChannel::SetSampleID(uint32 nSfx) +{ + Sample = nSfx; +} + +void CChannel::SetFreq(int32 freq) +{ + Frequency = freq; +} + +void CChannel::SetCurrentFreq(uint32 freq) +{ + SetPitch(ALfloat(freq) / Frequency); +} + +void CChannel::SetLoopCount(int32 loopCount) // fake. TODO: +{ + if ( !HasSource() ) return; + alSourcei(alChannel, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); +} + +void CChannel::SetLoopPoints(ALint start, ALint end) +{ + LoopPoints[0] = start; + LoopPoints[1] = end; +} + +void CChannel::SetPosition(float x, float y, float z) +{ + if ( !HasSource() ) return; + alSource3f(alChannel, AL_POSITION, x, y, z); +} + +void CChannel::SetDistances(float max, float min) +{ + if ( !HasSource() ) return; + alSourcef (alChannel, AL_MAX_DISTANCE, max); + alSourcef (alChannel, AL_REFERENCE_DISTANCE, min); + alSourcef (alChannel, AL_MAX_GAIN, 1.0f); + alSourcef (alChannel, AL_ROLLOFF_FACTOR, 1.0f); +} + +void CChannel::SetPan(uint32 pan) +{ + SetPosition((pan-63)/64.0f, 0.0f, sqrtf(1.0f-SQR((pan-63)/64.0f))); +} + +void CChannel::SetBuffer(ALuint buffer) +{ + Buffer = buffer; +} + +void CChannel::ClearBuffer() +{ + if ( !HasSource() ) return; + SetBuffer(AL_NONE); + alSourcei(alChannel, AL_BUFFER, AL_NONE); +} + +void CChannel::SetReverbMix(ALuint slot, float mix) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilter == AL_FILTER_NULL ) return; + + Mix = mix; + EAX3_SetReverbMix(alFilter, mix); + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); +} + +void CChannel::UpdateReverb(ALuint slot) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilter == AL_FILTER_NULL ) return; + EAX3_SetReverbMix(alFilter, Mix); + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); +} + +#endif
\ No newline at end of file diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h new file mode 100644 index 00000000..d9ffea22 --- /dev/null +++ b/src/audio/oal/channel.h @@ -0,0 +1,51 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include "oal/oal_utils.h" +#include <AL/al.h> +#include <AL/alext.h> +#include <AL/efx.h> + + +class CChannel +{ + ALuint alChannel; + ALuint alFilter; + ALuint Buffer; + float Pitch, Gain; + float Mix; + int32 Frequency; + float Position[3]; + float Distances[2]; + int32 LoopCount; + ALint LoopPoints[2]; + uint32 Sample; +public: + CChannel(); + void SetDefault(); + void Reset(); + void Init(bool Is2D = false); + void Term(); + void Start(); + void Stop(); + bool HasSource(); + bool IsUsed(); + void SetPitch(float pitch); + void SetGain(float gain); + void SetVolume(int32 vol); + void SetSampleID(uint32 nSfx); + void SetFreq(int32 freq); + void SetCurrentFreq(uint32 freq); + void SetLoopCount(int32 loopCount); // fake + void SetLoopPoints(ALint start, ALint end); + void SetPosition(float x, float y, float z); + void SetDistances(float max, float min); + void SetPan(uint32 pan); + void SetBuffer(ALuint buffer); + void ClearBuffer(); + void SetReverbMix(ALuint slot, float mix); + void UpdateReverb(ALuint slot); +}; + +#endif
\ No newline at end of file diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp new file mode 100644 index 00000000..a2df61c1 --- /dev/null +++ b/src/audio/oal/oal_utils.cpp @@ -0,0 +1,176 @@ +#include "oal_utils.h" + +#ifdef AUDIO_OAL + +LPALGENEFFECTS alGenEffects; +LPALDELETEEFFECTS alDeleteEffects; +LPALISEFFECT alIsEffect; +LPALEFFECTI alEffecti; +LPALEFFECTIV alEffectiv; +LPALEFFECTF alEffectf; +LPALEFFECTFV alEffectfv; +LPALGETEFFECTI alGetEffecti; +LPALGETEFFECTIV alGetEffectiv; +LPALGETEFFECTF alGetEffectf; +LPALGETEFFECTFV alGetEffectfv; +LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +LPALGENFILTERS alGenFilters; +LPALDELETEFILTERS alDeleteFilters; +LPALISFILTER alIsFilter; +LPALFILTERI alFilteri; +LPALFILTERIV alFilteriv; +LPALFILTERF alFilterf; +LPALFILTERFV alFilterfv; +LPALGETFILTERI alGetFilteri; +LPALGETFILTERIV alGetFilteriv; +LPALGETFILTERF alGetFilterf; +LPALGETFILTERFV alGetFilterfv; + + +void EFXInit() +{ + if (alIsExtensionPresent((ALchar*)"EAX3.0")) + DEV("\nBIG EAX IN TOWN\n"); + else + DEV("\nNO EAX\n"); + + + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x)) + LOAD_PROC(LPALGENEFFECTS, alGenEffects); + LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects); + LOAD_PROC(LPALISEFFECT, alIsEffect); + LOAD_PROC(LPALEFFECTI, alEffecti); + LOAD_PROC(LPALEFFECTIV, alEffectiv); + LOAD_PROC(LPALEFFECTF, alEffectf); + LOAD_PROC(LPALEFFECTFV, alEffectfv); + LOAD_PROC(LPALGETEFFECTI, alGetEffecti); + LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv); + LOAD_PROC(LPALGETEFFECTF, alGetEffectf); + LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv); + + LOAD_PROC(LPALGENFILTERS, alGenFilters); + LOAD_PROC(LPALDELETEFILTERS, alDeleteFilters); + LOAD_PROC(LPALISFILTER, alIsFilter); + LOAD_PROC(LPALFILTERI, alFilteri); + LOAD_PROC(LPALFILTERIV, alFilteriv); + LOAD_PROC(LPALFILTERF, alFilterf); + LOAD_PROC(LPALFILTERFV, alFilterfv); + LOAD_PROC(LPALGETFILTERI, alGetFilteri); + LOAD_PROC(LPALGETFILTERIV, alGetFilteriv); + LOAD_PROC(LPALGETFILTERF, alGetFilterf); + LOAD_PROC(LPALGETFILTERFV, alGetFilterfv); + + LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots); + LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots); + LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); +#undef LOAD_PROC +} + + +void SetEffectsLevel(ALuint uiFilter, float level) +{ + alFilteri(uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(uiFilter, AL_LOWPASS_GAIN, 1.0f); + alFilterf(uiFilter, AL_LOWPASS_GAINHF, level); +} + +static inline float gain_to_mB(float gain) +{ + return (gain > 1e-5f) ? (float)(log10f(gain) * 2000.0f) : -10000l; +} + +static inline float mB_to_gain(float millibels) +{ + return (millibels > -10000.0f) ? powf(10.0f, millibels/2000.0f) : 0.0f; +} + +static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval) +{ + if(val >= maxval) return maxval; + if(val <= minval) return minval; + return val; +} + +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti (effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + alEffectf (effect, AL_EAXREVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf (effect, AL_EAXREVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf (effect, AL_EAXREVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf (effect, AL_EAXREVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf (effect, AL_EAXREVERB_GAINLF, mB_to_gain((float)props->lRoomLF)); + alEffectf (effect, AL_EAXREVERB_DECAY_TIME, props->flDecayTime); + alEffectf (effect, AL_EAXREVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf (effect, AL_EAXREVERB_DECAY_LFRATIO, props->flDecayLFRatio); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, &props->vReflectionsPan.x); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, &props->vReverbPan.x); + alEffectf (effect, AL_EAXREVERB_ECHO_TIME, props->flEchoTime); + alEffectf (effect, AL_EAXREVERB_ECHO_DEPTH, props->flEchoDepth); + alEffectf (effect, AL_EAXREVERB_MODULATION_TIME, props->flModulationTime); + alEffectf (effect, AL_EAXREVERB_MODULATION_DEPTH, props->flModulationDepth); + alEffectf (effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf (effect, AL_EAXREVERB_HFREFERENCE, props->flHFReference); + alEffectf (effect, AL_EAXREVERB_LFREFERENCE, props->flLFReference); + alEffectf (effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti (effect, AL_EAXREVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + + alEffectf(effect, AL_REVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf(effect, AL_REVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf(effect, AL_REVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf(effect, AL_REVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf(effect, AL_REVERB_DECAY_TIME, props->flDecayTime); + alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EAX3_SetReverbMix(ALuint filter, float mix) +{ + //long vol=(long)linear_to_dB(mix); + //DSPROPERTY_EAXBUFFER_ROOMHF, + //DSPROPERTY_EAXBUFFER_ROOM, + //DSPROPERTY_EAXBUFFER_REVERBMIX, + + long mbvol = gain_to_mB(mix); + float mb = mbvol; + float mbhf = mbvol; + + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(filter, AL_LOWPASS_GAIN, mB_to_gain(Min(mb, 0.0f))); + alFilterf(filter, AL_LOWPASS_GAINHF, mB_to_gain(mbhf)); +} + +#endif
\ No newline at end of file diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h new file mode 100644 index 00000000..af45a944 --- /dev/null +++ b/src/audio/oal/oal_utils.h @@ -0,0 +1,48 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include "eax.h" +#include "AL/efx.h" + + +void EFXInit(); +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EAX3_SetReverbMix(ALuint filter, float mix); +void SetEffectsLevel(ALuint uiFilter, float level); + +extern LPALGENEFFECTS alGenEffects; +extern LPALDELETEEFFECTS alDeleteEffects; +extern LPALISEFFECT alIsEffect; +extern LPALEFFECTI alEffecti; +extern LPALEFFECTIV alEffectiv; +extern LPALEFFECTF alEffectf; +extern LPALEFFECTFV alEffectfv; +extern LPALGETEFFECTI alGetEffecti; +extern LPALGETEFFECTIV alGetEffectiv; +extern LPALGETEFFECTF alGetEffectf; +extern LPALGETEFFECTFV alGetEffectfv; +extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +extern LPALGENFILTERS alGenFilters; +extern LPALDELETEFILTERS alDeleteFilters; +extern LPALISFILTER alIsFilter; +extern LPALFILTERI alFilteri; +extern LPALFILTERIV alFilteriv; +extern LPALFILTERF alFilterf; +extern LPALFILTERFV alFilterfv; +extern LPALGETFILTERI alGetFilteri; +extern LPALGETFILTERIV alGetFilteriv; +extern LPALGETFILTERF alGetFilterf; +extern LPALGETFILTERFV alGetFilterfv; +#endif diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp new file mode 100644 index 00000000..a65c9794 --- /dev/null +++ b/src/audio/oal/stream.cpp @@ -0,0 +1,118 @@ +#include "stream.h" +#include "common.h" + +#ifdef AUDIO_OAL + +void CStream::Initialise() +{ + //mpg123_init(); +} + +void CStream::Terminate() +{ + //mpg123_exit(); +} + +CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) : + m_alSource(source), + m_alBuffers(buffers), + m_nBitRate(0), + m_nFormat(0), + m_nFreq(0), + m_nLength(0), + m_nLengthMS(0), + m_nBufferSize(0), + m_pBuffer(NULL), + m_bIsOpened(false), + m_bPaused(true) + +{ + strcpy(m_aFilename, filename); + + //DEV("Stream %s\n", m_aFilename); + + /* + if ( true ) + { + m_nBitRate = (wBitsPerSample * nChannels * wfex.nSamplesPerSec)/1000; + m_nLength = ulDataSize; + m_nLengthMS = m_nLength*8 / m_nBitRate; + m_nBufferSize = nAvgBytesPerSec >> 2; + m_nBufferSize -= (m_nLength % wfex.nBlockAlign); + m_pBuffer = malloc(m_nBufferSize); + m_bIsOpened = true; + return; + }*/ +} + +CStream::~CStream() +{ + Delete(); +} + +void CStream::Delete() +{ + if ( m_pBuffer ) + { + free(m_pBuffer); + m_pBuffer = NULL; + } +} + +bool CStream::IsOpened() +{ + return m_bIsOpened; +} + +bool CStream::IsPlaying() +{ + return false; +} + +void CStream::SetPause(bool bPause) +{ +} + +void CStream::SetVolume(uint32 nVol) +{ + +} + +void CStream::SetPan(uint8 nPan) +{ +} + +void CStream::SetPos(uint32 nPos) +{ +} + +uint32 CStream::GetPos() +{ + return 0; +} + +uint32 CStream::GetLength() +{ + return m_nLengthMS; +} + +bool CStream::Setup() +{ + if ( !IsOpened() ) + return false; + + return IsOpened(); +} + +void CStream::Start() +{ + +} + +void CStream::Update() +{ + if ( !IsOpened() ) + return; +} + +#endif
\ No newline at end of file diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h new file mode 100644 index 00000000..666d42e0 --- /dev/null +++ b/src/audio/oal/stream.h @@ -0,0 +1,57 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include <AL/al.h> + +#define NUM_STREAMBUFFERS 5 +#define STREAMBUFFER_SIZE 0x4000 + +class CStream +{ + char m_aFilename[128]; + ALuint &m_alSource; + ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; + + bool m_bIsOpened; + bool m_bPaused; + + uint32 m_nLength; + uint32 m_nLengthMS; + uint32 m_nBitRate; + + unsigned long m_nFormat; + unsigned long m_nFreq; + + uint32 m_nBufferSize; + void *m_pBuffer; + + ALint iTotalBuffersProcessed; + + bool FillBuffer(ALuint alBuffer); + int32 FillBuffers(); +public: + static void Initialise(); + static void Terminate(); + + CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]); + ~CStream(); + + void Delete(); + + bool IsOpened(); + bool IsPlaying(); + void SetPause (bool bPause); + void SetVolume(uint32 nVol); + void SetPan (uint8 nPan); + void SetPos (uint32 nPos); + + uint32 GetPos(); + uint32 GetLength(); + + bool Setup(); + void Start(); + void Update(void); +}; + +#endif
\ No newline at end of file |