diff options
author | erorcun <erayorcunus@gmail.com> | 2020-05-11 02:23:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-11 02:23:36 +0200 |
commit | c66c45f4c8921564dc705c690e25848c330c4b26 (patch) | |
tree | 82c935c912f9436fcc87d4c5e910db89bbf0dda7 /src | |
parent | Merge pull request #531 from Bigbossbro08/master (diff) | |
parent | oal update (diff) | |
download | re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar.gz re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar.bz2 re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar.lz re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar.xz re3-c66c45f4c8921564dc705c690e25848c330c4b26.tar.zst re3-c66c45f4c8921564dc705c690e25848c330c4b26.zip |
Diffstat (limited to '')
-rw-r--r-- | src/audio/AudioManager.cpp | 4 | ||||
-rw-r--r-- | src/audio/AudioManager.h | 4 | ||||
-rw-r--r-- | src/audio/DMAudio.cpp | 23 | ||||
-rw-r--r-- | src/audio/DMAudio.h | 2 | ||||
-rw-r--r-- | src/audio/miles/sampman_mss.h | 339 | ||||
-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 | 210 | ||||
-rw-r--r-- | src/audio/oal/channel.h | 51 | ||||
-rw-r--r-- | src/audio/oal/oal_utils.cpp | 169 | ||||
-rw-r--r-- | src/audio/oal/oal_utils.h | 48 | ||||
-rw-r--r-- | src/audio/oal/stream.cpp | 520 | ||||
-rw-r--r-- | src/audio/oal/stream.h | 112 | ||||
-rw-r--r-- | src/audio/openal/samp_oal.cpp | 1404 | ||||
-rw-r--r-- | src/audio/openal/samp_oal.h | 340 | ||||
-rw-r--r-- | src/audio/sampman.cpp | 7 | ||||
-rw-r--r-- | src/audio/sampman.h | 348 | ||||
-rw-r--r-- | src/audio/sampman_miles.cpp (renamed from src/audio/miles/sampman_mss.cpp) | 70 | ||||
-rw-r--r-- | src/audio/sampman_oal.cpp | 1404 | ||||
-rw-r--r-- | src/core/Game.cpp | 19 | ||||
-rw-r--r-- | src/core/common.h | 2 | ||||
-rw-r--r-- | src/core/config.h | 3 | ||||
-rw-r--r-- | src/core/re3.cpp | 14 |
23 files changed, 3348 insertions, 2123 deletions
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index be68d40f..b76c2cc3 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -9245,7 +9245,7 @@ cAudioManager::ResetTimers(uint32 time) SampleManager.SetEffectsFadeVolume(0); SampleManager.SetMusicFadeVolume(0); MusicManager.ResetMusicAfterReload(); -#ifdef OPENAL +#ifdef AUDIO_OAL SampleManager.Service(); #endif } @@ -9301,7 +9301,7 @@ cAudioManager::ServiceSoundEffects() ProcessMissionAudio(); AdjustSamplesVolume(); ProcessActiveQueues(); -#ifdef OPENAL +#ifdef AUDIO_OAL SampleManager.Service(); #endif for (int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 3e20b993..99d67444 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -471,6 +471,8 @@ public: void DebugShit(); }; -//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error"); +#ifdef AUDIO_MSS +static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error"); +#endif extern cAudioManager AudioManager; diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 11c85dbd..f1b9707b 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -5,6 +5,7 @@ #include "AudioManager.h" #include "AudioScriptObject.h" #include "sampman.h" +#include "Text.h" cDMAudio DMAudio; @@ -104,6 +105,28 @@ cDMAudio::Get3DProviderName(uint8 id) return AudioManager.Get3DProviderName(id); } +int8 cDMAudio::AutoDetect3DProviders(void) +{ + for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ ) + { + wchar buff[64]; + + char *name = Get3DProviderName(i); + AsciiToUnicode(name, buff); + char *providername = UnicodeToAscii(buff); + strupr(providername); +#if defined(AUDIO_MSS) + if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") ) + return i; +#elif defined(AUDIO_OAL) + if ( !strcmp(providername, "OPENAL SOFT") ) + return i; +#endif + } + + return -1; +} + int8 cDMAudio::GetCurrent3DProviderIndex(void) { diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index 428f08b4..052fdb81 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -34,6 +34,8 @@ public: uint8 GetNum3DProvidersAvailable(void); char *Get3DProviderName(uint8 id); + int8 AutoDetect3DProviders(void); + int8 GetCurrent3DProviderIndex(void); int8 SetCurrent3DProvider(uint8 which); diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h deleted file mode 100644 index ebedfb63..00000000 --- a/src/audio/miles/sampman_mss.h +++ /dev/null @@ -1,339 +0,0 @@ -#pragma once -#include "common.h" -#include "AudioSamples.h" - -#define MAX_VOLUME 127 - -struct tSample { - int32 nOffset; - uint32 nSize; - int32 nFrequency; - int32 nLoopStart; - int32 nLoopEnd; -}; - -enum -{ - SAMPLEBANK_MAIN, - SAMPLEBANK_PED, - MAX_SAMPLEBANKS, - SAMPLEBANK_INVALID -}; - -#define MAX_PEDSFX 7 -#define PED_BLOCKSIZE 79000 - -#define MAXPROVIDERS 64 - -#define MAXCHANNELS 28 -#define MAXCHANNELS_SURROUND 24 -#define MAX2DCHANNELS 1 -#define CHANNEL2D MAXCHANNELS - -#define MAX_MP3STREAMS 2 - -#define DIGITALRATE 32000 -#define DIGITALBITS 16 -#define DIGITALCHANNELS 2 - -#define MAX_DIGITAL_MIXER_CHANNELS 32 - -class cSampleManager -{ - uint8 m_nEffectsVolume; - uint8 m_nMusicVolume; - uint8 m_nEffectsFadeVolume; - uint8 m_nMusicFadeVolume; - uint8 m_nMonoMode; - char unk; - char m_szCDRomRootPath[80]; - bool m_bInitialised; - uint8 m_nNumberOfProviders; - char *m_aAudioProviders[MAXPROVIDERS]; - tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; - -public: - - - - cSampleManager(void) : - m_nNumberOfProviders(0) - { } - - ~cSampleManager(void) - { } - - void SetSpeakerConfig(int32 nConfig); - uint32 GetMaximumSupportedChannels(void); - - uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; } - void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; } - - char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; } - void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; } - - int8 GetCurrent3DProviderIndex(void); - int8 SetCurrent3DProvider(uint8 which); - - bool IsMP3RadioChannelAvailable(void); - - void ReleaseDigitalHandle (void); - void ReacquireDigitalHandle(void); - - bool Initialise(void); - void Terminate (void); - - bool CheckForAnAudioFileOnCD(void); - char GetCDAudioDriveLetter (void); - - void UpdateEffectsVolume(void); - - void SetEffectsMasterVolume(uint8 nVolume); - void SetMusicMasterVolume (uint8 nVolume); - void SetEffectsFadeVolume (uint8 nVolume); - void SetMusicFadeVolume (uint8 nVolume); - - bool LoadSampleBank (uint8 nBank); - void UnloadSampleBank (uint8 nBank); - bool IsSampleBankLoaded(uint8 nBank); - - bool IsPedCommentLoaded(uint32 nComment); - bool LoadPedComment (uint32 nComment); - - int32 _GetPedCommentSlot(uint32 nComment); - - int32 GetSampleBaseFrequency (uint32 nSample); - int32 GetSampleLoopStartOffset(uint32 nSample); - int32 GetSampleLoopEndOffset (uint32 nSample); - uint32 GetSampleLength (uint32 nSample); - - bool UpdateReverb(void); - - void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); - bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); - void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); - void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); - void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); - void SetChannelVolume (uint32 nChannel, uint32 nVolume); - void SetChannelPan (uint32 nChannel, uint32 nPan); - void SetChannelFrequency (uint32 nChannel, uint32 nFreq); - void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); - void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); - bool GetChannelUsedFlag (uint32 nChannel); - void StartChannel (uint32 nChannel); - void StopChannel (uint32 nChannel); - - void PreloadStreamedFile (uint8 nFile, uint8 nStream); - void PauseStream (uint8 nPauseFlag, uint8 nStream); - void StartPreloadedStreamedFile (uint8 nStream); - bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); - void StopStreamedFile (uint8 nStream); - int32 GetStreamedFilePosition (uint8 nStream); - void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); - int32 GetStreamedFileLength (uint8 nStream); - bool IsStreamPlaying (uint8 nStream); - bool InitialiseSampleBanks(void); -}; - -extern cSampleManager SampleManager; -extern int32 BankStartOffset[MAX_SAMPLEBANKS]; - -static char StreamedNameTable[][25]= -{ - "AUDIO\\HEAD.WAV", - "AUDIO\\CLASS.WAV", - "AUDIO\\KJAH.WAV", - "AUDIO\\RISE.WAV", - "AUDIO\\LIPS.WAV", - "AUDIO\\GAME.WAV", - "AUDIO\\MSX.WAV", - "AUDIO\\FLASH.WAV", - "AUDIO\\CHAT.WAV", - "AUDIO\\HEAD.WAV", - "AUDIO\\POLICE.WAV", - "AUDIO\\CITY.WAV", - "AUDIO\\WATER.WAV", - "AUDIO\\COMOPEN.WAV", - "AUDIO\\SUBOPEN.WAV", - "AUDIO\\JB.MP3", - "AUDIO\\BET.MP3", - "AUDIO\\L1_LG.MP3", - "AUDIO\\L2_DSB.MP3", - "AUDIO\\L3_DM.MP3", - "AUDIO\\L4_PAP.MP3", - "AUDIO\\L5_TFB.MP3", - "AUDIO\\J0_DM2.MP3", - "AUDIO\\J1_LFL.MP3", - "AUDIO\\J2_KCL.MP3", - "AUDIO\\J3_VH.MP3", - "AUDIO\\J4_ETH.MP3", - "AUDIO\\J5_DST.MP3", - "AUDIO\\J6_TBJ.MP3", - "AUDIO\\T1_TOL.MP3", - "AUDIO\\T2_TPU.MP3", - "AUDIO\\T3_MAS.MP3", - "AUDIO\\T4_TAT.MP3", - "AUDIO\\T5_BF.MP3", - "AUDIO\\S0_MAS.MP3", - "AUDIO\\S1_PF.MP3", - "AUDIO\\S2_CTG.MP3", - "AUDIO\\S3_RTC.MP3", - "AUDIO\\S5_LRQ.MP3", - "AUDIO\\S4_BDBA.MP3", - "AUDIO\\S4_BDBB.MP3", - "AUDIO\\S2_CTG2.MP3", - "AUDIO\\S4_BDBD.MP3", - "AUDIO\\S5_LRQB.MP3", - "AUDIO\\S5_LRQC.MP3", - "AUDIO\\A1_SSO.WAV", - "AUDIO\\A2_PP.WAV", - "AUDIO\\A3_SS.WAV", - "AUDIO\\A4_PDR.WAV", - "AUDIO\\A5_K2FT.WAV", - "AUDIO\\K1_KBO.MP3", - "AUDIO\\K2_GIS.MP3", - "AUDIO\\K3_DS.MP3", - "AUDIO\\K4_SHI.MP3", - "AUDIO\\K5_SD.MP3", - "AUDIO\\R0_PDR2.MP3", - "AUDIO\\R1_SW.MP3", - "AUDIO\\R2_AP.MP3", - "AUDIO\\R3_ED.MP3", - "AUDIO\\R4_GF.MP3", - "AUDIO\\R5_PB.MP3", - "AUDIO\\R6_MM.MP3", - "AUDIO\\D1_STOG.MP3", - "AUDIO\\D2_KK.MP3", - "AUDIO\\D3_ADO.MP3", - "AUDIO\\D5_ES.MP3", - "AUDIO\\D7_MLD.MP3", - "AUDIO\\D4_GTA.MP3", - "AUDIO\\D4_GTA2.MP3", - "AUDIO\\D6_STS.MP3", - "AUDIO\\A6_BAIT.WAV", - "AUDIO\\A7_ETG.WAV", - "AUDIO\\A8_PS.WAV", - "AUDIO\\A9_ASD.WAV", - "AUDIO\\K4_SHI2.MP3", - "AUDIO\\C1_TEX.MP3", - "AUDIO\\EL_PH1.MP3", - "AUDIO\\EL_PH2.MP3", - "AUDIO\\EL_PH3.MP3", - "AUDIO\\EL_PH4.MP3", - "AUDIO\\YD_PH1.MP3", - "AUDIO\\YD_PH2.MP3", - "AUDIO\\YD_PH3.MP3", - "AUDIO\\YD_PH4.MP3", - "AUDIO\\HD_PH1.MP3", - "AUDIO\\HD_PH2.MP3", - "AUDIO\\HD_PH3.MP3", - "AUDIO\\HD_PH4.MP3", - "AUDIO\\HD_PH5.MP3", - "AUDIO\\MT_PH1.MP3", - "AUDIO\\MT_PH2.MP3", - "AUDIO\\MT_PH3.MP3", - "AUDIO\\MT_PH4.MP3", - "AUDIO\\MISCOM.WAV", - "AUDIO\\END.MP3", - "AUDIO\\lib_a1.WAV", - "AUDIO\\lib_a2.WAV", - "AUDIO\\lib_a.WAV", - "AUDIO\\lib_b.WAV", - "AUDIO\\lib_c.WAV", - "AUDIO\\lib_d.WAV", - "AUDIO\\l2_a.WAV", - "AUDIO\\j4t_1.WAV", - "AUDIO\\j4t_2.WAV", - "AUDIO\\j4t_3.WAV", - "AUDIO\\j4t_4.WAV", - "AUDIO\\j4_a.WAV", - "AUDIO\\j4_b.WAV", - "AUDIO\\j4_c.WAV", - "AUDIO\\j4_d.WAV", - "AUDIO\\j4_e.WAV", - "AUDIO\\j4_f.WAV", - "AUDIO\\j6_1.WAV", - "AUDIO\\j6_a.WAV", - "AUDIO\\j6_b.WAV", - "AUDIO\\j6_c.WAV", - "AUDIO\\j6_d.WAV", - "AUDIO\\t4_a.WAV", - "AUDIO\\s1_a.WAV", - "AUDIO\\s1_a1.WAV", - "AUDIO\\s1_b.WAV", - "AUDIO\\s1_c.WAV", - "AUDIO\\s1_c1.WAV", - "AUDIO\\s1_d.WAV", - "AUDIO\\s1_e.WAV", - "AUDIO\\s1_f.WAV", - "AUDIO\\s1_g.WAV", - "AUDIO\\s1_h.WAV", - "AUDIO\\s1_i.WAV", - "AUDIO\\s1_j.WAV", - "AUDIO\\s1_k.WAV", - "AUDIO\\s1_l.WAV", - "AUDIO\\s3_a.WAV", - "AUDIO\\s3_b.WAV", - "AUDIO\\el3_a.WAV", - "AUDIO\\mf1_a.WAV", - "AUDIO\\mf2_a.WAV", - "AUDIO\\mf3_a.WAV", - "AUDIO\\mf3_b.WAV", - "AUDIO\\mf3_b1.WAV", - "AUDIO\\mf3_c.WAV", - "AUDIO\\mf4_a.WAV", - "AUDIO\\mf4_b.WAV", - "AUDIO\\mf4_c.WAV", - "AUDIO\\a1_a.WAV", - "AUDIO\\a3_a.WAV", - "AUDIO\\a5_a.WAV", - "AUDIO\\a4_a.WAV", - "AUDIO\\a4_b.WAV", - "AUDIO\\a4_c.WAV", - "AUDIO\\a4_d.WAV", - "AUDIO\\k1_a.WAV", - "AUDIO\\k3_a.WAV", - "AUDIO\\r1_a.WAV", - "AUDIO\\r2_a.WAV", - "AUDIO\\r2_b.WAV", - "AUDIO\\r2_c.WAV", - "AUDIO\\r2_d.WAV", - "AUDIO\\r2_e.WAV", - "AUDIO\\r2_f.WAV", - "AUDIO\\r2_g.WAV", - "AUDIO\\r2_h.WAV", - "AUDIO\\r5_a.WAV", - "AUDIO\\r6_a.WAV", - "AUDIO\\r6_a1.WAV", - "AUDIO\\r6_b.WAV", - "AUDIO\\lo2_a.WAV", - "AUDIO\\lo6_a.WAV", - "AUDIO\\yd2_a.WAV", - "AUDIO\\yd2_b.WAV", - "AUDIO\\yd2_c.WAV", - "AUDIO\\yd2_c1.WAV", - "AUDIO\\yd2_d.WAV", - "AUDIO\\yd2_e.WAV", - "AUDIO\\yd2_f.WAV", - "AUDIO\\yd2_g.WAV", - "AUDIO\\yd2_h.WAV", - "AUDIO\\yd2_ass.WAV", - "AUDIO\\yd2_ok.WAV", - "AUDIO\\h5_a.WAV", - "AUDIO\\h5_b.WAV", - "AUDIO\\h5_c.WAV", - "AUDIO\\ammu_a.WAV", - "AUDIO\\ammu_b.WAV", - "AUDIO\\ammu_c.WAV", - "AUDIO\\door_1.WAV", - "AUDIO\\door_2.WAV", - "AUDIO\\door_3.WAV", - "AUDIO\\door_4.WAV", - "AUDIO\\door_5.WAV", - "AUDIO\\door_6.WAV", - "AUDIO\\t3_a.WAV", - "AUDIO\\t3_b.WAV", - "AUDIO\\t3_c.WAV", - "AUDIO\\k1_b.WAV", - "AUDIO\\cat1.WAV" -}; 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..7742a06a --- /dev/null +++ b/src/audio/oal/channel.cpp @@ -0,0 +1,210 @@ +#include "channel.h" + +#ifdef AUDIO_OAL +#include "common.h" +#include "sampman.h" + +extern bool IsFXSupported(); + +CChannel::CChannel() +{ + alSource = AL_NONE; + alFilter = AL_FILTER_NULL; + SetDefault(); +} + +void CChannel::SetDefault() +{ + alBuffer = 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, &alSource); + if ( HasSource() ) + { + alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE); + if ( IsFXSupported() ) + alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if ( Is2D ) + { + alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef (alSource, AL_GAIN, 1.0f); + } + else + { + if ( IsFXSupported() ) + alGenFilters(1,&alFilter); + } + } +} + +void CChannel::Term() +{ + Stop(); + if ( HasSource() ) + { + if ( IsFXSupported() ) + { + alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if(alFilter != AL_FILTER_NULL) + alDeleteFilters(1,&alFilter); + } + + alDeleteSources(1, &alSource); + } + alSource = AL_NONE; + alFilter = AL_FILTER_NULL; +} + +void CChannel::Start() +{ + if ( !HasSource() ) return; + + if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) + alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei (alSource, AL_BUFFER, alBuffer); + alSourcePlay(alSource); +} + +void CChannel::Stop() +{ + if ( HasSource() ) + alSourceStop(alSource); + + Reset(); +} + +bool CChannel::HasSource() +{ + return alSource != AL_NONE; +} + +bool CChannel::IsUsed() +{ + if ( HasSource() ) + { + ALint sourceState; + alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState); + return sourceState == AL_PLAYING; + } + return false; +} + +void CChannel::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(alSource, AL_PITCH, pitch); +} + +void CChannel::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(alSource, 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(alSource, 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(alSource, AL_POSITION, x, y, z); +} + +void CChannel::SetDistances(float max, float min) +{ + if ( !HasSource() ) return; + alSourcef (alSource, AL_MAX_DISTANCE, max); + alSourcef (alSource, AL_REFERENCE_DISTANCE, min); + alSourcef (alSource, AL_MAX_GAIN, 1.0f); + alSourcef (alSource, AL_ROLLOFF_FACTOR, 1.0f); +} + +void CChannel::SetPan(uint32 pan) +{ + SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f))); +} + +void CChannel::SetBuffer(ALuint buffer) +{ + alBuffer = buffer; +} + +void CChannel::ClearBuffer() +{ + if ( !HasSource() ) return; + SetBuffer(AL_NONE); + alSourcei(alSource, 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(alSource, 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(alSource, 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..4dd09ca1 --- /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 alSource; + ALuint alFilter; + ALuint alBuffer; + 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..4119672f --- /dev/null +++ b/src/audio/oal/oal_utils.cpp @@ -0,0 +1,169 @@ +#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() +{ + /* 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..9bca0546 --- /dev/null +++ b/src/audio/oal/stream.cpp @@ -0,0 +1,520 @@ +#include "stream.h" + +#ifdef AUDIO_OAL +#include "common.h" +#include "sampman.h" + +typedef long ssize_t; + +#include <sndfile.h> +#include <mpg123.h> + +#pragma comment( lib, "libsndfile-1.lib" ) +#pragma comment( lib, "libmpg123.lib" ) + +class CSndFile : public IDecoder +{ + SNDFILE *m_pfSound; + SF_INFO m_soundInfo; +public: + CSndFile(const char *path) : + m_pfSound(nil) + { + memset(&m_soundInfo, 0, sizeof(m_soundInfo)); + m_pfSound = sf_open(path, SFM_READ, &m_soundInfo); + } + + ~CSndFile() + { + if ( m_pfSound ) + { + sf_close(m_pfSound); + m_pfSound = nil; + } + } + + bool IsOpened() + { + return m_pfSound != nil; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + return m_soundInfo.frames; + } + + uint32 GetSampleRate() + { + return m_soundInfo.samplerate; + } + + uint32 GetChannels() + { + return m_soundInfo.channels; + } + + void Seek(uint32 milliseconds) + { + if ( !IsOpened() ) return; + sf_seek(m_pfSound, ms2samples(milliseconds), SF_SEEK_SET); + } + + uint32 Tell() + { + if ( !IsOpened() ) return 0; + return samples2ms(sf_seek(m_pfSound, 0, SF_SEEK_CUR)); + } + + uint32 Decode(void *buffer) + { + if ( !IsOpened() ) return 0; + return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize(); + } +}; + +class CMP3File : public IDecoder +{ + mpg123_handle *m_pMH; + bool m_bOpened; + uint32 m_nRate; + uint32 m_nChannels; +public: + CMP3File(const char *path) : + m_pMH(nil), + m_bOpened(false), + m_nRate(0), + m_nChannels(0) + { + m_pMH = mpg123_new(nil, nil); + if ( m_pMH ) + { + long rate = 0; + int channels = 0; + int encoding = 0; + + m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK + && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; + m_nRate = rate; + m_nChannels = channels; + + if ( IsOpened() ) + { + mpg123_format_none(m_pMH); + mpg123_format(m_pMH, rate, channels, encoding); + } + } + } + + ~CMP3File() + { + if ( m_pMH ) + { + mpg123_close(m_pMH); + mpg123_delete(m_pMH); + m_pMH = nil; + } + } + + bool IsOpened() + { + return m_bOpened; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if ( !IsOpened() ) return 0; + return mpg123_length(m_pMH); + } + + uint32 GetSampleRate() + { + return m_nRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if ( !IsOpened() ) return; + mpg123_seek(m_pMH, ms2samples(milliseconds)*GetSampleSize(), SEEK_SET); + } + + uint32 Tell() + { + if ( !IsOpened() ) return 0; + return samples2ms(mpg123_tell(m_pMH)/GetSampleSize()); + } + + uint32 Decode(void *buffer) + { + if ( !IsOpened() ) return 0; + + size_t size; + int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size); + if (err != MPG123_OK && err != MPG123_DONE) return 0; + return size; + } +}; + +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_pBuffer(nil), + m_bPaused(false), + m_bActive(false), + m_pSoundFile(nil), + m_bReset(false), + m_nVolume(0), + m_nPan(0), + m_nPosBeforeReset(0) + +{ + strcpy(m_aFilename, filename); + + DEV("Stream %s\n", m_aFilename); + + if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) + m_pSoundFile = new CMP3File(m_aFilename); + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) + m_pSoundFile = new CSndFile(m_aFilename); + else + m_pSoundFile = nil; + ASSERT(m_pSoundFile != nil); + if (m_pSoundFile && m_pSoundFile->IsOpened() ) + { + m_pBuffer = malloc(m_pSoundFile->GetBufferSize()); + ASSERT(m_pBuffer!=nil); + + DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec()); + DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount()); + DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate()); + DEV("Channels: %d\n", m_pSoundFile->GetChannels()); + DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples()); + DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate()))); + DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60); + + return; + } +} + +CStream::~CStream() +{ + Delete(); +} + +void CStream::Delete() +{ + Stop(); + ClearBuffers(); + + if ( m_pSoundFile ) + { + delete m_pSoundFile; + m_pSoundFile = nil; + } + + if ( m_pBuffer ) + { + free(m_pBuffer); + m_pBuffer = nil; + } +} + +bool CStream::HasSource() +{ + return m_alSource != AL_NONE; +} + +bool CStream::IsOpened() +{ + return m_pSoundFile->IsOpened(); +} + +bool CStream::IsPlaying() +{ + if ( !HasSource() || !IsOpened() ) return false; + + if ( m_pSoundFile->IsOpened() && !m_bPaused ) + { + ALint sourceState; + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + if ( m_bActive || sourceState == AL_PLAYING ) + return true; + } + + return false; +} + +void CStream::Pause() +{ + if ( !HasSource() ) return; + ALint sourceState = AL_PAUSED; + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED ) + alSourcePause(m_alSource); +} + +void CStream::SetPause(bool bPause) +{ + if ( !HasSource() ) return; + if ( bPause ) + { + Pause(); + m_bPaused = true; + } + else + { + if (m_bPaused) + SetPlay(true); + m_bPaused = false; + } +} + +void CStream::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(m_alSource, AL_PITCH, pitch); +} + +void CStream::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(m_alSource, AL_GAIN, gain); +} + +void CStream::SetPosition(float x, float y, float z) +{ + if ( !HasSource() ) return; + alSource3f(m_alSource, AL_POSITION, x, y, z); +} + +void CStream::SetVolume(uint32 nVol) +{ + m_nVolume = nVol; + SetGain(ALfloat(nVol) / MAX_VOLUME); +} + +void CStream::SetPan(uint8 nPan) +{ + m_nPan = nPan; + SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f))); +} + +void CStream::SetPosMS(uint32 nPos) +{ + if ( !m_pSoundFile->IsOpened() ) return; + m_pSoundFile->Seek(nPos); + ClearBuffers(); +} + +uint32 CStream::GetPosMS() +{ + if ( !HasSource() ) return 0; + if ( !m_pSoundFile->IsOpened() ) return 0; + + ALint offset; + //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); + alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset); + + return m_pSoundFile->Tell() + - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1)) + + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()); +} + +uint32 CStream::GetLengthMS() +{ + if ( !m_pSoundFile->IsOpened() ) return 0; + return m_pSoundFile->GetLength(); +} + +bool CStream::FillBuffer(ALuint alBuffer) +{ + if ( !HasSource() ) + return false; + if ( !m_pSoundFile->IsOpened() ) + return false; + if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) ) + return false; + + uint32 size = m_pSoundFile->Decode(m_pBuffer); + if( size == 0 ) + return false; + + alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, + m_pBuffer, size, m_pSoundFile->GetSampleRate()); + + return true; +} + +int32 CStream::FillBuffers() +{ + int32 i = 0; + for ( i = 0; i < NUM_STREAMBUFFERS; i++ ) + { + if ( !FillBuffer(m_alBuffers[i]) ) + break; + alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]); + } + + return i; +} + +void CStream::ClearBuffers() +{ + if ( !HasSource() ) return; + + ALint buffersQueued; + alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued); + + ALuint value; + while (buffersQueued--) + alSourceUnqueueBuffers(m_alSource, 1, &value); +} + +bool CStream::Setup() +{ + if ( m_pSoundFile->IsOpened() ) + { + m_pSoundFile->Seek(0); + alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE); + //SetPosition(0.0f, 0.0f, 0.0f); + SetPitch(1.0f); + //SetPan(m_nPan); + //SetVolume(100); + } + + return IsOpened(); +} + +void CStream::SetPlay(bool state) +{ + if ( !HasSource() ) return; + if ( state ) + { + ALint sourceState = AL_PLAYING; + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PLAYING ) + alSourcePlay(m_alSource); + m_bActive = true; + } + else + { + ALint sourceState = AL_STOPPED; + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED ) + alSourceStop(m_alSource); + m_bActive = false; + } +} + +void CStream::Start() +{ + if ( !HasSource() ) return; + if ( FillBuffers() != 0 ) + SetPlay(true); +} + +void CStream::Stop() +{ + if ( !HasSource() ) return; + SetPlay(false); +} + +void CStream::Update() +{ + if ( !IsOpened() ) + return; + + if ( !HasSource() ) + return; + + if ( m_bReset ) + return; + + if ( !m_bPaused ) + { + ALint sourceState; + ALint buffersProcessed = 0; + + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); + + ALint looping = AL_FALSE; + alGetSourcei(m_alSource, AL_LOOPING, &looping); + + if ( looping == AL_TRUE ) + { + TRACE("stream set looping"); + alSourcei(m_alSource, AL_LOOPING, AL_TRUE); + } + + while( buffersProcessed-- ) + { + ALuint buffer; + + alSourceUnqueueBuffers(m_alSource, 1, &buffer); + + if ( m_bActive && FillBuffer(buffer) ) + alSourceQueueBuffers(m_alSource, 1, &buffer); + } + + if ( sourceState != AL_PLAYING ) + { + alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); + SetPlay(buffersProcessed!=0); + } + } +} + +void CStream::ProviderInit() +{ + if ( m_bReset ) + { + if ( Setup() ) + { + SetPan(m_nPan); + SetVolume(m_nVolume); + SetPosMS(m_nPosBeforeReset); + if (m_bActive) + FillBuffers(); + SetPlay(m_bActive); + if ( m_bPaused ) + Pause(); + } + + m_bReset = false; + } +} + +void CStream::ProviderTerm() +{ + m_bReset = true; + m_nPosBeforeReset = GetPosMS(); + + ClearBuffers(); +} + +#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..f1e5f458 --- /dev/null +++ b/src/audio/oal/stream.h @@ -0,0 +1,112 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include <AL/al.h> + +#define NUM_STREAMBUFFERS 4 + +class IDecoder +{ +public: + virtual ~IDecoder() { } + + virtual bool IsOpened() = 0; + + virtual uint32 GetSampleSize() = 0; + virtual uint32 GetSampleCount() = 0; + virtual uint32 GetSampleRate() = 0; + virtual uint32 GetChannels() = 0; + + uint32 GetAvgSamplesPerSec() + { + return GetChannels() * GetSampleRate(); + } + + uint32 ms2samples(uint32 ms) + { + return float(ms) / 1000.0f * float(GetChannels()) * float(GetSampleRate()); + } + + uint32 samples2ms(uint32 sm) + { + return float(sm) * 1000.0f / float(GetChannels()) / float(GetSampleRate()); + } + + uint32 GetBufferSamples() + { + //return (GetAvgSamplesPerSec() >> 2) - (GetSampleCount() % GetChannels()); + return (GetAvgSamplesPerSec() / 4); // 250ms + } + + uint32 GetBufferSize() + { + return GetBufferSamples() * GetSampleSize(); + } + + virtual void Seek(uint32 milliseconds) = 0; + virtual uint32 Tell() = 0; + + uint32 GetLength() + { + return float(GetSampleCount()) * 1000.0f / float(GetSampleRate()); + } + + virtual uint32 Decode(void *buffer) = 0; +}; + +class CStream +{ + char m_aFilename[128]; + ALuint &m_alSource; + ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; + + bool m_bPaused; + bool m_bActive; + + void *m_pBuffer; + + bool m_bReset; + uint32 m_nVolume; + uint8 m_nPan; + uint32 m_nPosBeforeReset; + + IDecoder *m_pSoundFile; + + bool HasSource(); + void SetPosition(float x, float y, float z); + void SetPitch(float pitch); + void SetGain(float gain); + void Pause(); + void SetPlay(bool state); + + bool FillBuffer(ALuint alBuffer); + int32 FillBuffers(); + void ClearBuffers(); +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 SetPosMS (uint32 nPos); + uint32 GetPosMS(); + uint32 GetLengthMS(); + + bool Setup(); + void Start(); + void Stop(); + void Update(void); + + void ProviderInit(); + void ProviderTerm(); +}; + +#endif
\ No newline at end of file diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp deleted file mode 100644 index e8213cd9..00000000 --- a/src/audio/openal/samp_oal.cpp +++ /dev/null @@ -1,1404 +0,0 @@ -#include <al.h> -#include <alc.h> -#include <mpg123_pre.h> -//#include <mpg123.h> -#include <time.h> -#include <io.h> -#include "samp_oal.h" -#include "AudioManager.h" -#include "MusicManager.h" -#include "Frontend.h" -#include "Timer.h" - -#pragma comment( lib, "libmpg123.lib" ) -#pragma comment( lib, "OpenAL32.lib" ) - -cSampleManager SampleManager; -int32 BankStartOffset[MAX_SAMPLEBANKS]; - - -/////////////////////////////////////////////////////////////// -class MP3Stream -{ -public: - mpg123_handle *m_pMPG; - FILE *m_fpFile; - unsigned char *m_pBuf; - char m_aFilename[128]; - size_t m_nBufSize; - size_t m_nLengthInBytes; - long m_nRate; - int m_nBitRate; - int m_nChannels; - int m_nEncoding; - int m_nLength; - int m_nBlockSize; - int m_nNumBlocks; - ALuint m_alSource; - ALuint m_alBuffers[5]; - unsigned char *m_pBlocks; - bool m_bIsFree; - bool m_bIsOpened; - bool m_bIsPaused; - int m_nVolume; - - void Initialize(void); - bool FillBuffer(ALuint alBuffer); - void Update(void); - void SetPos(uint32 nPos); - int32 FillBuffers(); - MP3Stream(char *filename, ALuint source, ALuint *buffers); - ~MP3Stream() { Delete(); } - void Delete(); - -}; -/////////////////////////////////////////////////////////////// - -char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; -char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; - -FILE *fpSampleDescHandle; -FILE *fpSampleDataHandle; -bool bSampleBankLoaded [MAX_SAMPLEBANKS]; -int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; -int32 nSampleBankSize [MAX_SAMPLEBANKS]; -int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; -int32 _nSampleDataEndOffset; - -int32 nPedSlotSfx [MAX_PEDSFX]; -int32 nPedSlotSfxAddr[MAX_PEDSFX]; -uint8 nCurrentPedSlot; - - - -uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; - -/////////////////////////////////////////////////////////////// -ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS]; -ALuint ALStreamSources[MAX_STREAMS]; -ALuint ALStreamBuffers[MAX_STREAMS][5]; -struct -{ - ALuint buffer; - ALuint timer; -}ALBuffers[SAMPLEBANK_MAX]; - -ALuint pedBuffers[MAX_PEDSFX]; -//bank0Buffers - -uint32 nNumMP3s; - -MP3Stream *mp3Stream[MAX_STREAMS]; -int8 nStreamPan [MAX_STREAMS]; -int8 nStreamVolume[MAX_STREAMS]; - -float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS]; -uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; -uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS]; -int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS]; -int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS]; -int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; - - -cSampleManager::cSampleManager(void) -{ - ; -} - -cSampleManager::~cSampleManager(void) -{ - ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL); - free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); - - if ( fpSampleDescHandle != NULL ) - { - fclose(fpSampleDescHandle); - fpSampleDescHandle = NULL; - } - - if ( fpSampleDataHandle != NULL ) - { - fclose(fpSampleDataHandle); - fpSampleDataHandle = NULL; - } -} - -void cSampleManager::SetSpeakerConfig(int32 nConfig) -{ - -} - -uint32 cSampleManager::GetMaximumSupportedChannels(void) -{ - return 20; -} - -uint32 cSampleManager::GetNum3DProvidersAvailable() -{ - return 1; -} - -void cSampleManager::SetNum3DProvidersAvailable(uint32 num) -{ - ; -} - -char *cSampleManager::Get3DProviderName(uint8 id) -{ - static char PROVIDER[256] = "OpenAL"; - return PROVIDER; -} - -void cSampleManager::Set3DProviderName(uint8 id, char *name) -{ - ; -} - -int8 cSampleManager::GetCurrent3DProviderIndex(void) -{ - return 0; -} - -int8 cSampleManager::SetCurrent3DProvider(uint8 which) -{ - return 0; -} - -bool -cSampleManager::IsMP3RadioChannelAvailable(void) -{ - return nNumMP3s != 0; -} - - -void cSampleManager::ReleaseDigitalHandle(void) -{ - -} - -void cSampleManager::ReacquireDigitalHandle(void) -{ - -} - -bool -cSampleManager::Initialise(void) -{ - ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; - - m_pDevice = alcOpenDevice(NULL); - ASSERT(m_pDevice != NULL); - - m_pContext = alcCreateContext(m_pDevice, attr); - ASSERT(m_pContext != NULL); - - alcMakeContextCurrent(m_pContext); - - mpg123_init(); - - - - for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) - { - m_aSamples[i].nOffset = 0; - m_aSamples[i].nSize = 0; - m_aSamples[i].nFrequency = MAX_FREQ; - m_aSamples[i].nLoopStart = 0; - m_aSamples[i].nLoopEnd = -1; - } - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - nStreamLength[i] = 3600000; - - for ( int32 i = 0; i < MAX_STREAMS; i++ ) - { - mp3Stream[i] = NULL; - nStreamVolume[i] = 100; - nStreamPan[i] = 63; - } - - alGenSources(MAX_STREAMS, (ALuint *)ALStreamSources); - alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers); - - m_nMonoMode = 0; - - m_nEffectsVolume = MAX_VOLUME; - m_nMusicVolume = MAX_VOLUME; - m_nEffectsFadeVolume = MAX_VOLUME; - m_nMusicFadeVolume = MAX_VOLUME; - - - memset(alChannel, 0, sizeof(alChannel)); - memset(nChannelVolume, 0, sizeof(nChannelVolume)); - memset(ChannelSample, 0, sizeof(ChannelSample)); - - for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ ) - ChannelPitch[i] = 1.0f; - - - fpSampleDescHandle = NULL; - fpSampleDataHandle = NULL; - - for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) - { - bSampleBankLoaded[i] = false; - nSampleBankDiscStartOffset[i] = 0; - nSampleBankSize[i] = 0; - nSampleBankMemoryStartAddress[i] = 0; - } - - alGenBuffers(MAX_PEDSFX, pedBuffers); - - for ( int32 i = 0; i < MAX_PEDSFX; i++ ) - { - nPedSlotSfx[i] = NO_SAMPLE; - nPedSlotSfxAddr[i] = 0; - } - - nCurrentPedSlot = 0; - - for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) - { - ALBuffers[i].buffer = 0; - ALBuffers[i].timer = 0; - } - - alListenerf (AL_GAIN, 1.0f); - alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); - alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f); - ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - alListenerfv(AL_ORIENTATION, orientation); - - if ( !InitialiseSampleBanks() ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]); - ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL); - - if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX); - ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL); - - alGenSources(MAXCHANNELS, alChannel); - for ( int32 i = 0; i < MAXCHANNELS; i++ ) - { - if ( alChannel[i] ) - alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE); - } - - alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]); - if ( alChannel[CHANNEL2D] ) - { - alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f); - } - - LoadSampleBank(SAMPLEBANK_MAIN); - - return true; -} - -void -cSampleManager::Terminate(void) -{ - mpg123_exit(); - alcMakeContextCurrent(NULL); - alcDestroyContext(m_pContext); - alcCloseDevice(m_pDevice); -} - -void -cSampleManager::UpdateSoundBuffers(void) -{ - for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) - { - if ( ALBuffers[i].timer > 0 ) - { - ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f); - - if ( ALBuffers[i].timer <= 0 ) - { - if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) ) - { - alDeleteBuffers(1, &ALBuffers[i].buffer); - - if ( alGetError() == AL_NO_ERROR ) - ALBuffers[i].buffer = 0; - else - ALBuffers[i].buffer = 120000; - } - } - } - } -} - -bool cSampleManager::CheckForAnAudioFileOnCD(void) -{ - return true; -} - -char cSampleManager::GetCDAudioDriveLetter(void) -{ - return '\0'; -} - -void -cSampleManager::SetEffectsMasterVolume(uint8 nVolume) -{ - m_nEffectsVolume = nVolume; -} - -void -cSampleManager::SetMusicMasterVolume(uint8 nVolume) -{ - m_nMusicVolume = nVolume; -} - -void -cSampleManager::SetEffectsFadeVolume(uint8 nVolume) -{ - m_nEffectsFadeVolume = nVolume; -} - -void -cSampleManager::SetMusicFadeVolume(uint8 nVolume) -{ - m_nMusicFadeVolume = nVolume; -} - -void -cSampleManager::SetMonoMode(uint8 nMode) -{ - m_nMonoMode = nMode; -} - -bool -cSampleManager::LoadSampleBank(uint8 nBank) -{ - ASSERT( nBank < MAX_SAMPLEBANKS ); - - if ( CTimer::GetIsCodePaused() ) - return false; - - if ( MusicManager.IsInitialised() - && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && nBank != SAMPLEBANK_MAIN ) - { - return false; - } - - if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) - return false; - - if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] ) - return false; - - bSampleBankLoaded[nBank] = true; - - return true; -} - -void -cSampleManager::UnloadSampleBank(uint8 nBank) -{ - ASSERT( nBank < MAX_SAMPLEBANKS ); - - ; // NOIMP -} - -bool -cSampleManager::IsSampleBankLoaded(uint8 nBank) -{ - ASSERT( nBank < MAX_SAMPLEBANKS ); - return true; -} - -bool -cSampleManager::IsPedCommentLoaded(uint32 nComment) -{ - ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); - - uint8 slot; - - for ( int32 i = 0; i < _TODOCONST(3); i++ ) - { - slot = nCurrentPedSlot - i - 1; - if ( nComment == nPedSlotSfx[slot] ) - return true; - } - - return false; -} - - -int32 -cSampleManager::_GetPedCommentSlot(uint32 nComment) -{ - uint8 slot; - - for (int32 i = 0; i < _TODOCONST(3); i++) - { - slot = nCurrentPedSlot - i - 1; - if (nComment == nPedSlotSfx[slot]) - return slot; - } - - return -1; -} - -bool -cSampleManager::LoadPedComment(uint32 nComment) -{ - ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); - - if ( CTimer::GetIsCodePaused() ) - return false; - - // no talking peds during cutsenes or the game end - if ( MusicManager.IsInitialised() ) - { - switch ( MusicManager.GetMusicMode() ) - { - case MUSICMODE_CUTSCENE: - { - return false; - - break; - } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED ) - return false; - - break; - } - } - } - - if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) - return false; - - if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) - return false; - - nPedSlotSfx[nCurrentPedSlot] = nComment; - - alBufferData(pedBuffers[nCurrentPedSlot], - AL_FORMAT_MONO16, - (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), - m_aSamples[nComment].nSize, - MAX_FREQ); - - if ( ++nCurrentPedSlot >= MAX_PEDSFX ) - nCurrentPedSlot = 0; - - return true; -} - -int32 -cSampleManager::GetBankContainingSound(uint32 offset) -{ - if ( offset >= BankStartOffset[SAMPLEBANK_PED] ) - return SAMPLEBANK_PED; - - if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] ) - return SAMPLEBANK_MAIN; - - return SAMPLEBANK_INVALID; -} - -int32 -cSampleManager::GetSampleBaseFrequency(uint32 nSample) -{ - ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); - return m_aSamples[nSample].nFrequency; -} - -int32 -cSampleManager::GetSampleLoopStartOffset(uint32 nSample) -{ - ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); - return m_aSamples[nSample].nLoopStart; -} - -int32 -cSampleManager::GetSampleLoopEndOffset(uint32 nSample) -{ - ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); - return m_aSamples[nSample].nLoopEnd; -} - -uint32 -cSampleManager::GetSampleLength(uint32 nSample) -{ - ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); - return m_aSamples[nSample].nSize >> 1; -} - -bool cSampleManager::UpdateReverb(void) -{ - return false; -} - -void -cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) -{ - ; // NOIMP -} - -bool -cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - ALuint buffer; - - if ( nSfx < SAMPLEBANK_MAX ) - { - int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset; - int32 size = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize; - - void *data = malloc(size); - ASSERT(data != NULL); - - if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) - { - free(data); - return false; - } - - if ( fread(data, 1, size, fpSampleDataHandle) != size ) - { - free(data); - return false; - } - - ALuint buf; - alGenBuffers(1, &buf); - alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ); - free(data); - - if ( !IsSampleBankLoaded(nBank) ) - return false; - - ALBuffers[nSfx].buffer = buf; - ALBuffers[nSfx].timer = 120000; - - buffer = ALBuffers[nSfx].buffer; - - ChannelSample[nChannel] = nSfx; - } - else - { - if ( !IsPedCommentLoaded(nSfx) ) - return false; - - int32 slot = _GetPedCommentSlot(nSfx); - - buffer = pedBuffers[slot]; - } - - if ( buffer == 0 ) - { - TRACE("No buffer to play id %d", nSfx); - return false; - } - - if ( GetChannelUsedFlag(nChannel) ) - { - TRACE("Stopping channel %d - really!!!", nChannel); - StopChannel(nChannel); - } - - alSourcei(alChannel[nChannel], AL_BUFFER, 0); - currentChannelVolume [nChannel] = -1; - currentChannelFrequency [nChannel] = -1; - currentChannelMaxFrontDistance[nChannel] = -1; - - if ( alChannel[nChannel] ) - { - alSourcei(alChannel[nChannel], AL_BUFFER, buffer); - alSourcef(alChannel[nChannel], AL_PITCH, 1.0f); - ChannelPitch[nChannel] = 1.0f; - return true; - } - - return false; -} - -void -cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - uint32 vol = nVolume; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - nChannelVolume[nChannel] = vol; - - // reduce the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) - { - nChannelVolume[nChannel] >>= 2; - } - - uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14; - if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack - channelVol >>= 1; - - if ( alChannel[nChannel] ) - { - if ( currentChannelVolume[nChannel] != channelVol ) - { - ALfloat gain = ALfloat(channelVol) / MAX_VOLUME; - alSourcef(alChannel[nChannel], AL_GAIN, gain); - currentChannelVolume[nChannel] = channelVol; - } - } -} - -void -cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ); - } -} - -void -cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax ) - { - alSourcef(alChannel[nChannel], AL_MAX_DISTANCE, fMax); - alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f); - alSourcef(alChannel[nChannel], AL_MAX_GAIN, 1.0f); - currentChannelMaxFrontDistance[nChannel] = int32(fMax); - } - } -} - -void -cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( nChannel == CHANNEL2D ) - { - uint32 vol = nVolume; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - nChannelVolume[nChannel] = vol; - - // increase the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) - { - nChannelVolume[nChannel] >>= 2; - } - - uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14; - if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack - channelVol >>= 1; - - if ( alChannel[nChannel] ) - { - if ( currentChannelVolume[nChannel] != channelVol ) - { - ALfloat gain = ALfloat(channelVol) / MAX_VOLUME; - alSourcef(alChannel[nChannel], AL_GAIN, gain); - currentChannelVolume[nChannel] = channelVol; - } - } - } -} - -void -cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - ; // NOIMP -} - -void -cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - if ( currentChannelFrequency[nChannel] != nFreq ) - { - ALfloat pitch = ALfloat(nFreq) / MAX_FREQ; - alSourcef(alChannel[nChannel], AL_PITCH, pitch); - currentChannelFrequency[nChannel] = nFreq; - - if ( Abs(1.0f - pitch) < 0.01f ) - ChannelPitch[nChannel] = 1.0f; - else - ChannelPitch[nChannel] = pitch; - } - } -} - -void -cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - ; // NOIMP -} - -void -cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( nLoopCount != 0 ) - alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE); - else - alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE); -} - -bool -cSampleManager::GetChannelUsedFlag(uint32 nChannel) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - ALint sourceState; - alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState); - return sourceState == AL_PLAYING; - } - - return false; -} - -void -cSampleManager::StartChannel(uint32 nChannel) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank - { - if ( ChannelPitch[nChannel] != 1.0f ) - ChannelPitch[nChannel] = 1.0f; - } - - alSourcef (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]); - alSourcePlay(alChannel[nChannel]); - } -} - -void -cSampleManager::StopChannel(uint32 nChannel) -{ - ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - - if ( alChannel[nChannel] ) - { - alSourceStop(alChannel[nChannel]); - - currentChannelVolume [nChannel] = -1; - currentChannelFrequency [nChannel] = -1; - currentChannelMaxFrontDistance[nChannel] = -1; - ChannelPitch [nChannel] = 1.0f; - } -} - -void -cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) -{ - char filename[256]; - - ASSERT( nStream < MAX_STREAMS ); - - if ( nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - delete mp3Stream[nStream]; - mp3Stream[nStream] = NULL; - } - - strcpy(filename, StreamedNameTable[nFile]); - - MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); - ASSERT(stream != NULL); - - mp3Stream[nStream] = stream; - - if ( stream->m_bIsOpened ) - { - ; - } - else - { - delete stream; - mp3Stream[nStream] = NULL; - } - } -} - -void -cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream ) - { - if ( nPauseFlag != 0 ) - { - if ( !stream->m_bIsPaused ) - { - alSourcePause(stream->m_alSource); - stream->m_bIsPaused = true; - } - } - else - { - if ( stream->m_bIsPaused ) - { - alSourcef(stream->m_alSource, AL_PITCH, 1.0f); - alSourcePlay(stream->m_alSource); - stream->m_bIsPaused = false; - } - } - } -} - -void -cSampleManager::StartPreloadedStreamedFile(uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream ) - { - stream->Initialize(); - if ( stream->m_bIsOpened ) - { - //NOTE: set pos here on mobile - - if ( stream->FillBuffers() != 0 ) - { - alSourcef(stream->m_alSource, AL_PITCH, 1.0f); - alSourcePlay(stream->m_alSource); - stream->m_bIsFree = false; - } - } - } -} - -bool -cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) -{ - char filename[256]; - - ASSERT( nStream < MAX_STREAMS ); - - if ( nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - delete mp3Stream[nStream]; - mp3Stream[nStream] = NULL; - } - - strcpy(filename, StreamedNameTable[nFile]); - - MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); - ASSERT(stream != NULL); - - mp3Stream[nStream] = stream; - - if ( stream->m_bIsOpened ) - { - stream->Initialize(); - nStreamLength[nFile] = stream->m_nLength; - //MusicManager.SetTrackInfoLength(nFile, stream->m_nLength); - - if ( stream->m_bIsOpened ) - { - if ( nPos != 0 ) - { - stream->SetPos(nPos); - } - - if ( stream->FillBuffers() != 0 ) - { - alSourcef(stream->m_alSource, AL_PITCH, 1.0f); - alSourcePlay(stream->m_alSource); - stream->m_bIsFree = false; - } - } - - return true; - } - else - { - delete stream; - mp3Stream[nStream] = NULL; - } - } - - return false; -} - -void -cSampleManager::StopStreamedFile(uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream ) - { - delete stream; - mp3Stream[nStream] = NULL; - } -} - -int32 -cSampleManager::GetStreamedFilePosition(uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream ) - { - return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate; - } - - return 0; -} - -void -cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - if ( nVolume > MAX_VOLUME ) - nVolume = MAX_VOLUME; - - if ( nPan > MAX_VOLUME ) - nPan = MAX_VOLUME; - - nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume; - nStreamPan [nStream] = nPan; - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream ) - { - uint32 vol; - if ( nEffectFlag ) - vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14; - else - vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14; - - if ( stream->m_nVolume != vol ) - { - if ( stream->m_bIsOpened ) - { - ALuint source = stream->m_alSource; - if ( source ) - { - ALfloat gain = ALfloat(vol) / MAX_VOLUME; - alSourcef(source, AL_GAIN, gain); - stream = mp3Stream[nStream]; - } - } - - stream->m_nVolume = vol; - } - } -} - -int32 -cSampleManager::GetStreamedFileLength(uint8 nStream) -{ - ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); - - return nStreamLength[nStream]; -} - -bool -cSampleManager::IsStreamPlaying(uint8 nStream) -{ - ASSERT( nStream < MAX_STREAMS ); - - MP3Stream *stream = mp3Stream[nStream]; - - if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused ) - { - ALint sourceState; - alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState); - if ( !stream->m_bIsFree || sourceState == AL_PLAYING ) - return true; - } - - return false; -} - -void -cSampleManager::Service(void) -{ - for ( int32 i = 0; i < MAX_STREAMS; i++ ) - { - if ( mp3Stream[i] ) - mp3Stream[i]->Update(); - } - - UpdateSoundBuffers(); -} - -bool -cSampleManager::InitialiseSampleBanks(void) -{ - int32 nBank = SAMPLEBANK_MAIN; - - fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); - if ( fpSampleDescHandle == NULL ) - return false; - - fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); - if ( fpSampleDataHandle == NULL ) - { - fclose(fpSampleDescHandle); - fpSampleDescHandle = NULL; - - return false; - } - - fseek(fpSampleDataHandle, 0, SEEK_END); - int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle); - rewind(fpSampleDataHandle); - - fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); - - fclose(fpSampleDescHandle); - fpSampleDescHandle = NULL; - - for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) - { - if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i ) - { - nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; - nBank++; - } - } - - nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN]; - nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED]; - - return true; -} - -/* -sub_1D8D40 -PreloadSoundBank(tSample *,uchar) -CheckOpenALChannels(void) -*/ - -void MP3Stream::Initialize(void) -{ - if ( !m_bIsOpened ) - return; - - mpg123_format_none(m_pMPG); - - mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); - mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); - mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); - mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); - - if ( mpg123_open_feed(m_pMPG) != MPG123_OK ) - return; - - const uint32 CHUNK_SIZE = 1024*5; - - if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE ) - { - Delete(); - return; - } - - m_nBufSize -= CHUNK_SIZE; - - mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE); - - if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK ) - { - Delete(); - return; - } - - mpg123_frameinfo info; - if ( mpg123_info(m_pMPG, &info) != MPG123_OK ) - { - Delete(); - return; - } - - m_nBitRate = info.bitrate; - m_nLength = 8 * m_nLengthInBytes / info.bitrate; - m_nBlockSize = mpg123_outblock(m_pMPG); - m_nNumBlocks = 5; - m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize); -} - -bool MP3Stream::FillBuffer(ALuint alBuffer) -{ - size_t done; - - uint8 *pBlockBuff = (uint8 *)m_pBlocks; - - bool fail = !(m_nBufSize > 1); - - int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done); - if ( alBuffer == 0 ) - { - if ( err == MPG123_OK ) - { - while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK ) - ; - } - - return true; - } - - int32 blocks = 0; - for ( blocks = 0; blocks < m_nNumBlocks; blocks++ ) - { - if ( err == MPG123_NEED_MORE ) - { - if ( fail ) - break; - - size_t readSize = m_nBufSize; - if ( readSize > 0x4000 ) - { - if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 ) - { - fail = true; - TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing"); - break; - } - - m_nBufSize -= 0x4000; - mpg123_feed(m_pMPG, m_pBuf, 0x4000); - } - else - { - if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize ) - { - fail = true; - break; - } - - m_nBufSize -= readSize; - mpg123_feed(m_pMPG, m_pBuf, readSize); - } - } - else if ( err == MPG123_OK ) - { - pBlockBuff += m_nBlockSize; - } - else - { - fail = true; - break; - } - - err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done); - } - - if ( blocks != 0 ) - { - if ( m_nChannels == 1 ) - alBufferData(alBuffer, AL_FORMAT_MONO16, m_pBlocks, m_nBlockSize*blocks, m_nRate); - else - alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate); - } - - if ( fail && blocks < m_nNumBlocks ) - m_bIsFree = true; - - return blocks != 0; -} - -void MP3Stream::Update(void) -{ - if ( !m_bIsOpened ) - return; - - if ( m_bIsFree ) - return; - - if ( !m_bIsPaused ) - { - ALint sourceState; - ALint buffersProcessed = 0; - - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); - - ALint looping = AL_FALSE; - alGetSourcei(m_alSource, AL_LOOPING, &looping); - - if ( looping == AL_TRUE ) - { - TRACE("stream set looping"); - alSourcei(m_alSource, AL_LOOPING, AL_TRUE); - } - - while( buffersProcessed-- ) - { - ALuint buffer; - - alSourceUnqueueBuffers(m_alSource, 1, &buffer); - - if ( !m_bIsFree && FillBuffer(buffer) ) - alSourceQueueBuffers(m_alSource, 1, &buffer); - } - - if ( sourceState != AL_PLAYING ) - { - alSourcef(m_alSource, AL_PITCH, 1.0f); - alSourcePlay(m_alSource); - } - } -} - -void MP3Stream::SetPos(uint32 nPos) -{ - uint32 pos = nPos; - if ( nPos > m_nLength ) - pos %= m_nLength; - - uint32 blockPos = m_nBitRate * pos / 8; - if ( blockPos > m_nLengthInBytes ) - blockPos %= m_nLengthInBytes; - - fseek(m_fpFile, blockPos, SEEK_SET); - - size_t done; - while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK ) - ; -} - -int32 MP3Stream::FillBuffers() -{ - int32 i = 0; - for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ ) - { - if ( !FillBuffer(m_alBuffers[i]) ) - break; - alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]); - } - - return i; -} - -MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers) -{ - strcpy(m_aFilename, filename); - memset(m_alBuffers, 0, sizeof(m_alBuffers)); - m_alSource = source; - memcpy(m_alBuffers, buffers, sizeof(m_alBuffers)); - m_nVolume = -1; - m_pBlocks = NULL; - m_pBuf = NULL; - m_pMPG = NULL; - m_bIsPaused = false; - m_bIsOpened = true; - m_bIsFree = true; - m_fpFile = fopen(m_aFilename, "rb"); - - if ( m_fpFile ) - { - m_nBufSize = filelength(fileno(m_fpFile)); - m_nLengthInBytes = m_nBufSize; - m_pMPG = mpg123_new(NULL, NULL); - m_pBuf = (unsigned char *)malloc(0x4000); - } - else - { - m_bIsOpened = false; - Delete(); - } -} - -void MP3Stream::Delete() -{ - if ( m_pMPG ) - { - mpg123_delete(m_pMPG); - m_pMPG = NULL; - } - - if ( m_fpFile ) - { - fclose(m_fpFile); - m_fpFile = NULL; - } - - if ( m_alSource ) - { - ALint sourceState = AL_STOPPED; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - if (sourceState != AL_STOPPED ) - alSourceStop(m_alSource); - - ALint buffersQueued; - alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued); - - ALuint value; - while (buffersQueued--) - alSourceUnqueueBuffers(m_alSource, 1, &value); - - m_alSource = 0; - } - - if ( m_pBlocks ) - { - free(m_pBlocks); - m_pBlocks = NULL; - } - - if ( m_pBuf ) - { - free(m_pBuf); - m_pBuf = NULL; - } - - m_bIsOpened = false; -}
\ No newline at end of file diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h deleted file mode 100644 index 8bbdbcc9..00000000 --- a/src/audio/openal/samp_oal.h +++ /dev/null @@ -1,340 +0,0 @@ -#pragma once -#include "common.h" -#include "AudioSamples.h" - -#define MAX_VOLUME 127 -//#define MAX_FREQ 22050 -#define MAX_FREQ 32000 - -struct tSample { - int32 nOffset; - uint32 nSize; - int32 nFrequency; - int32 nLoopStart; - int32 nLoopEnd; -}; - -enum -{ - SAMPLEBANK_MAIN, - SAMPLEBANK_PED, - MAX_SAMPLEBANKS, - SAMPLEBANK_INVALID -}; - -#define MAX_PEDSFX 7 -#define PED_BLOCKSIZE 79000 - - -//#define MAXCHANNELS 21 android -#define MAXCHANNELS 28 -#define MAX2DCHANNELS 1 -#define CHANNEL2D MAXCHANNELS - -#define MAX_STREAMS 2 - -struct ALCdevice_struct; -struct ALCcontext_struct; -typedef struct ALCdevice_struct ALCdevice; -typedef struct ALCcontext_struct ALCcontext; - -class cSampleManager -{ - int field_0; - ALCdevice *m_pDevice; - ALCcontext *m_pContext; - - uint8 m_nEffectsVolume; - uint8 m_nMusicVolume; - uint8 m_nEffectsFadeVolume; - uint8 m_nMusicFadeVolume; - uint8 m_nMonoMode; - char _pad0[3]; - tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; - -public: - - - - cSampleManager(void); - ~cSampleManager(void); - - void SetSpeakerConfig(int32 nConfig); - uint32 GetMaximumSupportedChannels(void); - - uint32 GetNum3DProvidersAvailable(); - void SetNum3DProvidersAvailable(uint32 num); - - char *Get3DProviderName(uint8 id); - void Set3DProviderName(uint8 id, char *name); - - int8 GetCurrent3DProviderIndex(void); - int8 SetCurrent3DProvider(uint8 which); - - bool IsMP3RadioChannelAvailable(void); - - void ReleaseDigitalHandle (void); - void ReacquireDigitalHandle(void); - - bool Initialise(void); - void Terminate (void); - - void UpdateSoundBuffers(void); - - bool CheckForAnAudioFileOnCD(void); - char GetCDAudioDriveLetter (void); - - void UpdateEffectsVolume(void); - - void SetEffectsMasterVolume(uint8 nVolume); - void SetMusicMasterVolume (uint8 nVolume); - void SetEffectsFadeVolume (uint8 nVolume); - void SetMusicFadeVolume (uint8 nVolume); - void SetMonoMode (uint8 nMode); - - bool LoadSampleBank (uint8 nBank); - void UnloadSampleBank (uint8 nBank); - bool IsSampleBankLoaded(uint8 nBank); - - bool IsPedCommentLoaded(uint32 nComment); - bool LoadPedComment (uint32 nComment); - int32 GetBankContainingSound(uint32 offset); - - int32 _GetPedCommentSlot(uint32 nComment); - - int32 GetSampleBaseFrequency (uint32 nSample); - int32 GetSampleLoopStartOffset(uint32 nSample); - int32 GetSampleLoopEndOffset (uint32 nSample); - uint32 GetSampleLength (uint32 nSample); - - bool UpdateReverb(void); - - void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); - bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); - void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); - void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); - void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); - void SetChannelVolume (uint32 nChannel, uint32 nVolume); - void SetChannelPan (uint32 nChannel, uint32 nPan); - void SetChannelFrequency (uint32 nChannel, uint32 nFreq); - void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); - void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); - bool GetChannelUsedFlag (uint32 nChannel); - void StartChannel (uint32 nChannel); - void StopChannel (uint32 nChannel); - - void PreloadStreamedFile (uint8 nFile, uint8 nStream); - void PauseStream (uint8 nPauseFlag, uint8 nStream); - void StartPreloadedStreamedFile (uint8 nStream); - bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); - void StopStreamedFile (uint8 nStream); - int32 GetStreamedFilePosition (uint8 nStream); - void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); - int32 GetStreamedFileLength (uint8 nStream); - bool IsStreamPlaying (uint8 nStream); - void Service(void); - bool InitialiseSampleBanks(void); -}; - -extern cSampleManager SampleManager; -extern int32 BankStartOffset[MAX_SAMPLEBANKS]; - -static char StreamedNameTable[][25]= -{ - "AUDIO\\HEAD.MP3", - "AUDIO\\CLASS.MP3", - "AUDIO\\KJAH.MP3", - "AUDIO\\RISE.MP3", - "AUDIO\\LIPS.MP3", - "AUDIO\\GAME.MP3", - "AUDIO\\MSX.MP3", - "AUDIO\\FLASH.MP3", - "AUDIO\\CHAT.MP3", - "AUDIO\\HEAD.MP3", - "AUDIO\\POLICE.MP3", - "AUDIO\\CITY.MP3", - "AUDIO\\WATER.MP3", - "AUDIO\\COMOPEN.MP3", - "AUDIO\\SUBOPEN.MP3", - "AUDIO\\JB.MP3", - "AUDIO\\BET.MP3", - "AUDIO\\L1_LG.MP3", - "AUDIO\\L2_DSB.MP3", - "AUDIO\\L3_DM.MP3", - "AUDIO\\L4_PAP.MP3", - "AUDIO\\L5_TFB.MP3", - "AUDIO\\J0_DM2.MP3", - "AUDIO\\J1_LFL.MP3", - "AUDIO\\J2_KCL.MP3", - "AUDIO\\J3_VH.MP3", - "AUDIO\\J4_ETH.MP3", - "AUDIO\\J5_DST.MP3", - "AUDIO\\J6_TBJ.MP3", - "AUDIO\\T1_TOL.MP3", - "AUDIO\\T2_TPU.MP3", - "AUDIO\\T3_MAS.MP3", - "AUDIO\\T4_TAT.MP3", - "AUDIO\\T5_BF.MP3", - "AUDIO\\S0_MAS.MP3", - "AUDIO\\S1_PF.MP3", - "AUDIO\\S2_CTG.MP3", - "AUDIO\\S3_RTC.MP3", - "AUDIO\\S5_LRQ.MP3", - "AUDIO\\S4_BDBA.MP3", - "AUDIO\\S4_BDBB.MP3", - "AUDIO\\S2_CTG2.MP3", - "AUDIO\\S4_BDBD.MP3", - "AUDIO\\S5_LRQB.MP3", - "AUDIO\\S5_LRQC.MP3", - "AUDIO\\A1_SSO.MP3", - "AUDIO\\A2_PP.MP3", - "AUDIO\\A3_SS.MP3", - "AUDIO\\A4_PDR.MP3", - "AUDIO\\A5_K2FT.MP3", - "AUDIO\\K1_KBO.MP3", - "AUDIO\\K2_GIS.MP3", - "AUDIO\\K3_DS.MP3", - "AUDIO\\K4_SHI.MP3", - "AUDIO\\K5_SD.MP3", - "AUDIO\\R0_PDR2.MP3", - "AUDIO\\R1_SW.MP3", - "AUDIO\\R2_AP.MP3", - "AUDIO\\R3_ED.MP3", - "AUDIO\\R4_GF.MP3", - "AUDIO\\R5_PB.MP3", - "AUDIO\\R6_MM.MP3", - "AUDIO\\D1_STOG.MP3", - "AUDIO\\D2_KK.MP3", - "AUDIO\\D3_ADO.MP3", - "AUDIO\\D5_ES.MP3", - "AUDIO\\D7_MLD.MP3", - "AUDIO\\D4_GTA.MP3", - "AUDIO\\D4_GTA2.MP3", - "AUDIO\\D6_STS.MP3", - "AUDIO\\A6_BAIT.MP3", - "AUDIO\\A7_ETG.MP3", - "AUDIO\\A8_PS.MP3", - "AUDIO\\A9_ASD.MP3", - "AUDIO\\K4_SHI2.MP3", - "AUDIO\\C1_TEX.MP3", - "AUDIO\\EL_PH1.MP3", - "AUDIO\\EL_PH2.MP3", - "AUDIO\\EL_PH3.MP3", - "AUDIO\\EL_PH4.MP3", - "AUDIO\\YD_PH1.MP3", - "AUDIO\\YD_PH2.MP3", - "AUDIO\\YD_PH3.MP3", - "AUDIO\\YD_PH4.MP3", - "AUDIO\\HD_PH1.MP3", - "AUDIO\\HD_PH2.MP3", - "AUDIO\\HD_PH3.MP3", - "AUDIO\\HD_PH4.MP3", - "AUDIO\\HD_PH5.MP3", - "AUDIO\\MT_PH1.MP3", - "AUDIO\\MT_PH2.MP3", - "AUDIO\\MT_PH3.MP3", - "AUDIO\\MT_PH4.MP3", - "AUDIO\\MISCOM.MP3", - "AUDIO\\END.MP3", - "AUDIO\\lib_a1.MP3", - "AUDIO\\lib_a2.MP3", - "AUDIO\\lib_a.MP3", - "AUDIO\\lib_b.MP3", - "AUDIO\\lib_c.MP3", - "AUDIO\\lib_d.MP3", - "AUDIO\\l2_a.MP3", - "AUDIO\\j4t_1.MP3", - "AUDIO\\j4t_2.MP3", - "AUDIO\\j4t_3.MP3", - "AUDIO\\j4t_4.MP3", - "AUDIO\\j4_a.MP3", - "AUDIO\\j4_b.MP3", - "AUDIO\\j4_c.MP3", - "AUDIO\\j4_d.MP3", - "AUDIO\\j4_e.MP3", - "AUDIO\\j4_f.MP3", - "AUDIO\\j6_1.MP3", - "AUDIO\\j6_a.MP3", - "AUDIO\\j6_b.MP3", - "AUDIO\\j6_c.MP3", - "AUDIO\\j6_d.MP3", - "AUDIO\\t4_a.MP3", - "AUDIO\\s1_a.MP3", - "AUDIO\\s1_a1.MP3", - "AUDIO\\s1_b.MP3", - "AUDIO\\s1_c.MP3", - "AUDIO\\s1_c1.MP3", - "AUDIO\\s1_d.MP3", - "AUDIO\\s1_e.MP3", - "AUDIO\\s1_f.MP3", - "AUDIO\\s1_g.MP3", - "AUDIO\\s1_h.MP3", - "AUDIO\\s1_i.MP3", - "AUDIO\\s1_j.MP3", - "AUDIO\\s1_k.MP3", - "AUDIO\\s1_l.MP3", - "AUDIO\\s3_a.MP3", - "AUDIO\\s3_b.MP3", - "AUDIO\\el3_a.MP3", - "AUDIO\\mf1_a.MP3", - "AUDIO\\mf2_a.MP3", - "AUDIO\\mf3_a.MP3", - "AUDIO\\mf3_b.MP3", - "AUDIO\\mf3_b1.MP3", - "AUDIO\\mf3_c.MP3", - "AUDIO\\mf4_a.MP3", - "AUDIO\\mf4_b.MP3", - "AUDIO\\mf4_c.MP3", - "AUDIO\\a1_a.MP3", - "AUDIO\\a3_a.MP3", - "AUDIO\\a5_a.MP3", - "AUDIO\\a4_a.MP3", - "AUDIO\\a4_b.MP3", - "AUDIO\\a4_c.MP3", - "AUDIO\\a4_d.MP3", - "AUDIO\\k1_a.MP3", - "AUDIO\\k3_a.MP3", - "AUDIO\\r1_a.MP3", - "AUDIO\\r2_a.MP3", - "AUDIO\\r2_b.MP3", - "AUDIO\\r2_c.MP3", - "AUDIO\\r2_d.MP3", - "AUDIO\\r2_e.MP3", - "AUDIO\\r2_f.MP3", - "AUDIO\\r2_g.MP3", - "AUDIO\\r2_h.MP3", - "AUDIO\\r5_a.MP3", - "AUDIO\\r6_a.MP3", - "AUDIO\\r6_a1.MP3", - "AUDIO\\r6_b.MP3", - "AUDIO\\lo2_a.MP3", - "AUDIO\\lo6_a.MP3", - "AUDIO\\yd2_a.MP3", - "AUDIO\\yd2_b.MP3", - "AUDIO\\yd2_c.MP3", - "AUDIO\\yd2_c1.MP3", - "AUDIO\\yd2_d.MP3", - "AUDIO\\yd2_e.MP3", - "AUDIO\\yd2_f.MP3", - "AUDIO\\yd2_g.MP3", - "AUDIO\\yd2_h.MP3", - "AUDIO\\yd2_ass.MP3", - "AUDIO\\yd2_ok.MP3", - "AUDIO\\h5_a.MP3", - "AUDIO\\h5_b.MP3", - "AUDIO\\h5_c.MP3", - "AUDIO\\ammu_a.MP3", - "AUDIO\\ammu_b.MP3", - "AUDIO\\ammu_c.MP3", - "AUDIO\\door_1.MP3", - "AUDIO\\door_2.MP3", - "AUDIO\\door_3.MP3", - "AUDIO\\door_4.MP3", - "AUDIO\\door_5.MP3", - "AUDIO\\door_6.MP3", - "AUDIO\\t3_a.MP3", - "AUDIO\\t3_b.MP3", - "AUDIO\\t3_c.MP3", - "AUDIO\\k1_b.MP3", - "AUDIO\\cat1.MP3" -}; diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp deleted file mode 100644 index aa6b67dc..00000000 --- a/src/audio/sampman.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "common.h" -#ifndef OPENAL -#include "miles\sampman_mss.cpp" -#else -#include "openal\samp_oal.cpp" -#endif
\ No newline at end of file diff --git a/src/audio/sampman.h b/src/audio/sampman.h index f454d236..d3c82943 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -1,7 +1,345 @@ #pragma once #include "common.h" -#ifndef OPENAL -#include "miles\sampman_mss.h" -#else -#include "openal\samp_oal.h" -#endif
\ No newline at end of file +#include "AudioSamples.h" + +#define MAX_VOLUME 127 +#define MAX_FREQ 22050 + +struct tSample { + int32 nOffset; + uint32 nSize; + int32 nFrequency; + int32 nLoopStart; + int32 nLoopEnd; +}; + +enum +{ + SAMPLEBANK_MAIN, + SAMPLEBANK_PED, + MAX_SAMPLEBANKS, + SAMPLEBANK_INVALID +}; + +#define MAX_PEDSFX 7 +#define PED_BLOCKSIZE 79000 + +#define MAXPROVIDERS 64 + +#define MAXCHANNELS 28 +#define MAXCHANNELS_SURROUND 24 +#define MAX2DCHANNELS 1 +#define CHANNEL2D MAXCHANNELS + +#define MAX_STREAMS 2 + +#define DIGITALRATE 32000 +#define DIGITALBITS 16 +#define DIGITALCHANNELS 2 + +#define MAX_DIGITAL_MIXER_CHANNELS 32 + +class cSampleManager +{ + uint8 m_nEffectsVolume; + uint8 m_nMusicVolume; + uint8 m_nEffectsFadeVolume; + uint8 m_nMusicFadeVolume; + uint8 m_nMonoMode; + char unk; + char m_szCDRomRootPath[80]; + bool m_bInitialised; + uint8 m_nNumberOfProviders; + char *m_aAudioProviders[MAXPROVIDERS]; + tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; + +public: + + + + cSampleManager(void); + ~cSampleManager(void); + + void SetSpeakerConfig(int32 nConfig); + uint32 GetMaximumSupportedChannels(void); + + uint32 GetNum3DProvidersAvailable(void); + void SetNum3DProvidersAvailable(uint32 num); + + char *Get3DProviderName(uint8 id); + void Set3DProviderName(uint8 id, char *name); + + int8 GetCurrent3DProviderIndex(void); + int8 SetCurrent3DProvider(uint8 which); + + bool IsMP3RadioChannelAvailable(void); + + void ReleaseDigitalHandle (void); + void ReacquireDigitalHandle(void); + + bool Initialise(void); + void Terminate (void); + +#ifdef AUDIO_OAL + void UpdateSoundBuffers(void); +#endif + + bool CheckForAnAudioFileOnCD(void); + char GetCDAudioDriveLetter (void); + + void UpdateEffectsVolume(void); + + void SetEffectsMasterVolume(uint8 nVolume); + void SetMusicMasterVolume (uint8 nVolume); + void SetEffectsFadeVolume (uint8 nVolume); + void SetMusicFadeVolume (uint8 nVolume); + void SetMonoMode (uint8 nMode); + + bool LoadSampleBank (uint8 nBank); + void UnloadSampleBank (uint8 nBank); + bool IsSampleBankLoaded(uint8 nBank); + + bool IsPedCommentLoaded(uint32 nComment); + bool LoadPedComment (uint32 nComment); + int32 GetBankContainingSound(uint32 offset); + + int32 _GetPedCommentSlot(uint32 nComment); + + int32 GetSampleBaseFrequency (uint32 nSample); + int32 GetSampleLoopStartOffset(uint32 nSample); + int32 GetSampleLoopEndOffset (uint32 nSample); + uint32 GetSampleLength (uint32 nSample); + + bool UpdateReverb(void); + + void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); + bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); + void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); + void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); + void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); + void SetChannelVolume (uint32 nChannel, uint32 nVolume); + void SetChannelPan (uint32 nChannel, uint32 nPan); + void SetChannelFrequency (uint32 nChannel, uint32 nFreq); + void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); + void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); + bool GetChannelUsedFlag (uint32 nChannel); + void StartChannel (uint32 nChannel); + void StopChannel (uint32 nChannel); + + void PreloadStreamedFile (uint8 nFile, uint8 nStream); + void PauseStream (uint8 nPauseFlag, uint8 nStream); + void StartPreloadedStreamedFile (uint8 nStream); + bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); + void StopStreamedFile (uint8 nStream); + int32 GetStreamedFilePosition (uint8 nStream); + void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); + int32 GetStreamedFileLength (uint8 nStream); + bool IsStreamPlaying (uint8 nStream); +#ifdef AUDIO_OAL + void Service(void); +#endif + bool InitialiseSampleBanks(void); +}; + +extern cSampleManager SampleManager; +extern uint32 BankStartOffset[MAX_SAMPLEBANKS]; + +static char StreamedNameTable[][25]= +{ + "AUDIO\\HEAD.WAV", + "AUDIO\\CLASS.WAV", + "AUDIO\\KJAH.WAV", + "AUDIO\\RISE.WAV", + "AUDIO\\LIPS.WAV", + "AUDIO\\GAME.WAV", + "AUDIO\\MSX.WAV", + "AUDIO\\FLASH.WAV", + "AUDIO\\CHAT.WAV", + "AUDIO\\HEAD.WAV", + "AUDIO\\POLICE.WAV", + "AUDIO\\CITY.WAV", + "AUDIO\\WATER.WAV", + "AUDIO\\COMOPEN.WAV", + "AUDIO\\SUBOPEN.WAV", + "AUDIO\\JB.MP3", + "AUDIO\\BET.MP3", + "AUDIO\\L1_LG.MP3", + "AUDIO\\L2_DSB.MP3", + "AUDIO\\L3_DM.MP3", + "AUDIO\\L4_PAP.MP3", + "AUDIO\\L5_TFB.MP3", + "AUDIO\\J0_DM2.MP3", + "AUDIO\\J1_LFL.MP3", + "AUDIO\\J2_KCL.MP3", + "AUDIO\\J3_VH.MP3", + "AUDIO\\J4_ETH.MP3", + "AUDIO\\J5_DST.MP3", + "AUDIO\\J6_TBJ.MP3", + "AUDIO\\T1_TOL.MP3", + "AUDIO\\T2_TPU.MP3", + "AUDIO\\T3_MAS.MP3", + "AUDIO\\T4_TAT.MP3", + "AUDIO\\T5_BF.MP3", + "AUDIO\\S0_MAS.MP3", + "AUDIO\\S1_PF.MP3", + "AUDIO\\S2_CTG.MP3", + "AUDIO\\S3_RTC.MP3", + "AUDIO\\S5_LRQ.MP3", + "AUDIO\\S4_BDBA.MP3", + "AUDIO\\S4_BDBB.MP3", + "AUDIO\\S2_CTG2.MP3", + "AUDIO\\S4_BDBD.MP3", + "AUDIO\\S5_LRQB.MP3", + "AUDIO\\S5_LRQC.MP3", + "AUDIO\\A1_SSO.WAV", + "AUDIO\\A2_PP.WAV", + "AUDIO\\A3_SS.WAV", + "AUDIO\\A4_PDR.WAV", + "AUDIO\\A5_K2FT.WAV", + "AUDIO\\K1_KBO.MP3", + "AUDIO\\K2_GIS.MP3", + "AUDIO\\K3_DS.MP3", + "AUDIO\\K4_SHI.MP3", + "AUDIO\\K5_SD.MP3", + "AUDIO\\R0_PDR2.MP3", + "AUDIO\\R1_SW.MP3", + "AUDIO\\R2_AP.MP3", + "AUDIO\\R3_ED.MP3", + "AUDIO\\R4_GF.MP3", + "AUDIO\\R5_PB.MP3", + "AUDIO\\R6_MM.MP3", + "AUDIO\\D1_STOG.MP3", + "AUDIO\\D2_KK.MP3", + "AUDIO\\D3_ADO.MP3", + "AUDIO\\D5_ES.MP3", + "AUDIO\\D7_MLD.MP3", + "AUDIO\\D4_GTA.MP3", + "AUDIO\\D4_GTA2.MP3", + "AUDIO\\D6_STS.MP3", + "AUDIO\\A6_BAIT.WAV", + "AUDIO\\A7_ETG.WAV", + "AUDIO\\A8_PS.WAV", + "AUDIO\\A9_ASD.WAV", + "AUDIO\\K4_SHI2.MP3", + "AUDIO\\C1_TEX.MP3", + "AUDIO\\EL_PH1.MP3", + "AUDIO\\EL_PH2.MP3", + "AUDIO\\EL_PH3.MP3", + "AUDIO\\EL_PH4.MP3", + "AUDIO\\YD_PH1.MP3", + "AUDIO\\YD_PH2.MP3", + "AUDIO\\YD_PH3.MP3", + "AUDIO\\YD_PH4.MP3", + "AUDIO\\HD_PH1.MP3", + "AUDIO\\HD_PH2.MP3", + "AUDIO\\HD_PH3.MP3", + "AUDIO\\HD_PH4.MP3", + "AUDIO\\HD_PH5.MP3", + "AUDIO\\MT_PH1.MP3", + "AUDIO\\MT_PH2.MP3", + "AUDIO\\MT_PH3.MP3", + "AUDIO\\MT_PH4.MP3", + "AUDIO\\MISCOM.WAV", + "AUDIO\\END.MP3", + "AUDIO\\lib_a1.WAV", + "AUDIO\\lib_a2.WAV", + "AUDIO\\lib_a.WAV", + "AUDIO\\lib_b.WAV", + "AUDIO\\lib_c.WAV", + "AUDIO\\lib_d.WAV", + "AUDIO\\l2_a.WAV", + "AUDIO\\j4t_1.WAV", + "AUDIO\\j4t_2.WAV", + "AUDIO\\j4t_3.WAV", + "AUDIO\\j4t_4.WAV", + "AUDIO\\j4_a.WAV", + "AUDIO\\j4_b.WAV", + "AUDIO\\j4_c.WAV", + "AUDIO\\j4_d.WAV", + "AUDIO\\j4_e.WAV", + "AUDIO\\j4_f.WAV", + "AUDIO\\j6_1.WAV", + "AUDIO\\j6_a.WAV", + "AUDIO\\j6_b.WAV", + "AUDIO\\j6_c.WAV", + "AUDIO\\j6_d.WAV", + "AUDIO\\t4_a.WAV", + "AUDIO\\s1_a.WAV", + "AUDIO\\s1_a1.WAV", + "AUDIO\\s1_b.WAV", + "AUDIO\\s1_c.WAV", + "AUDIO\\s1_c1.WAV", + "AUDIO\\s1_d.WAV", + "AUDIO\\s1_e.WAV", + "AUDIO\\s1_f.WAV", + "AUDIO\\s1_g.WAV", + "AUDIO\\s1_h.WAV", + "AUDIO\\s1_i.WAV", + "AUDIO\\s1_j.WAV", + "AUDIO\\s1_k.WAV", + "AUDIO\\s1_l.WAV", + "AUDIO\\s3_a.WAV", + "AUDIO\\s3_b.WAV", + "AUDIO\\el3_a.WAV", + "AUDIO\\mf1_a.WAV", + "AUDIO\\mf2_a.WAV", + "AUDIO\\mf3_a.WAV", + "AUDIO\\mf3_b.WAV", + "AUDIO\\mf3_b1.WAV", + "AUDIO\\mf3_c.WAV", + "AUDIO\\mf4_a.WAV", + "AUDIO\\mf4_b.WAV", + "AUDIO\\mf4_c.WAV", + "AUDIO\\a1_a.WAV", + "AUDIO\\a3_a.WAV", + "AUDIO\\a5_a.WAV", + "AUDIO\\a4_a.WAV", + "AUDIO\\a4_b.WAV", + "AUDIO\\a4_c.WAV", + "AUDIO\\a4_d.WAV", + "AUDIO\\k1_a.WAV", + "AUDIO\\k3_a.WAV", + "AUDIO\\r1_a.WAV", + "AUDIO\\r2_a.WAV", + "AUDIO\\r2_b.WAV", + "AUDIO\\r2_c.WAV", + "AUDIO\\r2_d.WAV", + "AUDIO\\r2_e.WAV", + "AUDIO\\r2_f.WAV", + "AUDIO\\r2_g.WAV", + "AUDIO\\r2_h.WAV", + "AUDIO\\r5_a.WAV", + "AUDIO\\r6_a.WAV", + "AUDIO\\r6_a1.WAV", + "AUDIO\\r6_b.WAV", + "AUDIO\\lo2_a.WAV", + "AUDIO\\lo6_a.WAV", + "AUDIO\\yd2_a.WAV", + "AUDIO\\yd2_b.WAV", + "AUDIO\\yd2_c.WAV", + "AUDIO\\yd2_c1.WAV", + "AUDIO\\yd2_d.WAV", + "AUDIO\\yd2_e.WAV", + "AUDIO\\yd2_f.WAV", + "AUDIO\\yd2_g.WAV", + "AUDIO\\yd2_h.WAV", + "AUDIO\\yd2_ass.WAV", + "AUDIO\\yd2_ok.WAV", + "AUDIO\\h5_a.WAV", + "AUDIO\\h5_b.WAV", + "AUDIO\\h5_c.WAV", + "AUDIO\\ammu_a.WAV", + "AUDIO\\ammu_b.WAV", + "AUDIO\\ammu_c.WAV", + "AUDIO\\door_1.WAV", + "AUDIO\\door_2.WAV", + "AUDIO\\door_3.WAV", + "AUDIO\\door_4.WAV", + "AUDIO\\door_5.WAV", + "AUDIO\\door_6.WAV", + "AUDIO\\t3_a.WAV", + "AUDIO\\t3_b.WAV", + "AUDIO\\t3_c.WAV", + "AUDIO\\k1_b.WAV", + "AUDIO\\cat1.WAV" +}; diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/sampman_miles.cpp index f3a6ba80..caf2917f 100644 --- a/src/audio/miles/sampman_mss.cpp +++ b/src/audio/sampman_miles.cpp @@ -1,3 +1,6 @@ +#include "common.h" + +#ifdef AUDIO_MSS #include <windows.h> #include <shobjidl.h> #include <shlguid.h> @@ -8,7 +11,7 @@ #include "eax-util.h" #include "mss.h" -#include "sampman_mss.h" +#include "sampman.h" #include "AudioManager.h" #include "MusicManager.h" #include "Frontend.h" @@ -18,7 +21,7 @@ #pragma comment( lib, "mss32.lib" ) cSampleManager SampleManager; -int32 BankStartOffset[MAX_SAMPLEBANKS]; +uint32 BankStartOffset[MAX_SAMPLEBANKS]; /////////////////////////////////////////////////////////////// char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; @@ -55,9 +58,9 @@ struct tMP3Entry uint32 nNumMP3s; tMP3Entry *_pMP3List; char _mp3DirectoryPath[MAX_PATH]; -HSTREAM mp3Stream [MAX_MP3STREAMS]; -int8 nStreamPan [MAX_MP3STREAMS]; -int8 nStreamVolume[MAX_MP3STREAMS]; +HSTREAM mp3Stream [MAX_STREAMS]; +int8 nStreamPan [MAX_STREAMS]; +int8 nStreamVolume[MAX_STREAMS]; uint32 _CurMP3Index; int32 _CurMP3Pos; bool _bIsMp3Active; @@ -261,6 +264,17 @@ set_new_provider(S32 index) return false; } +cSampleManager::cSampleManager(void) : + m_nNumberOfProviders(0) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + void cSampleManager::SetSpeakerConfig(int32 which) { @@ -296,6 +310,26 @@ cSampleManager::GetMaximumSupportedChannels(void) return _maxSamples; } +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return m_nNumberOfProviders; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + m_nNumberOfProviders = num; +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + return m_aAudioProviders[id]; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + m_aAudioProviders[id] = name; +} + int8 cSampleManager::GetCurrent3DProviderIndex(void) { @@ -1084,7 +1118,7 @@ cSampleManager::Initialise(void) TRACE("stream"); { - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) + for ( int32 i = 0; i < MAX_STREAMS; i++ ) { mp3Stream [i] = NULL; nStreamPan [i] = 63; @@ -1199,7 +1233,7 @@ cSampleManager::Initialise(void) void cSampleManager::Terminate(void) { - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) + for ( int32 i = 0; i < MAX_STREAMS; i++ ) { if ( mp3Stream[i] ) { @@ -1366,6 +1400,12 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume) m_nMusicFadeVolume = nVolume; } +void +cSampleManager::SetMonoMode(uint8 nMode) +{ + m_nMonoMode = nMode; +} + bool cSampleManager::LoadSampleBank(uint8 nBank) { @@ -1476,6 +1516,18 @@ cSampleManager::LoadPedComment(uint32 nComment) } int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + if ( offset >= BankStartOffset[SAMPLEBANK_PED] ) + return SAMPLEBANK_PED; + + if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] ) + return SAMPLEBANK_MAIN; + + return SAMPLEBANK_INVALID; +} + +int32 cSampleManager::GetSampleBaseFrequency(uint32 nSample) { return m_aSamples[nSample].nFrequency; @@ -1664,7 +1716,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) OutputDebugString(AIL_last_error()); return false; } - + return true; } } @@ -2255,3 +2307,5 @@ cSampleManager::InitialiseSampleBanks(void) return true; } + +#endif
\ No newline at end of file diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp new file mode 100644 index 00000000..bbaeae4c --- /dev/null +++ b/src/audio/sampman_oal.cpp @@ -0,0 +1,1404 @@ +#include "common.h" +//#define JUICY_OAL + +#ifdef AUDIO_OAL +#include "sampman.h" + +#include <time.h> +#include <io.h> + +#include "eax.h" +#include "eax-util.h" + +#include <AL/al.h> +#include <AL/alc.h> +#include <AL/alext.h> +#include <AL/efx.h> +#include <AL/efx-presets.h> + +#include "oal/oal_utils.h" +#include "oal/aldlist.h" +#include "oal/channel.h" +#include "oal/stream.h" + +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" + +//TODO: fix eax3 reverb +//TODO: max channals +//TODO: loop count +//TODO: mp3 player + +#pragma comment( lib, "OpenAL32.lib" ) + +cSampleManager SampleManager; +bool _bSampmanInitialised = false; + +uint32 BankStartOffset[MAX_SAMPLEBANKS]; + +int prevprovider=-1; +int curprovider=-1; +int usingEAX=0; +int usingEAX3=0; +//int speaker_type=0; +ALCdevice *ALDevice = NULL; +ALCcontext *ALContext = NULL; +unsigned int _maxSamples; +float _fPrevEaxRatioDestination; +bool _usingEFX; +float _fEffectsLevel; +ALuint ALEffect = AL_EFFECT_NULL; +ALuint ALEffectSlot = AL_EFFECTSLOT_NULL; +struct +{ + char id[256]; + char name[256]; + int sources; +}providers[MAXPROVIDERS]; + +int defaultProvider; + + +char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; +char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; + +FILE *fpSampleDescHandle; +FILE *fpSampleDataHandle; +bool bSampleBankLoaded [MAX_SAMPLEBANKS]; +int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; +int32 nSampleBankSize [MAX_SAMPLEBANKS]; +int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; +int32 _nSampleDataEndOffset; + +int32 nPedSlotSfx [MAX_PEDSFX]; +int32 nPedSlotSfxAddr[MAX_PEDSFX]; +uint8 nCurrentPedSlot; + +ALuint pedBuffers[MAX_PEDSFX]; + +CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS]; +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; +ALuint ALStreamSources[MAX_STREAMS]; +ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS]; +struct +{ + ALuint buffer; + ALuint timer; + + bool IsEmpty() { return timer == 0; } + void Set(ALuint buf) { buffer = buf; } + void Wait() { timer = 10000; } + void Init() + { + buffer = 0; + timer = 0; + } + void Term() + { + if ( buffer != 0 && alIsBuffer(buffer) ) + alDeleteBuffers(1, &buffer); + timer = 0; + } + void Update() + { + if ( !(timer > 0) ) return; + timer -= ALuint(CTimer::GetTimeStepInMilliseconds()); + if ( timer > 0 ) return; + if ( buffer != 0 && alIsBuffer(buffer) ) + { + alDeleteBuffers(1, &buffer); + timer = ( alGetError() == AL_NO_ERROR ) ? 0 : 10000; + } + } +}ALBuffers[SAMPLEBANK_MAX]; + +uint32 nNumMP3s; +CStream *aStream[MAX_STREAMS]; +uint8 nStreamPan [MAX_STREAMS]; +uint8 nStreamVolume[MAX_STREAMS]; + +/////////////////////////////////////////////////////////////// +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS +EAXLISTENERPROPERTIES StartEAX3 = + {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; + +EAXLISTENERPROPERTIES FinishEAX3 = + {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; + +EAXLISTENERPROPERTIES EAX3Params; + + +bool IsFXSupported() +{ + return usingEAX || usingEAX3 || _usingEFX; +} + +void EAX_SetAll(const EAXLISTENERPROPERTIES *allparameters) +{ + if ( usingEAX || usingEAX3 ) + EAX3_Set(ALEffect, allparameters); + else + EFX_Set(ALEffect, allparameters); +} + +static void +add_providers() +{ + SampleManager.SetNum3DProvidersAvailable(0); + + ALDeviceList *pDeviceList = NULL; + pDeviceList = new ALDeviceList(); + + if ((pDeviceList) && (pDeviceList->GetNumDevices())) + { + const int devNumber = Min(pDeviceList->GetNumDevices(), MAXPROVIDERS); + int n = 0; + + for (int i = 0; i < devNumber; i++) + { + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + + if ( alGetEnumValue("AL_EFFECT_EAXREVERB") != 0 + || pDeviceList->IsExtensionSupported(i, "EAX2.0") + || pDeviceList->IsExtensionSupported(i, "EAX3.0") + || pDeviceList->IsExtensionSupported(i, "EAX4.0") + || pDeviceList->IsExtensionSupported(i, "EAX5.0") ) + { + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + strcat(providers[n].name, " EAX"); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + + if ( n < MAXPROVIDERS ) + { + strcpy(providers[n].id, pDeviceList->GetDeviceName(i)); + strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name)); + strcat(providers[n].name, " EAX3"); + providers[n].sources = pDeviceList->GetMaxNumSources(i); + SampleManager.Set3DProviderName(n, providers[n].name); + n++; + } + } + } + SampleManager.SetNum3DProvidersAvailable(n); + + for(int j=n;j<MAXPROVIDERS;j++) + SampleManager.Set3DProviderName(j, NULL); + + defaultProvider = pDeviceList->GetDefaultDevice(); + if ( defaultProvider > MAXPROVIDERS ) + defaultProvider = 0; + } + + delete pDeviceList; +} + +static void +release_existing() +{ + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].Term(); + aChannel[CHANNEL2D].Term(); + + if ( IsFXSupported() ) + { + if ( alIsEffect(ALEffect) ) + { + alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL); + alDeleteEffects(1, &ALEffect); + ALEffect = AL_EFFECT_NULL; + } + + if (alIsAuxiliaryEffectSlot(ALEffectSlot)) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL); + + alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot); + ALEffectSlot = AL_EFFECTSLOT_NULL; + } + } + + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + CStream *stream = aStream[i]; + if (stream) + stream->ProviderTerm(); + + alDeleteSources(1, &ALStreamSources[i]); + alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + } + + alDeleteBuffers(MAX_PEDSFX, pedBuffers); + + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + ALBuffers[i].Term(); + } + + if ( ALContext ) + { + alcMakeContextCurrent(NULL); + alcSuspendContext(ALContext); + alcDestroyContext(ALContext); + } + if ( ALDevice ) + alcCloseDevice(ALDevice); + + ALDevice = NULL; + ALContext = NULL; + + _fPrevEaxRatioDestination = 0.0f; + _usingEFX = false; + _fEffectsLevel = 0.0f; + + DEV("release_existing()\n"); +} + +static bool +set_new_provider(int index) +{ + if ( curprovider == index ) + return true; + + curprovider = index; + + release_existing(); + + if ( curprovider != -1 ) + { + DEV("set_new_provider()\n"); + + //TODO: + _maxSamples = MAXCHANNELS; + + ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; + + ALDevice = alcOpenDevice(providers[index].id); + ASSERT(ALDevice != NULL); + + ALContext = alcCreateContext(ALDevice, attr); + ASSERT(ALContext != NULL); + + alcMakeContextCurrent(ALContext); + + const char* ext=(const char*)alGetString(AL_EXTENSIONS); + ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL); + if ( strstr(ext,"AL_SOFT_loop_points")==NULL ) + { + curprovider=-1; + release_existing(); + return false; + } + + alListenerf (AL_GAIN, 1.0f); + alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); + alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f); + ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; + alListenerfv(AL_ORIENTATION, orientation); + + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); + + if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + alGenAuxiliaryEffectSlots(1, &ALEffectSlot); + alGenEffects(1, &ALEffect); + } + + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + alGenSources(1, &ALStreamSources[i]); + alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + + CStream *stream = aStream[i]; + if (stream) + stream->ProviderInit(); + } + + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + ALBuffers[i].Init(); + } + + alGenBuffers(MAX_PEDSFX, pedBuffers); + + usingEAX = 0; + usingEAX3 = 0; + _usingEFX = false; + + if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3") + && alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + EAX_SetAll(&FinishEAX3); + + usingEAX = 1; + usingEAX3 = 1; + + DEV("EAX3\n"); + } + else if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) ) + { + EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]); + + if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX")], " EAX")) + { + usingEAX = 1; + DEV("EAX1\n"); + } + else + { + _usingEFX = true; + DEV("EFX\n"); + } + } + + //SampleManager.SetSpeakerConfig(speaker_type); + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].Init(); + aChannel[CHANNEL2D].Init(true); + + if ( IsFXSupported() ) + { + /**/ + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + /**/ + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].SetReverbMix(ALEffectSlot, 0.0f); + } + + return true; + } + + return false; +} + +cSampleManager::cSampleManager(void) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void cSampleManager::SetSpeakerConfig(int32 nConfig) +{ + +} + +uint32 cSampleManager::GetMaximumSupportedChannels(void) +{ + if ( _maxSamples > MAXCHANNELS ) + return MAXCHANNELS; + + return _maxSamples; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return m_nNumberOfProviders; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + m_nNumberOfProviders = num; +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + return m_aAudioProviders[id]; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + m_aAudioProviders[id] = name; +} + +int8 cSampleManager::GetCurrent3DProviderIndex(void) +{ + return curprovider; +} + +int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + ASSERT( nProvider < m_nNumberOfProviders ); + int savedprovider = curprovider; + + if ( nProvider < m_nNumberOfProviders ) + { + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; + else + return -1; + } + else + return curprovider; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + + +void cSampleManager::ReleaseDigitalHandle(void) +{ + if ( ALDevice ) + { + prevprovider = curprovider; + release_existing(); + curprovider = -1; + } +} + +void cSampleManager::ReacquireDigitalHandle(void) +{ + if ( ALDevice ) + { + if ( prevprovider != -1 ) + set_new_provider(prevprovider); + } +} + +bool +cSampleManager::Initialise(void) +{ + if ( _bSampmanInitialised ) + return true; + + EFXInit(); + CStream::Initialise(); + + { + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = MAX_FREQ; + m_aSamples[i].nLoopStart = 0; + m_aSamples[i].nLoopEnd = -1; + } + + m_nEffectsVolume = MAX_VOLUME; + m_nMusicVolume = MAX_VOLUME; + m_nEffectsFadeVolume = MAX_VOLUME; + m_nMusicFadeVolume = MAX_VOLUME; + + m_nMonoMode = 0; + } + + { + curprovider = -1; + prevprovider = -1; + + _usingEFX = false; + usingEAX =0; + usingEAX3=0; + + _fEffectsLevel = 0.0f; + + _maxSamples = 0; + + ALDevice = NULL; + ALContext = NULL; + } + + { + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + } + + { + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + } + + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + nChannelVolume[i] = 0; + } + + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + aStream[i] = NULL; + nStreamVolume[i] = 100; + nStreamPan[i] = 63; + } + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + nStreamLength[i] = 0; + } + + { + add_providers(); + + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]); + ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL); + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX); + ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL); + } + + + { + _bSampmanInitialised = true; + + if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders ) + { + set_new_provider(defaultProvider); + } + else + { + Terminate(); + return false; + } + } + + { + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + + if ( aStream[0] && aStream[0]->IsOpened() ) + { + uint32 tatalms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + } + } + + LoadSampleBank(SAMPLEBANK_MAIN); + + return true; +} + +void +cSampleManager::Terminate(void) +{ + release_existing(); + + for (int32 i = 0; i < MAX_STREAMS; i++) + { + CStream *stream = aStream[i]; + if (stream) + { + delete stream; + aStream[i] = NULL; + } + } + + CStream::Terminate(); + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 ) + { + free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]); + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0; + } + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 ) + { + free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0; + } + + _bSampmanInitialised = false; +} + +void +cSampleManager::UpdateSoundBuffers(void) +{ + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + ALBuffers[i].Update(); + } +} + +bool cSampleManager::CheckForAnAudioFileOnCD(void) +{ + return true; +} + +char cSampleManager::GetCDAudioDriveLetter(void) +{ + return '\0'; +} + +void +cSampleManager::UpdateEffectsVolume(void) +{ + if ( _bSampmanInitialised ) + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( GetChannelUsedFlag(i) ) + { + if ( nChannelVolume[i] != 0 ) + aChannel[i].SetVolume(m_nEffectsFadeVolume*nChannelVolume[i]*m_nEffectsVolume >> 14); + } + } + } +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ + m_nEffectsVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ + m_nMusicVolume = nVolume; +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ + m_nEffectsFadeVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ + m_nMusicFadeVolume = nVolume; +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ + m_nMonoMode = nMode; +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + if ( CTimer::GetIsCodePaused() ) + return false; + + if ( MusicManager.IsInitialised() + && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && nBank != SAMPLEBANK_MAIN ) + { + return false; + } + + if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + return false; + + if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] ) + return false; + + bSampleBankLoaded[nBank] = true; + + return true; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + bSampleBankLoaded[nBank] = false; +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + return bSampleBankLoaded[nBank]; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + uint8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; + if ( nComment == nPedSlotSfx[slot] ) + return true; + } + + return false; +} + + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + uint8 slot; + + for (int32 i = 0; i < _TODOCONST(3); i++) + { + slot = nCurrentPedSlot - i - 1; + if (nComment == nPedSlotSfx[slot]) + return slot; + } + + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + if ( CTimer::GetIsCodePaused() ) + return false; + + // no talking peds during cutsenes or the game end + if ( MusicManager.IsInitialised() ) + { + switch ( MusicManager.GetMusicMode() ) + { + case MUSICMODE_CUTSCENE: + { + return false; + + break; + } + + case MUSICMODE_FRONTEND: + { + if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED ) + return false; + + break; + } + } + } + + if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) + return false; + + if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) + return false; + + nPedSlotSfx[nCurrentPedSlot] = nComment; + + alBufferData(pedBuffers[nCurrentPedSlot], + AL_FORMAT_MONO16, + (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), + m_aSamples[nComment].nSize, + m_aSamples[nComment].nFrequency); + + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) + nCurrentPedSlot = 0; + + return true; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + if ( offset >= BankStartOffset[SAMPLEBANK_PED] ) + return SAMPLEBANK_PED; + + if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] ) + return SAMPLEBANK_MAIN; + + return SAMPLEBANK_INVALID; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nSize / sizeof(uint16); +} + +bool cSampleManager::UpdateReverb(void) +{ + if ( !usingEAX && !_usingEFX ) + return false; + + if ( AudioManager.GetFrameCounter() & 15 ) + return false; + + float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); + float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); + float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); + + float normy = norm(y, 5.0f, 40.0f); + float normx = norm(x, 5.0f, 40.0f); + float normz = norm(z, 5.0f, 40.0f); + + #define ZR(v, a, b) (((v)==0)?(a):(b)) + #define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val)))) + + float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f); + + #undef CALCRATIO + #undef ZE + + fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + + if ( fRatio == _fPrevEaxRatioDestination ) + return false; + +#ifdef JUICY_OAL + if ( usingEAX3 || _usingEFX ) +#else + if ( usingEAX3 ) +#endif + { + if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) + { + EAX_SetAll(&EAX3Params); + + /* + if ( IsFXSupported() ) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + aChannel[i].UpdateReverb(ALEffectSlot); + } + */ + + _fEffectsLevel = 1.0f - fRatio * 0.5f; + } + } + else + { + if ( _usingEFX ) + _fEffectsLevel = (1.0f - fRatio) * 0.4f; + else + _fEffectsLevel = (1.0f - fRatio) * 0.7f; + } + + _fPrevEaxRatioDestination = fRatio; + + return true; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( usingEAX || _usingEFX ) + { + if ( IsFXSupported() ) + { + alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect); + + if ( nReverbFlag != 0 ) + aChannel[nChannel].SetReverbMix(ALEffectSlot, _fEffectsLevel); + else + aChannel[nChannel].SetReverbMix(ALEffectSlot, 0.0f); + } + } +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + ALuint buffer; + + if ( nSfx < SAMPLEBANK_MAX ) + { + if ( !IsSampleBankLoaded(nBank) ) + return false; + + int32 addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; + + if ( ALBuffers[nSfx].IsEmpty() ) + { + ALuint buf; + alGenBuffers(1, &buf); + alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency); + ALBuffers[nSfx].Set(buf); + } + ALBuffers[nSfx].Wait(); + + buffer = ALBuffers[nSfx].buffer; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + + buffer = pedBuffers[slot]; + } + + if ( buffer == 0 ) + { + TRACE("No buffer to play id %d", nSfx); + return false; + } + + if ( GetChannelUsedFlag(nChannel) ) + { + TRACE("Stopping channel %d - really!!!", nChannel); + StopChannel(nChannel); + } + + aChannel[nChannel].Reset(); + if ( aChannel[nChannel].HasSource() ) + { + aChannel[nChannel].SetSampleID (nSfx); + aChannel[nChannel].SetFreq (m_aSamples[nSfx].nFrequency); + aChannel[nChannel].SetLoopPoints (0, -1); + aChannel[nChannel].SetBuffer (buffer); + aChannel[nChannel].SetPitch (1.0f); + return true; + } + + return false; +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // reduce channel volume when JB.MP3 or S4_BDBD.MP3 playing + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] = vol / 4; + } + + // no idea, does this one looks like a bug or it's SetChannelVolume ? + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetPosition(-fX, fY, fZ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + ASSERT( nChannel != CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + aChannel[nChannel].SetDistances(fMax, fMin); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel == CHANNEL2D ); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nChannel == CHANNEL2D ) + { + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // reduce the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] = vol / 4; + } + + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + ASSERT(nChannel == CHANNEL2D); + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nChannel == CHANNEL2D ) + { + aChannel[nChannel].SetPan(nPan); + } +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetCurrentFreq(nFreq); +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetLoopPoints(nLoopStart / (DIGITALBITS / 8), nLoopEnd / (DIGITALBITS / 8)); +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].SetLoopCount(nLoopCount); +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + return aChannel[nChannel].IsUsed(); +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].Start(); +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + aChannel[nChannel].Stop(); +} + +void +cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) +{ + char filename[256]; + + ASSERT( nStream < MAX_STREAMS ); + + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( aStream[nStream] ) + { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + strcpy(filename, StreamedNameTable[nFile]); + + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + if ( !stream->IsOpened() ) + { + delete stream; + aStream[nStream] = NULL; + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + stream->SetPause(nPauseFlag != 0); + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( stream->Setup() ) + { + stream->Start(); + } + } +} + +bool +cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) +{ + char filename[256]; + + ASSERT( nStream < MAX_STREAMS ); + + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( aStream[nStream] ) + { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + strcpy(filename, StreamedNameTable[nFile]); + + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + + if ( stream->IsOpened() ) + { + nStreamLength[nFile] = stream->GetLengthMS(); + if ( stream->Setup() ) + { + if ( nPos != 0 ) + stream->SetPosMS(nPos); + + stream->Start(); + } + + return true; + } + else + { + delete stream; + aStream[nStream] = NULL; + } + } + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + delete stream; + aStream[nStream] = NULL; + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + return stream->GetPosMS(); + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + if ( nVolume > MAX_VOLUME ) + nVolume = MAX_VOLUME; + + if ( nPan > MAX_VOLUME ) + nPan = MAX_VOLUME; + + nStreamVolume[nStream] = nVolume; + nStreamPan [nStream] = nPan; + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( nEffectFlag ) + stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14); + else + stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14); + + stream->SetPan(nPan); + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); + + return nStreamLength[nStream]; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + CStream *stream = aStream[nStream]; + + if ( stream ) + { + if ( stream->IsPlaying() ) + return true; + } + + return false; +} + +void +cSampleManager::Service(void) +{ + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + CStream *stream = aStream[i]; + + if ( stream ) + stream->Update(); + } + + UpdateSoundBuffers(); +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + int32 nBank = SAMPLEBANK_MAIN; + + fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); + if ( fpSampleDescHandle == NULL ) + return false; + + fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); + if ( fpSampleDataHandle == NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + return false; + } + + fseek(fpSampleDataHandle, 0, SEEK_END); + int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle); + rewind(fpSampleDataHandle); + + fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); + + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { +#ifdef FIX_BUGS + if (nBank >= MAX_SAMPLEBANKS) break; +#endif + if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i ) + { + nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; + nBank++; + } + } + + nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN]; + nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED]; + + return true; +} + +#endif
\ No newline at end of file diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 969e0cdf..c50471f1 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -220,22 +220,9 @@ bool CGame::InitialiseOnceAfterRW(void) if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 ) { CMenuManager::m_PrefsSpeakers = 0; - - for ( int32 i = 0; i < DMAudio.GetNum3DProvidersAvailable(); i++ ) - { - wchar buff[64]; - - char *name = DMAudio.Get3DProviderName(i); - AsciiToUnicode(name, buff); - char *providername = UnicodeToAscii(buff); - strupr(providername); - - if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") ) - { - FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = i; - break; - } - } + int8 provider = DMAudio.AutoDetect3DProviders(); + if ( provider != -1 ) + FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider; } DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); diff --git a/src/core/common.h b/src/core/common.h index 41773877..f79b199b 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -212,6 +212,7 @@ void mysrand(unsigned int seed); void re3_debug(const char *format, ...); void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...); void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func); +void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); @@ -219,6 +220,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) #define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) +#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) #define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) ) #define ASSERT assert diff --git a/src/core/config.h b/src/core/config.h index 20e5d679..ae30b539 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -198,7 +198,8 @@ enum Config { #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number //#define USE_TEXTURE_POOL -//#define OPENAL +//#define AUDIO_OAL +#define AUDIO_MSS // Particle //#define PC_PARTICLE diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 2c07836a..0ab32999 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -462,6 +462,20 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons OutputDebugStringA(buff); } +void re3_usererror(const char *format, ...) +{ + va_list va; + va_start(va, format); + vsprintf_s(re3_buff, re3_buffsize, format, va); + va_end(va); + + ::MessageBoxA(nil, re3_buff, "RE3 Error!", + MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); + + raise(SIGABRT); + _exit(3); +} + #ifdef VALIDATE_SAVE_SIZE int32 _saveBufCount; #endif |